隐语的SPU目前主要实现了四种方式的PSI
一、ECHD-PSI协议:
参考《隐私计算 跨平台互联互通 开放协议 第1部分:ECDH-PSI》
主要包括5个主要步骤:
ECDH-PSI 包括以下 5 个主要步骤:
- 数据预处理:每个参与方对自己的原始数据进行哈希运算,然后将哈希值映射到椭圆曲线上的点。
- 一次加密:使用本地私钥对椭圆曲线点进行点乘操作,生成一次加密数据。
- 数据交换:各参与方互相发送加密后的数据集合。
- 二次加密:使用本地私钥对收到的数据进行二次加密。
- 交集计算:通过比较本地二次加密后的数据与对方返回的数据,计算集合的交集
在执行协议之前,参与方首先需要协商算法版本、PSI类型、椭圆曲线参数,并确定待求交集合的数据大小。
特点:
- 性能上支持Curve25519、FourQ曲线,增加了intel-crypto multi-buffer的支持
- 测评及合规需求:增加了SM2曲线支持,增加了Secp256k1曲线支持
- 互联互通:能够实现异构隐私计算平台间的计算
二、KKRT16 PSI
KKRT16-PSI的实现如下:
python
输入:接收方(Receiver,Bob):集合 X={x_1,x2,...,xn}。发送方(Sender,Alice):集合 Y={y_1,y_2,...,y_m}。
输出:双方交集 Z=X∩Y。
1. 初始化:
输入集合 X (Bob) 和 Y (Alice),设置哈希表大小为 1.2n。
2. 接收方 (Bob) 预处理:
- 使用 Cuckoo 哈希将集合 X 映射到哈希表:
for x in X:
if h1(x) 空:
存储 x 到 h1(x)
else if h2(x) 空:
存储 x 到 h2(x)
else if h3(x) 空:
存储 x 到 h3(x)
else:
放弃或重新调整哈希表
3. OT 初始化:
- Bob 和 Alice 执行基本 OT,生成批量 OT 的初始密钥。
- 扩展生成 1.2n 个密钥 {k_1, k_2, ..., k_1.2n},共享给 Alice 和 Bob。
4. 批量 OPRF 映射:
- Alice 对集合 Y 计算 OPRF 映射值:
for y in Y:
计算 F(k_i, y)
发送所有 F(k_i, y) 给 Bob。
- Bob 对哈希表中的槽位计算 OPRF 映射值:
for x in 哈希表:
if x 非空:
计算 F(k_i, x)
5. 交集计算:
- Bob 比较 F(k_i, x) 和 Alice 提供的 F(k_i, y):
if F(k_i, x) == F(k_i, y):
x 属于交集 Z
- 输出交集 Z。
隐语上对KKRT16 PSI主要做了两个方面的性能优化
一个是矩阵转置
一个是布谷鸟哈希
论文参考链接:
More efficient oblivious transfer and extensions for faster secure computation
VASA: Vector AES Instructions for Security Applications
Scalable Private Set Intersection Based on OT Extension
Efficient Circuit-based PSI with Linear Communication
三、BC22 PCG PSI
BC22 PCG PSI通过共享种子生生高效的伪随机对,优化了传统PSI协议的通信开销,同样也利用了布谷鸟哈希、Simple Hash、BarK-OPRF技术。流程如下:
伪代码如下:
python
算法:BC22 PCG PSI 协议
输入:
- 接收方 (Bob):集合 X = {x_1, x_2, ..., x_n}
- 发送方 (Alice):集合 Y = {y_1, y_2, ..., y_m}
输出:
- 交集 Z = X ∩ Y
---
1. 初始化参数
- 双方协商:
- 安全参数 q(有限域 F_q 的大小)
- 哈希表大小 N(如 N = 1.2n)
- 使用的哈希函数 {h1, h2, h3}
- 共享随机种子 seed
---
2. PCG 随机数生成与扩展
- Bob 和 Alice 使用共享的随机种子 seed,通过 PCG 协议生成伪随机向量:
- Bob 生成: u ∈ F_q^n 和 v ∈ F_q^n
- Alice 生成偏移向量 Δ ∈ F_q^n
- 计算: w = Δ ⋅ u + v
- 随机向量用于生成多项式系数和 OPRF 随机性。
---
3. 哈希映射
3.1 Bob 插入 Cuckoo 哈希表:
- 初始化大小为 1.2N 的 Cuckoo 哈希表。
- 对于集合 X 中的每个元素 x ∈ X:
- 计算 h1(x), h2(x), h3(x)
- 如果 h1(x) 对应的桶为空,则存入 h1(x)
- 否则尝试 h2(x), h3(x)
- 如果所有桶都被占用,则抛出错误或调整哈希表。
3.2 Alice 插入 Simple 哈希表:
- 初始化大小为 2N 的 Simple 哈希表。
- 对集合 Y 中的每个元素 y ∈ Y:
- 使用简单哈希函数计算位置,插入哈希表。
---
4. 计算 OPRF
4.1 Bob:计算并掩码多项式系数
- 使用 PCG 生成的随机向量 u, v:
- 对哈希表中每个非空槽位,计算多项式系数 p_i
- 掩码处理: Masked(p_i) = p_i ⊕ v[i]
- 存储掩码后的多项式系数 Masked(p_i)。
4.2 Alice:计算并混淆 OPRF 值
- 对集合 Y 中每个元素 y,使用 Simple 哈希:
- 根据哈希表位置计算 OPRF 映射值 F(k, y) = H(k ⊕ y)
- 混淆处理: Shuffle(F(k, y))
- 将混淆后的 OPRF 值发送给 Bob。
---
5. 交集计算
- Bob 对收到的 OPRF 值逐一比较:
- 对哈希表中每个槽位的掩码多项式系数 Masked(p_i):
- 恢复原始多项式系数: p_i = Masked(p_i) ⊕ v[i]
- 计算 OPRF 映射值 F(k, x)
- 比较 F(k, x) 是否等于收到的 OPRF 值 F(k, y)
- 如果相等,则 x ∈ Z
- 输出交集 Z。
---
6. 输出结果
- Bob 输出交集 Z = X ∩ Y
这个协议无论是计算开销还是通信成本上都要优于前两种算法。
四、Unbalanced PSI
之前的PSI基于一个假设,就是假设参与者各自所拥有的数据集量大致上是均衡相等的,但实际应用上,也有许多参与者在数据集量上是不对等的,举个例子,社交网络中,当用户开启联系人发现功能,用户所拥有的数据集就是自己手机上的联系人,一般是几百个或几千个,但是社交网络的服务器上包含了所有注册用户的信息,是以百万千万计算的,这个场景下参与者的数据集量是严重不对等的,要求客户端用户使用与服务端相同的协议计算PSI显然是困难的,就引出一个Unbalanced的PSI。
在Unbalanced PSI方面,隐语目前实现了基于ec-oprf 的PSI和SHE 的PSI。下面以论文《 Faster Unbalanced Private Set Intersection》简单说明下不均衡数据集下的PSI。
先给出文献中协议流程:
1 离线阶段 服务端预处理: 服务端为集合 X X 中的每个元素计算伪随机值: t x i = H 2 ( H 1 ( x i ) α ) H 1 , H 2 :哈希函数。 α :服务端的私钥。 这些值被插入到 C u c k o o F i l t e r 中以便于压缩存储。 传输过滤器: 服务端将生成的 C u c k o o F i l t e r 发送给客户端,客户端存储该过滤器。 2 在线阶段 客户端生成查询: 客户端对集合 Y Y 中的每个元素计算哈希值: P y j = H 1 ( y j ) G G :椭圆曲线基点。 使用随机私钥 β j 加密: a y j = H 1 ( y j ) β j 客户端将加密点 a y j 发送给服务端。 服务端处理查询: 服务端接收到 a y j ,并使用其私钥 α 计算: b y j = a y j α 将结果 b y j 返回给客户端。 客户端解密和查询交集: 客户端使用 β j 去掩码: t y j = H 2 ( b y j 1 / β j ) 查询 t y j 是否存在于 C u c k o o F i l t e r 中: 若存在,则 y j ∈ X ∩ Y 。 \begin{align*} &1 离线阶段\\ & 服务端预处理:\\ & 服务端为集合 XX 中的每个元素计算伪随机值:\\ & t_{x_i}=H_2(H_1(x_i)^α)\\ & H_1,H_2:哈希函数。\\ & α:服务端的私钥。\\ & 这些值被插入到 Cuckoo Filter 中以便于压缩存储。\\ & 传输过滤器:\\ & 服务端将生成的 Cuckoo Filter 发送给客户端,客户端存储该过滤器。\\ &2 在线阶段\\ & 客户端生成查询:\\ & 客户端对集合 YY 中的每个元素计算哈希值:\\ & P_{y_j}=H_1(y_j)^G\\ & G:椭圆曲线基点。\\ & 使用随机私钥 β_j加密:\\ & a_{y_j}=H_1(y_j)^{βj}\\ & 客户端将加密点 a_{y_j}发送给服务端。\\ & 服务端处理查询:\\ & 服务端接收到 a_{y_j},并使用其私钥 α 计算:\\ & b_{y_j}=a_{y_j}^α\\ & 将结果 b_{y_j} 返回给客户端。\\ & 客户端解密和查询交集:\\ & 客户端使用 βj去掩码:\\ & t_{y_j}=H_2(b_{y_j}^{1/β_j})\\ & 查询 t_{y_j} 是否存在于 Cuckoo Filter 中:\\ & 若存在,则 y_j∈X∩Y。\\ \end{align*} 1离线阶段服务端预处理:服务端为集合XX中的每个元素计算伪随机值:txi=H2(H1(xi)α)H1,H2:哈希函数。α:服务端的私钥。这些值被插入到CuckooFilter中以便于压缩存储。传输过滤器:服务端将生成的CuckooFilter发送给客户端,客户端存储该过滤器。2在线阶段客户端生成查询:客户端对集合YY中的每个元素计算哈希值:Pyj=H1(yj)GG:椭圆曲线基点。使用随机私钥βj加密:ayj=H1(yj)βj客户端将加密点ayj发送给服务端。服务端处理查询:服务端接收到ayj,并使用其私钥α计算:byj=ayjα将结果byj返回给客户端。客户端解密和查询交集:客户端使用βj去掩码:tyj=H2(byj1/βj)查询tyj是否存在于CuckooFilter中:若存在,则yj∈X∩Y。
伪代码如下:
shell
1. 离线阶段(服务端预处理):
for x in 服务端集合 X:
t_x = H2(H1(x)^α) // 使用服务端私钥 α 计算伪随机值
插入 Cuckoo Filter(t_x)
将 Cuckoo Filter 发送给客户端。
2. 在线阶段:
客户端查询:
for y in 客户端集合 Y:
a_y = H1(y)^β // 使用随机密钥 β 加密
发送 a_y 给服务端。
服务端处理:
for a_y in 接收到的值:
b_y = a_y^α // 使用服务端私钥 α 处理查询
返回 b_y 给客户端。
客户端解密和查询交集:
for b_y in 接收到的值:
t_y = H2(b_y^(1/β)) // 去掩码计算伪随机值
if t_y ∈ Cuckoo Filter:
添加 y 到交集结果。
3. 返回交集结果。
这篇文章里,作者主要引入了Cuckoo Filter来压缩数据,降低客户端需要存储的数据量,使用GLS-254椭圆曲线来提高计算性能,还顺带着优化了下Baldi等人提出的基于公钥加密的PSI协议,来适用于数据集非均衡的场景。
优化 Baldi 等人提出的基于公钥加密的 PSI 协议:
- 引入改进措施,使协议适合于不对称集合场景。
- 保障客户端侧的前向安全性。
Cuckoo Filter 的应用:
- 使用 Cuckoo Filter 来压缩数据,降低客户端需要存储的数据量。
- 提供更低的空间占用和查找复杂度,支持删除操作。
高效的椭圆曲线实现:
- 使用 GLS-254 曲线进行优化,大幅提升计算性能。
- 提供更高效的点压缩算法。
五、调用架构
隐语在PSI的实现架构上,分为四层:
-
bucket_psi:
- 支持分桶求交,适合大规模数据交集计算。
- 提供高级 API,覆盖生产级数据查重、结果广播等完整流程。
-
memory_psi:
- 算法内核级 API,面向小规模数据的高效计算。
-
Operator(算法操作层):
-
提供统一接口,封装具体协议(如 KKRT、BC22)。
-
支持注册工厂模式,提升协议接入效率。
-
-
Batch Provider(批量数据读取层):
- 提供内存或文件(如 CSV)中的数据批量处理功能。