{
    "componentChunkName": "component---src-templates-blog-tsx",
    "path": "/blog/2022/SafeInternetSurfing",
    "result": {"data":{"markdownRemark":{"frontmatter":{"author":"lhzbxx","classify":"科普","date":"2022 年 01 月 14 日","title":"网上冲浪安全指南：怎样保护账号安全"},"html":"<p>在互联网构建的数字世界中，我们在不同的公共社区、论坛和私人领土都有一个属于自己的数字身份。每个人当然都不愿意身份被盗用或者信息被泄露，但总会有不法之徒试图破坏秩序，造成难以估量的损失。那么，在享受网上冲浪便利的同时，我们有哪些手段可以保障我们的信息安全呢？</p>\n<!-- endexcerpt -->\n<h3>前提</h3>\n<p>本文仅从使用者角度出发，谈论信息泄露的防范措施，但无法杜绝系统本身的安全性问题。不管你的汽车做了多少层措施以减少意外伤害，请不要在危险道路上行驶。<strong>信息安全的一个重要前提是，远离脆弱的信息系统。</strong></p>\n<p>如果你无法识别系统的安全性，请至少不要在不知名的网站或移动应用中留下你的隐私信息。如果需要进一步核实，这两个网站能够帮到你：<a href=\"https://www.similarweb.com/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Similar Web</a> 和 <a href=\"https://urlscan.io/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">urlscan</a>。</p>\n<p>还有三点老生常谈的事项，在此反复提醒一下：</p>\n<ul>\n<li>请用正版的操作系统</li>\n<li>杜绝盗版软件、流氓软件</li>\n<li>照片共享到社交媒体前移除位置和隐私数据</li>\n</ul>\n<p>进一步的，有些危险的行为习惯也需要警惕：</p>\n<ul>\n<li>远离公共 WiFi 网络，如果一定要用，请用 VPN</li>\n<li>不要点击陌生的链接（来自短信、邮件或者其他通讯工具）</li>\n</ul>\n<h3>从黑客角度出发</h3>\n<p>当我们谈及信息安全的时候，本质上就是防御黑客行为。</p>\n<p>而从黑客角度来说，你的头像、ID、快递单号、习惯用语、购买记录、宠物……都会成为泄密的渠道。而本文谈及的安全指南仅限于防范数字生活中的财产损失，而非保护个人隐私问题（其实绝大部分人也不需要做到数字身份的隔离）。</p>\n<p>此外，黑客在施展攻击时，并不在意对方账户有多少余额，他们有很多种方式从中牟利。</p>\n<p>从一个宏观的角度去思考该问题，畅想一下未来：<u>当下 Web 3.0 的口号越来越响亮，我们拥有的数字资产并不一定只是有形资产的证明，社交、兴趣、信用、虚拟形象这些无形资产也会 token 化。随着数字世界与其承载的资产扩张，其相应的安全产业自然也会随之升级。网络攻防会以令人意想不到的方式随时发生。</u></p>\n<p>让我们回到当下。</p>\n<p>当前互联网存在的信息系统依旧普遍采用账号系统做身份认证，保护个人信息安全其实也就是保护账号安全。接下来介绍的工具，能够做到非常简单而有效地保护个人的账号安全。</p>\n<h3>第一层：密码管理器</h3>\n<p>你至少需要做到：</p>\n<ol>\n<li>抛弃简单的或重复的密码</li>\n<li>拥有一个合格的密码管理器</li>\n</ol>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 740px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/eefe9d8c61eff800ba25e83d23911a9a/50383/password_strength.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 81.25%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAIAAACZeshMAAAACXBIWXMAAAxOAAAMTgF/d4wjAAAC00lEQVQozz2SWXKzOhBG2f9SsoCk4uQG4niKBzAGMRmLGQkhkI0w4CHh1m+qch5U/dKl/k63EIZhmqaapqmqGgQBISRJEs55kiSqqs5mM0VRNE0zDGO73a7X69VqNR6PN5tNHMdC0zRlWX58fIxGoyiKKKWj0YhSWpZlGIaMsfP5fL/fGWOGYex2O13Xl8ulpmmXy0VACJ1OJwih7/uc87ZtD4dD13VlWUZRxDnvuu50OlFKTdM0DENV1SiKIISEEAFCqGmabdsAgN1u5zjOcrn8+fkpy/JwOGw2G1EUAQBZlgVBkCSJ53lt27quez6fBU3TMMYAgNls5nne5XKBEMZxjBB6f39/eXmRJEkUxa+vr67r+r7//f3t+x4hdL1eBd/3m6aRZXm1Wg0R9vu9bdtpmuq6rijKkNPzvCiKwjBMksRxHNM00zQVRFGcTqeLxWIymWCMi6IYOtM05ZxbljWfz8/nc57nhBDO+ff393Q6PR6PVVUJjuOkaRpFURAEg+3iQRzHEEL3geM4tm17nuf7PgBgv98XRUEpFaqq+ksyvAOEkDiOh1ERQlmWWZYly7IkSZRShNDtdhNkWTZNU32w3W4Xi4VhGPP5XNd1QghjjFLadV1RFE9PT6Zp+g9kWc7zXPA8jxCS53mapsO0GOMgCAY3GGOEEGMsyzIAAGNMkiSMsaIoh8NBKMuybduu6xhjbdvWdd11Xdu2RVGEYQgAWK1WhmFkWcYYwxiLosgY45wHQSCcTqe+77Msm81m8/l8s9ncbre+7ymlw6nneY4xHvwjhKqqIoTYtg0h/Pdz3/dt23LOr9dr0zSDsKIo8jy3LEsURfzgeDyGYTidTsfjseu6dV3/a+acN02TZZmqqp7n2Q+2261lWQCAQZ6u667rrtdrCCFCqK7rpmmEvw1VVTUej9/e3l5fXyeTyX8PhuL5+VmSpM/PT0VR7vf73zr/B9wsS7KvupxbAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"来自 XKCD 的漫画\"\n        title=\"来自 XKCD 的漫画\"\n        src=\"/static/eefe9d8c61eff800ba25e83d23911a9a/50383/password_strength.png\"\n        srcset=\"/static/eefe9d8c61eff800ba25e83d23911a9a/804b2/password_strength.png 384w,\n/static/eefe9d8c61eff800ba25e83d23911a9a/50383/password_strength.png 740w\"\n        sizes=\"(max-width: 740px) 100vw, 740px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n        decoding=\"async\"\n      />\n  </a>\n    </span></p>\n<p>绝大多数平台在注册时都会提醒你采用高强度的密码，我的建议是：</p>\n<ul>\n<li>不同平台的密码不要重复，也不要采用同一模式设置</li>\n<li>不要以大众熟悉的元素或流行文化作为参考</li>\n<li>不要在密码中添加与自身关联的信息，如纪念日、亲友名称</li>\n<li>不要仅在首尾添加特殊字符，那样不会让密码更强大</li>\n</ul>\n<p>密码管理器是一个让你一劳永逸的软件，它如同一个保险箱，确保你的密码被安全地储存。同时，这类软件通常都是跨平台的，支持自动填充到网站和应用程序中。而你只需要一把钥匙，即「主密码」，解锁该保险箱。</p>\n<p>常用的密码管理器有 1Password、LastPass、Bitwarden、Enpass、KeePass 等等，如果需要详细了解和比较这类工具的特性，请访问 <a href=\"https://alternativeto.net/category/security/password-manager/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">AlertnativeTo</a>。</p>\n<p>笔者日常使用的是 Bitwarden。Bitwarden 完全免费且开源（支持自行部署服务），支持市面上主流的操作系统和浏览器，也支持保存信用卡、安全问题、TOTP 这类信息。</p>\n<p>这里再小小的科普一下 TOTP (Time-based One-Time Password)，有时被翻译为安全口令。如果你有用过 Steam 或银行的 USB Key 应该就能明白，其本质是在硬件设备上内置一个生成的「种子」，根据时间变化每隔一定周期更新一次的密码轮。它是一个<a href=\"https://tools.ietf.org/html/rfc6238\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">通用标准协议</a>。只要拿到「种子」，密码管理器就能够帮你计算出当前的 OTP (One-Time Password)，就不需要打开特定的应用程序来查看了。</p>\n<h3>第二层：主密码</h3>\n<p>当你拥有了一个坚不可摧的保险箱，那么接下来需要做的事情就是，妥善保管箱子的钥匙，即「主密码」。鉴于主密码的重要性，如果主密码泄露或者遗忘，后果简直是灾难性的。</p>\n<p>想象一下，也许你去了一个缺少现代技术覆盖的小岛远离尘嚣，拥抱大自然了一两个月，在你惬意地晒着阳光吮吸着 X 牌甜美冰饮的时刻，突然记不得自己的主密码是什么了。这下子真的与世隔绝了，恐怕一时之间慌乱得想回到过去抽当初的自己一巴掌。</p>\n<p>为了防止出现这种麻烦事，我们需要一个东西，确保自己的主密码不会被窃取，同时自己也能随时找到它。</p>\n<p>有一个算法叫做 <strong>Shamir's Secret Sharing (SSS)</strong>，是密码学中最古老的保密内容共享方案之一。SSS 技术的基础原理是 Lagrange interpolation theorem（拉格朗日插值定理），出自 Adi Shamir（RSA 算法的发明者之一）的论文<a href=\"https://web.mit.edu/6.857/OldStuff/Fall03/ref/Shamir-HowToShareASecret.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">《How to Share a Secret》</a>。顺便提一下，在 SSS 基础之上增加了校验流程，有一个更强大的构造方案称为 <a href=\"https://www.cs.umd.edu/~gasarch/TOPICS/secretsharing/feldmanVSS.pdf\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Verifiable Secret Sharing (VSS)</a>，是一些共识算法的重要技术。不过保管主密码的话，我们只需要 SSS 就够了。</p>\n<p>SSS 的原理形象的解释是这样子的：</p>\n<p>全球饮料巨头 X 公司有一口特殊的水源让它长盛不衰，它作为核心商业机密藏在一个巨大的保险库里。现在保险库的密码被转换为 n 个铭牌，按照持有的股份发放给 X 公司的高管，其中集齐了 k(k≤n) 个铭牌后，才能解锁该保险库。如此一来，居心叵测的少数高管无法从中谋取私利，不慎被盗取的一两个铭牌也无法发挥作用。</p>\n<p>而具体到数学原理，这里简单介绍一下，是通过构造一个多项式，其中密码被表示为 <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub></mrow><annotation encoding=\"application/x-tex\">a_0</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.5806em;vertical-align:-0.15em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3011em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">0</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span></span></span></span></span> 有限域 <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>G</mi><mi>F</mi><mo stretchy=\"false\">(</mo><mi>q</mi><mo stretchy=\"false\">)</mo></mrow><annotation encoding=\"application/x-tex\">GF(q)</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.13889em;\">GF</span><span class=\"mopen\">(</span><span class=\"mord mathnormal\" style=\"margin-right:0.03588em;\">q</span><span class=\"mclose\">)</span></span></span></span></span>。一个典型的有限域例子是用梅森质数 (<span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><msup><mn>2</mn><mn>251</mn></msup><mo>−</mo><mn>1</mn></mrow><annotation encoding=\"application/x-tex\">2^{251}-1</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.8974em;vertical-align:-0.0833em;\"></span><span class=\"mord\"><span class=\"mord\">2</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8141em;\"><span style=\"top:-3.063em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\">251</span></span></span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">−</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.6444em;\"></span><span class=\"mord\">1</span></span></span></span></span>) 做模运算的集合。</p>\n<div class=\"math math-display\"><span class=\"katex-display\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\"><semantics><mrow><mi>f</mi><mrow><mo fence=\"true\">(</mo><mi>x</mi><mo fence=\"true\">)</mo></mrow><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><mo>+</mo><msub><mi>a</mi><mn>1</mn></msub><mi>x</mi><mo>+</mo><msub><mi>a</mi><mn>2</mn></msub><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><msub><mi>a</mi><mn>3</mn></msub><msup><mi>x</mi><mn>3</mn></msup><mo>+</mo><mo>⋯</mo><mo>+</mo><msub><mi>a</mi><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></msub><msup><mi>x</mi><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></msup><mtext> </mtext><mtext> ⁣</mtext></mrow><annotation encoding=\"application/x-tex\">f\\left(x\\right)=a_0+a_1x+a_2x^2+a_3x^3+\\cdots+a_{k-1}x^{k-1}\\,\\!</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"minner\"><span class=\"mopen delimcenter\" style=\"top:0em;\">(</span><span class=\"mord mathnormal\">x</span><span class=\"mclose delimcenter\" style=\"top:0em;\">)</span></span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.7333em;vertical-align:-0.15em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3011em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">0</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.7333em;vertical-align:-0.15em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3011em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">1</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span><span class=\"mord mathnormal\">x</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.0141em;vertical-align:-0.15em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3011em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span><span class=\"mord\"><span class=\"mord mathnormal\">x</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8641em;\"><span style=\"top:-3.113em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">2</span></span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.0141em;vertical-align:-0.15em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3011em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">3</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span><span class=\"mord\"><span class=\"mord mathnormal\">x</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8641em;\"><span style=\"top:-3.113em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">3</span></span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.6667em;vertical-align:-0.0833em;\"></span><span class=\"minner\">⋯</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">+</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:1.1074em;vertical-align:-0.2083em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3361em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.03148em;\">k</span><span class=\"mbin mtight\">−</span><span class=\"mord mtight\">1</span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.2083em;\"><span></span></span></span></span></span></span><span class=\"mord\"><span class=\"mord mathnormal\">x</span><span class=\"msupsub\"><span class=\"vlist-t\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.8991em;\"><span style=\"top:-3.113em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.03148em;\">k</span><span class=\"mbin mtight\">−</span><span class=\"mord mtight\">1</span></span></span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span></span></span></span></span></div>\n<p>想象一下在一个平面中，两点定义一条直线，三点定义一条抛物线，以此类推，<span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>k</mi></mrow><annotation encoding=\"application/x-tex\">k</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.6944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.03148em;\">k</span></span></span></span></span> 个点定义了一条唯一 <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding=\"application/x-tex\">k-1</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.7778em;vertical-align:-0.0833em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.03148em;\">k</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">−</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:0.6444em;\"></span><span class=\"mord\">1</span></span></span></span></span> 次曲线。我们选定了 n 个点，其中每一个点的坐标为 <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mrow><mo fence=\"true\">(</mo><mi>i</mi><mo separator=\"true\">,</mo><mi>f</mi><mrow><mo fence=\"true\">(</mo><mi>i</mi><mo fence=\"true\">)</mo></mrow><mo fence=\"true\">)</mo></mrow><mtext> </mtext><mtext> ⁣</mtext></mrow><annotation encoding=\"application/x-tex\">\\left(i,f\\left(i\\right)\\right)\\,\\!</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"minner\"><span class=\"mopen delimcenter\" style=\"top:0em;\">(</span><span class=\"mord mathnormal\">i</span><span class=\"mpunct\">,</span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"minner\"><span class=\"mopen delimcenter\" style=\"top:0em;\">(</span><span class=\"mord mathnormal\">i</span><span class=\"mclose delimcenter\" style=\"top:0em;\">)</span></span><span class=\"mclose delimcenter\" style=\"top:0em;\">)</span></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mspace\" style=\"margin-right:-0.1667em;\"></span></span></span></span></span>。</p>\n<p>那么，在给定的子集 <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><mi>k</mi></mrow><annotation encoding=\"application/x-tex\">k</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.6944em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.03148em;\">k</span></span></span></span></span> 中，用 <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub></mrow><annotation encoding=\"application/x-tex\">a_0</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.5806em;vertical-align:-0.15em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3011em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">0</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span></span></span></span></span> 得到插值，形如公式：</p>\n<div class=\"math math-display\"><span class=\"katex-display\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\" display=\"block\"><semantics><mrow><mstyle scriptlevel=\"0\" displaystyle=\"true\"><mi>f</mi><mo stretchy=\"false\">(</mo><mn>0</mn><mo stretchy=\"false\">)</mo><mo>=</mo><munderover><mo>∑</mo><mrow><mi>j</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></munderover><msub><mi>y</mi><mi>j</mi></msub><munderover><mo>∏</mo><mstyle scriptlevel=\"1\"><mtable rowspacing=\"0.1em\" columnspacing=\"0.2778em\"><mtr><mtd><mstyle scriptlevel=\"1\" displaystyle=\"false\"><mrow><mi>m</mi><mspace width=\"0.1952em\"></mspace><mo>=</mo><mspace width=\"0.1952em\"></mspace><mn>0</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=\"1\" displaystyle=\"false\"><mrow><mi>m</mi><mspace width=\"0.1952em\"></mspace><mo mathvariant=\"normal\">≠</mo><mspace width=\"0.1952em\"></mspace><mi>j</mi></mrow></mstyle></mtd></mtr></mtable></mstyle><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></munderover><mfrac><msub><mi>x</mi><mi>m</mi></msub><mrow><msub><mi>x</mi><mi>m</mi></msub><mo>−</mo><msub><mi>x</mi><mi>j</mi></msub></mrow></mfrac></mstyle></mrow><annotation encoding=\"application/x-tex\">\\displaystyle f(0)=\\sum _{j=0}^{k-1}y_{j}\\prod _{\\begin{smallmatrix}m\\,=\\,0\\\\m\\,\\neq \\,j\\end{smallmatrix}}^{k-1}{\\frac {x_{m}}{x_{m}-x_{j}}}</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:1em;vertical-align:-0.25em;\"></span><span class=\"mord mathnormal\" style=\"margin-right:0.10764em;\">f</span><span class=\"mopen\">(</span><span class=\"mord\">0</span><span class=\"mclose\">)</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span><span class=\"mrel\">=</span><span class=\"mspace\" style=\"margin-right:0.2778em;\"></span></span><span class=\"base\"><span class=\"strut\" style=\"height:3.8514em;vertical-align:-2.0153em;\"></span><span class=\"mop op-limits\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:1.8361em;\"><span style=\"top:-1.8723em;margin-left:0em;\"><span class=\"pstrut\" style=\"height:3.05em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.05724em;\">j</span><span class=\"mrel mtight\">=</span><span class=\"mord mtight\">0</span></span></span></span><span style=\"top:-3.05em;\"><span class=\"pstrut\" style=\"height:3.05em;\"></span><span><span class=\"mop op-symbol large-op\">∑</span></span></span><span style=\"top:-4.3em;margin-left:0em;\"><span class=\"pstrut\" style=\"height:3.05em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.03148em;\">k</span><span class=\"mbin mtight\">−</span><span class=\"mord mtight\">1</span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:1.4138em;\"><span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\" style=\"margin-right:0.03588em;\">y</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3117em;\"><span style=\"top:-2.55em;margin-left:-0.0359em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.05724em;\">j</span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.2861em;\"><span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mop op-limits\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:1.8361em;\"><span style=\"top:-1.5593em;margin-left:0em;\"><span class=\"pstrut\" style=\"height:3.05em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mtight\"><span class=\"mtable\"><span class=\"col-align-c\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:1.1067em;\"><span style=\"top:-3.1622em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\">m</span><span class=\"mspace mtight\" style=\"margin-right:0.1952em;\"></span><span class=\"mrel mtight\">=</span><span class=\"mspace mtight\" style=\"margin-right:0.1952em;\"></span><span class=\"mord mtight\">0</span></span></span><span style=\"top:-2.2878em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\">m</span><span class=\"mspace mtight\" style=\"margin-right:0.1952em;\"></span><span class=\"mrel mtight\"><span class=\"mrel mtight\"><span class=\"mord vbox mtight\"><span class=\"thinbox mtight\"><span class=\"rlap mtight\"><span class=\"strut\" style=\"height:0.8889em;vertical-align:-0.1944em;\"></span><span class=\"inner\"><span class=\"mord mtight\"><span class=\"mrel mtight\"></span></span></span><span class=\"fix\"></span></span></span></span></span><span class=\"mrel mtight\">=</span></span><span class=\"mspace mtight\" style=\"margin-right:0.1952em;\"></span><span class=\"mord mathnormal mtight\" style=\"margin-right:0.05724em;\">j</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.6067em;\"><span></span></span></span></span></span></span></span></span></span></span><span style=\"top:-3.05em;\"><span class=\"pstrut\" style=\"height:3.05em;\"></span><span><span class=\"mop op-symbol large-op\">∏</span></span></span><span style=\"top:-4.3em;margin-left:0em;\"><span class=\"pstrut\" style=\"height:3.05em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.03148em;\">k</span><span class=\"mbin mtight\">−</span><span class=\"mord mtight\">1</span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:2.0153em;\"><span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.1667em;\"></span><span class=\"mord\"><span class=\"mord\"><span class=\"mopen nulldelimiter\"></span><span class=\"mfrac\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:1.1076em;\"><span style=\"top:-2.314em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"mord\"><span class=\"mord\"><span class=\"mord mathnormal\">x</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.1514em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\">m</span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mbin\">−</span><span class=\"mspace\" style=\"margin-right:0.2222em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">x</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3117em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\" style=\"margin-right:0.05724em;\">j</span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.2861em;\"><span></span></span></span></span></span></span></span></span><span style=\"top:-3.23em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"frac-line\" style=\"border-bottom-width:0.04em;\"></span></span><span style=\"top:-3.677em;\"><span class=\"pstrut\" style=\"height:3em;\"></span><span class=\"mord\"><span class=\"mord\"><span class=\"mord mathnormal\">x</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.1514em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\"><span class=\"mord mathnormal mtight\">m</span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.9721em;\"><span></span></span></span></span></span><span class=\"mclose nulldelimiter\"></span></span></span></span></span></span></span></div>\n<p>便能得到正确的 <span class=\"math math-inline\"><span class=\"katex\"><span class=\"katex-mathml\"><math xmlns=\"http://www.w3.org/1998/Math/MathML\"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub></mrow><annotation encoding=\"application/x-tex\">a_0</annotation></semantics></math></span><span class=\"katex-html\" aria-hidden=\"true\"><span class=\"base\"><span class=\"strut\" style=\"height:0.5806em;vertical-align:-0.15em;\"></span><span class=\"mord\"><span class=\"mord mathnormal\">a</span><span class=\"msupsub\"><span class=\"vlist-t vlist-t2\"><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.3011em;\"><span style=\"top:-2.55em;margin-left:0em;margin-right:0.05em;\"><span class=\"pstrut\" style=\"height:2.7em;\"></span><span class=\"sizing reset-size6 size3 mtight\"><span class=\"mord mtight\">0</span></span></span></span><span class=\"vlist-s\">​</span></span><span class=\"vlist-r\"><span class=\"vlist\" style=\"height:0.15em;\"><span></span></span></span></span></span></span></span></span></span></span>。</p>\n<p>文末附有 Python 版实现的源代码，如果想直接体验一下，请访问<a href=\"https://iancoleman.io/shamir/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">在线版本</a>。如果你日常用 Linux 工作，那么看一看 <code class=\"language-text\">ssss-split</code> 和 <code class=\"language-text\">ssss-combine</code> 的手册页吧。</p>\n<p>现在，你已经掌握了密码共享的方式。现在你可以分成几个部分，交给信任的亲友，存储到他们的密码管理器中；或者记录到某些隐匿的地方。</p>\n<p>主密码，安全 ✅</p>\n<h3>第三层：2FA 与 SIM 卡 PIN 码</h3>\n<p>除了账号的密码本身，一些平台会提供<strong>双因子验证 (Two-factor authentication, 2FA)</strong> 的功能。</p>\n<p>总的来说，个人的生理特征（虹膜、指纹）和私人物品（卡片、钥匙）都是一个因子，加上密码构成了双因子。</p>\n<p>除了密码，最常用的因子还是我们通常随身携带的手机。手机或邮箱验证码、上文中提到的 OTOP，都是互联网平台典型的 2FA。笔者建议重要的账号能开启 2FA 就开启。</p>\n<p>不过国内平台支持 OTOP 的比较少；如果你有国外平台账号的话，建议采用 <a href=\"https://alternativeto.net/software/2fa-authenticator-2fas-/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">2FA Authenticator</a>，笔者个人使用的是 Authy，一些大厂出品的如 Google Authenticator 和 Microsoft Authenticator 也都值得信赖。</p>\n<p>详细说一下国内的情况，短信验证本质上是验证 SIM 卡。我们要确保 SIM 卡丢失或被恶意拷贝的时候验证一次。</p>\n<p>SIM 卡可以<strong>设置 PIN (Personal Identification Number) 码</strong>，如果你用 iPhone 的话，参考<a href=\"https://support.apple.com/zh-cn/HT201529\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">这篇官方文档</a>完成设置。顺便一提，如果遗忘了 PIN 码，需要拿 PUK (Personal Identification Number Unlock Key) 码去运营商那里解锁 PIN 码，如果多次猜测错误，就会永久性锁卡（就只能更换 SIM 卡了）。</p>\n<p>最后，记得给手机设置上六位以上的密码。</p>\n<p>让我们开始网上冲浪吧！</p>\n<h3>参考资料</h3>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token triple-quoted-string string\">\"\"\"\nThe following Python implementation of Shamir's Secret Sharing is\nreleased into the Public Domain under the terms of CC0 and OWFa:\nhttps://creativecommons.org/publicdomain/zero/1.0/\nhttp://www.openwebfoundation.org/legal/the-owf-1-0-agreements/owfa-1-0\n\nSee the bottom few lines for usage. Tested on Python 2 and 3.\n\"\"\"</span>\n\n<span class=\"token keyword\">from</span> __future__ <span class=\"token keyword\">import</span> division\n<span class=\"token keyword\">from</span> __future__ <span class=\"token keyword\">import</span> print_function\n\n<span class=\"token keyword\">import</span> random\n<span class=\"token keyword\">import</span> functools\n\n<span class=\"token comment\"># 12th Mersenne Prime</span>\n<span class=\"token comment\"># (for this application we want a known prime number as close as</span>\n<span class=\"token comment\"># possible to our security level; e.g.  desired security level of 128</span>\n<span class=\"token comment\"># bits -- too large and all the ciphertext is large; too small and</span>\n<span class=\"token comment\"># security is compromised)</span>\n_PRIME <span class=\"token operator\">=</span> <span class=\"token number\">2</span> <span class=\"token operator\">**</span> <span class=\"token number\">127</span> <span class=\"token operator\">-</span> <span class=\"token number\">1</span>\n<span class=\"token comment\"># 13th Mersenne Prime is 2**521 - 1</span>\n\n_RINT <span class=\"token operator\">=</span> functools<span class=\"token punctuation\">.</span>partial<span class=\"token punctuation\">(</span>random<span class=\"token punctuation\">.</span>SystemRandom<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>randint<span class=\"token punctuation\">,</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">_eval_at</span><span class=\"token punctuation\">(</span>poly<span class=\"token punctuation\">,</span> x<span class=\"token punctuation\">,</span> prime<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">\"\"\"Evaluates polynomial (coefficient tuple) at x, used to generate a\n    shamir pool in make_random_shares below.\n    \"\"\"</span>\n    accum <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n    <span class=\"token keyword\">for</span> coeff <span class=\"token keyword\">in</span> <span class=\"token builtin\">reversed</span><span class=\"token punctuation\">(</span>poly<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        accum <span class=\"token operator\">*=</span> x\n        accum <span class=\"token operator\">+=</span> coeff\n        accum <span class=\"token operator\">%=</span> prime\n    <span class=\"token keyword\">return</span> accum\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">make_random_shares</span><span class=\"token punctuation\">(</span>secret<span class=\"token punctuation\">,</span> minimum<span class=\"token punctuation\">,</span> shares<span class=\"token punctuation\">,</span> prime<span class=\"token operator\">=</span>_PRIME<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">\"\"\"\n    Generates a random shamir pool for a given secret, returns share points.\n    \"\"\"</span>\n    <span class=\"token keyword\">if</span> minimum <span class=\"token operator\">></span> shares<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">raise</span> ValueError<span class=\"token punctuation\">(</span><span class=\"token string\">\"Pool secret would be irrecoverable.\"</span><span class=\"token punctuation\">)</span>\n    poly <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span>secret<span class=\"token punctuation\">]</span> <span class=\"token operator\">+</span> <span class=\"token punctuation\">[</span>_RINT<span class=\"token punctuation\">(</span>prime <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span>minimum <span class=\"token operator\">-</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>\n    points <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">,</span> _eval_at<span class=\"token punctuation\">(</span>poly<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">,</span> prime<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n              <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> shares <span class=\"token operator\">+</span> <span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">return</span> points\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">_extended_gcd</span><span class=\"token punctuation\">(</span>a<span class=\"token punctuation\">,</span> b<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">\"\"\"\n    Division in integers modulus p means finding the inverse of the\n    denominator modulo p and then multiplying the numerator by this\n    inverse (Note: inverse of A is B such that A*B % p == 1) this can\n    be computed via extended Euclidean algorithm\n    http://en.wikipedia.org/wiki/Modular_multiplicative_inverse#Computation\n    \"\"\"</span>\n    x <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n    last_x <span class=\"token operator\">=</span> <span class=\"token number\">1</span>\n    y <span class=\"token operator\">=</span> <span class=\"token number\">1</span>\n    last_y <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n    <span class=\"token keyword\">while</span> b <span class=\"token operator\">!=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        quot <span class=\"token operator\">=</span> a <span class=\"token operator\">//</span> b\n        a<span class=\"token punctuation\">,</span> b <span class=\"token operator\">=</span> b<span class=\"token punctuation\">,</span> a <span class=\"token operator\">%</span> b\n        x<span class=\"token punctuation\">,</span> last_x <span class=\"token operator\">=</span> last_x <span class=\"token operator\">-</span> quot <span class=\"token operator\">*</span> x<span class=\"token punctuation\">,</span> x\n        y<span class=\"token punctuation\">,</span> last_y <span class=\"token operator\">=</span> last_y <span class=\"token operator\">-</span> quot <span class=\"token operator\">*</span> y<span class=\"token punctuation\">,</span> y\n    <span class=\"token keyword\">return</span> last_x<span class=\"token punctuation\">,</span> last_y\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">_divmod</span><span class=\"token punctuation\">(</span>num<span class=\"token punctuation\">,</span> den<span class=\"token punctuation\">,</span> p<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">\"\"\"Compute num / den modulo prime p\n\n    To explain what this means, the return value will be such that\n    the following is true: den * _divmod(num, den, p) % p == num\n    \"\"\"</span>\n    inv<span class=\"token punctuation\">,</span> _ <span class=\"token operator\">=</span> _extended_gcd<span class=\"token punctuation\">(</span>den<span class=\"token punctuation\">,</span> p<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> num <span class=\"token operator\">*</span> inv\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">_lagrange_interpolate</span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">,</span> x_s<span class=\"token punctuation\">,</span> y_s<span class=\"token punctuation\">,</span> p<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">\"\"\"\n    Find the y-value for the given x, given n (x, y) points;\n    k points will define a polynomial of up to kth order.\n    \"\"\"</span>\n    k <span class=\"token operator\">=</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span>x_s<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">assert</span> k <span class=\"token operator\">==</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">set</span><span class=\"token punctuation\">(</span>x_s<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"points must be distinct\"</span>\n    <span class=\"token keyword\">def</span> <span class=\"token function\">PI</span><span class=\"token punctuation\">(</span>vals<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>  <span class=\"token comment\"># upper-case PI -- product of inputs</span>\n        accum <span class=\"token operator\">=</span> <span class=\"token number\">1</span>\n        <span class=\"token keyword\">for</span> v <span class=\"token keyword\">in</span> vals<span class=\"token punctuation\">:</span>\n            accum <span class=\"token operator\">*=</span> v\n        <span class=\"token keyword\">return</span> accum\n    nums <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>  <span class=\"token comment\"># avoid inexact division</span>\n    dens <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span>k<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        others <span class=\"token operator\">=</span> <span class=\"token builtin\">list</span><span class=\"token punctuation\">(</span>x_s<span class=\"token punctuation\">)</span>\n        cur <span class=\"token operator\">=</span> others<span class=\"token punctuation\">.</span>pop<span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">)</span>\n        nums<span class=\"token punctuation\">.</span>append<span class=\"token punctuation\">(</span>PI<span class=\"token punctuation\">(</span>x <span class=\"token operator\">-</span> o <span class=\"token keyword\">for</span> o <span class=\"token keyword\">in</span> others<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        dens<span class=\"token punctuation\">.</span>append<span class=\"token punctuation\">(</span>PI<span class=\"token punctuation\">(</span>cur <span class=\"token operator\">-</span> o <span class=\"token keyword\">for</span> o <span class=\"token keyword\">in</span> others<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    den <span class=\"token operator\">=</span> PI<span class=\"token punctuation\">(</span>dens<span class=\"token punctuation\">)</span>\n    num <span class=\"token operator\">=</span> <span class=\"token builtin\">sum</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span>_divmod<span class=\"token punctuation\">(</span>nums<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">*</span> den <span class=\"token operator\">*</span> y_s<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span> <span class=\"token operator\">%</span> p<span class=\"token punctuation\">,</span> dens<span class=\"token punctuation\">[</span>i<span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span> p<span class=\"token punctuation\">)</span>\n               <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span>k<span class=\"token punctuation\">)</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">(</span>_divmod<span class=\"token punctuation\">(</span>num<span class=\"token punctuation\">,</span> den<span class=\"token punctuation\">,</span> p<span class=\"token punctuation\">)</span> <span class=\"token operator\">+</span> p<span class=\"token punctuation\">)</span> <span class=\"token operator\">%</span> p\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">recover_secret</span><span class=\"token punctuation\">(</span>shares<span class=\"token punctuation\">,</span> prime<span class=\"token operator\">=</span>_PRIME<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">\"\"\"\n    Recover the secret from share points\n    (x, y points on the polynomial).\n    \"\"\"</span>\n    <span class=\"token keyword\">if</span> <span class=\"token builtin\">len</span><span class=\"token punctuation\">(</span>shares<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;</span> <span class=\"token number\">3</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">raise</span> ValueError<span class=\"token punctuation\">(</span><span class=\"token string\">\"need at least three shares\"</span><span class=\"token punctuation\">)</span>\n    x_s<span class=\"token punctuation\">,</span> y_s <span class=\"token operator\">=</span> <span class=\"token builtin\">zip</span><span class=\"token punctuation\">(</span><span class=\"token operator\">*</span>shares<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> _lagrange_interpolate<span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">,</span> x_s<span class=\"token punctuation\">,</span> y_s<span class=\"token punctuation\">,</span> prime<span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">\"\"\"Main function\"\"\"</span>\n    secret <span class=\"token operator\">=</span> <span class=\"token number\">1234</span>\n    shares <span class=\"token operator\">=</span> make_random_shares<span class=\"token punctuation\">(</span>secret<span class=\"token punctuation\">,</span> minimum<span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\">,</span> shares<span class=\"token operator\">=</span><span class=\"token number\">6</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Secret:                                                     '</span><span class=\"token punctuation\">,</span>\n          secret<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Shares:'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> shares<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">for</span> share <span class=\"token keyword\">in</span> shares<span class=\"token punctuation\">:</span>\n            <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'  '</span><span class=\"token punctuation\">,</span> share<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Secret recovered from minimum subset of shares:             '</span><span class=\"token punctuation\">,</span>\n          recover_secret<span class=\"token punctuation\">(</span>shares<span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token number\">3</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'Secret recovered from a different minimum subset of shares: '</span><span class=\"token punctuation\">,</span>\n          recover_secret<span class=\"token punctuation\">(</span>shares<span class=\"token punctuation\">[</span><span class=\"token operator\">-</span><span class=\"token number\">3</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">if</span> __name__ <span class=\"token operator\">==</span> <span class=\"token string\">'__main__'</span><span class=\"token punctuation\">:</span>\n    main<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>"}},"pageContext":{"slug":"/blog/2022/SafeInternetSurfing"}},
    "staticQueryHashes": ["844979529"]}