[{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/diffie-hellman/","section":"Tags","summary":"","title":"Diffie-Hellman","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/fhe/","section":"Tags","summary":"","title":"FHE","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/hash/","section":"Tags","summary":"","title":"Hash","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/iknp/","section":"Tags","summary":"","title":"IKNP","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/ot/","section":"Tags","summary":"","title":"OT","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/ot-extension/","section":"Tags","summary":"","title":"OT Extension","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/phe/","section":"Tags","summary":"","title":"PHE","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/post/","section":"Posts","summary":"","title":"Posts","type":"post"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/psi/","section":"Tags","summary":"","title":"PSI","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/rsa/","section":"Tags","summary":"","title":"RSA","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/%E5%A4%9A%E9%A1%B9%E5%BC%8F/","section":"Tags","summary":"","title":"多项式","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0/","section":"Tags","summary":"","title":"联邦学习","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/%E7%9B%B2%E7%AD%BE%E5%90%8D/","section":"Tags","summary":"","title":"盲签名","type":"tags"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/%E5%90%8C%E6%80%81%E5%8A%A0%E5%AF%86/","section":"Tags","summary":"","title":"同态加密","type":"tags"},{"content":"这是一篇持续更新的复习笔记，用来整理《隐私集合计算中的关键技术》PPT 的学习内容。目前已经整理到 第 29 页。重点不是记住一堆缩写，而是理解各种 PSI 协议为什么出现、怎样运行，以及它们之间有什么联系。\n以后学习这份 PPT 的新内容都会继续追加在本文末尾，并注明页码范围，已经讲过的内容不再重复。\n先建立整张知识地图 # 隐私保护技术包含安全多方计算、差分隐私、同态加密、零知识证明、匿名化、联邦学习和可信执行环境等多个方向。\n其中，安全多方计算（Secure Multi-Party Computation，MPC）研究的是：多方怎样在不公开各自输入的情况下，共同完成一个计算。\n隐私集合计算（Private Set Operation，PSO）是 MPC 中的一类具体问题，当前最先接触的是：\nPSI（Private Set Intersection）：隐私集合求交； PSU（Private Set Union）：隐私集合求并。 假设 Alice 持有集合：\n$$X=\\{\\text{张三，李四，王五}\\}$$Bob 持有集合：\n$$Y=\\{\\text{李四，王五，赵六}\\}$$普通集合运算很简单：\n$$X\\cap Y=\\{\\text{李四，王五}\\}$$$$X\\cup Y=\\{\\text{张三，李四，王五，赵六}\\}$$“隐私”二字增加了一个重要要求：完成运算时，不应把交集之外的私有元素随意泄露给对方。\n因此可以先这样记：\nPSI 回答“我们共同拥有哪些元素”，PSU 回答“合起来一共有哪些元素”，同时尽量隐藏不该公开的集合信息。\nPSI 到底能用来做什么 # PSI 的本质是跨主体的数据匹配。两个主体不能直接交换完整名单，但又需要知道双方有哪些共同记录。\n私有联系人发现 # 手机里有 500 个联系人，社交平台有大量注册用户。用户想知道通讯录里谁已经注册，却不希望把完整通讯录直接交给平台。\n这里两个集合分别是：\n用户的通讯录； 平台的注册用户。 PSI 输出共同联系人，而不是公开两边的完整名单。\n广告转化率计算 # 广告平台知道“哪些人看过广告”，电商平台知道“哪些人购买了商品”。两边求交后可以得到：\n$$\\text{看过广告的用户}\\cap\\text{购买用户}$$这个交集能够帮助计算广告转化效果。广告平台不必交出全部曝光用户，电商也不必公开全部购买用户。\n有时业务只需要交集大小，例如“共有 357 人完成购买”，不需要具体名单。这类功能称为 PSI Cardinality（PSI-CA）。\n拼车和位置匹配 # 两名用户各有一组候选位置或路线。系统需要寻找共同上车点，却不应暴露双方的完整活动轨迹。PSI 可以用于寻找共同位置。\n纵向联邦学习的数据对齐 # 这是最容易混淆、也最值得理解的应用。要讲清楚它，需要把“数据对齐”和“联合训练”分开。\n数据对齐和纵向联邦学习不是一回事 # 假设银行掌握：\n用户 收入 贷款 张三 8000 10 万 李四 6000 5 万 王五 9000 20 万 电商平台掌握：\n用户 消费金额 购物频率 李四 3000 高 王五 5000 高 赵六 1000 低 双方想联合训练信用风险模型，但用户并不完全重合。第一步要找出双方都有记录的用户：\n$$\\{\\text{张三，李四，王五}\\}\\cap\\{\\text{李四，王五，赵六}\\} =\\{\\text{李四，王五}\\}$$这一步叫作数据对齐、样本对齐或实体对齐。\n数据对齐只是找姓名吗 # 不一定。姓名可能重名，也可能存在不同写法。真实系统常使用手机号、身份证号、邮箱、用户 ID，或者经过规范化和密码学处理的标识。\n数据对齐真正解决的是：\n银行中的这条记录和电商中的那条记录，是否属于同一个实体？\n因此，找到共同用户并建立对应关系才叫数据对齐。找到以后，把双方没有的数据直接补到一张表中，并不叫数据对齐。\n“逻辑上拼成一张表”是不是纵向联邦学习 # 也不是。对齐后，我们在逻辑上知道：\n1 李四：银行掌握收入、贷款；电商掌握消费金额、购物频率。 但双方的原始数据仍然留在各自机构，并没有真的集中到同一张表。\n纵向联邦学习的完整过程可以分成三步：\n数据对齐：用 PSI 找到共同用户； 逻辑关联：确认两边哪些记录属于同一个人； 联合训练：双方基于各自的特征计算必要的中间结果，共同训练一个模型。 所以更准确的定义是：\n纵向联邦学习是多个参与方针对大致相同的用户，利用各自掌握的不同特征，在不直接集中原始数据的情况下联合训练模型。\n训练模型是什么意思 # 训练模型就是让计算机从历史样本中学习规律。例如：\n1 收入 + 贷款 + 消费金额 + 购物频率 → 是否违约 给模型许多已经知道结果的历史用户，模型逐渐学习输入特征与违约风险之间的关系。以后面对新用户，就可以输出风险预测。\nPSI 不负责训练模型。它发生在训练之前，解决的是“参与训练的共同用户是谁”。\n横向联邦学习与纵向联邦学习 # 两者可以用“行”和“列”来记：\n类型 用户样本 特征 例子 横向联邦学习 不同 相似 不同地区医院都有年龄、血压、血糖 纵向联邦学习 大致相同 不同 银行有收入，电商有消费行为 横向联邦学习像增加更多“行”，纵向联邦学习像增加更多“特征列”。\nPSI 中谁是发送方，谁知道结果 # 一种常见定义是：\nSender 持有集合 $X$； Receiver 持有集合 $Y$； Receiver 最终获得 $X\\cap Y$； Sender 不应得到 $Y$ 的私有信息； Receiver 不应得到 $X$ 中交集之外的元素。 但 Sender 和 Receiver 描述的是协议角色和输出权限，并不等同于“谁发送了网络消息”。多数 PSI 协议中双方都会发送数据。\n更不能死记 Alice 永远是 Sender、Bob 永远是 Receiver。具体哪个参与方获得交集，要看协议设计：\n可以只让一方得到完整交集； 可以让双方都得到交集； 可以只输出交集大小； 也可以把结果以秘密共享形式输出，双方都不能单独看到。 在当前学习的三种具体流程中：\n方案 PPT 流程中的结果方 Hash PSI Bob 比较并得到交集 DH PSI Bob 完成最后比较 RSA PSI Alice 完成最后比较 因此，看协议时应先问三件事：双方各持有什么、交换什么、谁获得什么输出。\n第 10 页：Hash PSI # Hash PSI 是理解后续方案的起点。\n假设 Alice 持有：\n$$X=\\{x_1,x_2,\\ldots,x_n\\}$$她用公开且统一的哈希函数 $H$ 计算：\n$$Z=\\{H(x_1),H(x_2),\\ldots,H(x_n)\\}$$Alice 把 $Z$ 发给 Bob。Bob 对自己的每个 $y_i$ 计算 $H(y_i)$，然后判断：\n$$H(y_i)\\in Z\\ ?$$如果答案为真，Bob 就认为 $y_i$ 位于交集中。\n相同的数据由不同的人计算，哈希值一样吗 # 只要满足下面两个条件，结果一定相同：\n输入的字节完全相同； 使用相同的哈希算法和参数。 哈希函数是确定性的，不会因为计算者是 Alice 还是 Bob 而改变结果。\n但“人眼看起来相同”不代表计算机收到的字节相同。例如：\n1 2 李四 李四[末尾多一个空格] 两者的哈希完全不同。13800138000 与 +8613800138000 也不同。因此真实 PSI 系统在哈希前还需要进行数据规范化，例如统一手机号格式、大小写、空格和字符编码。\n哈希碰撞会不会影响判断 # 理论上可能存在两个不同输入得到相同哈希：\n$$x\\ne y,\\qquad H(x)=H(y)$$这叫哈希碰撞。现代密码学哈希函数的目标是让攻击者极难构造这种碰撞。入门理解 Hash PSI 时，可以先把碰撞概率视为足够低，但工程设计仍需要选择安全的哈希函数。\nHash PSI 为什么不够安全 # Alice 发送的是公开哈希值。如果元素来自很小、很容易猜测的空间，Bob 可以准备候选值逐个计算哈希。\n例如，若集合元素只是 11 位手机号，Bob 可以对大量候选手机号计算哈希，再和 Alice 发来的哈希表比较。这叫字典攻击或穷举攻击。\n所以“只发哈希”并不等于安全。Hash PSI 的优点是快、通信轮数少，缺点是对低熵数据的猜测攻击抵抗力不足。\n第 11 页：DH PSI # DH PSI 在哈希结果外又增加一层只有参与者自己知道的秘密指数。\nAlice 随机选择秘密数 $\\alpha$，对自己的元素计算：\n$$X_\\alpha=\\{H(x_i)^\\alpha\\}$$Bob 随机选择秘密数 $\\beta$，对自己的元素计算：\n$$Y_\\beta=\\{H(y_j)^\\beta\\}$$双方交换这些结果后，再分别进行一次指数运算，得到：\n$$X_{\\alpha\\beta}=\\{(H(x_i)^\\alpha)^\\beta\\}$$$$Y_{\\alpha\\beta}=\\{(H(y_j)^\\beta)^\\alpha\\}$$关键公式是：\n$$(H(x)^\\alpha)^\\beta=H(x)^{\\alpha\\beta} =(H(x)^\\beta)^\\alpha$$如果 $x=y$，双方最终会得到相同的双重指数结果，因此可以进行匹配。\n这里的直觉是：Alice 和 Bob 各自给数据上了一把秘密锁。由于指数运算顺序可以交换，相同元素最终会得到同样的“双锁结果”；外部观察者又不知道 $\\alpha$ 和 $\\beta$，不能像简单 Hash PSI 那样直接建立字典表。\nDH PSI 与 ElGamal 有什么关系 # RSA、ElGamal 都属于公钥密码，但数学体系不同。\nElGamal 中常见：\n$$y=g^x$$其中 $x$ 是私钥，$y$ 是公钥；加密时还会选择随机数 $k$：\n$$c_1=g^k,\\qquad c_2=m\\cdot y^k$$DH PSI 与 ElGamal 都大量使用群上的指数运算，安全性与离散对数、Diffie-Hellman 类困难问题有关。因此，学过 ElGamal 后再看 $H(x)^\\alpha$、$H(x)^{\\alpha\\beta}$，会比直接从零理解更自然。\n严格实现时，$H(x)$ 不能只是任意整数，还要通过合适的 Hash-to-Group 方法映射到协议使用的密码群中。\n第 12 页：RSA PSI 与盲签名 # RSA 生成一对密钥：\n$$\\text{公钥 }(N,e),\\qquad \\text{私钥 }d$$教科书中的基础 RSA 关系可以写成：\n$$c=m^e\\bmod N$$$$m=c^d\\bmod N$$也就是公钥加密、私钥解密。\n数字签名解决的是身份与完整性问题，正确表述是：私钥签名、公钥验证。现实中的 RSA 加密和签名分别需要 OAEP、RSA-PSS 等安全编码，不能把“签名”简单等同为“私钥加密”。\n现实系统都是公钥加密、私钥解密吗 # 大量数据通常不会直接用 RSA 或 ElGamal 加密，因为公钥运算较慢。实际系统通常使用混合方式：\n1 2 3 4 5 6 7 公钥密码或 DH ↓ 协商或封装一个会话密钥 ↓ AES、ChaCha20 等对称密码 ↓ 高速加密大量数据 HTTPS 就采用这类总体思路。公钥密码常负责密钥协商、身份认证和数字签名，对称密码负责数据传输。\nRSA PSI 的盲化、盲签名与去盲 # 设 Alice 的集合较小，Bob 的集合很大。Bob 持有 RSA 公私钥 $(N,e)$ 和 $d$。\nAlice 对自己的元素 $x_i$ 先计算：\n$$m=H(x_i)$$然后选择随机数 $r_i$，构造：\n$$m'=m\\cdot r_i^e\\pmod N$$这一步叫盲化。Bob 看到的是掺入随机因子的 $m\u0026rsquo;$，不能直接看到原来的 $m$。\nBob 使用私钥对盲化后的消息计算：\n$$s'=(m')^d\\pmod N$$代入 $m\u0026rsquo;$：\n$$s'=(m\\cdot r_i^e)^d =m^d\\cdot r_i^{ed} \\equiv m^d\\cdot r_i\\pmod N$$这个动作叫盲签名：Bob 完成了私钥运算，却不知道自己处理的原始消息。\nAlice 收到 $s\u0026rsquo;$ 后，使用 $r_i$ 的模逆去盲：\n$$s=s'\\cdot r_i^{-1}\\pmod N$$最终得到：\n$$s=m^d=H(x_i)^d\\pmod N$$三个概念要分清：\n步骤 执行者 作用 盲化 Blinding Alice 用随机数遮住原始消息 盲签名 Blind Signing Bob 用私钥处理盲化消息 去盲 Unblinding Alice 去掉随机因子，得到正常签名结果 可以把它类比成把文件放进一个特殊信封：Bob 不打开信封就在外面盖章；Alice 拆掉信封后，得到等价于直接盖在文件上的章。\n怎样通过盲签名找到交集 # Bob 对自己的每个 $y_j$ 直接计算：\n$$H(y_j)^d$$并把结果发给 Alice。Alice 已经通过盲签名和去盲得到了自己的 $H(x_i)^d$。如果 $x_i=y_j$，则：\n$$H(x_i)^d=H(y_j)^d$$Alice 比较两组结果，就能找出交集。\n为什么让小集合方生成随机数 # RSA 私钥运算比较昂贵。若 Alice 只有 1000 个元素，Bob 有 100 万个元素，让 Alice 对 1000 个元素盲化，Bob 在线处理这 1000 个盲化值，通常比反过来更合适。Bob 自己的大集合表示还可能提前预计算。\n因此这类方法适合：\n$$|X|\\ll|Y|$$也就是非平衡 PSI。\n三种 PSI 放在一起比较 # 方案 核心表示 安全直觉 主要优点 主要代价或问题 Hash PSI $H(x)$ 相同输入得到相同摘要 快、简单、通信轮数少 低熵数据容易被穷举 DH PSI $H(x)^\\alpha$ 双方秘密指数可交换 比简单 Hash 更能抵抗字典攻击 公钥群运算较慢 RSA PSI $H(x)r^e$ 盲化后由私钥方处理 适合非平衡集合 RSA 私钥运算开销较大 这三种方法形成了一条清楚的学习路线：\n1 2 3 4 5 6 7 直接比较 Hash ↓ 发现容易被猜测 加入 DH 秘密指数 ↓ 需要理解公钥群运算 使用 RSA 盲化与盲签名 ↓ 适配非平衡集合 根据业务规模和安全要求选择方案 PPT 第 13～14 页：同态加密 PSI 与多项式判零 # 前面已经学习了 Hash、DH 和 RSA PSI。第 13～14 页继续回答同一个问题：怎样在不暴露集合元素的情况下判断成员关系？这一部分引入同态加密，并用“乘积为零”和“多项式的根”完成判断。\n先理解同态加密：密文也能参加计算 # 普通加密通常可以抽象成：\n$$m\\xrightarrow{\\operatorname{Enc}}c$$其中 $m$ 是明文，$c$ 是密文。没有私钥的人看到 $c$，无法知道 $m$。但普通密文主要用于保存和传输，要计算时通常需要先解密。\n同态加密的特别之处在于：某些运算可以直接在密文上完成，解密后的结果等价于在明文上计算。\n例如一种支持加法的同态加密满足：\n$$\\operatorname{Enc}(a)\\oplus\\operatorname{Enc}(b) =\\operatorname{Enc}(a+b)$$这里的 $\\oplus$ 表示某种“密文运算”，不一定是普通整数加号。计算方不知道 $a$ 和 $b$，却能得到 $a+b$ 的密文。持有私钥的人解密后得到：\n$$\\operatorname{Dec}(\\operatorname{Enc}(a+b))=a+b$$一个容易理解的例子\n医院甲保存患者人数 $120$，医院乙保存患者人数 $80$。双方不想公开各自人数，但需要得到总数。\n如果使用加法同态加密，计算方可以拿到：\n$$\\operatorname{Enc}(120),\\quad \\operatorname{Enc}(80)$$然后在密文上相加，得到：\n$$\\operatorname{Enc}(200)$$计算方全程没有看到 120 和 80。最后由有解密权的一方得到 200。\n因此可以先记住：\n普通加密重点是“把数据藏起来”，同态加密还允许“藏着数据做计算”。\nFHE 和 PHE 有什么区别 # 部分同态加密 PHE\nPHE 是 Partially Homomorphic Encryption。它只支持一种运算，或支持范围有限的运算。\n常见例子包括：\nPaillier：典型的加法同态； 某些形式的 ElGamal：典型的乘法同态。 例如加法同态方案通常能完成：\n$$\\operatorname{Enc}(a+b)$$以及“密文乘明文常数”对应的：\n$$\\operatorname{Enc}(ka)$$但它不能随意把加法和乘法无限组合。\n全同态加密 FHE\nFHE 是 Fully Homomorphic Encryption。它支持足够丰富的密文加法和密文乘法，因此原则上可以组合出任意有限电路的计算。\n这并不意味着 FHE 没有限制。真实方案还要考虑：\n密文比明文大很多； 密文运算远慢于普通运算； 运算会引入噪声； 参数、乘法深度和是否需要自举都会影响性能。 所以 PPT 说 FHE 能力强，但“密文长度大、计算性能不占优势”，原因就在这里。\n对比 PHE FHE 支持的运算 一种或有限种 可组合加法与乘法 能完成的计算 结构受限 理论上更通用 性能 通常相对轻量 通常更重 本文对应页 第 14 页 第 13 页 第 13 页：基于 FHE 的 PSI # 假设 Alice 持有：\n$$X=\\{x_1,x_2,\\ldots,x_n\\}$$Bob 持有：\n$$Y=\\{y_1,y_2,\\ldots,y_m\\}$$目标是让 Bob 找到：\n$$X\\cap Y$$这一方案的直觉是：Bob 把自己的元素加密，Alice 不知道这些元素，却可以在密文上检测它们是否等于自己集合中的某个元素。\n第一步：Bob 加密自己的集合\nBob 生成 FHE 密钥：\n$$ (pk,sk)\\leftarrow\\operatorname{KeyGen}()$$其中 $pk$ 是公钥，$sk$ 是私钥。然后对每个 $y_i$ 加密：\n$$c_i=\\operatorname{Enc}_{pk}(y_i)$$Bob 把 $c_i$ 发给 Alice，自己保留私钥。Alice 只看到密文，不知道 $y_i$。\n第二步：Alice 在密文上构造“判零表达式”\nAlice 针对每个 $c_i$ 计算：\n$$d_i=\\operatorname{Eval}\\left( r_i\\prod_{x\\in X}(y_i-x) \\right)$$严格来说，Alice 实际操作的是 $c_i=\\operatorname{Enc}(y_i)$，上式写的是密文计算所对应的明文逻辑。$r_i$ 是 Alice 选择的非零随机数。\n为什么这个乘积能判断成员关系？\n如果 $y_i$ 等于 $X$ 中的某个元素，例如 $y_i=x_j$，乘积中一定出现：\n$$y_i-x_j=0$$于是：\n$$\\prod_{x\\in X}(y_i-x)=0$$反过来，如果 $y_i$ 不等于 $X$ 中的任何元素，每个差值通常都非零，乘积也非零。\n因此：\n$$y_i\\in X \\iff \\prod_{x\\in X}(y_i-x)=0$$第三步：Bob 解密并判断\nAlice 把 $d_i$ 返回给 Bob。Bob 使用私钥解密：\n$$z_i=\\operatorname{Dec}_{sk}(d_i)$$如果：\n$$z_i=0$$就说明 $y_i\\in X$；否则说明 $y_i\\notin X$。Bob 对自己的每个元素都做判断，便得到交集。\n用数字完整走一遍\n假设：\n$$X=\\{2,5,8\\},\\qquad Y=\\{3,5,9\\}$$先忽略密文，只观察计算的明文含义。\n对于 $y=5$：\n$$(5-2)(5-5)(5-8) =3\\times0\\times(-3) =0$$无论非零随机数 $r$ 是多少，$r\\times0$ 仍然是 0，所以 Bob 解密后知道 5 属于交集。\n对于 $y=3$：\n$$(3-2)(3-5)(3-8) =1\\times(-2)\\times(-5) =10$$乘积不是 0，因此 Bob 知道 3 不在 Alice 的集合中。\n最终得到：\n$$X\\cap Y=\\{5\\}$$为什么要乘随机数 r_i\n成员对应的结果必须保持为 0：\n$$r_i\\times0=0$$非成员对应的结果则被随机化：\n$$r_i\\times z_i$$如果 Alice 直接返回确定的非零计算结果，Bob 可能从结果大小、重复关系或其他结构中获得额外信息。随机数的作用是遮蔽这些非零值，让 Bob 主要只区分“0”和“非 0”。\n需要注意，正式协议是在选定的有限域或模环中运算，并要求随机数和参数满足协议条件。本文的整数例子只用于解释判零思想。\n第 14 页：基于 PHE 的多项式 PSI # 第 14 页不直接加密 Bob 的每个元素，而是让 Alice 把自己的集合编码成一个多项式。\n一句话概括：\nAlice 把集合元素变成多项式的根，加密多项式系数；Bob 用自己的元素在密文上求值，Alice 解密后识别交集。\n第一步：把集合写成多项式\nAlice 根据集合 $X$ 构造：\n$$P(t)=\\prod_{x\\in X}(t-x)$$假设：\n$$X=\\{2,5,8\\}$$那么：\n$$P(t)=(t-2)(t-5)(t-8)$$把集合中的元素代入，多项式的值一定是 0：\n$$P(2)=P(5)=P(8)=0$$数学中，如果 $P(a)=0$，就称 $a$ 是 $P$ 的一个根。所以 $P(t)$ 的根恰好就是 Alice 的集合元素。\n这就把集合成员判断转换成了多项式判零：\n$$y\\in X\\iff P(y)=0$$第二步：展开并加密多项式系数\n把多项式展开：\n$$P(t)=a_nt^n+a_{n-1}t^{n-1}+\\cdots+a_1t+a_0$$Alice 不发送明文系数，否则 Bob 可能分析甚至还原多项式的根。Alice 加密每个系数：\n$$\\operatorname{Enc}(a_0),\\operatorname{Enc}(a_1),\\ldots, \\operatorname{Enc}(a_n)$$然后把这些密文发给 Bob。\n第三步：Bob 在密文上计算多项式值\nBob 知道自己的明文 $y_i$，因此知道 $y_i^j$。利用加法同态和“密文乘明文常数”，他可以计算：\n$$\\operatorname{Enc}(P(y_i)) = \\operatorname{Enc}\\left( \\sum_{j=0}^{n}a_jy_i^j \\right)$$这里有个容易产生的疑问：计算多项式不是需要乘法吗，为什么 PHE 也能做？\n原因是 Bob 并没有把两个加密系数相乘。$a_j$ 是加密的，$y_i^j$ 是 Bob 已知的明文常数。很多加法同态方案可以把密文按明文常数缩放，再把结果相加，所以不需要 FHE 那样的任意密文乘法。\n第四步：随机化并带回元素\nBob 选择非零随机数 $r_i$，计算：\n$$\\operatorname{Enc}(r_iP(y_i)+y_i)$$然后发给 Alice 解密。\n为什么还要加上 $y_i$？分两种情况看。\n情况一：Bob 的元素属于交集\n如果 $y_i\\in X$，那么：\n$$P(y_i)=0$$所以：\n$$r_iP(y_i)+y_i=0+y_i=y_i$$Alice 解密后直接得到这个共同元素，并能确认它属于自己的集合。\n情况二：Bob 的元素不属于交集\n如果 $y_i\\notin X$，那么 $P(y_i)\\neq0$，结果为：\n$$r_iP(y_i)+y_i$$由于 $r_i$ 是随机的，这个值被随机化，不应直接暴露 Bob 原来的 $y_i$。Alice 只把能与自己集合元素匹配的解密结果识别为交集。\n用数字走完第 14 页 # 设 Alice 持有：\n$$X=\\{2,5\\}$$Alice 构造：\n$$P(t)=(t-2)(t-5)=t^2-7t+10$$她加密系数 $1,-7,10$，把系数密文发给 Bob。Bob 持有：\n$$Y=\\{3,5\\}$$Bob 处理元素 5\n$$P(5)=25-35+10=0$$假设 Bob 选择 $r=13$：\n$$rP(5)+5=13\\times0+5=5$$Alice 解密得到 5。因为 $5\\in X$，所以确认它是共同元素。\nBob 处理元素 3\n$$P(3)=9-21+10=-2$$假设 Bob 选择 $r=11$：\n$$rP(3)+3=11\\times(-2)+3=-19$$Alice 解密得到的值不是自己集合中的元素，于是不会把它加入交集。\n最终得到：\n$$X\\cap Y=\\{5\\}$$同样，这只是帮助理解的整数演示。实际协议在有限域或模空间内计算，并需要避免编码冲突、模运算造成的误判以及恶意参与方攻击。\n第 13 页和第 14 页到底有什么关系 # 两页看起来使用了不同技术，底层的成员判断却完全一致。\n第 13 页直接计算：\n$$\\prod_{x\\in X}(y_i-x)$$第 14 页先定义：\n$$P(t)=\\prod_{x\\in X}(t-x)$$再计算：\n$$P(y_i)=\\prod_{x\\in X}(y_i-x)$$所以它们都依靠：\n$$y_i\\in X \\iff \\prod_{x\\in X}(y_i-x)=0 \\iff P(y_i)=0$$区别在于怎样安全完成这次判零计算。\n对比 第 13 页 FHE PSI 第 14 页 PHE PSI 加密对象 Bob 的集合元素 Alice 的多项式系数 Alice 表示集合的方式 直接使用每个 $x$ 用根构造 $P(t)$ 计算位置 Alice 在 Bob 的密文上计算 Bob 用自己的明文代入密文多项式 主要判断 解密结果是否为 0 解密结果是否恢复为共同元素 解密者 Bob Alice 交集获得者 Bob Alice 能力与代价 FHE 通用但较重 PHE 运算受限但通常更轻 把两页记成两条流程 # 第 13 页\n$$\\text{Bob 加密 }y_i \\rightarrow \\text{Alice 在密文上计算乘积} \\rightarrow \\text{Bob 解密} \\rightarrow 0\\text{ 表示属于交集}$$第 14 页\n$$\\text{Alice 用集合构造多项式} \\rightarrow \\text{加密多项式系数} \\rightarrow \\text{Bob 在密文上代入 }y_i \\rightarrow \\text{Alice 解密并识别交集}$$ 常见疑问 # 为什么不直接把多项式发给 Bob\n因为多项式的根就是 Alice 的集合元素。直接公开完整多项式，可能让 Bob 通过求根等方法恢复 Alice 的集合。加密系数正是为了让 Bob 能求值，却看不到系数和根。\n为什么“结果为 0”能判断相等\n因为构造中包含每一个差值 $(y_i-x)$。只要 $y_i$ 等于某个 $x$，对应差值就是 0，整个乘积也必然为 0。\n随机数会不会把交集结果弄错\n不会破坏成员对应的 0，因为：\n$$r\\times0=0$$它主要改变非零结果，用来减少非交集信息的泄露。正式协议还会限定随机数的取值范围，并在选定代数结构中证明正确性和安全性。\nFHE 越强，为什么不全部使用 FHE\n密码方案不仅要“能算”，还要考虑时间、内存、带宽和实现复杂度。如果任务只需要加法同态和明文常数乘法，PHE 已经够用，使用更重的 FHE 未必划算。\nPPT 第 15 页：先弄懂一次 1-out-of-2 OT # 第 15～21 页属于同一条知识链：\n$$\\text{第 15 页：用 DH 完成一次 OT}\\longrightarrow\\text{第 16～21 页：用少量 Base OT 扩展出大量 OT}$$第 15 页已经完整实现了一次 OT：Alice 把明文消息 $m_0,m_1$ 分别加密成 $C_0,C_1$ 发给 Bob，Bob 算出自己所选分支的密钥并解出 $m_b$。\n什么是 1-out-of-2 OT # OT 是 Oblivious Transfer，中文通常译为“不经意传输”。在 1-out-of-2 OT 中：\nAlice 是 Sender，持有两条消息 $m_0,m_1$； Bob 是 Receiver，持有选择位 $b\\in{0,1}$； Bob 只得到 $m_b$，不能同时得到另一条消息； Alice 不知道 Bob 选择了 0 还是 1。 因此，“1-out-of-2”就是“从两条消息中秘密选择一条”。这里的 0 和 1 是两个分支的编号。\n第 15 页的完整通信顺序 # 双方约定一个循环群、生成元 $g$ 和相应安全参数。以下指数都在协议规定的群中计算。\n第一步：Alice 随机选择秘密指数。\nAlice 随机选择秘密数 $\\alpha$，计算：\n$$A=g^\\alpha$$然后把 $A$ 发给 Bob。Alice 不发送 $\\alpha$。\n第二步：Bob确定选择位并随机选择秘密指数。\nBob 决定选择位 $b\\in{0,1}$。$b$ 是 Bob 想选哪条消息的输入，不一定是随机数；在某些随机 OT 场景中它才会随机产生。\nBob 再随机选择秘密数 $\\beta$，计算：\n$$B=A^b g^\\beta$$然后把 $B$ 发给 Alice。Bob 不发送 $b$ 和 $\\beta$。\n第三步：Alice在本地生成两把候选密钥。\n$$K_0=B^\\alpha$$$$K_1=(B/A)^\\alpha$$实际系统通常还会把这些群元素送入 KDF 或 Hash，得到固定长度的对称密钥。Alice 使用两把密钥分别保护消息：\n$$C_0=\\operatorname{Enc}_{K_0}(m_0),\\qquad C_1=\\operatorname{Enc}_{K_1}(m_1)$$Alice 把 $C_0,C_1$ 都发给 Bob，但不会发送 $K_0,K_1$。\n第四步：Bob自己计算解密密钥。\nBob 在本地计算：\n$$K_B=A^\\beta$$这把密钥不是 Alice 通过网络发来的。协议利用 DH 的交换性质，让它自动等于 Alice 两把密钥中的一把。\n为什么 Bob 的密钥恰好匹配一把 # 如果 Bob 选择 $b=0$：\n$$B=A^0g^\\beta=g^\\beta$$于是：\n$$K_0=B^\\alpha=g^{\\alpha\\beta}=A^\\beta=K_B$$所以 Bob 能用 $K_B$ 解开 $C_0$，得到 $m_0$。\n如果 Bob 选择 $b=1$：\n$$B=Ag^\\beta$$因此：\n$$K_1=(B/A)^\\alpha=g^{\\alpha\\beta}=A^\\beta=K_B$$所以 Bob 能解开 $C_1$，得到 $m_1$。\n这不是双方把密钥发出来进行比较，而是：\n$$b=0\\Rightarrow K_B=K_0,\\qquad b=1\\Rightarrow K_B=K_1$$Bob 自己算出的密钥天然落在所选分支上。\nBob 解出明文，为什么还不一定等于求出了交集 # PPT 中的 $m_0,m_1$ 的确是 Alice 持有的两条明文消息。Alice 用两把密钥加密它们：\n$$C_0=\\operatorname{Enc}_{K_0}(m_0),\\qquad C_1=\\operatorname{Enc}_{K_1}(m_1)$$Bob 根据选择位 $b$ 算出对应密钥 $K_B$，因此可以解开 $C_b$，得到 $m_b$。到这里，1-out-of-2 OT 已经成功完成。\n但“得到所选消息”和“得到集合交集”是两个层次：\nOT 只保证 Bob 从两条消息中秘密取得一条； PSI 还要定义这两条消息分别表示什么，以及 Bob 怎样根据解出的内容判断自己的某个元素是否也属于 Alice 的集合； 如果后续已经把 $m_0,m_1$ 设计成某个元素的匹配结果、标签或解密材料，那么 Bob 解出 $m_b$ 就是在执行 PSI 的一个具体步骤； 如果 $m_0,m_1$ 只是普通消息，那么这次 OT 本身不会自动产生交集。 例如，Alice 的两条消息只是“苹果”和“香蕉”，Bob 解出“香蕉”，只能说明他秘密选择了第二条消息。若协议另行规定“能正确解出的标签表示元素存在于交集”，Bob 才能据此完成相应的交集判断。因此，第 15 页完成了 OT；它是否已经产生 PSI 信息，取决于 PPT 后续怎样定义 $m_0,m_1$ 的含义。\n这种公式是固定规则吗 # OT 的功能目标是固定的：Sender 有两条消息，Receiver 秘密选择其中一条。但 $B=A^bg^\\beta$ 并不是所有 OT 必须采用的公式，它是这个 DH-based OT 为实现功能目标而设计的数学结构。\n可以把设计思路反过来看：协议希望实现“$b=0$ 时匹配 $K_0$，$b=1$ 时匹配 $K_1$”，因此构造了 $B,K_0,K_1$ 的上述关系。\n容易混淆的提醒： 这里使用了 DH 的共享值性质，但没有使用 ElGamal 的完整加密格式；也没有通过“比较两把密钥”决定结果。\nPPT 第 16～21 页：IKNP OT 扩展 # 如果 PSI 需要上百万次 OT，而每次都运行第 15 页的公钥运算，成本会很高。OT Extension 的作用是：\n$$\\boxed{\\text{少量昂贵的 Base OT}+\\text{大量 XOR、Hash 等便宜运算}\\Rightarrow\\text{大量 OT}}$$这里学习的是 IKNP 的核心构造。它不改变 OT 的功能，只降低批量生成 OT 的成本。\n先看最终想得到什么 # 设最终要扩展出 $n$ 个 OT。对于每个 $i$：\nAlice 最终拥有两个候选密钥 $(K_i^0,K_i^1)$； Bob 拥有选择位 $r_i\\in{0,1}$； Bob 只拥有 $K_i^{r_i}$； Alice 不知道每个 $r_i$。 安全参数记作 $\\lambda$，一般远小于 $n$。PPT 的小矩阵只是演示，实际 $\\lambda$ 会按安全要求选取。\n五个符号先分清 # 符号 谁持有 含义 $r=(r_1,\\ldots,r_n)$ Bob 最终 $n$ 个 OT 的选择向量 $s=(s_1,\\ldots,s_\\lambda)$ Alice Base OT 阶段的选择向量 $T,T'$ Bob 两个 $n\\times\\lambda$ 比特矩阵 $Q$ Alice 做完 $\\lambda$ 次 Base OT 后拼成的矩阵 $t_i,q_i$ Bob / Alice $T,Q$ 的第 $i$ 行 $r_i$ 和 $s_j$ 不是同一个选择：$r_i$ 控制第 $i$ 个最终 OT，$s_j$ 控制第 $j$ 个 Base OT。\n用到的知识： 第 15 页的 1-out-of-2 OT、比特 XOR、矩阵的行列、Hash。\n暂时不用： 集合元素、交集判断、同态加密和 RSA。此处生成的是后续协议要用的密钥材料。\n第一步：Bob把最终选择编码成矩阵 R # Bob 有选择向量：\n$$r=(r_1,r_2,\\ldots,r_n)^T$$每个 $r_i$ 表示第 $i$ 个最终 OT 选择 0 分支还是 1 分支。它是协议输入；如果 PPT 的特定构造要求随机 OT，可以随机选择，但一般不能把所有选择位都默认说成随机数。\nBob 把每个 $r_i$ 横向重复 $\\lambda$ 次，得到 $n\\times\\lambda$ 矩阵 $R$。若 $r_i=0$，第 $i$ 行全为 0；若 $r_i=1$，第 $i$ 行全为 1。\n第二步：Bob随机生成 T，再构造 T' # Bob 随机生成 $n\\times\\lambda$ 比特矩阵 $T$，然后定义：\n$$T'=T\\oplus R$$$\\oplus$ 表示逐位 XOR：\n$x$ $y$ $x\\oplus y$ 0 0 0 0 1 1 1 0 1 1 1 0 因此：\n$$x\\oplus0=x,\\qquad x\\oplus1=\\overline{x}$$对第 $i$ 行有：\n$$r_i=0\\Rightarrow t'_i=t_i$$$$r_i=1\\Rightarrow t'_i\\text{ 是 }t_i\\text{ 的逐位翻转}$$“逐位相反”就是相同位置一个为 0、另一个为 1，所以两行 XOR 后得到全 1。\n第三步：角色暂时反转，按列做 Base OT # 最终大量 OT 中 Alice 是 Sender、Bob 是 Receiver；但在 $\\lambda$ 次 Base OT 中角色反过来：\nBob 是 Base OT 的 Sender； Alice 是 Base OT 的 Receiver。 Bob 把 $T$ 的第 $j$ 列 $T^{(j)}$ 和 $T\u0026rsquo;$ 的第 $j$ 列 $T\u0026rsquo;^{(j)}$ 作为两条消息。Alice 随机选择长度为 $\\lambda$ 的秘密比特串：\n$$s=(s_1,s_2,\\ldots,s_\\lambda)$$在第 $j$ 次 Base OT 中：\n$$s_j=0\\Rightarrow\\text{Alice得到 }T^{(j)}$$$$s_j=1\\Rightarrow\\text{Alice得到 }T'^{(j)}$$这不是从矩阵推导出的自然规律，而是 1-out-of-2 OT 接口中事先约定的分支编号：选择位 0 取第一条，选择位 1 取第二条。\n因为矩阵只有 $\\lambda$ 列，所以这里只运行 $\\lambda$ 次昂贵的 Base OT，而不是 $n$ 次。\n第四步：Alice把收到的列拼成 Q # Alice 每次 Base OT 得到一列，把 $\\lambda$ 列按原顺序拼起来，形成 $n\\times\\lambda$ 矩阵 $Q$。\n这一步的视角切换非常关键：\n前半段按列做 $\\lambda$ 次 Base OT，后半段按行解释成 $n$ 个扩展 OT。\n$Q$ 不是交集，也不是集合匹配结果；它是 Alice 得到的相关随机比特矩阵。\n第五步：推导 q_i 与 t_i 的关系 # 观察第 $i$ 行、第 $j$ 列。Alice 根据 $s_j$ 选 $T$ 或 $T\u0026rsquo;$ 的第 $j$ 列，而：\n$$t'_{i,j}=t_{i,j}\\oplus r_i$$因此：\n$$q_{i,j}=t_{i,j}\\oplus(r_i\\land s_j)$$$\\land$ 表示 AND。把一整行合起来：\n$$q_i=t_i\\oplus(r_i\\land s)$$于是得到：\n$$q_i=\\begin{cases}t_i,\u0026r_i=0\\\\t_i\\oplus s,\u0026r_i=1\\end{cases}$$这个关系不是所有 OT 天生遵守的定律，而是采用 $T\u0026rsquo;=T\\oplus R$ 和按 $s_j$ 选列之后推导出的必然结论。\n第六步：为什么 Alice 还要形成两个候选值 # 仅有 $q_i$ 与 $t_i$ 的相关性，还没有明确形成标准 OT 的两个分支。Alice 对每一行定义：\n$$\\text{第 0 个候选}=q_i,\\qquad\\text{第 1 个候选}=q_i\\oplus s$$Bob 始终持有 $t_i$：\n$$r_i=0\\Rightarrow t_i=q_i$$$$r_i=1\\Rightarrow t_i=q_i\\oplus s$$所以 Bob 的 $t_i$ 恰好等于 Alice 两个候选值中的一个。这时第 $i$ 个扩展 OT 的“二选一”结构才真正形成。\n第七步：Hash 成为可用的密钥 # Alice 计算：\n$$K_i^0=H(i\\parallel q_i),\\qquad K_i^1=H(i\\parallel(q_i\\oplus s))$$Bob 计算：\n$$K_i=H(i\\parallel t_i)$$于是：\n$$r_i=0\\Rightarrow K_i=K_i^0,\\qquad r_i=1\\Rightarrow K_i=K_i^1$$这里的 $\\parallel$ 表示拼接，$i$ 是第几次 OT 的编号。把编号放进哈希输入，可以让不同行即使碰巧出现相同的比特串，也使用不同的密钥。Hash 在这里用于把相关比特串变成适合后续使用的密钥材料。它不是第 10 页那种“直接对集合元素做 Hash 再求交”的 Hash PSI，也没有用 Hash 直接判断交集。\n用一个小矩阵走完 OT 扩展 # 下面的数字仅用于教学演示，安全参数很小，不能用于真实系统。\n设最终需要 $n=3$ 个 OT，演示用 $\\lambda=2$。Bob 的选择向量取：\n$$r=(0,1,0)^T$$这里 $r$ 表示示例中希望选择的分支，不把它说成随机数。扩展后：\n$$R=\\begin{pmatrix}0\u00260\\\\1\u00261\\\\0\u00260\\end{pmatrix}$$Bob 随机选择示例矩阵：\n$$T=\\begin{pmatrix}1\u00260\\\\0\u00261\\\\1\u00261\\end{pmatrix}$$计算：\n$$T'=T\\oplus R=\\begin{pmatrix}1\u00260\\\\1\u00260\\\\1\u00261\\end{pmatrix}$$Alice 随机选择 Base OT 选择向量：\n$$s=(1,0)$$第 1 次 Base OT 中 $s_1=1$，Alice 取得 $T\u0026rsquo;$ 的第 1 列；第 2 次中 $s_2=0$，取得 $T$ 的第 2 列。拼接得到：\n$$Q=\\begin{pmatrix}1\u00260\\\\1\u00261\\\\1\u00261\\end{pmatrix}$$逐行检查：\n$i$ $r_i$ Bob 的 $t_i$ Alice 的 $q_i$ 关系 1 0 10 10 $q_1=t_1$ 2 1 01 11 $q_2=t_2\\oplus s$ 3 0 11 11 $q_3=t_3$ 还差最后一步：把每一行的关系变成真正可使用的一次 OT。Alice 对每行算出两个候选比特串；Bob 用自己持有的 $t_i$ 算出其中一个：\n第几次 OT Alice 的第 0 个候选 $q_i$ Alice 的第 1 个候选 $q_i\\oplus s$ Bob 的 $t_i$ Bob 选择 1 10 00 10 第 0 个 2 11 01 01 第 1 个 3 11 01 11 第 0 个 例如第 2 行，$q_2=11$，而 $s=10$，所以第 1 个候选是 $11\\oplus10=01$。Bob 手中的 $t_2$ 恰好也是 $01$；他能算出第 1 个分支的密钥 $H(2\\parallel01)$。Alice 则同时算出 $H(2\\parallel11)$ 和 $H(2\\parallel01)$，但不知道 Bob 选了哪个分支。这里的 0、1 都是分支编号，不是集合元素。\n现在给三次 OT 分别放入两条示例明文：\n第几次 OT Alice 的第 0 条明文 $m_i^0$ Alice 的第 1 条明文 $m_i^1$ Bob 最终解出的明文 1 红色 蓝色 红色 2 小猫 小狗 小狗 3 高山 大海 高山 Alice 用每行的两把密钥分别加密两条明文，并把两个密文都发给 Bob。以第 2 次 OT 为例：\n$$C_2^0=\\operatorname{Enc}_{H(2\\parallel11)}(\\text{小猫}),\\qquad C_2^1=\\operatorname{Enc}_{H(2\\parallel01)}(\\text{小狗})$$Bob 用 $H(2\\parallel t_2)=H(2\\parallel01)$ 解开 $C_2^1$，得到“小狗”。第 1、3 次同理，分别解出“红色”和“高山”。Bob 只掌握每行所选分支的密钥；Alice 不知道他的选择向量 $r=(0,1,0)^T$。\n至此，例子才完整展示了三次扩展 OT。 这些明文只是教学用的普通消息，不能从“红色、小狗、高山”推得集合交集。只有后续 PSI 协议规定消息与集合匹配的关系，才能用 OT 的输出判断交集。示例中的 $\\lambda=2$ 仅便于手算，真实协议需要足够大的安全参数、正确的密钥派生与安全加密；这里展示的是功能关系，不是可直接使用的安全实现。\nPPT 第 22～29 页：把基础工具接回 PSI # 前面已经知道怎样完成一次 OT，也知道怎样批量扩展 OT。接下来要回答的是：这些工具怎样处理集合元素，最后得到交集？读这几页时，先把“最终想完成的功能”“实现功能的密码工具”和“存放数据的结构”分开。\n层次 本阶段的概念 负责什么 最终目标 PSI 让约定的结果方找出共同元素 中间功能 OPRF、混淆电路 GC 分别生成受密钥控制的匹配标签、执行约定的安全计算 密码工具 OT、OT 扩展、DH、VOLE 支撑中间功能的具体实现 数据结构 布隆过滤器 BF、OKVS 把集合或键值关系组织成便于协议使用的形式 这里有三条学习路线：OT + BF 用二选一计算位数组的 AND；DH 或 VOLE + OKVS 先实现 OPRF，再比较标签；GC + BF 把相关位运算放进安全电路。 它们可以实现相近的匹配目标，使用的中间表示不同。下面各例都把执行步骤接到最终判断，随机选取的量会明确标明。\nPPT 第 22～23 页：布隆过滤器与 OT 如何配合 # 布隆过滤器的插入、查询和误判 # 布隆过滤器由长度为 \\(m\\) 的位数组和 \\(k\\) 个哈希函数组成。位数组初始全为 0；插入元素 \\(x\\) 时，将 \\(h_1(x),\\ldots,h_k(x)\\) 指定的位置全部置为 1。查询一个元素时，重新计算这些位置：只要有一个位置为 0，就能确定它没有插入；全部为 1，则只能判断它可能存在。\n原因是不同元素可以共用位置。一个没有插入的元素，其全部查询位置可能碰巧已被其他元素置为 1，这叫假阳性。普通 BF 在没有删除操作、构造和查询保持一致时，对已经插入的元素没有假阴性。PPT 的误判率近似式为：\n$$P_f\\approx(1-e^{-kn/m})^k$$这里的 \\(m,k,n\\) 分别是数组长度、哈希函数数目、已插入元素数目。这个概率由数据结构参数决定，与 OT 能否安全传输消息是两件不同的事。\n用一个位数组例子走完流程 # 设 Alice 持有 \\(X=\\{A,B\\}\\)，Bob 持有 \\(Y=\\{B,C\\}\\)。教学用数组长度为 6，下标从 0 开始，使用两个公开哈希函数。约定本例中计算出的哈希位置如下；这些位置是哈希输出，不是每次查询重新随机选择的位置。\n元素 两个哈希位置 A 0、2 B 1、4 C 3、5 插入各自的集合后，双方分别得到：\n1 2 3 下标 0 1 2 3 4 5 BF_X 1 1 1 0 1 0 BF_Y 0 1 0 1 1 1 第一步：Alice 为每个位置准备两条 OT 消息。 在位置 \\(i\\) 上，她提供 \\((m_i^0,m_i^1)=(0,BF_X[i])\\)。这里两条消息的内容可能相同，例如 \\(BF_X[i]=0\\) 时两条消息都是 0；二选一说的是两个分支，并不要求消息内容不同。\n第二步：Bob 用自己对应的 BF 位作选择。 他令 \\(b_i=BF_Y[i]\\)。这里 \\(b_i\\) 由集合编码决定，不是随机选择位：选 0 得到 0，选 1 得到 \\(BF_X[i]\\)。\n第三步：Bob 拼接所有 OT 输出。 每个输出恰好为 \\(BF_X[i]\\land BF_Y[i]\\)，得到：\n1 AND结果 0 1 0 0 1 0 第四步：Bob 用自己的元素查询。 B 的位置 1、4 都为 1，因而被保留；C 的位置 3、5 为 0，因而被排除。本例的候选交集为 \\(\\{B\\}\\)。\n这里完成了从集合、位数组、OT 消息到匹配判断的完整功能链。若数组很长，就需要很多次 OT；前面学的 OT 扩展正好用于减少这些 OT 的公钥运算成本。直接重复 Base OT 也可以完成这些二选一，效率会不同。\n位数组 AND 为什么还要谨慎理解 # PPT 用 \\(BF_{X\\cap Y}\\) 表示 AND 结果，这是方便讲解的记号。一般情况下，两个 BF 的 AND 不等于只用真实交集重新构造的 BF：不同的非交集元素也可能把共同位置置为 1。用 Bob 的元素查询时仍会产生假阳性。\n此外，上述朴素流程让 Bob 学到一些 Alice 的 BF 位，不能仅凭“用了 OT”就断言完整 PSI 隐私已经成立。PPT 提到的 GBF（混淆布隆过滤器）用多比特字符串和分享关系等机制保护表示，带来额外通信成本。BF 与 GBF 的具体编码规则不同，不能把普通 0/1 BF 例子直接当作 GBF 的安全实现。\n本块用到： 哈希定位、位数组、AND、OT 和 OT 扩展。暂时不用： 同态加密、多项式判零、OPRF。哈希负责定位，OT 负责保护选择；准确性和隐私性还需分别检查。\nPPT 第 24～25 页：OPRF 先生成标签，再完成匹配 # 第 24 页先给功能接口 # 伪随机函数 PRF 写为 \\(F_k(x)\\)：在同一密钥 \\(k\\) 下，相同输入总得到相同输出；输出从没有密钥的一方看来应像随机值。函数名称和算法可以公开，秘密的是密钥。OPRF 让 Bob 在不直接向 Alice 公开输入 \\(y\\) 的情况下，取得 \\(F_k(y)\\)，同时保护 Alice 的密钥。这个功能定义也可参考 RFC 9497 对 OPRF 的说明。\n用 \\(X=\\{A,B\\}\\)、\\(Y=\\{B,C\\}\\) 说明第 24 页的完整流程：Alice 持有秘密密钥 \\(k\\)，本地计算 \\(Z=\\{F_k(A),F_k(B)\\}\\)；Bob 通过 OPRF 取得 \\(F_k(B),F_k(C)\\)。Alice 将自己的标签集合 Z 发给 Bob，Bob 检查自己的两个标签是否出现在 Z 中，最后识别出 B。\nOPRF 阶段本身只负责取得函数值；Alice 发标签、Bob 比较并恢复对应的本地元素，才把它接成 PSI。它与普通 Hash PSI 都会比较标签，但普通公开哈希可被任何人离线计算，OPRF 的计算受秘密密钥和协议查询控制。接收方仍可能提交自己选择的查询，具体 PSI 还应说明允许的输入、查询次数和威胁模型。\n第 25 页用 DH 实现这个接口 # 设双方约定阶为素数 \\(q\\) 的合适群，\\(H_G(y)\\) 把输入映射到群元素。Alice 随机选择非零秘密密钥 \\(k\\)；Bob 对每次输入随机选择非零盲化指数 \\(\\beta\\)。流程是：\nBob 发 \\(H_G(y)^\\beta\\) 给 Alice。 Alice 对收到的群元素做 \\(k\\) 次幂，返回 \\(H_G(y)^{\\beta k}\\)。 Bob 使用 \\(\\beta^{-1}\\) 去盲，得到 \\(H_G(y)^k\\)。 Alice 本地计算自己元素的相同形式，双方再按第 24 页完成标签比较。 $$\\left(H_G(y)^{\\beta k}\\right)^{\\beta^{-1}}=H_G(y)^k$$这里的逆元是在模群阶 q 的指数运算中计算的，满足 \\(\\beta\\beta^{-1}\\equiv1\\pmod q\\)，并非负数 \\(-\\beta\\)。PPT 第 25 页的去盲写法需要按这个含义理解；其 H 也应理解为合适的群映射，不能对任意比特串直接做群运算。规范中的去盲步骤同样使用盲化标量的逆元，实际输出还包含约定的最终哈希处理，见 RFC 9497 的 OPRF 协议。\n可手算的 DH 例子 # 仅为演示，使用模 23 乘法群中的阶 11 子群，因此群元素运算模 23，指数逆元模 11。设教学映射得到 \\(H_G(A)=2,H_G(B)=4,H_G(C)=8\\)。Alice 本次随机选得 \\(k=3\\)，Bob 对 B、C 的查询分别随机选得 \\(\\beta_B=2,\\beta_C=3\\)。\nBob 的输入 发送的盲化值 Alice 返回 Bob 的逆元 Bob 去盲后的值 B \\(4^2\\bmod23=16\\) \\(16^3\\bmod23=2\\) \\(2^{-1}\\bmod11=6\\) \\(2^6\\bmod23=18\\) C \\(8^3\\bmod23=6\\) \\(6^3\\bmod23=9\\) \\(3^{-1}\\bmod11=4\\) \\(9^4\\bmod23=6\\) Alice 对自己的 A、B 本地计算，分别得到 \\(2^3\\bmod23=8\\) 和 \\(4^3\\bmod23=18\\)。因此 Alice 的比较值集合是 \\(\\{8,18\\}\\)；Bob 将 B 对应到 18、C 对应到 6，只有 B 匹配。本例小参数和教学映射仅用于验证等式，实际系统还需要足够大的群、规范的群映射与最终哈希。\n本块用到： PRF/OPRF 接口、群指数、模群阶的逆元、盲化和标签比较。暂时不用： BF、OKVS、VOLE、密文多项式。第 24 页讲“接口怎样用于 PSI”，第 25 页讲“怎样实现接口”。\nPPT 第 26～27 页：VOLE 与线性 OKVS 如何实现 OPRF # 先统一 Encode 和 Decode 的记号 # OKVS 将若干键值关系编码到一个结构中。本文统一使用“查询键在前，编码结构在后”的记号：\n$$\\mathbf D=\\operatorname{Encode}(\\{(u_i,v_i)\\})$$$$\\operatorname{Decode}(u_i,\\mathbf D)=v_i$$这里 \\(u_i\\) 是 key，\\(v_i\\) 是 value；\\(\\mathbf D\\) 是编码向量，并不是明文键值表。PPT 第 26 页与第 27 页对 Decode 参数的先后顺序不同；读图时应先辨认哪个是查询键、哪个是编码结构，不要把参数顺序变化当成新运算。符号 u 用来区分普通查询键与 OPRF 秘密密钥。\nEncode 的正确性要求保证已编码的键解出约定值；对未编码的键，不保证固定值，也不保证一定非零。一个确定的编码结构 D 和查询键 x，通常会得到确定的解码结果，并非每调用一次就重新抽随机数。其“像随机值”的表现来自编码随机性和构造的分布性质。\n还要注意，OKVS 的键隐藏性质依赖具体定义、值的分布和使用方式。知道某些期望值后，查询者可能利用输出做判断。第 27 页全部编码为零，因此协议额外用随机向量遮住 D；不能仅凭“OKVS”这个名称就认定裸露 D 也安全。\n第 27 页默认需要线性 Decode # 第 27 页用到的 OKVS 对编码向量的解码必须满足以下线性性质：\n$$\\operatorname{Decode}(x,\\mathbf U+\\mathbf V)=\\operatorname{Decode}(x,\\mathbf U)+\\operatorname{Decode}(x,\\mathbf V)$$$$\\operatorname{Decode}(x,\\Delta\\mathbf D)=\\Delta\\operatorname{Decode}(x,\\mathbf D)$$运算在同一个有限域中进行，所有向量长度和公共解码参数相同。这里“线性”针对向量 U、V、D，不表示可以把查询键 x 随意相加拆分。一种理解方式是：对于固定查询键 x，Decode 选取向量中的若干位置，或计算一个由 x 决定的线性组合。具体安全 OKVS 可能使用稀疏线性系统等结构，但本阶段先掌握上述两个等式即可。\nVOLE 提供哪一种关系 # OLE 让一方秘密持有线性函数参数 a、b，另一方秘密持有输入 x，后者取得 \\(ax+b\\)。VOLE 把相关关系批量扩展到向量。第 27 页所用相关随机性分配如下：\n参与方 持有的量 Alice 秘密域元素 \\(\\Delta\\)、向量 \\(\\mathbf B\\) Bob 向量 \\(\\mathbf A\\)、向量 \\(\\mathbf C\\) 共同成立的关系 \\(\\mathbf C=\\Delta\\mathbf A+\\mathbf B\\) 相关随机量通过协议产生，不能把 A、B、C 都独立随机选好后再要求它们恰好满足等式。举例时可先随机选 A、B、Δ，再按关系计算 C；真实协议要同时保证正确分配和隐私。PPT 第 26 页介绍 OLE/VOLE 接口，第 27 页使用相关随机性，左右两方持有什么应以当前图为准。\n完整流程：从零值编码到标签匹配 # 第一步：双方取得 VOLE 输出。 Alice 得到 Δ、B，Bob 得到 A、C，满足上表关系。这里暂时没有输入双方集合的匹配信息。\n第二步：Bob 把自己的集合编码为零值。 对 \\(Y=\\{y_1,\\ldots,y_n\\}\\)，构造：\n$$\\mathbf D=\\operatorname{Encode}(\\{(y_i,0)\\})$$于是每个 Bob 的真实输入都保证 \\(\\operatorname{Decode}(y_i,\\mathbf D)=0\\)。value 设为零是本构造的设计选择，用来消除随后出现的附加项。\n第三步：Bob 发送被随机向量遮住的结构。 他发 \\(\\mathbf M=\\mathbf A+\\mathbf D\\)；不直接发送集合 Y 或裸编码 D。在适合本构造的相关随机性与安全模型下，A 起遮罩作用。保护效果来自完整协议的条件，并非“把两个向量相加”天然能保护任意输入。\n第四步：Alice 生成自己的函数密钥向量。 她利用 B、Δ、M 计算：\n$$\\mathbf K=\\mathbf B+\\Delta\\mathbf M=\\mathbf B+\\Delta(\\mathbf A+\\mathbf D)=\\mathbf C+\\Delta\\mathbf D$$Alice 可直接用前半个表达式计算 K，无需知道 Bob 的 A、C、D。后半个表达式用于证明正确性。K 一般不同于 C；两者的差仍然是 ΔD。\n第五步：各自对本地元素生成标签。 Alice 对 \\(x\\in X\\) 算 \\(H(\\operatorname{Decode}(x,\\mathbf K))\\)；Bob 对 \\(y\\in Y\\) 算 \\(H(\\operatorname{Decode}(y,\\mathbf C))\\)。Alice 把自己的标签集合发给 Bob，Bob 用自己标签与本地元素的对应关系恢复交集，这一步接回第 24 页的 OPRF-PSI 框架。\nAlice 不知道 y_i，为什么红框写 Decode(y_i,K) # 红框是在证明共同输入处的输出一致，并没有新增一次消息发送。真实执行时 Alice 使用自己的 x，Bob 使用自己的 y；若某个 \\(x_j=y_i\\)，证明者就可以用同一个变量 \\(y_i\\) 比较两个理论结果。\n$$\\operatorname{Decode}(y_i,\\mathbf K)=\\operatorname{Decode}(y_i,\\mathbf C)+\\Delta\\operatorname{Decode}(y_i,\\mathbf D)=\\operatorname{Decode}(y_i,\\mathbf C)$$最后一步成立，是因为 Bob 已将 \\((y_i,0)\\) 编入 D。消失的是解码后的附加项 \\(\\Delta\\operatorname{Decode}(y_i,\\mathbf D)=\\Delta\\times0\\)，并不是整个向量 ΔD 变为零。Alice 可以不知道某个查询点，却仍然拥有在该点定义的函数；证明者分析该函数，也不意味着 Alice 获得了那个点。\n从 Encode 开始手算的线性例子 # 之前直接指定几个 Decode 输出，会让人不清楚数字是否符合编码规则。下面给出实际向量，并定义公开解码规则，所有结果都从向量算出来。这是验证线性等式的教学模型，不具备实际安全 OKVS 的键隐藏和高强度安全保证。\n设 \\(X=\\{2,7\\}\\)，\\(Y=\\{2,5\\}\\)，所有加减乘法都在 \\(\\mathbb F_{101}\\) 中进行，也就是结果模 101。编码向量有三个分量，针对本例的三个键，公开解码规则如下：\n$$\\operatorname{Decode}(2,(u_0,u_1,u_2))=u_0+u_1\\pmod{101}$$$$\\operatorname{Decode}(5,(u_0,u_1,u_2))=u_1+u_2\\pmod{101}$$$$\\operatorname{Decode}(7,(u_0,u_1,u_2))=u_0+u_2\\pmod{101}$$这些规则只展示本例用到的查询点。它们是教学参数，参与方无需知道对方具体持有哪些键；真实结构要有覆盖输入域的公共解码算法。\n先完成 Encode。 为了把 (2,0)、(5,0) 编进去，需要解两个约束：\\(d_0+d_1=0\\)、\\(d_1+d_2=0\\)。Bob 随机选得自由分量 \\(d_1=3\\)，据约束算得：\n$$\\mathbf D=(98,3,98)$$因此 Decode(2,D) 和 Decode(5,D) 都是 \\(101\\bmod101=0\\)；未编码的键 7 则解出 \\(196\\bmod101=95\\)。95 是从本次随机编码得到的向量推出来的，不是另外随意指定的随机数。 本模型中若自由分量改了，未编码键的输出也会改变；固定 D 后重复查询 7，仍得到 95。\n再产生相关随机性。 教学中假设这次随机选得 \\(\\Delta=3\\)、\\(\\mathbf A=(4,7,9)\\)、\\(\\mathbf B=(6,2,8)\\)，据关系计算：\n$$\\mathbf C=3\\mathbf A+\\mathbf B=(18,23,35)$$实际 VOLE 按协议将这些量分配给双方；此处把它们写在一张纸上，仅供验证，并非双方互相公开全部向量。\nBob 发 M，Alice 算 K。 分量均模 101：\n$$\\mathbf M=\\mathbf A+\\mathbf D=(1,10,6)$$$$\\mathbf K=\\mathbf B+3\\mathbf M=(9,32,26)$$也可以核对 \\(\\mathbf C+3\\mathbf D=(9,32,26)\\)，两种算法一致。最后按同一解码规则逐点检查：\n查询键 Decode(键,D) Decode(键,C) Decode(键,K) 验证关系 2 0 \\(18+23=41\\) \\(9+32=41\\) \\(41+3\\times0=41\\) 5 0 \\(23+35=58\\) \\(32+26=58\\) \\(58+3\\times0=58\\) 7 95 \\(18+35=53\\) \\(9+26=35\\) \\((53+3\\times95)\\bmod101=35\\) 真实执行时，Alice 只计算自己元素 2、7 对应的 \\(H(41),H(35)\\)；Bob 只需要自己元素 2、5 对应的 \\(H(41),H(58)\\)。Alice 发送这两个标签后，Bob 识别到标签 H(41) 对应自己的元素 2，于是得到 \\(\\{2\\}\\)。表中为 5 计算 K、为 7 计算 C，是旁观者的验证，不是要求双方知道对方元素。\n本例不同输出没有碰撞。实际参数中，未编码键的解码结果仍可能偶然为零，不同键或最终哈希也可能碰撞；需要足够大的域、足够长的标签和构造的整体分析。哈希不能把已经相同的两个域值变成不同值，也不能靠把小域值哈希得很长就补回安全强度。\n本块用到： 有限域、相关随机向量、Encode 正确性、Decode 对向量的线性、哈希标签比较。暂时不用： DH 指数、BF、GC、FHE/PHE。重点是区分真实执行、正确性证明和教学者的全知算例。\nPPT 第 28～29 页：混淆电路如何计算，怎样接到 BF # 输入比特与导线标签 # 把目标函数拆成 AND、XOR、NOT 等逻辑门后，GC 用随机字符串代表每根导线上的 0 和 1。一根导线有两个不同的随机标签，例如 \\(W_a^0,W_a^1\\)。上标 0、1 是说明书中的含义；计算方拿到一个标签字符串时，并没有自动得到两种标签与比特含义的完整映射。\nPPT 把 GC 概括为“OT + 逻辑电路”，适合记住连接关系；完整过程还包括随机标签生成、门的混淆、输入标签传递和输出解码。这里可以先用一个 AND 门弄清每一方在做什么。\n一个 AND 门的完整执行例子 # 目标是 \\(c=a\\land b\\)。设 Alice 的输入 \\(a=1\\)，Bob 的输入 \\(b=0\\)；这两个输入是本例的私有数据，不把它们说成随机数。Alice 则为三根导线随机生成标签 \\((A_0,A_1)\\)、\\((B_0,B_1)\\)、\\((C_0,C_1)\\)。\n第一步：Alice 混淆真值表。 用两个输入标签保护对应的输出标签，并打乱表项。下面表示加密前的逻辑关系；实际发出的表项不直接写明输入比特：\nAlice 输入 Bob 输入 用哪些标签打开表项 得到的输出标签 0 0 \\(A_0,B_0\\) \\(C_0\\) 0 1 \\(A_0,B_1\\) \\(C_0\\) 1 0 \\(A_1,B_0\\) \\(C_0\\) 1 1 \\(A_1,B_1\\) \\(C_1\\) 第二步：双方交付正确的输入标签。 Alice 根据自己的 \\(a=1\\) 发送 A₁。对于 Bob 的输入导线，Alice 通过 OT 提供 B₀、B₁，Bob 使用私有选择位 \\(b=0\\)，只拿到 B₀；Alice 不应从 OT 得知 b。输入位数多时，这些 OT 也可用 OT 扩展执行。\n第三步：Bob 计算这个门。 Bob 持有 A₁、B₀，按照混淆方案找到并打开对应表项，取得 C₀。教学上可以理解为只有对应的一项能正确打开；实际方案通常有标签标记等机制帮助定位，并不一定需要逐项尝试。\n第四步：解读约定输出。 Bob 根据输出解码信息知道 C₀ 表示 0，得到 \\(1\\land0=0\\)。多门电路中，中间的输出标签会作为下一个门的输入标签；不必把中间比特逐门公开。最后哪些结果给 Bob、哪些给 Alice，由目标功能规定，并非 GC 一律向双方公开。\n“保护输入”也不是说输出无法透露任何信息。输出本身可能推出某个输入，例如 Bob 知道 b=1，若 AND 结果为 0，他就能推知 a=0。协议要保护的是约定输出和允许泄露信息之外的内容。\n用同一个 BF 例子接回第 29 页 # 沿用前面 \\(BF_X=111010\\)、\\(BF_Y=010111\\) 的数组，Alice 为自己各位交付对应导线标签；Bob 通过六次 OT 取得自己各位的标签；Bob 计算六个混淆 AND 门，按约定解码得到 010010。再查询 B 的位置 1、4，保留 B；查询 C 的位置 3、5，排除 C。\n这展示了“GC 安全执行位运算，再做 BF 查询”的功能。若直接输出完整 AND 数组，它仍可能泄露协议不打算公开的结构；需要更严格输出控制时，可把成员查询等后续步骤也纳入安全计算，并只输出约定结果。GC 不会自动消除 BF 的假阳性。\nPPT 第 29 页以共同元素落到下标 0、6 来说明匹配。但图中画出的两条输入位数组相同，AND 输出却少了其他若干个 1，数字之间并不一致。相同数组逐位 AND 后应保持原样，复习时请按正确的位运算规则计算。\n本块用到： 逻辑门、随机导线标签、门表混淆、输入 OT、输出解码，以及 BF 查询。暂时不用： VOLE/OKVS 的代数消项、DH 去盲、密文多项式。现阶段先能沿着输入标签走到输出，后续研究 GC 时再深入 Free-XOR、Half-Gates 等优化。\n第 22～29 页的复习对照 # 路线 中间拿到什么 接回 PSI 的最后一步 要检查的条件 OT + BF 按位二选一得到的 AND 数组 用本地元素查询对应位置 BF 误判、位信息泄露、GBF 等具体设计 DH + OPRF 对已查询元素去盲得到的函数标签 Alice 发本地标签，Bob 对照并恢复本地元素 群映射、逆元、安全参数、查询与输出规则 VOLE + 线性 OKVS + OPRF 编码点处一致的解码值及其哈希 Alice 发本地标签，Bob 对照并恢复本地元素 Decode 线性、相关随机性、编码遮罩、碰撞概率 GC + BF 约定电路的输出 按设计做成员判断或解码匹配结果 电路输出范围、输入保护、BF 误判 这几条路线中的集合元素、密钥、随机遮罩和标签承担不同职责。看到一个公式时，先标出谁实际持有它的输入，再判断它是本地计算、消息发送，还是正确性证明；尤其不要因证明中出现了对方的变量，就认为协议泄露了对方的数据。\n当前整理进度：PPT 第 29 页，已合并本阶段关于流程联系、Encode/Decode、去盲和 GC 的追问。第 30 页为目录，后续新增学习从第 31 页继续整理。\n","date":"2026年9月19日","externalUrl":null,"permalink":"/p/%E9%9A%90%E7%A7%81%E9%9B%86%E5%90%88%E8%AE%A1%E7%AE%97%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E4%BB%8E%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5%E5%88%B0%E5%90%84%E7%B1%BB-psi-%E5%8D%8F%E8%AE%AE/","section":"Posts","summary":"这是一篇持续更新的复习笔记，用来整理《隐私集合计算中的关键技术》PPT 的学习内容。目前已经整理到 第 29 页。重点不是记住一堆缩写，而是理解各种 PSI 协议为什么出现、怎样运行，以及它们之间有什么联系。\n以后学习这份 PPT 的新内容都会继续追加在本文末尾，并注明页码范围，已经讲过的内容不再重复。\n","title":"隐私集合计算学习笔记：从基础概念到各类 PSI 协议","type":"post"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/categories/%E9%9A%90%E7%A7%81%E8%AE%A1%E7%AE%97/","section":"Categories","summary":"","title":"隐私计算","type":"categories"},{"content":"","date":"2026年9月19日","externalUrl":null,"permalink":"/tags/%E9%9A%90%E7%A7%81%E8%AE%A1%E7%AE%97/","section":"Tags","summary":"","title":"隐私计算","type":"tags"},{"content":"欢迎来到 METEOR - 一个关于技术与生活的个人博客。\n","date":"2026年9月19日","externalUrl":null,"permalink":"/","section":"主页","summary":"欢迎来到 METEOR - 一个关于技术与生活的个人博客。\n","title":"主页","type":"page"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/tee/","section":"Tags","summary":"","title":"TEE","type":"tags"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E5%8F%98%E8%89%B2%E9%BE%99%E5%93%88%E5%B8%8C/","section":"Tags","summary":"","title":"变色龙哈希","type":"tags"},{"content":"很多人第一次接触区块链时，会记住“不可篡改”四个字，却不一定知道这四个字是怎样实现的。再往前一步，就会遇到几个容易混淆的概念：哈希为什么会因为一点改动而完全不同？哈希碰撞是不是一定代表系统不安全？陷门又是什么？\n这篇文章把这些概念串成一条线：哈希函数 → 区块链的链式结构 → 哈希碰撞 → 变色龙哈希 → 可编辑区块链。\n一句话理解区块链 # 区块链是一种由多个节点共同保存和校验的、使用密码学保护的链式账本。数据被打包进区块，区块按顺序连接；区块一旦确认，历史记录通常只能追加，不能直接修改。\n它依赖三件事：\n分布式保存：不是一台服务器保存唯一副本，而是多个节点各自保存账本。 密码学校验：哈希、数字签名等机制帮助节点发现数据是否被改动。 共识机制：节点按照规则确认哪些区块可以加入账本。 所以，“不可篡改”不是说物理上绝对不能改，而是说：一旦修改历史数据，伪造者必须同时通过哈希校验、节点验证和共识规则，现实成本通常非常高。\n哈希：数据的数字指纹 # 哈希函数可以把任意长度的输入，计算成固定长度的摘要。例如，SHA-256 会输出 256 位结果，通常写成一串十六进制字符。\n可以把它理解成文件的“数字指纹”：\n1 2 H(\u0026#34;hello world\u0026#34;) = b94d27b9... H(\u0026#34;hello worle\u0026#34;) = fdbae57d... 上面只把最后一个字母改了，但输出看起来完全不同。这是密码学哈希的雪崩效应：输入只改变一位，输出中也会有大量比特随机翻转。\n雪崩效应的意义是让人无法根据输出的局部变化猜出输入改了哪里，同时让篡改很容易被检测出来。\n区块为什么能连成一条链 # 一个区块通常包含交易或其他记录、时间戳，以及区块头信息。区块头会保存前一个区块的哈希值：\n1 区块 A --Hash(A)--\u0026gt; 区块 B --Hash(B)--\u0026gt; 区块 C 假设有人修改了区块 A 中的一笔记录：\nA 的内容变了，Hash(A) 发生巨大变化； B 中保存的仍是旧的 Hash(A)，因此链接校验失败； B 的区块内容也无法保持原来的链条关系，后面的 C、D 等区块会继续受到影响。 这就是传统区块链“修改一个历史区块，会引起连锁失效”的直观原因。攻击者不只要重新计算后续区块，还要让其他节点接受这条伪造链。\n哈希碰撞到底是什么 # 哈希碰撞指两段不同的输入得到相同的哈希输出：\n$$M_1 \\ne M_2,\\quad H(M_1)=H(M_2)$$从数学上说，输入空间通常是无限的，而输出空间是固定的，所以碰撞一定存在。这可以由鸽巢原理直接推出。\n但在工程上，重要的是“能不能在可接受的时间内主动找到碰撞”。SHA-256 的设计目标就是让攻击者几乎无法构造出实用碰撞。也就是说，碰撞在理论上存在，并不代表系统容易被碰撞攻击。\n因此要区分两件事：\n普通密码哈希的碰撞：通常是需要避免的安全问题。 变色龙哈希的可控碰撞：经过授权后主动生成，是一种设计出来的功能。 陷门是什么 # 陷门可以理解为一把特殊的秘密钥匙。没有这把钥匙时，某个问题在计算上很难解决；持有钥匙后，解决同一个问题就变得容易。\n在可编辑区块链中，陷门通常属于变色龙哈希的密钥材料。它不是让任何人都能修改区块，而是让被授权的一方可以在保持哈希值不变的情况下，把旧消息替换成新消息。\n变色龙哈希：允许授权的“同指纹替换” # 变色龙哈希（Chameleon Hash）是一种带陷门的哈希原语。它同时具备两种看似矛盾的性质：\n没有陷门的人，仍然很难构造碰撞； 持有陷门的人，可以把不同消息适配成相同的哈希值。 标准定义通常包括四个算法：\nSetup：生成公共参数； KeyGen：生成公钥和陷门密钥； Hash：根据消息和随机数计算哈希； Adapt：持有陷门的一方，把旧消息对应的随机数调整为新随机数，使新旧消息的哈希保持一致。 形式上可以写成：\n$$CH(pk,m_1,r_1)=CH(pk,m_2,r_2)=h$$其中 $m_1 \\ne m_2$，但哈希结果仍然是同一个 $h$。注意，通常不是“只改消息、哈希自动不变”，而是需要使用陷门计算配套的新随机数。\n可编辑区块链怎样工作 # 传统区块链使用普通哈希连接区块，历史数据一改，后面的链就会失效。可编辑区块链则在特定位置使用变色龙哈希：\n原始区块内容 $m_1$ 和随机数 $r_1$ 计算出哈希 $h$； $h$ 被写入区块头，并被后续区块引用； 当出现合法的删除、修正或脱敏请求时，经过授权的编辑方把内容改为 $m_2$； 编辑方使用陷门计算新的随机数 $r_2$； 新旧内容仍满足 CH(pk,m₁,r₁) = CH(pk,m₂,r₂) = h。 这样，区块内容可以被修订，后续区块引用的哈希仍然有效。\n这并不意味着任何人可以偷偷改账。一个可靠的可编辑区块链还需要身份认证、审批策略、编辑日志和审计机制，明确记录“谁在什么时间、因为什么原因、修改了什么内容”。\n为什么需要可编辑区块链 # 传统区块链的永久保存能力适合存证，却可能与现实中的数据治理要求发生冲突：\n用户要求删除个人敏感信息； 业务发现链上记录录入错误； 链上出现不应公开保存的非法或违规内容； 数据法规要求数据主体拥有更正或删除权。 可编辑区块链试图在两者之间取得平衡：保留区块链的可验证性和审计能力，同时允许经过严格授权的有限修订。\n三种常见实现思路 # 1. 基于变色龙哈希 # 用变色龙哈希替换部分普通哈希，编辑时通过陷门维持链式摘要不变。这是研究最广泛的一类方案，但陷门管理和权限控制很关键。\n2. 双链或多链 # 主链保留原始记录，修正链记录后续编辑结果。读取数据时按照规则解释两条链。它更容易表达修改历史，但会增加存储和查询开销。\n3. 基于共识投票的重写 # 由节点投票决定是否接受一次历史修订，必要时切换到新的链。它适合重大事件，通常不适合频繁的细粒度编辑。\n最大风险：陷门不能由一个人随意掌握 # 如果一个管理员独占完整陷门，他理论上可以修改很多历史内容，这会形成新的单点风险。常见的解决思路是使用 Shamir 秘密共享：\n把陷门拆成多个份额，交给不同机构； 设置 $(k,n)$ 门限，至少 $k$ 个机构同意才能执行编辑； 单独一个机构拿到自己的份额，也无法完成修改。 再配合多方审批、身份签名和不可编辑的审计日志，可以降低滥用风险。\n传统区块链与可编辑区块链 # 对比项 传统区块链 可编辑区块链 历史数据 默认不可修改 允许受控修订 主要摘要 普通密码哈希 常使用变色龙哈希 修改权限 原则上不提供 需要授权和审计 优点 结构简单，篡改成本高 更容易满足纠错、脱敏和合规要求 新风险 脏数据可能永久存在 陷门泄露或权限滥用 最后用五句话记住它们 # 哈希是数据指纹，输入稍微变化，输出通常会发生巨大变化。 区块链把前一区块的哈希写进后一区块，因此历史篡改会产生连锁校验失败。 哈希碰撞是不同输入得到相同输出；普通哈希要求碰撞难以构造。 陷门是让特定持有者可以解决某个困难问题的秘密钥匙。 变色龙哈希利用陷门产生可控碰撞，使可编辑区块链能够在授权、可审计的前提下修订历史数据。 可编辑区块链的关键，不是把区块链变成一个谁都能修改的数据库，而是把“修改”变成一种有权限、有条件、有记录、可追责的系统操作。\n","date":"2026年9月15日","externalUrl":null,"permalink":"/p/%E4%BB%8E%E5%93%88%E5%B8%8C%E5%88%B0%E5%8F%AF%E7%BC%96%E8%BE%91%E5%8C%BA%E5%9D%97%E9%93%BE%E6%8A%8A%E5%8C%BA%E5%9D%97%E9%93%BE%E7%9A%84%E6%A0%B8%E5%BF%83%E6%A6%82%E5%BF%B5%E8%AE%B2%E6%98%8E%E7%99%BD/","section":"Posts","summary":"很多人第一次接触区块链时，会记住“不可篡改”四个字，却不一定知道这四个字是怎样实现的。再往前一步，就会遇到几个容易混淆的概念：哈希为什么会因为一点改动而完全不同？哈希碰撞是不是一定代表系统不安全？陷门又是什么？\n","title":"从哈希到可编辑区块链：把区块链的核心概念讲明白","type":"post"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E5%A4%9A%E6%96%B9%E5%AE%89%E5%85%A8%E8%AE%A1%E7%AE%97/","section":"Tags","summary":"","title":"多方安全计算","type":"tags"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E5%93%88%E5%B8%8C/","section":"Tags","summary":"","title":"哈希","type":"tags"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E5%8F%AF%E7%BC%96%E8%BE%91%E5%8C%BA%E5%9D%97%E9%93%BE/","section":"Tags","summary":"","title":"可编辑区块链","type":"tags"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E7%A7%98%E5%AF%86%E5%85%B1%E4%BA%AB/","section":"Tags","summary":"","title":"秘密共享","type":"tags"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/categories/%E5%AF%86%E7%A0%81%E5%AD%A6/","section":"Categories","summary":"","title":"密码学","type":"categories"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E5%AF%86%E7%A0%81%E5%AD%A6/","section":"Tags","summary":"","title":"密码学","type":"tags"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/categories/%E5%8C%BA%E5%9D%97%E9%93%BE/","section":"Categories","summary":"","title":"区块链","type":"categories"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E5%8C%BA%E5%9D%97%E9%93%BE/","section":"Tags","summary":"","title":"区块链","type":"tags"},{"content":"先想一个问题：两家医院想合作统计某种疾病的患者情况，但谁都不能把完整病历交给对方，怎么办？\n如果把数据全部汇总，计算很简单，但隐私风险很大；如果完全不共享，合作又无法进行。隐私计算研究的就是：数据不直接公开，任务仍然可以完成。\n这句话也常被说成“数据可用不可见”。下面我们一步一步理解它。\n一、隐私计算究竟在保护什么 # 普通加密主要保护数据的存储和传输。比如你把文件加密后放到云盘，别人打不开；但云盘要处理文件时，往往需要先解密。\n隐私计算还希望保护“计算过程”。服务器可以参与计算，却不应该看到完整原始数据。\n举例：银行和医院想计算共同客户的数量。理想结果是双方只知道“共有 100 人”，而不是看到对方的完整客户名单。\n二、多方安全计算：大家一起算，谁也不交底 # 多方安全计算（MPC）允许多个参与者共同计算一个函数，只公开事先约定的结果。\n还是刚才的例子：医院 A、医院 B 和医院 C 想统计三方共同患者数。协议运行后得到数字 100，但任何一家医院都不应该知道另外两家的完整名单。\nMPC 常用秘密共享。一份秘密会被拆成多份，单独拿到一份没有意义，只有足够多的参与者合作才能恢复或完成计算。\nMPC 的研究方向包括：如何减少通信、如何支持更多参与方、有人恶意发送错误数据时如何发现，以及有人掉线时协议能否继续。\n三、秘密共享：不要把钥匙交给一个人 # 秘密共享（SS）就像把保险柜钥匙拆成五片，规定至少三片才能打开。一个人拿到一片，无法打开保险柜。\n在系统中，可以把解密密钥拆给五家机构，规定三家同意后才能解密敏感结果。这样既能防止一个管理员滥用权限，也能避免某个人离职导致密钥彻底丢失。\n研究时常见的问题是：门限能否动态调整？某个机构退出后如何补发份额？如何防止参与者提交假的份额？\n四、PSI：只找共同数据 # 隐私集合交集（PSI）专门解决“双方有哪些相同元素”这个问题。\n例子：电商平台有用户集合 A，银行有用户集合 B。双方运行 PSI 后，得到 $A\\cap B$，也就是共同用户；A 中独有的用户和 B 中独有的用户不会直接暴露。\nPSI 是隐私数据处理里最常用的基础任务，可以用于联合风控、跨平台推荐、患者匹配和数据跨域连接。\n研究重点包括大规模 PSI、多方 PSI、带标签 PSI、可更新 PSI，以及如何降低通信量。\n五、PSU：合并数据但隐藏来源 # 隐私集合并集（PSU）与 PSI 相反，目标是得到多个集合的并集，同时尽量不暴露每个元素来自哪一方。\n例子：多家机构想共同建立一份去重后的黑名单。PSU 可以让大家得到完整的去重集合，而不直接标明某个用户最初由哪家机构提交。\nPSU 通常需要传输更多结果，因此如何减少输出大小、保护元素来源，是重要研究问题。\n六、PMT：只回答“在不在” # 私密成员测试（PMT）用于判断一个元素是否属于某个集合，但不公开整个集合。\n例子：平台想判断某个账号是否在风险名单中。查询方只得到“是”或“否”，看不到风险名单中的其他账号。\nPMT 适合黑名单检查、资格验证和隐私检索。研究时要关注查询方能否通过大量提问反推出整个集合。\n七、OT：只能拿走自己选的那一份 # 不经意传输（OT）可以这样理解：老师准备十道答案，学生只选择其中一道，老师不知道学生选了哪一道，学生也拿不到其余答案。\n在密码协议中，OT 是许多 MPC 和 PSI 方案的基础组件。它让双方交换必要信息，却减少不必要的泄露。\n研究方向包括批量 OT、低通信 OT、抗恶意攻击 OT，以及适合移动设备和大规模网络的实现。\n八、OPRF 和 OPPRF：共同计算指纹，但不互相交出秘密 # OPRF 是“隐私保护的伪随机函数”。一方拥有密钥，另一方提供输入，双方共同得到一个结果，但输入方看不到密钥，密钥方也看不到完整输入。\n例子：双方都把用户手机号转换成伪随机指纹，再比较指纹是否相同；任何一方都不需要直接看到对方的手机号。\nOPPRF 是可编程版本，可以对特定输入设置特定输出，适合更复杂的匹配规则，例如“只有满足某个条件的记录才返回标签”。\n研究重点包括更快的构造、更短的通信，以及如何支持批量输入和动态更新。\n九、OKVS：一张经过保护的查找表 # OKVS 可以先理解为一种隐私键值表。输入一个键，可以查到对应的值，但表的构造和存储方式经过特殊设计，适合放进隐私协议。\n例子：把用户编号作为键，把风险标签作为值。协议可以在不公开整张表的情况下完成查询。\nOKVS 经常和 PSI、OPRF 一起使用。研究者会关注它的空间大小、构造速度和查询错误率。\n十、ORAM：连“查了哪一行”也隐藏起来 # 即使数据内容已经加密，服务器观察访问位置和访问顺序，也可能猜出用户在查什么。ORAM（不经意 RAM）就是为了隐藏这种访问模式。\n例子：你查询加密数据库中的第 10 条记录。如果服务器每次都看到你访问第 10 条，可能推断这条记录很重要。ORAM 会重新排列和填充访问，让服务器难以判断真实目标。\nORAM 的代价是额外读写和通信，因此研究方向主要是降低访问开销、支持并发查询和适配云数据库。\n十一、模糊匹配：不完全相同，也能判断相似 # 普通 PSI 只能判断两个字符串是否完全相等。但现实数据经常有错别字、格式差异和缺失字符。\n例子：“张三”“张 三”和“张珊”可能指向同一个人。模糊匹配希望在不公开姓名的情况下判断两条记录是否足够相似。\n难点是相似度计算可能泄露更多信息，而且编辑距离、集合相似度等计算都比精确匹配更昂贵。如何同时保证准确率、效率和隐私，是这一方向的核心问题。\n十二、多方和阈值：从两个人合作到多个机构共同决策 # 两方协议只涉及甲乙，多方协议还要处理机构数量增加、网络不稳定、参与方串通等问题。\n阈值机制则规定“至少多少方同意才可以继续”。例如五家医院中至少三家同意，才能解密联合统计结果或执行一次数据删除。\n这类研究通常会结合秘密共享、门限签名和身份认证，重点是防止单点控制，同时保证合法参与者能够完成任务。\n十三、TEE：用硬件提供一个安全房间 # 可信执行环境（TEE）可以看成处理器里的安全房间。程序和数据在房间内运行，操作系统和云管理员不能直接查看。\n例子：保险公司把风险模型放进 TEE，医院把数据送入安全区域，模型在里面计算，外部只能拿到规定的统计结果。\nTEE 通常比纯密码协议快，但需要信任硬件和厂商，还要防侧信道攻击、回滚攻击和伪造远程证明。因此研究者会关注如何验证环境真实可信，以及硬件失守后如何降低损失。\n十四、这些组件最终要解决什么业务问题 # 把上面的知识串起来，就会得到几个具体应用：\n加密数据查询：服务器不解密，也能完成条件查询； 隐私数据获取：用户只拿到被授权的字段； 分布式数据清洗：多方找出标签冲突和重复记录，却不交换完整数据； 数据跨域连接：不同机构识别共同记录，用于联合分析； 密态数据处理：在保护状态下完成统计、比较和模型计算。 例如，两家医院可以先用 PSI 找到共同患者，再用 PMT 检查某类风险标签，使用 MPC 计算统计结果，最后用秘密共享控制谁能解密结果。这就是一个完整的隐私数据处理流程。\n十五、新手怎样开始学习 # 建议按这条路线来：\n先掌握哈希、对称加密、公钥加密和数字签名； 再学习秘密共享和安全模型； 接着理解 OT、OPRF 和 PSI 的基本流程； 跑通一个开源 PSI 或 MPC 项目； 根据兴趣深入 OKVS、ORAM、模糊匹配、多方协议或 TEE； 最后选择一个具体问题做实验，例如动态 PSI、隐私数据清洗或通信优化。 要记住：不要把“会背很多缩写”当成学会隐私计算。真正重要的是看到一个业务问题时，能回答三件事：哪些数据需要隐藏？允许泄露什么结果？怎样证明协议确实安全且能运行？\n总结 # 隐私计算的目标，是让数据在不直接公开的情况下产生价值。MPC 负责共同计算，秘密共享负责分散控制权，PSI/PSU/PMT 负责集合处理，OT/OPRF/OPPRF/OKVS 提供密码学积木，ORAM 隐藏访问模式，模糊匹配处理不完全相同的数据，多方和阈值机制管理协作权限，TEE 则用硬件换取更高执行效率。\n这些技术最后都指向同一个研究问题：如何让数据跨机构流动和计算，同时把隐私泄露控制在可接受范围内。\n","date":"2026年9月15日","externalUrl":null,"permalink":"/p/%E5%85%A5%E9%97%A8%E9%9A%90%E7%A7%81%E8%AE%A1%E7%AE%97%E4%BB%8E%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90%E7%9C%8B%E6%87%82%E4%B8%BB%E8%A6%81%E7%A0%94%E7%A9%B6%E6%96%B9%E5%90%91/","section":"Posts","summary":"先想一个问题：两家医院想合作统计某种疾病的患者情况，但谁都不能把完整病历交给对方，怎么办？\n","title":"入门隐私计算：从一个例子看懂主要研究方向","type":"post"},{"content":"","date":"2026年9月15日","externalUrl":null,"permalink":"/tags/%E9%9A%90%E7%A7%81%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86/","section":"Tags","summary":"","title":"隐私数据处理","type":"tags"},{"content":"","date":"2026年8月30日","externalUrl":null,"permalink":"/tags/dkg/","section":"Tags","summary":"","title":"DKG","type":"tags"},{"content":"","date":"2026年8月30日","externalUrl":null,"permalink":"/tags/elgamal/","section":"Tags","summary":"","title":"ElGamal","type":"tags"},{"content":"","date":"2026年8月30日","externalUrl":null,"permalink":"/tags/frost/","section":"Tags","summary":"","title":"FROST","type":"tags"},{"content":"把一把私钥交给单个人保管很方便，但也很脆弱：私钥一旦泄露，攻击者就能解密全部历史密文；保管者离线或丢失密钥，合法用户同样无法恢复数据。\n门限密码学给出的思路是：不让任何一个人持有完整私钥。私钥被拆成多个份额，只有达到门限的一组参与者协作，才能完成解密或签名。本文从 ElGamal 出发，系统梳理这条主线：\nElGamal 为什么可以“分布式解密”； Shamir $(t,n)$ 门限秘密共享怎样拆分和恢复秘密； 如何把“恢复秘密”改造成“不暴露秘密的联合解密”； DKG、主动份额更新为什么能减少单点风险和长期泄露风险； 门限签名、特殊份额、加权份额、可变阈值分别解决什么问题。 先建立整体图景 # 设系统私钥为 $x$，公钥为 $Y$。传统公钥密码体制中，一个人保存 $x$；门限体制中，$x$ 被共享为 $x_1,\\ldots,x_n$。系统仍然只公布一个公钥 $Y$，对外的加密方式不变；区别只在于解密时，参与者各自计算一份部分解密，聚合者把足够多的部分解密合成为明文。\n因此，门限方案不是“把密文切成几块”，而是“把私钥的控制权切成几块”。\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 加密者：使用系统公钥 Y 加密 │ ▼ 密文 (C1, C2) │ ┌──────────┼──────────┐ ▼ ▼ ▼ P1 P2 Pn 持有 x1 持有 x2 持有 xn │ │ │ 部分解密 部分解密 部分解密 └──── 足够 t 份 ────┘ ▼ 聚合者恢复 m 下面先看“原始 ElGamal 私钥究竟做了什么”，再把这个动作分配给多人。\n1. ElGamal：加密和解密到底在抵消什么？ # 1.1 密钥生成 # 在模素数 $p$ 的乘法群中选生成元 $g$，私钥是随机指数 $x$，公钥为：\n$$ Y=g^x\\pmod p. $$公开 $(p,g,Y)$，只保留 $x$。这里的“生成元”是指不断计算 $g,g^2,g^3,\\ldots$ 能产生群内元素的基；“离散对数问题”则是指已知 $g$ 和 $g^x$，在合适的大群中很难反推出指数 $x$。这正是 ElGamal 把 $x$ 当私钥的安全基础。\n1.2 加密与解密 # 要加密消息 $m$，加密者随机选择一次性随机数 $r$：\n$$ C_1=g^r\\pmod p,\\qquad C_2=Y^r\\cdot m\\pmod p. $$密文为 $C=(C_1,C_2)$。解密者计算：\n$$ \\begin{aligned} m\u0026=C_2\\cdot C_1^{-x}\\pmod p\\\\ \u0026=(Y^r\\cdot m)\\cdot(g^r)^{-x}\\\\ \u0026=(g^{xr}\\cdot m)\\cdot g^{-rx}=m\\pmod p. \\end{aligned} $$关键点只有一个：$C_1^x=g^{rx}$ 正好是 $C_2$ 中的“掩码”。谁能得到 $C_1^x$，谁就能去掉掩码。 门限解密要做的就是让多人共同得到 $C_1^x$，但没有任何单人知道 $x$。\n1.3 一个作业式的手算例子 # 取：\n$$ p=2027,\\quad g=1002,\\quad x=90,\\quad r=411,\\quad m=888. $$可计算得到：\n$$ Y=g^x\\bmod p=30, $$$$ C_1=g^r\\bmod p=1514,\\qquad C_2=Y^r\\cdot m\\bmod p=235. $$所以密文为 $C=(1514,235)$。解密时不是计算 $C_1^{-x}$ 的小数倒数，而是在模 $p$ 的乘法群中求逆：\n$$ m=C_2\\cdot C_1^{-90}\\pmod{2027}=888. $$这里的上标 $-x$ 很重要：它表示“先求 $C_1^x$，再求其模逆元”，并不是把 $C_1$ 写成普通文本后在旁边减去 $x$。\n工程提示：真实系统会使用远大于 2027 的安全参数；通常还会在大素数阶子群中运算。上面的数值只用于说明计算过程，不能用于真实安全场景。\n2. Shamir 秘密共享：把秘密藏在多项式常数项里 # 2.1 $(t,n)$ 门限的含义 # $(t,n)$ 方案把秘密分给 $n$ 人，任意不少于 $t$ 人可以恢复秘密；少于 $t$ 人则得不到关于秘密的有效信息。最常用的构造是 Shamir 秘密共享。\n在有限域 $\\mathbb{F}_q$ 中，秘密为 $s$。“有限域”可以先简单理解为：所有加、减、乘、除（除以 0 以外）都在模 $q$ 意义下进行，且结果仍落在同一个有限集合里。随机选择一个 $t-1$ 次多项式：\n$$ f(z)=s+a_1z+a_2z^2+\\cdots+a_{t-1}z^{t-1}\\pmod q. $$其中随机系数 $a_1,\\ldots,a_{t-1}$ 决定了多项式的其他形状，而常数项固定为 $f(0)=s$。把第 $i$ 个份额定义为 $s_i=f(i)$。由于一个 $t-1$ 次多项式由 $t$ 个不同点唯一确定，任意 $t$ 个参与者可以插值得到 $f(0)$；但少于 $t$ 个点时，仍然有多个多项式可能经过这些点，常数项不确定。\n2.2 $(4,7)$ 的可计算例子 # 为了共享 ElGamal 私钥 $x=90$，取 $q=1013$，构造：\n$$ f(z)=90+z+z^2+z^3\\pmod{1013}. $$于是 7 个份额为：\n$$ (x_1,x_2,x_3,x_4,x_5,x_6,x_7)=(93,104,129,174,245,348,489). $$例如选取 $P_1,P_2,P_3,P_4$。“拉格朗日插值”是利用若干已知点还原唯一多项式的方法；其中的 $\\lambda_i$ 是把各个份额加权组合回常数项 $f(0)$ 的系数。在 $z=0$ 处，它们为：\n$$ (\\lambda_1,\\lambda_2,\\lambda_3,\\lambda_4)=(4,-6,4,-1). $$因此：\n$$ \\begin{aligned} x\u0026=\\sum_{i=1}^4\\lambda_i x_i\\\\ \u0026=4\\times93-6\\times104+4\\times129-174=90\\pmod{1013}. \\end{aligned} $$这解释了门限恢复，但直接让大家把 $x_i$ 发给聚合者并不理想：聚合者会恢复出完整私钥 $x$。下一节把插值“搬到指数上”，避免泄露 $x$。\n3. 门限 ElGamal 解密：恢复 $C_1^x$，而不是恢复 $x$ # 每个参与者 $P_i$ 用自己的份额计算部分解密。“部分解密”是不能单独还原明文、但可与其他部分解密组合的群元素：\n$$ D_i=C_1^{x_i}\\pmod p. $$聚合者不需要知道任何 $x_i$，只需要收集至少 $t$ 个 $D_i$，并使用同一组拉格朗日系数：\n$$ \\begin{aligned} D\u0026=\\prod_{i\\in S}D_i^{\\lambda_i}\\pmod p\\\\ \u0026=\\prod_{i\\in S}\\left(C_1^{x_i}\\right)^{\\lambda_i}\\\\ \u0026=C_1^{\\sum_{i\\in S}\\lambda_i x_i}=C_1^x\\pmod p. \\end{aligned} $$最后：\n$$ m=C_2\\cdot D^{-1}\\pmod p. $$对上面的 $(4,7)$ 例子，前四个用户的部分解密可聚合为 $D=838$，从而恢复 $m=888$。即使聚合者收到了 $D_i$，它得到的也是这一次密文对应的 $C_1^x$，而不是某个用户的私钥份额。\n一个容易忽略的严格条件 # Shamir 份额的运算域阶 $q$ 与 ElGamal 指数所在群的阶必须匹配。“子群”是大群中自身仍满足群运算规则的一个较小集合；实践中通常选择 $q\\mid(p-1)$ 的素数阶子群，并让公开基 $h$ 的阶为 $q$，然后使用 $h^x$ 而不是任意整个群生成元的指数。这样“在模 $q$ 下恢复指数”与群中的指数计算完全一致。\n教学手算中，如果插值恰好恢复的是整数 $x=90$，常常看不出这个问题；在真实方案中，忽略它会导致正确性或安全性问题。\n4. DKG：不让中心生成或看见完整私钥 # “中心化分发”很简单：可信中心先选 $f(z)$，再私下把 $f(i)$ 发给用户。但中心在一开始见过 $x=f(0)$，它仍然是单点风险。\n分布式密钥生成（Distributed Key Generation，DKG）就是“多方共同生成一把密钥”的协议：每个用户各自贡献一部分秘密，最终得到共同公钥，但没有人从头到尾见过完整私钥。第 $j$ 个用户选择：\n$$ f_j(z)=a_{j0}+a_{j1}z+\\cdots+a_{j,t-1}z^{t-1}. $$它将 $f_j(i)$ 私下发送给用户 $P_i$。用户 $P_i$ 的最终份额是：\n$$ x_i=\\sum_{j=1}^{n}f_j(i). $$等价的总多项式为：\n$$ F(z)=\\sum_{j=1}^{n}f_j(z),\\qquad x=F(0)=\\sum_{j=1}^{n}a_{j0}. $$公钥贡献可写为 $Y_j=h^{a_{j0}}$，系统公钥为：\n$$ Y=\\prod_{j=1}^{n}Y_j=h^{\\sum_j a_{j0}}=h^x. $$没有任何一个用户主动选择了完整 $x$，也不应该知道它。实际 DKG 还必须加入可验证秘密共享（VSS）承诺：否则恶意用户可以给不同接收者发送彼此不一致的份额，破坏后续解密或签名。\nPedersen VSS 的直观作用 # Pedersen VSS 会让分发者公开多项式系数的“承诺”。承诺可以理解成一个不可随意篡改的密封标签：它不泄露系数本身，但接收者能据此验证“我收到的份额确实来自同一个多项式”。它解决的不是“如何保密”，而是“如何在不信任分发者时仍能检查正确性”。\n5. 主动份额更新：防止攻击者跨时间收集份额 # 即使每一时刻攻击者都拿不到 $t$ 份份额，长期攻击者也可能先后入侵不同用户，慢慢收集到足够多的旧份额。这就是长期密钥的“积累泄露”风险。\n最直接的办法是完全重新分发：重新生成一个常数项仍为 $x$ 的新多项式，并安全发送全部份额。它有效，但通信开销大。\n更优雅的方法是给原多项式加一个常数项为零的随机多项式：\n$$ h(z)=b_1z+b_2z^2+\\cdots+b_{t-1}z^{t-1},\\qquad h(0)=0. $$令 $f\u0026rsquo;(z)=f(z)+h(z)$，则：\n$$ f'(0)=f(0)+h(0)=x. $$因此系统私钥 $x$ 和公钥 $Y$ 不变，但每个用户的份额变为：\n$$ x_i'=x_i+h(i)\\pmod q. $$例如在上一节的多项式上取：\n$$ h(z)=2z+3z^2+4z^3\\pmod{1013}. $$更新后得到：\n$$ f'(z)=90+3z+4z^2+5z^3\\pmod{1013}. $$核心结论：新旧份额不能混用。每轮更新都要有 epoch（轮次）标识；epoch 就是“这是第几代份额”的版本号。旧份额必须安全删除，否则攻击者仍可把不同时期的份额拼在一起。\n6. 门限签名：把“联合解密”变成“联合授权” # DKG 与份额更新并不限于解密。它们同样可用于门限签名：系统的公钥 $Y$ 对外验证签名，而任何不少于 $t$ 个参与者共同产生一个签名。\n以 Schnorr/FROST 类型签名为例，签名参与者集合为 $S$。Schnorr 是一种基于离散对数的签名体制；FROST 是其高效门限化实现，设计目标是让多人的签名份额聚合为一份普通大小、可由系统公钥验证的签名：\n每个 $P_i$ 选择一次性随机数 $k_i$，发出承诺 $R_i=h^{k_i}$； 聚合者计算 $R=\\prod_{i\\in S}R_i$ 和挑战 $e=H(M\\mathbin{|}R)$； 每个参与者返回签名份额： $$ z_i=k_i+e\\lambda_i x_i\\pmod q; $$ 聚合者计算 $z=\\sum_{i\\in S}z_i\\pmod q$，输出 $\\sigma=(R,z)$； 验证者检查： $$ h^z\\stackrel{?}{=}R\\cdot Y^e\\pmod p. $$因为 $\\sum_i\\lambda_i x_i=x$，验证等式成立。\n一个很小的验证例子 # 取 $p=23,q=11,h=4,x=3$，则 $Y=4^3\\bmod23=18$。使用 $f(z)=3+2z\\pmod{11}$ 做 $(2,3)$ 分享，份额为 $(5,7,9)$。令 $P_1,P_2$ 签名，它们的拉格朗日系数是：\n$$ \\lambda_1=2,\\qquad\\lambda_2=10. $$若 $k_1=1,k_2=2,e=4$，则：\n$$ R=4^1\\cdot4^2\\bmod23=18, $$$$ z_1=1+4\\cdot2\\cdot5\\equiv8\\pmod{11},\\qquad z_2=2+4\\cdot10\\cdot7\\equiv7\\pmod{11}. $$所以 $z=4$。验证：\n$$ 4^4\\bmod23=3,\\qquad18\\cdot18^4\\bmod23=3. $$两边相等，签名通过。\nFROST 的工程实现比这个教学式过程更严格：必须使用两轮随机数承诺和绑定因子，并且绝不能复用 $k_i$。复用签名随机数会泄露私钥份额。\n7. 不只是“任意 t 人”：特殊份额与加权份额 # 7.1 必须包含某位特殊参与者 # 有时访问策略不是“任意 $t$ 人”，而是“董事长必须在场，且再加至少 $r$ 名普通成员”。可以把秘密拆为：\n$$ x=u+v\\pmod q. $$把 $u$ 只交给特殊用户 $P_$，把 $v$ 用 $(r,n-1)$ Shamir 方案分给普通用户。只有 $P_$ 和至少 $r$ 名普通用户同时参与，才可得到：\n$$ C_1^u\\cdot C_1^v=C_1^{u+v}=C_1^x. $$例如 $x=90,u=30,v=60$，并把 $v$ 做 $(3,6)$ 分享。没有 $P_*$ 时，即使普通用户重构了 60，也无法得到完整指数 90。\n7.2 给参与者不同权重 # 若 A、B、C、D 的权重分别为 $3,2,1,1$，总门限为 $W=4$，则 A+C 可以授权，B+C+D 也可以授权，而 C+D 不可以。\n一个直观实现是把权重 $w_i$ 视为 $w_i$ 个虚拟份额，再运行 $(W,\\sum_iw_i)$ Shamir 共享。更一般的复杂访问策略，则应使用线性秘密共享方案（LSSS）。LSSS 的意思是“把秘密编码为若干线性份额”：满足策略的一组用户能用线性组合恢复秘密，不满足策略的用户则不能；它可以表达“AND、OR、加权门限、指定角色必须出现”等单调访问结构。\n8. 可变阈值：不能只在解密时改一个数字 # 一批固定的 $(t,n)$ Shamir 份额不可能在不改变份额的前提下，同时具有多个门限。安全等级变化时，需要执行重分享；它指的是由当前合法用户协作生成一批新份额，使新份额仍对应同一秘密、但多项式次数和门限已经改变。\n设当前合法集合为 $S$，旧份额为 $x_i$，旧门限下的拉格朗日系数为 $\\lambda_i$。每个 $P_i$ 构造一个新多项式 $q_i(z)$，使其常数项为：\n$$ q_i(0)=\\lambda_i x_i, $$且次数为 $t_{\\mathrm{new}}-1$。新用户 $P_j$ 收到各方的值后计算：\n$$ x_j'=\\sum_{i\\in S}q_i(j)\\pmod q. $$新总多项式 $Q(z)=\\sum_iq_i(z)$ 满足：\n$$ Q(0)=\\sum_{i\\in S}\\lambda_i x_i=x, $$但它的次数已经变成 $t_{\\mathrm{new}}-1$，所以阈值也随之变成 $t_{\\mathrm{new}}$。整个过程中不需要公开 $x$。\n降低阈值是安全降级，应该由当前较高门限的合法集合批准；密文、份额和部分解密都应绑定策略编号与轮次，防止不同级别、不同轮次的数据混用。\n9. 如何为实际系统选方案？ # 需求 更合适的方案 单位内部、可信密钥管理员 中心化 Shamir 分发 多机构共同托管密钥 DKG + VSS 长期保存高价值私钥 DKG + 主动份额更新 多人联合批准交易或发布 FROST 类 $(t,n)$ 门限签名 某角色必须参与 特殊份额或 LSSS 访问结构 人员权限有不同权重 加权分享或 LSSS 安全等级需要调整 经授权的重分享 总结 # ElGamal 的解密本质是去掉 $C_1^x$ 产生的掩码；Shamir 秘密共享让 $x$ 可以被门限恢复；门限 ElGamal 则让参与者在不显式恢复 $x$ 的情况下协作得到 $C_1^x$。在此基础上，DKG 消除“可信中心见过完整私钥”的风险，主动份额更新抵抗长期份额收集，门限签名把联合解密的能力扩展为联合授权。\n真正值得记住的不是某一条公式，而是三条设计原则：\n秘密在常数项，门限由多项式次数决定。 联合操作应聚合密码学结果，而不是暴露私钥份额。 安全状态带有时间和策略：份额、轮次、群阶与访问结构必须严格匹配。 掌握这条主线后，继续阅读 MPC、门限 ECDSA、分布式钱包、属性加密或零知识证明时，会更容易看清它们在解决的到底是“谁能计算、谁能授权、谁不该看到秘密”。\n","date":"2026年8月30日","externalUrl":null,"permalink":"/p/%E4%BB%8E-elgamal-%E5%88%B0%E9%97%A8%E9%99%90%E7%A7%98%E5%AF%86%E5%85%B1%E4%BA%AB%E4%B8%80%E7%AF%87%E7%9C%8B%E6%87%82%E5%88%86%E5%B8%83%E5%BC%8F%E8%A7%A3%E5%AF%86dkg-%E4%B8%8E%E9%97%A8%E9%99%90%E7%AD%BE%E5%90%8D%E7%9A%84%E6%95%99%E7%A8%8B/","section":"Posts","summary":"把一把私钥交给单个人保管很方便，但也很脆弱：私钥一旦泄露，攻击者就能解密全部历史密文；保管者离线或丢失密钥，合法用户同样无法恢复数据。\n门限密码学给出的思路是：不让任何一个人持有完整私钥。私钥被拆成多个份额，只有达到门限的一组参与者协作，才能完成解密或签名。本文从 ElGamal 出发，系统梳理这条主线：\nElGamal 为什么可以“分布式解密”； Shamir $(t,n)$ 门限秘密共享怎样拆分和恢复秘密； 如何把“恢复秘密”改造成“不暴露秘密的联合解密”； DKG、主动份额更新为什么能减少单点风险和长期泄露风险； 门限签名、特殊份额、加权份额、可变阈值分别解决什么问题。 ","title":"从 ElGamal 到门限秘密共享：一篇看懂分布式解密、DKG 与门限签名的教程","type":"post"},{"content":"","date":"2026年8月30日","externalUrl":null,"permalink":"/tags/%E9%97%A8%E9%99%90%E5%AF%86%E7%A0%81/","section":"Tags","summary":"","title":"门限密码","type":"tags"},{"content":"","date":"2026年8月17日","externalUrl":null,"permalink":"/tags/abe/","section":"Tags","summary":"","title":"ABE","type":"tags"},{"content":" 什么是属性基加密（ABE）？ # 属性基加密（Attribute-Based Encryption, ABE）是一种基于属性的公钥加密方案。与传统公钥加密（PKI）不同，ABE 不再用「某个用户身份」来标识公钥和私钥，而是用一组属性（Attributes）。\n核心思想：加密时指定一个「谁能解密」的策略，解密时用户的私钥包含其拥有的属性。当用户属性满足策略时，即可解密。\nABE 有两种基本范式：\n范式 策略在哪 含义 KP-ABE（密钥策略） 私钥中 用户私钥绑定策略，密文携带属性 CP-ABE（密文策略） 密文中 密文绑定策略，用户私钥携带属性 论文背景 # ABE 的概念最早由 Sahai 和 Waters（2005） 提出，但他们的方案是 KP-ABE 范式：用户的私钥中包含访问策略，而密文只携带一组属性。\nKP-ABE 的问题：数据所有者（加密者）无法控制「谁能访问」。策略是预先嵌入在用户密钥里的，这意味着你必须知道所有合法用户的属性集合才能生成密钥——这对实际场景非常不友好。\nBethencourt、Sahai、Waters（2007） 在论文 \u0026ldquo;Ciphertext-Policy Attribute-Based Encryption\u0026rdquo; 中提出了 CP-ABE，将策略与属性的角色完全反转：\n✅ 密文携带访问策略（Access Policy） ✅ 用户私钥携带属性集合 这样，数据所有者在加密时就能精确控制「只有满足这个策略的用户才能解密」，而用户只需持有自己的属性密钥即可。\nCP-ABE 的核心创新 # 1. 角色反转 # 1 2 3 4 5 6 7 KP-ABE（2005）： 密文 \u0026lt;- 属性集合 {医生, 内科} 私钥 \u0026lt;- 访问策略「医生 AND 内科」 CP-ABE（2007）： 密文 \u0026lt;- 访问策略「医生 AND 内科」 私钥 \u0026lt;- 属性集合 {医生, 内科} 2. 基于 LSSS 的访问结构 # 论文使用 线性秘密共享方案（LSSS, Linear Secret Sharing Scheme） 来表达任意单调访问结构。\nLSSS 的核心：用一个矩阵 M 和一个向量 v 来表示访问策略：\n矩阵的每一行对应一个属性 向量 v 是秘密的编码，满足 M * λ = (s, 0, 0, \u0026hellip;, 0) 一个属性集合满足策略，当且仅当存在一组系数使对应行线性组合出 v 示例：策略「(A AND B) OR (C AND D)」对应的 LSSS 矩阵：\n行 属性 向量 1 A (1, 0) 2 B (1, 0) 3 C (0, 1) 4 D (0, 1) 3. 双线性配对上的构造 # 方案基于 双线性配对（Bilinear Pairing） 和 DBDH（Decisional Bilinear Diffie-Hellman） 假设：\n加密阶段：将明文与访问策略结合，生成携带策略的密文 密钥生成：根据用户属性集合生成私钥 解密阶段：利用双线性配对验证属性是否满足策略，并恢复明文 方案组成 # Setup（系统初始化） # 生成系统公共参数 PK 和主密钥 MK：\n1 2 PK = (g, e(g,g)^α, {H(i)=g^a_i | i ∈ U}) MK = (α, a_1, ..., a_|U|) KeyGen（密钥生成） # 对用户属性集 S，生成私钥：\n1 D_S = {D = g^r * H(σ_j)^r | j ∈ S}, D_tilde = g^r Encrypt（加密） # 给定明文 M 和访问策略 A，生成密文：\n1 CT = (A, C = M * e(g,g)^(α*s), C_tilde = g^s, {C_j = g^(a_j*λ_j)}) 其中 λ_j 是 LSSS 矩阵对应的秘密共享值。\nDecrypt（解密） # 用户用私钥 D_S 解密：\n检查属性集 S 是否满足策略 A 若满足，找到对应行和系数 {w_j} 通过配对运算恢复共享值 从共享值中恢复明文 M 安全性 # 论文在 标准模型 下证明了选择性安全（Selective Security），基于 DBDH 假设。\n安全性证明使用 归约（Reduction） 技术：假设存在一个能攻破 CP-ABE 的攻击者 A，则可以构造一个解决 DBDH 问题的算法 B，从而矛盾。\n应用价值 # CP-ABE 在以下场景有重要应用：\n场景 说明 云存储访问控制 数据上传时指定策略，云服务商无法绕过策略解密 电子健康记录 按角色和权限属性精细控制病历访问 物联网数据分发 按设备属性加密，满足条件的设备自动解密 数字版权管理 按用户订阅属性控制内容访问 局限与后续发展 # 论文中的原始方案存在以下限制：\n选择性安全：攻击者必须先声明挑战属性集，实际中可能不够强 密文膨胀：密文大小与策略复杂度成正比 密钥托管问题：主密钥持有者可生成任意属性密钥 不支持非单调策略：只能表达单调访问结构（AND/OR），无法表达 NOT 后续改进方向：\n双系统加密：达到自适应安全（Adaptive Security） 密钥策略与密文策略的融合：支持更灵活的策略表达 可撤销 ABE：解决密钥托管和用户撤销问题 高效实现：减少双线性配对计算次数 学习心得 # 这篇论文是属性基加密领域的里程碑之作。从 KP-ABE 到 CP-ABE 的范式反转看似简单，但实现起来需要在双线性配对上做大量精巧的数学构造。特别是将 LSSS 与加密结合的设计，展现了密码学方案设计中「抽象代数工具 + 密码学假设」的经典范式。\n理解了这篇论文后，再去看后续的 ABE 变体（如内积 ABE、功能加密等）会顺畅很多——它们大多是在这个基础上做的扩展和加强。\n论文原文：Bethencourt, J., Sahai, A., \u0026amp; Waters, B. (2007). Ciphertext-Policy Attribute-Based Encryption. IEEE Symposium on Security and Privacy, 40-53.\n论文链接：https://ieeexplore.ieee.org/abstract/document/4223236\n","date":"2026年8月17日","externalUrl":null,"permalink":"/p/cp-abe%E5%AF%86%E6%96%87%E7%AD%96%E7%95%A5%E5%B1%9E%E6%80%A7%E5%9F%BA%E5%8A%A0%E5%AF%86bethencourt-sahai-waters-2007/","section":"Posts","summary":"什么是属性基加密（ABE）？ # 属性基加密（Attribute-Based Encryption, ABE）是一种基于属性的公钥加密方案。与传统公钥加密（PKI）不同，ABE 不再用「某个用户身份」来标识公钥和私钥，而是用一组属性（Attributes）。\n","title":"CP-ABE：密文策略属性基加密（Bethencourt-Sahai-Waters 2007）","type":"post"},{"content":"","date":"2026年8月17日","externalUrl":null,"permalink":"/tags/%E8%AE%BF%E9%97%AE%E6%8E%A7%E5%88%B6/","section":"Tags","summary":"","title":"访问控制","type":"tags"},{"content":"","date":"2026年8月17日","externalUrl":null,"permalink":"/tags/%E5%B1%9E%E6%80%A7%E5%9F%BA%E5%8A%A0%E5%AF%86/","section":"Tags","summary":"","title":"属性基加密","type":"tags"},{"content":" 先从一个场景说起 # 想象你有一份机密文档，放在云盘上。你希望：\n公司内部**部门是「研发部」且职级是「经理以上」**的人可以打开 其他人，哪怕知道文件在哪，也打不开 传统加密的做法是：生成一把密码，发给每个符合条件的人。问题来了——如果公司有一天新增了 100 个经理，你得给每个人单独发一把密码；如果有人离职了，你还得逐个通知他「密码作废」并重新加密文件。\n这太麻烦了。 属性加密（Attribute-Based Encryption，简称 ABE）就是来解决这个问题的。\n什么是属性加密？ # 一句话概括：ABE 让加密文件「认识属性，不认识具体的人」。\n类比：智能门禁 # 想象一个智能大楼的刷卡门禁：\n传统方式 ABE 方式 保安记住每个能进的人是谁，逐个核对 门禁只看「你是不是研发部的经理」这个条件 新人来了要更新名单 只要新人的工牌上有「研发部+经理」属性，自动放行 人走了要从名单删除 只要收回他的工牌（私钥）就行 ABE 就是把这套逻辑搬到了加密世界里：\n加密时：你指定一个规则——「只有同时拥有『研发部』和『经理』属性的人才能解密」 解密时：用户用携带自己属性的私钥去尝试解密，属性满足规则就成功，不满足就失败 ABE 的两种流派 # ABE 有两种主要范式，它们的核心区别是「规则写在谁身上」：\n类型 规则（策略）在哪里 举例 KP-ABE（密钥策略） 用户的私钥里 用户的私钥说：「我能解密『研发部』的文件」，文件只需标注「研发部」即可 CP-ABE（密文策略） 密文里 文件说：「只有『研发部』的人能开」，用户私钥只需携带「研发部」属性 实际中 CP-ABE 更常用——因为文件上传者可以直接指定谁能看，不需要预先知道所有用户的身份。\nABE 怎么用？四个关键角色 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 +--------------------------------------------------+ | 权威机构（Authority） | | 生成系统参数，根据用户属性发放私钥 | +------------------------+-------------------------+ | 发放私钥 v +--------------------------------------------------+ | 数据上传者（User A） | | 用属性规则加密文件 -\u0026gt; 上传到云 | | 例：「部门=研发 AND 职级\u0026gt;=经理」 | +------------------------+-------------------------+ | 加密后的文件 v +--------------------------------------------------+ | 云存储服务器 | | 只存文件，不看内容 | +------------------------+-------------------------+ | 下载文件 v +--------------------------------------------------+ | 数据下载者（User B） | | 用自己的私钥（含属性）尝试解密 | | 属性满足规则 -\u0026gt; 解密成功 | | 属性不满足 -\u0026gt; 解密失败 | +--------------------------------------------------+ 研究人员都在攻克哪些难题？ # 上面说的只是 ABE 的理想形态。现实应用中有一堆问题需要解决。两篇综述论文（《基于属性加密技术研究综述》和《云存储环境下属性基加密综述》）系统地梳理了以下方向：\n难题一：效率太慢 # 问题：ABE 的核心运算叫「双线性配对」（Bilinear Pairing），这是一种数学上很安全的运算，但非常耗时。如果访问规则很复杂（比如涉及几十种属性），加密和解密的速度会让人无法接受。\n解决方案：\n在线/离线拆分（Hohenberger \u0026amp; Waters, 2014）：把计算分成两部分——离线阶段预先算好（不依赖具体数据），在线阶段只做少量计算。就像提前备好食材，炒菜时只加热就行。 密文大小恒定：无论规则多复杂，加密后的文件体积不变。这对网络传输很重要。 快速解密：让解密端（通常是手机等弱设备）的计算量尽量少。 外包解密：把繁重的解密计算交给云服务器做，但云服务器只能帮忙算，看不到最终结果。用户只需要在本地做一次轻量级验证。 通俗理解：就像你去餐厅吃饭，后厨（云）负责切菜炒菜（重计算），你只需在桌上把菜拌匀就能吃（轻验证），餐厅老板看不到你吃的是什么。\n难题二：规则被偷看了 # 问题：在标准 ABE 中，文件的访问规则是明文写在密文里的。任何人下载了文件，虽然打不开内容，但能读到规则——「只有研发部经理能看」——这就泄露了信息。\n解决方案：策略隐藏（Policy Hiding）。加密后连规则本身也是加密的，只有符合条件的用户解密后才能看到规则。\n通俗理解：传统方式是门上贴着「只有经理能进」；策略隐藏是门什么也不贴，你刷一下卡才知道自己能不能进。\n难题三：谁来给用户发属性？ # 问题：一个公司可能有 HR、财务、研发等多个部门，每个部门有自己的属性体系。如果只有一个权威机构管所有属性，那它就成了万能管理员——能签发任何属性，这是巨大的安全风险。\n解决方案：多授权中心（Multi-Authority ABE）。不同的属性由不同的机构签发：\nHR 部门管「部门」属性 人力资源部管「职级」属性 用户从多个机构收集自己的属性私钥，拼在一起就能解密 通俗理解：就像你考驾照需要车管所发，身份证需要派出所发，大学文凭需要学校发——各司其职，没有谁能单独给你完整的身份。\n难题四：人在江湖，身份会变 # 问题：员工离职了、转岗了、或者只是临时外借，他的属性需要改变。传统做法是：重新给他签发私钥，同时把所有相关文件重新加密——工作量巨大。\n解决方案：属性撤销（Attribute Revocation）。系统支持高效地撤销某个用户的某个属性，而不需要重新加密所有文件。\n通俗理解：就像门禁系统里把离职员工的权限一键删除，而不需要把所有门的锁都换掉。\n难题五：加密后没法搜索 # 问题：文件加密上传后，连文件名和内容都是密文。你没法在云端搜索「研发部 2024 预算」这类关键词——搜不了。\n解决方案：可搜索属性加密（Searchable ABE）。允许用户在加密数据上执行关键词搜索，服务器帮助过滤，但不知道用户搜了什么，也不知道文件的明文内容。\n通俗理解：就像你在图书馆的加密档案室搜书，管理员帮你找到可能匹配的书，但管理员不知道你搜的关键词是什么，也不知道书里写了什么。\n难题六：私钥被卖了怎么办？ # 问题：如果某个用户的私钥被盗，被盗用的用户用它解密了不该看的文件，系统无法知道是谁泄露的。\n解决方案：叛徒追踪（Traitor Tracing）。系统能在发现私钥被滥用时，反向追溯到是哪位用户泄露了私钥。\n通俗理解：就像图书馆的书被偷了，虽然书上的名字被撕掉了，但书里夹着的追踪墨水能定位到是谁拿走的。\n难题七：安全性还不够强 # 问题：早期 ABE 方案只能证明「选择性安全」（Selective Security）——攻击者必须在攻击前声明目标属性集。这在实际中不够强。\n解决方案：\n自适应安全（Adaptive Security）：攻击者可以随时选择攻击目标，安全性仍然成立。 双系统加密技术：通过巧妙构造两套加密系统，实现从选择性安全到自适应安全的跨越。 难题八：混合策略 # 问题：有时候 KP-ABE 和 CP-ABE 各有优势，能否结合？\n解决方案：双策略 ABE（Dual-Policy ABE），同时支持密钥策略和密文策略，提供更灵活的访问控制能力。\n未来方向展望 # 两篇综述都指出了以下值得关注的方向：\n方向 说明 抗量子 ABE 未来的量子计算机能破解当前的 ABE 方案，需要基于格（Lattice）等抗量子假设重新设计 更细粒度的策略 支持「属性值范围」（如年龄 25~35）而非简单的「有无属性」 联邦学习 + ABE 多方数据在不解密的情况下联合训练 AI 模型 区块链 + ABE 用区块链管理属性签发和撤销，解决单点信任问题 更高效的实现 减少双线性配对次数，让 ABE 能在手机等弱设备上实用 小结 # 属性加密的核心魅力在于：它把「谁能访问数据」这件事，从人变成了属性。这让数据共享变得前所未有的灵活——你不需要知道具体是谁，只需要定义规则。\n但它也带来了复杂的工程挑战：计算效率、策略隐私、多机构协作、身份动态变化、加密后搜索……每一个问题背后都有研究者用精妙的数学在寻找答案。\n理解 ABE 的这些核心问题和方案，是进入现代密码学和隐私计算领域的重要一步。\n参考文献：\n王生玉, 汪金苗, 董清风, 朱瑞瑾. 基于属性加密技术研究综述[J]. 信息网络安全, 2019, 19(9): 76-80. 赵志远, 王建华, 朱智强, 孙磊. 云存储环境下属性基加密综述[J]. 计算机应用研究, 2018, 35(4). Sahai A, Waters B. Fuzzy Identity-based Encryption[C]. Eurocrypt 2005. Bethencourt J, Sahai A, Waters B. Ciphertext-Policy Attribute-Based Encryption[C]. IEEE S\u0026amp;P 2007. ","date":"2026年8月17日","externalUrl":null,"permalink":"/p/%E5%B1%9E%E6%80%A7%E5%8A%A0%E5%AF%86%E9%80%9A%E4%BF%97%E6%8C%87%E5%8D%97%E8%AE%A9%E4%BA%91%E4%B8%8A%E7%9A%84%E6%95%B0%E6%8D%AE%E8%AE%A4%E4%BA%BA%E4%B8%8D%E8%AE%A4%E8%84%B8/","section":"Posts","summary":"先从一个场景说起 # 想象你有一份机密文档，放在云盘上。你希望：\n","title":"属性加密通俗指南：让云上的数据「认人不认脸」","type":"post"},{"content":"","date":"2026年8月17日","externalUrl":null,"permalink":"/tags/%E4%BA%91%E5%AD%98%E5%82%A8/","section":"Tags","summary":"","title":"云存储","type":"tags"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/markdown/","section":"Tags","summary":"","title":"Markdown","type":"tags"},{"content":"Markdown 是一种轻量级标记语言，让你可以用纯文本格式编写文档。以下是常用语法总结。\n标题 # 用 # 号表示标题，一个 # 是一级标题，最多六个。\n1 2 3 4 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 文本样式 # 1 2 3 4 5 **粗体文本** *斜体文本* ***粗斜体文本*** ~~删除线文本~~ `行内代码` 效果：粗体文本、斜体文本、粗斜体文本、删除线文本、行内代码\n列表 # 无序列表 # 1 2 3 - 项目一 - 项目二 - 子项目 效果：\n项目一 项目二 子项目 有序列表 # 1 2 3 1. 第一步 2. 第二步 3. 第三步 效果：\n第一步 第二步 第三步 链接与图片 # 1 2 [链接文字](https://example.com) ![图片描述](图片URL) 引用 # 1 2 \u0026gt; 这是一段引用文字 \u0026gt; 可以多行 效果：\n这是一段引用文字 可以多行\n代码块 # 用三个反引号包裹代码，可以指定语言实现高亮：\n1 2 3 4 ```python def hello(): print(\u0026#34;Hello, World!\u0026#34;) ``` 效果：\n1 2 def hello(): print(\u0026#34;Hello, World!\u0026#34;) 表格 # 1 2 3 4 | 左对齐 | 居中对齐 | 右对齐 | |:-------|:-------:|-------:| | 内容1 | 内容2 | 内容3 | | 内容4 | 内容5 | 内容6 | 效果：\n左对齐 居中对齐 右对齐 内容1 内容2 内容3 内容4 内容5 内容6 分割线 # 用三个或更多 -、* 或 _：\n1 --- 任务列表 # 1 2 3 - [x] 已完成 - [ ] 未完成 - [ ] 待办事项 效果：\n已完成 未完成 待办事项 脚注 # 1 2 3 这里有个脚注[^1] [^1]: 这是脚注内容 数学公式 # 行内公式用 $...$，块级公式用 $$...$$：\n1 2 3 4 5 $E = mc^2$ $$ \\sum_{i=1}^{n} i = \\frac{n(n+1)}{2} $$ 快捷键速查 # 功能 语法 加粗 **文本** 斜体 *文本* 标题 # 标题 链接 [文字](链接) 图片 ![描述](URL) 代码 `代码` 引用 \u0026gt; 引用 列表 - 项目 掌握这些基本语法就够日常使用了！\n","date":"2026年7月16日","externalUrl":null,"permalink":"/p/markdown-%E8%AF%AD%E6%B3%95%E9%80%9F%E6%9F%A5%E6%89%8B%E5%86%8C/","section":"Posts","summary":"Markdown 是一种轻量级标记语言，让你可以用纯文本格式编写文档。以下是常用语法总结。\n","title":"Markdown 语法速查手册","type":"post"},{"content":" 什么是同态加密？ # 同态加密（Homomorphic Encryption）是一种特殊的加密方式，允许在密文上直接进行计算，解密后的结果与在明文上计算的结果相同。\n简单来说：数据加密后依然可以计算。\nMicrosoft SEAL 简介 # Microsoft SEAL 是微软开发的开源同态加密库，支持以下三种方案：\nBFV：支持整数加法和乘法 CKKS：支持近似浮点数运算 BGV：支持整数运算，更适合批处理 快速上手 # 安装 # 1 2 3 4 git clone https://github.com/microsoft/SEAL.git cd SEAL cmake -S . -B build cmake --build build 基本使用示例 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 #include \u0026#34;seal/seal.h\u0026#34; using namespace seal; // 创建加密参数 EncryptionParameters params(scheme_type::ckks); size_t poly_modulus_degree = 8192; params.set_poly_modulus_degree(poly_modulus_degree); coeff_modulus_id = CoeffModulus::Create(poly_modulus_degree, {60, 40, 40, 60}); // 创建 SEALContext auto context = SEALContext::Create(params); // 创建编码器、加密器、评估器 CKKSEncoder encoder(context); Encryptor encryptor(context, key_generator.public_key()); Evaluator evaluator(context); Decryptor decryptor(context, key_generator.secret_key()); // 编码、加密、计算、解密 std::vector\u0026lt;double\u0026gt; input = {0.5, 1.0, 1.5, 2.0}; Plaintext plain; encoder.encode(input, scale, plain); Ciphertext encrypted; encryptor.encrypt(plain, encrypted); // 在密文上进行加法 evaluator.add_inplace(encrypted, encrypted); 实际应用场景 # 隐私保护的机器学习：在加密数据上训练模型 安全多方计算：多方协作计算而不泄露各自数据 云计算隐私：将数据加密后上传云端计算 学习心得 # 同态加密的计算开销很大，但随着硬件加速和算法优化，正在逐步走向实用。SEAL 的文档和示例非常完善，是入门同态加密的好选择。\n项目地址：https://github.com/microsoft/SEAL\n","date":"2026年7月16日","externalUrl":null,"permalink":"/p/microsoft-seal-%E5%85%A5%E9%97%A8%E5%90%8C%E6%80%81%E5%8A%A0%E5%AF%86%E5%AE%9E%E6%88%98/","section":"Posts","summary":"什么是同态加密？ # 同态加密（Homomorphic Encryption）是一种特殊的加密方式，允许在密文上直接进行计算，解密后的结果与在明文上计算的结果相同。\n","title":"Microsoft SEAL 入门：同态加密实战","type":"post"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/page/","section":"Pages","summary":"","title":"Pages","type":"page"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/seal/","section":"Tags","summary":"","title":"SEAL","type":"tags"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/stm32/","section":"Tags","summary":"","title":"STM32","type":"tags"},{"content":" 关于这个博客 # 欢迎来到 METEOR，一个关于技术与生活的个人博客。\n这个博客使用 Hugo 和 Blowfish 主题构建，通过 GitHub Actions 自动部署。\n","date":"2026年7月16日","externalUrl":null,"permalink":"/%E5%85%B3%E4%BA%8E/","section":"Pages","summary":"关于这个博客 # 欢迎来到 METEOR，一个关于技术与生活的个人博客。\n","title":"关于","type":"page"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/","section":"Categories","summary":"","title":"技术分享","type":"categories"},{"content":" 研究背景 # 随着现代生活节奏的加快，许多家庭主人因为工作需要经常出差，导致家中的绿植长时间无人照料。植物因长期缺乏水分和光照，容易出现叶子枯黄、生长不良等问题，严重时甚至会导致植株死亡。\n为了解决这一问题，本项目设计了一套家用智能灌溉系统，能够自动监测环境数据并智能控制灌溉，让用户即使不在家也能呵护心爱的绿植。\n系统概述 # 本项目旨在构建一套适合家庭使用的智能灌溉系统，主要功能包括：\n实时监测：采集土壤湿度、温度、光照等环境数据 智能灌溉：根据监测数据自动调节灌溉水量和时间 语音控制：集成语音模块，支持语音指令操作 远程操控：通过WiFi将数据上云，支持手机小程序远程控制 系统架构 # 智能灌溉系统采用三层架构设计：\n1 2 3 4 5 6 7 8 9 10 ┌─────────────────────────────────────────────────────┐ │ 应用层 │ │ 串口屏显示 │ 小程序控制 │ 云平台数据存储 │ ├─────────────────────────────────────────────────────┤ │ 网络层 │ │ ESP8266 WiFi │ ZX-D30 蓝牙 │ ├─────────────────────────────────────────────────────┤ │ 感知层 │ │ 土壤湿度传感器 │ 温度传感器 │ 光照传感器 │ └─────────────────────────────────────────────────────┘ 层级 组件 功能 感知层 土壤湿度传感器、DS18B20温度传感器、BH1750光照传感器 采集环境数据 网络层 ESP8266 WiFi、ZX-D30蓝牙 数据传输与通信 应用层 TJC3224T124串口屏、继电器水泵、云平台小程序 用户交互与控制 硬件设备 # 系统核心硬件包括：\n设备 型号 功能说明 主控芯片 STM32F103C8T6 系统核心，负责数据处理和设备通信 温湿度传感器 DHT11 实时采集环境温湿度 光照传感器 BH1750 监测光照强度 土壤湿度传感器 电容式 检测土壤含水量 语音模块 ASRPRO 实现语音控制功能 WiFi模块 ESP8266 无线网络连接，数据上云 蓝牙模块 ZX-D30 近距离无线通信 串口屏 TJC3224T124 显示系统状态 继电器模块 5V继电器 控制水泵开关 水泵 直流潜水泵 执行灌溉操作 软件设计 # 系统软件基于 MQTT 协议实现数据上云，用户可通过小程序远程监控和控制灌溉系统。\n数据流程 # 1 2 3 传感器采集 → STM32处理 → ESP8266上传 → 云平台存储 → 小程序显示 ↓ 语音模块本地控制 主要功能模块 # 数据采集模块：定时读取各传感器数据 灌溉决策算法：根据土壤湿度自动判断是否灌溉 通信模块：通过MQTT协议与云平台通信 用户界面：串口屏本地显示 + 小程序远程控制 总结与展望 # 本项目实现了家用智能灌溉系统的基本功能，能够自动监测环境数据并智能控制灌溉。未来可从以下方面继续优化：\nAI 算法：引入机器学习，根据植物种类和生长阶段优化灌溉策略 多传感器融合：增加雨滴传感器、水位传感器，实现更精准的控制 能源管理：集成太阳能供电，实现绿色环保 语音交互：升级语音模块，支持更自然的对话交互 本项目为个人学习实践，持续更新中\u0026hellip;\n","date":"2026年7月16日","externalUrl":null,"permalink":"/p/%E5%AE%B6%E7%94%A8%E6%99%BA%E8%83%BD%E7%81%8C%E6%BA%89%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E4%B8%8E%E5%AE%9E%E7%8E%B0/","section":"Posts","summary":"研究背景 # 随着现代生活节奏的加快，许多家庭主人因为工作需要经常出差，导致家中的绿植长时间无人照料。植物因长期缺乏水分和光照，容易出现叶子枯黄、生长不良等问题，严重时甚至会导致植株死亡。\n","title":"家用智能灌溉系统设计与实现","type":"post"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/%E6%95%99%E7%A8%8B/","section":"Tags","summary":"","title":"教程","type":"tags"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/%E5%B5%8C%E5%85%A5%E5%BC%8F/","section":"Tags","summary":"","title":"嵌入式","type":"tags"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/%E7%89%A9%E8%81%94%E7%BD%91/","section":"Tags","summary":"","title":"物联网","type":"tags"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/categories/%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98/","section":"Categories","summary":"","title":"项目实战","type":"categories"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/%E5%86%99%E4%BD%9C/","section":"Tags","summary":"","title":"写作","type":"tags"},{"content":"","date":"2026年7月16日","externalUrl":null,"permalink":"/tags/%E6%99%BA%E8%83%BD%E5%AE%B6%E5%B1%85/","section":"Tags","summary":"","title":"智能家居","type":"tags"},{"content":" 什么是不经意传输？ # 不经意传输（Oblivious Transfer, OT）是安全多方计算的基础协议之一。\n场景：发送方有两条消息 m0 和 m1，接收方选择接收其中一条。协议保证：\n接收方只能获得自己选择的消息 发送方不知道接收方选择了哪条 OT 扩展（OT Extension） # 基础 OT 协议通信开销大，OT 扩展技术可以用少量基础 OT 生成大量 OT 实例。\nlibOTe 简介 # libOTe 是俄亥俄州立大学（OSU）密码学组开发的高性能 C++20 OT 扩展库。\n支持的协议 # 半诚实模型：\n1-out-of-2 Silent OT 1-out-of-2 Correlated OT 1-out-of-N OT VOLE（向量不经意线性求值） 恶意模型：\nKOS15 协议 Silent OT 特点 # 高性能：使用 SSE 指令和向量化优化 跨平台：支持 Windows、Linux、macOS 易用：提供简洁的 API 和前端示例 编译与使用 # 1 2 3 git clone https://github.com/osu-crypto/libOTe.git cd libOTe python3 build.py 基本示例 # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include \u0026#34;libOTe/TwoChooseOne/TcoOtExtReceiver.h\u0026#34; #include \u0026#34;libOTe/TwoChooseOne/TcoOtExtSender.h\u0026#34; // 创建 OT 扩展实例 OttExtReceiver* receiver = new IknpOtExtReceiver(); OttExtSender* sender = new IknpOtExtSender(); // 执行 OT 扩展 sender-\u0026gt;genBaseOts(choice); receiver-\u0026gt;genBaseOts(choice); std::vector\u0026lt;block\u0026gt; messages(128); sender-\u0026gt;send(messages, numOTs, prng, coproto::io); receiver-\u0026gt;receive(messages, choiceBits, numOTs, prng, coproto::io); 在隐私计算中的应用 # OT 扩展是许多 MPC 协议的基础组件：\nPSI（隐私集合交集） PIR（隐私信息检索） 安全函数评估（SFE） 项目地址：https://github.com/osu-crypto/libOTe\n","date":"2026年7月15日","externalUrl":null,"permalink":"/p/libote%E4%B8%8D%E7%BB%8F%E6%84%8F%E4%BC%A0%E8%BE%93%E6%89%A9%E5%B1%95%E5%BA%93%E8%AF%A6%E8%A7%A3/","section":"Posts","summary":"什么是不经意传输？ # 不经意传输（Oblivious Transfer, OT）是安全多方计算的基础协议之一。\n","title":"libOTe：不经意传输扩展库详解","type":"post"},{"content":"","date":"2026年7月15日","externalUrl":null,"permalink":"/tags/mpc/","section":"Tags","summary":"","title":"MPC","type":"tags"},{"content":"","date":"2026年7月15日","externalUrl":null,"permalink":"/tags/%E4%B8%8D%E7%BB%8F%E6%84%8F%E4%BC%A0%E8%BE%93/","section":"Tags","summary":"","title":"不经意传输","type":"tags"},{"content":" 什么是隐私集合交集（PSI）？ # 隐私集合交集（Private Set Intersection）允许两方在不泄露各自集合内容的前提下，计算出两个集合的交集。\n应用场景：\n基因数据对比 联合风控 好友推荐 广告转化率统计 Vole-PSI 的创新 # Vole-PSI 基于向量不经意线性求值（Vector OLE）构建，相比传统 OT-based PSI 方案：\n通信效率更高：向量 OLE 的通信开销与集合大小近似线性 计算更快：利用 OKVS（Oblivious Key-Value Store）减少计算量 支持 Circuit PSI：结果以秘密共享形式输出 技术原理 # 向量 OLE（Vector OLE） # 向量 OLE 是 OT 的推广形式：\n发送方输入向量 a，接收方输入标量 b 输出：发送方得到 r，接收方得到 s = a · b + r 协议流程 # 双方通过 Vector OLE 生成关联的掩码值 使用 OKVS 编码各自集合 通过掩码值匹配交集元素 编译与使用 # 1 2 3 git clone https://github.com/Visa-Research/volepsi.git cd volepsi python3 build.py -DVOLE_PSI_ENABLE_BOOST=ON 前端使用 # 1 2 3 4 5 # 发送方 ./frontend -role sender -set input_sender.txt -output result.txt # 接收方 ./frontend -role receiver -set input_receiver.txt -output result.txt 性能对比 # 方案 通信开销 计算时间（1M 元素） ECDH-PSI O(n) ~10s OT-based PSI O(n) ~5s Vole-PSI O(n) ~2s 学习心得 # Vole-PSI 的代码结构清晰，依赖管理做得很好。通过学习这个项目，我对向量 OLE 和 OKVS 有了更深入的理解。\n项目地址：https://github.com/Visa-Research/volepsi\n","date":"2026年7月14日","externalUrl":null,"permalink":"/p/vole-psi%E5%9F%BA%E4%BA%8E%E5%90%91%E9%87%8F-ole-%E7%9A%84%E9%9A%90%E7%A7%81%E9%9B%86%E5%90%88%E4%BA%A4%E9%9B%86/","section":"Posts","summary":"什么是隐私集合交集（PSI）？ # 隐私集合交集（Private Set Intersection）允许两方在不泄露各自集合内容的前提下，计算出两个集合的交集。\n","title":"Vole-PSI：基于向量 OLE 的隐私集合交集","type":"post"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"在这里发现所有文章、搜索内容、浏览分类。\n","externalUrl":null,"permalink":"/articles/","section":"Pages","summary":"在这里发现所有文章、搜索内容、浏览分类。\n","title":"文章","type":"page"},{"content":"这里收录了一些值得常去看看的朋友与博客。\n","externalUrl":null,"permalink":"/%E5%8F%8B%E9%93%BE/","section":"Pages","summary":"这里收录了一些值得常去看看的朋友与博客。\n","title":"友链","type":"page"}]