A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang="fr">
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset="utf-8">
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name="viewport" content="width=device-width,initial-scale=1">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>App Assisted Contact Tracing (archive) — David Larlet</title>
  13. <!-- That good ol' feed, subscribe :). -->
  14. <link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/">
  15. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  16. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png">
  17. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png">
  18. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png">
  19. <link rel="manifest" href="/static/david/icons2/site.webmanifest">
  20. <link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c">
  21. <link rel="shortcut icon" href="/static/david/icons2/favicon.ico">
  22. <meta name="msapplication-TileColor" content="#f0f0ea">
  23. <meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- Documented, feel free to shoot an email. -->
  26. <link rel="stylesheet" href="/static/david/css/style_2020-06-19.css">
  27. <!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. -->
  28. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  29. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  30. <link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin>
  31. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  32. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  33. <link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin>
  34. <script type="text/javascript">
  35. function toggleTheme(themeName) {
  36. document.documentElement.classList.toggle(
  37. 'forced-dark',
  38. themeName === 'dark'
  39. )
  40. document.documentElement.classList.toggle(
  41. 'forced-light',
  42. themeName === 'light'
  43. )
  44. }
  45. const selectedTheme = localStorage.getItem('theme')
  46. if (selectedTheme !== 'undefined') {
  47. toggleTheme(selectedTheme)
  48. }
  49. </script>
  50. <meta name="robots" content="noindex, nofollow">
  51. <meta content="origin-when-cross-origin" name="referrer">
  52. <!-- Canonical URL for SEO purposes -->
  53. <link rel="canonical" href="https://lucumr.pocoo.org/2020/4/3/contact-tracing/">
  54. <body class="remarkdown h1-underline h2-underline h3-underline hr-center ul-star pre-tick">
  55. <article>
  56. <h1>App Assisted Contact Tracing</h1>
  57. <nav>
  58. <p class="center">
  59. <a href="/david/" title="Aller à l’accueil" tabindex="1">🏠</a>
  60. </p>
  61. </nav>
  62. <hr>
  63. <h2><a href="https://lucumr.pocoo.org/2020/4/3/contact-tracing/">Source originale du contenu</a></h2>
  64. <p class=date>written on Friday, April 3, 2020
  65. <p>I don't know how I thought the world would look like 10 years ago, but a
  66. pandemic that prevents us from going outside was not what I was picturing.
  67. It's about three weeks now that I and my family are spending at home in
  68. Austria instead of going to work or having the kids at daycare, two of
  69. those weeks were under mandatory social distancing because of SARS-CoV-2.</p>
  70. <p>And as cute as <a class="reference external" href="https://en.wikipedia.org/wiki/Social_distancing">social distancing</a>
  71. and “flattening the curve” sounds at first, the consequences to our daily
  72. lives are beyond anything I could have imagined would happen in my
  73. lifetime.</p>
  74. <p>What is still conveniently forgotten is that the curve really only stays
  75. flat if we're doing this for a very, very long time. And quite frankly,
  76. I'm not sure for how long our society will be able to do this. Even just
  77. closing restaurants is costing tens of thousands of jobs and closing
  78. schools is going to set back the lives of many children growing up. Many
  79. people are currently separated from their loved ones with no easy way to
  80. get to them because international travel grinded to a halt.</p>
  81. <div class="section" id="technology-to-the-rescue">
  82. <h2>Technology to the Rescue</h2>
  83. <p>So to cut a very long story short: we can get away without social
  84. distancing with the help of technology. This is why: the most efficient
  85. way to fight the outbreak of a pandemic is isolating cases. If you can
  86. catch them before they can infect others you can starve the virus. Now
  87. the issue with this is obviously that you have people running around with
  88. the virus who can infect others but are not symptomatic. So we can only
  89. do the second next best thing: if we can find all the people they had
  90. contact with when they finally become symptomatic, we can narrow down the
  91. search radius for tests.</p>
  92. <p>So a very successful approach could be:</p>
  93. <ol class="arabic simple">
  94. <li>find a covid-19 suspect</li>
  95. <li>test the person</li>
  96. <li>when they are positive, test all of their close contacts</li>
  97. </ol>
  98. <p>So how do we find their cases? The tool of choice in many countries
  99. already are apps. They send out a beacon signal and collect beacon
  100. signals of other users around. When someone tests positive, healthcare
  101. services can notice contacts.</p>
  102. </div>
  103. <div class="section" id="avoiding-orwell">
  104. <h2>Avoiding Orwell</h2>
  105. <p>Now this is where it gets interesting. Let's take Austria for instance
  106. where I live. We have around 9 million residents here. Let's assume
  107. we're aiming for 60% of resident using that app. That sounds like a
  108. surveillance state and scalability nightmare for a country known for
  109. building scalable apps.</p>
  110. <p>But let's think for a moment what is actually necessary to achieve our
  111. goal: it turns out we could largely achieve what we want without a
  112. centralized infrastructure.</p>
  113. <p>Let's set the window of people we care about to something like 5 days.
  114. This means that if someone tests positive, that person's contacts of the
  115. last 5 days ideally get informed about a covid case they had contact with.
  116. How do we design such a system that it's not a privacy invading behemoth?</p>
  117. <p>The app upon installation would roll a random ID and store it. Then it
  118. encrypts the ID it just created with the public key of a central
  119. governmental authority and broadcasts it to other people around via
  120. bluetooth. It then cycles this ID in regular intervals.</p>
  121. <p>When another device (the infected person) sees this ID it measures signal
  122. strength and time observed. When enough time was spent with the other
  123. person and that contact was “close enough” it records the broadcast
  124. (encrypted ID) on the device. The device also just deletes records older
  125. than 5 days.</p>
  126. <p>When person is identified as infected they need to export the contacts
  127. from their app and send it to the health ministry. They could use their
  128. private key to decrypt the IDs and then get in contact with the
  129. potential contacts.</p>
  130. <p>How do they do that? One option does involve a system like a push
  131. notification service. That would obviously require the device to register
  132. their unique ID with a central server and a push notification channel but
  133. this would not reveal much.</p>
  134. <p>Another option could be to do the check in manually which would work for
  135. non connected IoT type of solutions. You could implement such a system as
  136. a token you need to regularly bring to a place to check if you are now
  137. considered a contact person. For instance one could deploy check-in
  138. stations at public transport hubs where you hold your token against and if
  139. one of your contacts was infected it would beep.</p>
  140. <p>Either way the central authority would not know who you are. Your only
  141. point of contact would be when you become a covid case. Most importantly
  142. this system could be created in a way where it's completely useless for
  143. tracking people but still be useful for contact tracing.</p>
  144. </div>
  145. <div class="section" id="the-phone-in-your-pocket">
  146. <h2>The Phone in your Pocket</h2>
  147. <p>I had conversations with a lot of people over the last few days about
  148. contact tracing apps and I noticed —&nbsp;particularly from technically minded
  149. people — an aversion against the idea of contact tracing via apps. This
  150. does not surprise me, because it's an emotional topic. However it does
  151. hammer home a point that people are very good at misjudging data privacy.</p>
  152. <p>Almost every person I know uses Google maps on their phone with location
  153. history enabled. With that, they also participate in a large data
  154. collection project where their location is constantly being transmitted to
  155. Google. They use this information to judge how fluid traffic is on the
  156. road, how many people are at stores, how busy public transit is etc. All
  157. that data is highly valuable and people love to use this data. I know I
  158. do. I'm also apparently entirely okay with that, even though I know there
  159. is an associated risk.</p>
  160. </div>
  161. <div class="section" id="the-future">
  162. <h2>The Future</h2>
  163. <p>My point here is a simple one: contact tracing if done well is
  164. significantly less privacy infringing than what many tech companies
  165. already do where we're okay with.</p>
  166. <p>I also believe that contact tracing via apps or hardware tokens is our
  167. best chance to return to a largely normal life without giving up all our
  168. civil liberties. I really hope that we're going to have informed and
  169. reasonable technical discussions about how to do contact tracing right and
  170. give this a fair chance.</p>
  171. </div>
  172. </article>
  173. <hr>
  174. <footer>
  175. <p>
  176. <a href="/david/" title="Aller à l’accueil">🏠</a> •
  177. <a href="/david/log/" title="Accès au flux RSS">🤖</a> •
  178. <a href="http://larlet.com" title="Go to my English profile" data-instant>🇨🇦</a> •
  179. <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">📮</a> •
  180. <abbr title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340">🧚</abbr>
  181. </p>
  182. <template id="theme-selector">
  183. <form>
  184. <fieldset>
  185. <legend>Thème</legend>
  186. <label>
  187. <input type="radio" value="auto" name="chosen-color-scheme" checked> Auto
  188. </label>
  189. <label>
  190. <input type="radio" value="dark" name="chosen-color-scheme"> Foncé
  191. </label>
  192. <label>
  193. <input type="radio" value="light" name="chosen-color-scheme"> Clair
  194. </label>
  195. </fieldset>
  196. </form>
  197. </template>
  198. </footer>
  199. <script src="/static/david/js/instantpage-3.0.0.min.js" type="module" defer></script>
  200. <script type="text/javascript">
  201. function loadThemeForm(templateName) {
  202. const themeSelectorTemplate = document.querySelector(templateName)
  203. const form = themeSelectorTemplate.content.firstElementChild
  204. themeSelectorTemplate.replaceWith(form)
  205. form.addEventListener('change', (e) => {
  206. const chosenColorScheme = e.target.value
  207. localStorage.setItem('theme', chosenColorScheme)
  208. toggleTheme(chosenColorScheme)
  209. })
  210. const selectedTheme = localStorage.getItem('theme')
  211. if (selectedTheme && selectedTheme !== 'undefined') {
  212. form.querySelector(`[value="${selectedTheme}"]`).checked = true
  213. }
  214. }
  215. const prefersColorSchemeDark = '(prefers-color-scheme: dark)'
  216. window.addEventListener('load', () => {
  217. let hasDarkRules = false
  218. for (const styleSheet of Array.from(document.styleSheets)) {
  219. let mediaRules = []
  220. for (const cssRule of styleSheet.cssRules) {
  221. if (cssRule.type !== CSSRule.MEDIA_RULE) {
  222. continue
  223. }
  224. // WARNING: Safari does not have/supports `conditionText`.
  225. if (cssRule.conditionText) {
  226. if (cssRule.conditionText !== prefersColorSchemeDark) {
  227. continue
  228. }
  229. } else {
  230. if (cssRule.cssText.startsWith(prefersColorSchemeDark)) {
  231. continue
  232. }
  233. }
  234. mediaRules = mediaRules.concat(Array.from(cssRule.cssRules))
  235. }
  236. // WARNING: do not try to insert a Rule to a styleSheet you are
  237. // currently iterating on, otherwise the browser will be stuck
  238. // in a infinite loop…
  239. for (const mediaRule of mediaRules) {
  240. styleSheet.insertRule(mediaRule.cssText)
  241. hasDarkRules = true
  242. }
  243. }
  244. if (hasDarkRules) {
  245. loadThemeForm('#theme-selector')
  246. }
  247. })
  248. </script>
  249. </body>
  250. </html>