1. 引言
前序博客:
在过去几个月里,以太坊基金会PSE的Machina iO团队 在研究和实现不可区分性混淆(indistinguishability obfuscation, iO)的过程中,注意到现有资料存在一个令人沮丧的缺口:大多数论文非常技术化且令人生畏,而面向初学者的文章又仅停留在模糊的功能层面概述------它们会告诉你 iO 能实现什么,却几乎不介绍如何构造它。
本文旨在弥合这一差距。将通过一个具体的端到端示例来讲解:构造一个非交互式的条件签名打印器(non-interactive conditional signature printer)。会分几次尝试来构建它,每次都用熟悉的密码原语作为积木。到最后,应该能获得关于 iO 背后理论构件的清晰路线图,并对它的能力有一个动手式的理解。
2. 目标:非交互式条件签名打印器
非交互式条件签名打印器 目标程序 f f f 行为如下:
- 给定一个消息 x x x,当 x x x 为素数时,输出在签名私钥 k k k 下的有效签名;否则输出 ⊥ \bot ⊥。
f ( k , x ) = { sign ( k , x ) if x is prime , ⊥ otherwise . f(k, x)= \begin{cases} \textsf{sign}(k, x) & \text{if } x \text{ is prime},\\ \bot & \text{otherwise}. \end{cases} f(k,x)={sign(k,x)⊥if x is prime,otherwise.
场景包括:
- 一个密钥拥有者(key owner),他生成该程序并持有签名私钥 k k k,
- 以及若干用户,他们提供数字 x x x 并期望在条件成立时获得签名。
任何可行的构造必须满足两个要求:
- 1)无交互(No interaction)。程序一旦发布,用户必须能独立运行它并(有条件地)获得签名,而无需与密钥拥有者通信。即便密钥拥有者去到无人荒岛上离线,系统也应能继续工作。
- 2)密钥隐私(Key privacy)。执行该程序不应泄露关于 k k k 的任何信息,除非这些信息已经从输出 f ( k , x ) f(k,x) f(k,x) 中显式推断出来。因此简单地公开源代码是不可行的,因为那会暴露该私钥。
在下面的各节中,将尝试用多种方式构建该程序:
- 先用公开真值表(public truth table),
- 然后用全同态加密(FHE),
- 接着用功能加密(FE),
- 最后用称之为不可区分性混淆(iO) 的增强版 FE。
3. 方案一------公开真值表(public truth table)
从最直观的方法开始:
- 让持有签名私钥 k k k 的密钥拥有者公开一张真值表,把每个可能的输入 x x x 映射到相应的输出 f ( k , x ) f(k,x) f(k,x)。
具体地,密钥拥有者固定输入域(如 64 位),并对每一个可能的 2 64 2^{64} 264 个输入预先计算对应的输出。可以把真值表想象成一个以每个 x i x_i xi 为键的大字典,其值就是对应的签名 f ( k , x i ) f(k,x_i) f(k,xi)。给定用户 Alice 的输入 x = 7 x=7 x=7,她可以查找该真值表并获得 f ( k , 7 ) f(k,7) f(k,7)。
虽然这种方法满足前面列出的两个要求,但它随着输入长度呈指数级扩大,因此不可行。
因此加入第三个要求:
- 3)密钥拥有者的工作量 不应 随用户输入位长呈指数增长。
4. 方案二------全同态加密(FHE)
全同态加密(FHE)总会在"对加密数据进行计算"的语境下被提及,因此它看起来可能是本问题的候选解法。
先列出 FHE 的核心 API,特别是其私钥(secret-key)变体。这里不会过多深入------与 iO 不同,关于 FHE 的优质资源网上已有大量资料可查。
F H E . K e y g e n ( ) → s k F H E . E n c ( k , s k ) → c t k F H E . E v a l ( f , c t k ) → c t f ( k ) F H E . D e c ( c t f ( k ) , s k ) → f ( k ) \begin{aligned} \mathsf{FHE.Keygen}() &\rightarrow sk\\ \mathsf{FHE.Enc}(k, sk) &\rightarrow ct_k\\ \mathsf{FHE.Eval}(f, ct_k) &\rightarrow ct_{f(k)}\\ \mathsf{FHE.Dec}(ct_{f(k)}, sk) &\rightarrow f(k) \end{aligned} FHE.Keygen()FHE.Enc(k,sk)FHE.Eval(f,ctk)FHE.Dec(ctf(k),sk)→sk→ctk→ctf(k)→f(k)
下面给出一个基于 FHE 的非交互式条件签名打印器的草图。密钥拥有者也是 FHE 的私钥 s k sk sk 的持有者。云端(cloud)的角色是存储密钥拥有者生成并公开的各种数据,并对所有人开放,包括密钥拥有者事先未知的用户(如 Bob 或 Carl)。

尽管 Alice 可以在加密的签名密钥 c t k ct_k ctk 和她的输入 7 7 7 上同态评估函数 f f f 来获得加密形式的输出 c t f ( k , 7 ) ct_{f(k,7)} ctf(k,7),但这仍然需要与密钥拥有者进一步交互以解密该密文。因此这违反了前面所提的"无交互"要求。另一方面,若把 FHE 的私钥 s k sk sk 一并公开,则虽然可以实现非交互式解密,但这会破坏应用的安全性------因为 Alice 也能据此解密 c t k ct_k ctk并获取 k k k。所以还需要更深入地思考......
5. 尝试三------功能加密(Functional Encryption, FE)
接下来要介绍的技术是功能加密(Functional Encryption, FE)。这是一种相对"不常见"的密码构建模块。这并不奇怪------本文作者花了好几个月才找到一个能充分展示其作用的动机性应用。先分析 FE 的核心接口(API),并通过一个示例来理解它的工作方式。之后才会准备好将 FE 应用于本文的目标问题。
F E . S e t u p ( ) → m p k , m s k F E . K e y g e n ( m s k , f ) → s k f F E . E n c ( k , m p k ) → c t k F E . D e c ( c t k , s k f ) → f ( k ) \begin{aligned} \mathsf{FE.Setup}() &\rightarrow mpk, msk\\ \mathsf{FE.Keygen}(msk, f) &\rightarrow sk_f\\ \mathsf{FE.Enc}(k, mpk) &\rightarrow ct_k\\ \mathsf{FE.Dec}(ct_k, sk_f) &\rightarrow f(k) \end{aligned} FE.Setup()FE.Keygen(msk,f)FE.Enc(k,mpk)FE.Dec(ctk,skf)→mpk,msk→skf→ctk→f(k)
本文选取的动机示例是电子邮件垃圾过滤。设想这样一个场景:
- 一方面,Daisy 不希望依赖某个能读取她全部邮件内容的云端邮件服务提供商;
- 另一方面,如果她使用一个"完全加密"的安全邮件云服务,该服务将无法检测垃圾邮件,从而迫使 Daisy 下载每一封邮件------包括垃圾邮件------浪费带宽与存储空间。
为了解决这个问题:
- Daisy 可以运行系统初始化 S e t u p Setup Setup,生成一对密钥:主公钥 m p k mpk mpk 和 主私钥 m s k msk msk。
- 她用 m s k msk msk 生成一个功能私钥 s k f sk_f skf,该功能私钥绑定到一个检测垃圾邮件的函数 f f f。
- 该函数 f f f 返回 1 1 1 表示邮件为垃圾邮件,否则返回 0 0 0。
- Daisy 将该功能密钥 s k f sk_f skf 分享给她的安全邮件云服务提供商。
- 此后,任何发件人都可以使用 Daisy 的主公钥 m p k mpk mpk 来加密邮件 k k k,生成密文 c t k ct_k ctk,并将该密文 c t k ct_k ctk 发送给其邮件提供商。
- 对于 Daisy 收到的每一封邮件,邮件提供商可以使用FE解密接口运行解密,从而得知邮件是否为垃圾邮件,仅将非垃圾邮件投递给 Daisy。
- 更重要的是,服务器除了"是否为垃圾邮件"这一信息外,无法获知任何关于邮件内容的额外信息。
- 另外需要注意的是,函数 f f f 对邮件接收方( s k f sk_f skf接收方)是公开的。
理解了 FE 的接口之后,可以回到原始问题:构造一个非交互式条件签名打印器。下面给出一个可能的设计草图:

尽管欣赏 FE 解密的非交互特性,但仍然存在一个关键问题:
- FE 解密不允许 Alice 自行注入其输入 x = 7 x=7 x=7。
那么,密钥拥有者该如何允许 Alice(以及其他未知用户)动态地选择输入呢?
一个天真(naive)方案是:
- 让密钥拥有者为每一个可能的输入组合生成一个功能密钥。
- 具体来说,对每一个可能的输入 x i x_i xi,密钥拥有者定义一个函数 f [ x i ] ( k ) f_{[x_i]}(k) f[xi](k),该函数在输入 k k k 时返回 f ( k , x i ) f(k, x_i) f(k,xi),其中 x i x_i xi 被硬编码到该函数定义中。
- 在这种情况下,Alice 可以使用专属于她输入 x = 7 x=7 x=7 的功能私钥 f [ 7 ] ( k ) f_{[7]}(k) f[7](k) 来获得解密结果 f ( k , 7 ) f(k,7) f(k,7)。
但这意味着密钥拥有者的工作量将随输入位数呈指数增长------这又回到了起点。
然而,换个角度看:
- 终于找到了让解密过程非交互化、且与特定函数绑定的方法。
现在只需要再加上一个小组件......
6. 尝试四------增强型功能加密(Augmented FE,意味着 iO)
现在来设想一个理想化的方案:
如果系统支持一个额外的接口(下图中蓝色部分),允许 Alice 在密钥拥有者提供的密文基础上,加入自己动态选择的输入 x x x,那会怎样?
F E . S e t u p ( ) → m p k , m s k F E . K e y g e n ( m s k , f ) → s k f F E . E n c ( k , m p k ) → c t k F E . E x t e n d C T ( c t k , x ) → c t k ∣ ∣ x F E . D e c ( c t k ∣ ∣ x , s k f ) → f ( k , x ) \begin{aligned} \mathsf{FE.Setup}() &\rightarrow mpk, msk\\ \mathsf{FE.Keygen}(msk, f) &\rightarrow sk_f\\ \mathsf{FE.Enc}(k, mpk) &\rightarrow ct_k\\ \color{blue}{\mathsf{FE.ExtendCT}(ct_k, x)} &\color{blue}{\rightarrow ct_{k || x}}\\ \mathsf{FE.Dec}(ct_{k || x}, sk_f) &\rightarrow f(k, x) \end{aligned} FE.Setup()FE.Keygen(msk,f)FE.Enc(k,mpk)FE.ExtendCT(ctk,x)FE.Dec(ctk∣∣x,skf)→mpk,msk→skf→ctk→ctk∣∣x→f(k,x)
基于这种增强型 FE 构造的应用草图如下:

成功了!
这种方案满足了最初设定的全部要求:
- 1)非交互性:Alice(以及任何其他用户)都可以在无需与密钥拥有者交互的情况下获得 f ( k , x ) f(k, x) f(k,x) 的结果;
- 2)安全性:用户除了输出结果 f ( k , x ) f(k,x) f(k,x) 外,无法获得关于 k k k 的任何信息。函数 f f f 本身是公开的,但这不会造成问题;
- 3)高效性:密钥拥有者无需为每个输入生成独立密钥,不存在指数级的计算开销。
在继续深入之前,注意到接口变得有些复杂。
在对其进行简化与重构的过程中,最终将其重新定义为------不可区分性混淆(Indistinguishability Obfuscation, iO)。
F E . S e t u p ( ) → m p k , m s k F E . K e y g e n ( m s k , f ) → s k f F E . E n c ( k , m p k ) → c t k } i O . O b f ( f ( k , ⋅ ) ) → C ~ F E . E x t e n d C T ( c t k , x ) → c t k ∥ x F E . D e c ( c t k ∥ x , s k f ) → f ( k , x ) } i O . E v a l ( C ~ , x ) ← f ( k , x ) \begin{aligned} % ---------- first group ---------- \left. \begin{array}{l} \mathsf{FE.Setup}() \rightarrow mpk, msk\\ \mathsf{FE.Keygen}(msk, f) \rightarrow sk_f\\ \mathsf{FE.Enc}(k, mpk) \rightarrow ct_k \end{array} \right\} &\;\mathsf{iO.Obf}(f(k,\cdot)) \rightarrow \tilde{C} \\[8pt] % ---------- second group ---------- \left. \begin{array}{l} \mathsf{FE.ExtendCT}(ct_k, x) \rightarrow ct_{k \,\|\, x}\\ \mathsf{FE.Dec}(ct_{k \,\|\, x}, sk_f) \rightarrow f(k, x) \end{array} \right\} &\;\mathsf{iO.Eval}(\tilde{C}, x) \leftarrow f(k, x) \end{aligned} FE.Setup()→mpk,mskFE.Keygen(msk,f)→skfFE.Enc(k,mpk)→ctk⎭ ⎬ ⎫FE.ExtendCT(ctk,x)→ctk∥xFE.Dec(ctk∥x,skf)→f(k,x)}iO.Obf(f(k,⋅))→C~iO.Eval(C~,x)←f(k,x)
现在一切(希望)都变得更加清晰了。
不可区分性混淆(Indistinguishability Obfuscation, iO) 可以被视为功能加密(Functional Encryption, FE)的扩展版本,它允许用户将自己的输入比特注入到密文中。
其接口的设计方式如下:
- 一个混淆器(obfuscator)(在本例中即密钥拥有者)定义一个公开函数 f f f,该函数的输入包括一个秘密值 k k k 以及一个尚未知的、固定长度的输入 x x x,然后输出该程序的混淆版本 C ~ \tilde{C} C~ )。
- 这个混淆后的程序可以公开发布,任何评估者(如 Alice)都可以输入自己的 x x x 来运行该程序,从而获得输出 f ( k , x ) f(k,x) f(k,x)。
最终,基于 iO 构造的非交互式条件签名打印器的示意图如下:

下图展示了我们所成功混淆的程序结构。特别地,虚线矩形内的所有内容即为混淆程序 C ~ \tilde{C} C~:
- 函数定义 f f f ------ 即程序要执行的一系列算术门运算 ------ 是公开的;
- 签名密钥 k k k 是私有的。

7. 最终构建模块(Final Building Blocks)
由此可知,iO 是实现非交互式条件签名打印器的关键,并且它可以被视为 支持密文扩展的功能加密(FE)的 扩展版本。
现在终于可以绘制出构建 iO 所需的核心密码原语地图,并指明主要的学术参考来源:

要构建本文的功能加密(FE),高度依赖:
- AKY24a(2024年论文Compact Pseudorandom Functional Encryption from Evasive LWE):其仅使用矩阵乘法(Matrix Multiplication)
- BGG+ 编码(见2015年视频 Attribute-based Encryption for Circuits)
- 格陷门(Lattice Trapdoors)(见2011年论文 Trapdoors for Lattices: Simpler, Tighter, Faster, Smaller)
一旦功能加密(FE)构建完成,就可以通过多种方式获得 iO,将这些方式统称为增强型功能加密(augmented FE)。
相关构造包括:
- AKY24b(2024年论文Pseudorandom Multi-Input Functional Encryption and Applications)
- AJ15(2015年视频 How to Construct Indistinguishability Obfuscation from Compact Functional Encryption)
- BV15(2015年视频 Indistinguishability Obfuscation from Functional Encryption∗)
这些方案通过递归使用功能加密(FE)来获得 iO,这也是当前 iO 构造的主要效率瓶颈。
与此相对,Machina iO团队的构造 SBP25(2025年论文Diamond iO: A Straightforward Construction of Indistinguishability Obfuscation from Lattices) 在非黑盒(non-black-box)的方式下,从 AKY24a(2024年论文Compact Pseudorandom Functional Encryption from Evasive LWE) 基础上直接由 FE 构建 iO,从而用简单的矩阵乘法取代了递归的 FE 调用。
- 该构造仅针对伪随机函数(pseudorandom functions)实现了 FE/iO,但可以通过 BDJ+24(2024年论文Pseudorandom Obfuscation and Applications) 中提出的转换方法,扩展为支持一般函数的 iO。
- 该构造描述了如何将 任意 支持一般函数的 FE 方案转换为 iO。
8. 结论(Conclusion)
在前面的章节中,探讨了多种构建非交互式条件签名打印器(non-interactive conditional signature printer)的方法。
在这些尝试中,基于 iO 的构造是唯一能够严格满足所有要求的方案。
尽管仍需进一步推动其实用化,但坚信 iO 技术有潜力开启过去无法实现的新型应用。
参考资料
1\] 2025年7月1日以太坊基金会PSE的Machina iO团队 博客 [UNBOXING IO: BUILDING FROM FAMILIAR CRYPTO BLOCKS](https://machina-io.com/posts/unboxing.html)