Skip to content

多密钥的公钥加密方案 BCP ​

类似于 Paillier, 这个方案是为了后面的 MPC 服务的。

BCP 是一种基于 Paillier 结构的双陷门公钥加密系统。它允许系统拥有一个主密钥(Master Key)和一个用户私钥(User Private Key)。

1. Setup ​

由可信第三方或分布式协议生成公共参数和主密钥:

  1. 选择两个大素数 p,q ,计算 n=p⋅q
  2. 计算 λ=lcm(p−1,q−1),可以用 lcm(a,b)⋅gcd(a,b)=a⋅b 来计算
  3. 选择生成元 g∈Zn2∗,使得 g 的阶是 n 的倍数(通常需满足 gcd(L(gλmodn2),n)=1)
  4. 计算 μ=L(gλmodn2)−1modn。
    • 其中函数 L(x)=x−1n
  • 公共参数 (Params): (n,n2,g)
  • 主密钥 (MK): (p,q,λ,μ)

2. KeyGen ​

用户生成自己的公私钥对:

  1. 用户随机选择私钥 a∈Zn2∗
  2. 计算公钥 h=gamodn2
  • 用户公钥 (PK): h
  • 用户私钥 (SK): a

3. Encrypt ​

给定明文 m∈Zn 和用户公钥 h:

  1. 随机选择随机数 r∈Zn2∗
  2. 计算 A=grmodn2
  3. 计算 B=hr⋅(1+m⋅n)modn2
  • 密文 (Ciphertext): C=(A,B)

解密 ​

BCP 方案支持两种解密方式。

方式一:使用用户私钥解密 (Exponent Decryption) ​

持有私钥 a 的用户可以直接解密:

m=L(BAamodn2)

证明: 展开 B 和 A:

BAa=hr⋅(1+mn)(gr)amodn2=(ga)r⋅(1+mn)gramodn2=gar⋅(1+mn)garmodn2=1+mnmodn2

应用 L(x) 函数:

L(1+mn)=(1+mn)−1n=mnn=m

证毕。

方式二:使用主密钥解密 (Factor Decryption) ​

持有主密钥 (p,q,λ,μ) 的一方(如监管者或 MPC 协议中的计算方)可以在不知道用户私钥 a 的情况下解密。

核心性质: 对于任意 x∈Zn2∗,有 xλ≡1(modn)。 因此存在唯一的 k∈Zn 使得:

xλ≡1+n⋅L(xλ)(modn2)
证明

记 n=pq,且 λ=lcm(p−1,q−1)。

因为 x∈Zn2∗,所以 gcd(x,n)=1,从而 xmodp∈Zp∗ 且 xmodq∈Zq∗。

由费马小定理:

xp−1≡1(modp),xq−1≡1(modq)

又因为 λ 同时是 p−1 与 q−1 的倍数,所以:

xλ≡1(modp),xλ≡1(modq)

由中国剩余定理(CRT)得到:

xλ≡1(modpq)(=(modn))

于是存在 k∈{0,1,…,n−1} 使得

xλ=1+kn

把上式视为模 n2 的同余式即可写作 xλ≡1+kn(modn2)。

因此(这里的 L 函数只对形如 1+n⋅(⋅) 的元素使用)

L(xλ)=xλ−1n≡k(modn)

证毕。

算法步骤:

  1. 恢复随机数 rmodn:r′=L(Aλ)⋅μmodn
  2. 恢复私钥 amodn:a′=L(hλ)⋅μmodn
  3. 计算中间项:term=L(Bλ)⋅μmodn
  4. 消除随机性:Δ=term−a′⋅r′modn
  5. 恢复明文:m=Δ⋅L(gλ)⋅λ−1modn

详细证明:

Step 1: 展开 L(Aλ)

Aλ=(gr)λ=(gλ)r=(1+nL(gλ))r=1+n⋅r⋅L(gλ)modn2

所以:

L(Aλ)=r⋅L(gλ)modn

乘以 μ=L(gλ)−1 后:

r′=r⋅L(gλ)⋅L(gλ)−1=rmodn

Step 2: 展开 L(hλ) 同理,因为 h=ga:

L(hλ)=a⋅L(gλ)modn→a′=amodn

Step 3: 展开 L(Bλ)

Bλ=(hr⋅(1+mn))λ=(gar)λ⋅(1+mn)λ=(gλ)ar⋅(1+mnλ)=(1+nL(gλ))ar⋅(1+nmλ)modn2=(1+n⋅ar⋅L(gλ))⋅(1+nmλ)modn2=1+n(arL(gλ)+mλ)modn2

所以:

L(Bλ)=arL(gλ)+mλmodn

乘以 μ 得到 term:

term=(arL(gλ)+mλ)μ=ar+mλμmodn

Step 4: 计算 Δ

Δ=term−a′r′=(ar+mλμ)−(a)(r)modn=mλμmodn

Step 5: 恢复 m 代码中最后计算 m=Δ⋅L(gλ)⋅λ−1。 代入 Δ:

mcalc=(mλμ)⋅L(gλ)⋅λ−1=m⋅(λλ−1)⋅(μL(gλ))=m⋅1⋅1=mmodn

证毕。

加法同态 ​

给定两条消息 m1,m2 :

Enc(m1)=(A1,B1)=(gr1,hr1(1+m1n))Enc(m2)=(A2,B2)=(gr2,hr2(1+m2n))

加法:

Enc(m1)⊕Enc(m2)=(A1⋅A2modn2,B1⋅B2modn2)=(gr1+r2modn2,hr1+r2(1+(m1+m2)n)modn2)=Enc(m1+m2)

标量乘 → 幂运算 ≈ 乘法:

Enc(m)k=(Akmodn2,Bkmodn2)=(grkmodn2,hrk(1+(mk)n)modn2)=Enc(m⋅k)

使用加法同态实现双方的乘法同态 ​

假设有两个参与方:

  1. 计算方 (Alice):拥有密文 Enc(a) 和 Enc(b),以及公钥 pk。她想计算 Enc(a⋅b),但没有私钥。
  2. 协助方 (Bob):拥有公钥 pk 和私钥 sk。

由于加法同态加密本身不支持直接的密文乘法(即 Enc(a)⋅Enc(b)≠Enc(a⋅b)),需要通过交互协议来完成。

协议流程 ​

1. 盲化 (Blinding/Masking) - Alice

计算方生成两个大的随机数 r1,r2∈G,混淆原始密文:

Enc(a+r1)=Enc(a)⊕Enc(r1)Enc(b+r2)=Enc(b)⊕Enc(r2)

计算方将这两个掩盖后的密文发送给协助方。

2. 解密与计算 - Bob

协助方收到密文后,使用私钥 sk 进行解密。由于引入了随机数 r1,r2,协助方只能看到掩盖后的值,无法得知 a 和 b:

Dec(Enc(a+r1))=a+r1Dec(Enc(b+r2))=b+r2

协助方在明文空间计算这两个值的乘积,并将结果重新加密后发回给计算方:

Result=Enc((a+r1)(b+r2))

3. 去盲 (Unblinding) - Alice

计算方收到 Enc((a+r1)(b+r2)) 后,利用已知的 r1,r2 和同态性质消除引入的随机项。

展开乘积公式:

(a+r1)(b+r2)=ab+ar2+br1+r1r2

为了得到 ab,需要减去后三项:

ab=(a+r1)(b+r2)−ar2−br1−r1r2

计算方利用标量乘同态性质(Enc(m)k=Enc(mk))计算这些中间项的负值密文:

  1. 计算 −ar2 的密文:Enc(−ar2)=Enc(a)−r2
  2. 计算 −br1 的密文:Enc(−br1)=Enc(b)−r1
  3. 计算 −r1r2 的密文:直接加密常数 Enc(−r1r2)

4. 最终聚合

计算方将所有部分通过同态加法聚合:

Enc(ab)=Enc((a+r1)(b+r2))⊕Enc(−ar2)⊕Enc(−br1)⊕Enc(−r1r2)

至此,计算方在未泄露 a,b 的情况下,成功获得了 Enc(a⋅b)。

多密钥的安全多方计算 ​

各用户 Pi 持有私有输入 mi,分别用各自公钥 pki 加密后上传至云服务器 C。要求在不泄露 mi 的前提下,计算函数 f(m1,...,mn)。

1. 初始化与上传 ​

  • 云服务器 S 执行 Setup,生成 PP=(N,k,g),MK=(p′,q′)
  • 广播 PP 给所有用户和云服务器 C
  • 每个用户 Pi 生成 (pki,ski),加密 mi 得到 ci=(Ai,Bi),上传至 C

此时,C 持有密文集合 {ci=Encpki(mi)}i=1n,但各密文使用不同公钥加密,无法直接同态运算。

2. 密文转换 ​

步骤 A:C 对每个密文进行盲化 ​

对每个 ci=(Ai,Bi),C 随机选择盲化因子 τi←$ZN,构造:

m~i=mi+τimodN

但由于 C 无法解密,它利用 加法同态性 构造 Encpki(m~i) 如下:

  • 生成 Encpki(τi)=(gti,hiti(1+τiN))
  • 计算:c~i=ci⊕Encpki(τi)=Encpki(mi+τi)

然后将 c~i 发送给云服务器 S。

步骤 B:S 使用 MK 解密得到 m~i ​

S 利用主密钥 MK 和公钥 pki 对 c~i 执行 主密钥解密,得到:

m~i=mi+τimodN

步骤 C:S 用统一公钥重新加密 ​

S 生成一个 临时统一公钥 pk∗=ga∗,并加密所有 m~i:

ci∗=Encpk∗(m~i)

发回给 C。

步骤 D:C 去除盲化因子 ​

C 已知 τi,可构造 Encpk∗(−τi),并计算:

Encpk∗(mi)=ci∗⊕Encpk∗(−τi)

现在,C 拥有所有 mi 在 同一公钥 pk∗ 下的密文,记为 {Encpk∗(mi)}。


3. 函数计算 ​

加法(直接利用同态性): ​

Encpk∗(∑i=1nmi)=⨁i=1nEncpk∗(mi)

乘法(需交互): ​

要计算 Encpk∗(mimj),由于 BCP 不是乘法同态,采用如下协议:

  1. C 随机选择 r1,r2←$ZN
  2. 计算:Enc(a+r1),Enc(b+r2)
  3. 发送给 S,S 解密得 a+r1,b+r2
  4. S 计算 (a+r1)(b+r2)=ab+ar2+br1+r1r2
  5. S 加密该值并返回:Enc((a+r1)(b+r2))
  6. C 本地计算:Enc(ab)=Enc((a+r1)(b+r2))⊖Enc(ar2)⊖Enc(br1)⊖Enc(r1r2)其中 Enc(ar2)=Enc(a)r2

4. 密文转换 ​

最终结果为 Encpk∗(f(m1,...,mn)),以下记为Encpk∗(Res) 。由于用户无 sk∗,需 C 与 S 再次交互,将结果 转换回可由用户联合解密的形式。

  1. C 盲化密文 (C,D):

    • 选择 τ←$ZN
    • 计算 Encpk∗(τ)
    • 计算并发送给 S: (C,D)=Encpk∗(Res+τ)=Encpk∗(Res)⊕Encpk∗(τ)
  2. S 解密, 得到 z=res+τ←Decpk∗(C,D)

  3. S 使用用户公钥 pki 加密 z,得到 Encpki(z)

  4. C 去盲:

  • 计算 Encpki(−τ)
  • 计算最终结果:
Encpki(Res)=Encpki(z)⊕Encpki(−τ)
  • 发送给用户 Encpki(Res)