基本概念
秘密共享(Secret Sharing,SS)是安全多方计算中的一种技术,主要概念是通过将秘密值分割成随机多份,并将这些份分发给不同方隐藏秘密值,每一方只能拥有一个通过共享得到的秘密值的一部分,可根据具体的场合,将所有的或者一定数量的共享数值来重新构造原始的秘密值。
值得注意的是数量不足的参与者是无法恢复秘密信息的,而范围内的部分参与者出现问题的时候,秘密仍然可以完整的恢复。
所以一个秘密共享方案的关键就是如何设计秘密拆分和恢复的方式。
shamir方案
基本思路是通过分发多项式,基于矢量方法和拉格朗日插值法构造。所谓插值法就是通过函数在有限个点处的取值状况来估算出函数在其他点处的近似值。
拉格朗日插值法
简单比喻就是类似线性代数里面的,找到基坐标,然后确定坐标,这里就是用多项式去确定多项式。
核心概念是假设在二维平面上有
k
+
1
k+1
k+1个点
(
x
0
,
y
0
)
,
…
,
(
x
i
,
y
i
)
,
…
,
(
x
k
,
y
k
)
(x_0,y_0),\dots,(x_i,y_i),\dots,(x_k,y_k)
(x0,y0),…,(xi,yi),…,(xk,yk),拉格朗日插值法可以找到且仅能找到次数不超过
k
k
k的一个多项式
L
(
x
)
=
∑
j
=
0
k
y
j
ℓ
j
(
x
)
L(x)=\sum_{j=0}^{k}y_j\ell_j(x)
L(x)=∑j=0kyjℓj(x),使得其恰好在
x
i
x_i
xi上取得值
y
i
y_i
yi,而在其它
x
x
x上取值为0。基本多项式如下,
ℓ
j
(
x
)
=
∏
i
=
0
,
i
≠
j
k
x
−
x
i
x
j
−
x
i
=
(
x
−
x
0
)
(
x
j
−
x
0
)
⋯
(
x
−
x
j
−
1
)
(
x
j
−
x
j
−
1
)
(
x
−
x
j
+
1
)
(
x
j
−
x
j
+
1
)
⋯
(
x
−
x
k
)
(
x
j
−
x
k
)
\ell_{\mathrm{j}}(\mathrm{x})=\prod_{\mathrm{i}=0, \mathrm{i} \neq \mathrm{j}}^{\mathrm{k}} \frac{\mathrm{x}-\mathrm{x}_{\mathrm{i}}}{\mathrm{x}_{\mathrm{j}}-\mathrm{x}_{\mathrm{i}}}=\frac{\left(\mathrm{x}-\mathrm{x}_{0}\right)}{\left(\mathrm{x}_{\mathrm{j}}-\mathrm{x}_{0}\right)} \cdots \frac{\left(\mathrm{x}-\mathrm{x}_{\mathrm{j}-1}\right)}{\left(\mathrm{x}_{\mathrm{j}}-\mathrm{x}_{\mathrm{j}-1}\right)} \frac{\left(\mathrm{x}-\mathrm{x}_{\mathrm{j}+1}\right)}{\left(\mathrm{x}_{\mathrm{j}}-\mathrm{x}_{\mathrm{j}+1}\right)} \cdots \frac{\left(\mathrm{x}-\mathrm{x}_{\mathrm{k}}\right)}{\left(\mathrm{x}_{\mathrm{j}}-\mathrm{x}_{\mathrm{k}}\right)}
ℓj(x)=∏i=0,i=jkxj−xix−xi=(xj−x0)(x−x0)⋯(xj−xj−1)(x−xj−1)(xj−xj+1)(x−xj+1)⋯(xj−xk)(x−xk)
该式子的特点就是在
x
j
x_j
xj处取值为1,其他则为0。把上面式子中的
x
x
x换成任何一个非
x
j
x_j
xj的值,都会使得有一个式子的分子为0,从而使得整个式子值为0。
两个点可以确定唯一的一次多项式,三个点就可以确定一个唯一的二次多项式。
思路
如要求一个二次多项式
y
=
a
0
+
a
1
x
+
a
2
x
2
y=a_0+a_1x+a_2x^{2}
y=a0+a1x+a2x2,有三个点
(
x
1
,
y
1
)
,
(
x
2
,
y
2
)
,
(
x
3
,
y
3
)
(x_1,y_1),(x_2,y_2),(x_3,y_3)
(x1,y1),(x2,y2),(x3,y3),带入到拉格朗日基本多项式里,能够分别得到三根曲线
f
1
(
x
)
,
f
2
(
x
)
,
f
3
(
x
)
f_1(x),f_2(x),f_3(x)
f1(x),f2(x),f3(x)满足在对应点处能取得值为1,而在其他两个点上取值为0。
将三个相加得到
f
(
x
)
=
y
1
f
1
(
x
)
+
y
2
f
2
(
x
)
+
y
3
f
3
(
x
)
f(x)=y_1f_1(x)+y_2f_2(x)+y_3f_3(x)
f(x)=y1f1(x)+y2f2(x)+y3f3(x)
这就是待求的多项式,至于为啥它就是那个多项式,可以用到线性代数
举例
假设多项式为
f
(
x
)
=
1
+
x
+
x
2
f(x)=1+x+x^2
f(x)=1+x+x2,曲线上有三个点
(
0
,
1
),(
1
,
3
),(
2
,
7
)
(0,1),(1,3),(2,7)
(0,1),(1,3),(2,7)带入到拉格朗日基础多项式里得到
f
0
(
x
)
=
(
x
−
x
1
)
(
x
−
x
2
)
(
x
0
−
x
1
)
(
x
0
−
x
2
)
=
(
x
−
1
)
(
x
−
2
)
(
0
−
1
)
(
0
−
2
)
=
x
2
−
3
x
+
2
2
f
1
(
x
)
=
(
x
−
x
0
)
(
x
−
x
2
)
(
x
1
−
x
0
)
(
x
1
−
x
2
)
=
(
x
−
0
)
(
x
−
2
)
(
1
−
0
)
(
1
−
2
)
=
x
2
−
2
x
−
1
f
2
(
x
)
=
(
x
−
x
0
)
(
x
−
x
1
)
(
x
2
−
x
0
)
(
x
2
−
x
1
)
=
(
x
−
0
)
(
x
−
1
)
(
2
−
0
)
(
2
−
1
)
=
x
2
−
x
2
f
(
x
)
=
f
0
(
x
)
+
3
f
1
(
x
)
+
7
f
2
(
x
)
=
x
2
+
x
+
1
\begin{array}{lcr} f_0(x)=\frac{(x-x_1)(x-x_2)}{(x_0-x_1)(x_0-x_2)}=\frac{(x-1)(x-2)}{(0-1)(0-2)}=\frac{x^2-3x+2}{2} \\ f_1(x)=\frac{(x-x_0)(x-x_2)}{(x_1-x_0)(x_1-x_2)}=\frac{(x-0)(x-2)}{(1-0)(1-2)}=\frac{x^2-2x}{-1} \\ f_2(x)=\frac{(x-x_0)(x-x_1)}{(x_2-x_0)(x_2-x_1)}=\frac{(x-0)(x-1)}{(2-0)(2-1)}=\frac{x^2-x}{2} \\ f(x)=f_0(x)+3f_1(x)+7f_2(x)=x^2+x+1 \end{array}
f0(x)=(x0−x1)(x0−x2)(x−x1)(x−x2)=(0−1)(0−2)(x−1)(x−2)=2x2−3x+2f1(x)=(x1−x0)(x1−x2)(x−x0)(x−x2)=(1−0)(1−2)(x−0)(x−2)=−1x2−2xf2(x)=(x2−x0)(x2−x1)(x−x0)(x−x1)=(2−0)(2−1)(x−0)(x−1)=2x2−xf(x)=f0(x)+3f1(x)+7f2(x)=x2+x+1
正确性验证
三个点自然可以通过解方程组的形式解出这个多项式,如
{
y
1
=
a
0
+
a
1
x
1
+
a
2
x
1
2
y
2
=
a
0
+
a
1
x
2
+
a
2
x
2
2
y
3
=
a
0
+
a
1
x
3
+
a
2
x
3
2
\left\{\begin{array}{l} y_{1}=a_{0}+a_{1} x_{1}+a_{2} x_{1}^{2} \\ y_{2}=a_{0}+a_{1} x_{2}+a_{2} x_{2}^{2} \\ y_{3}=a_{0}+a_{1} x_{3}+a_{2} x_{3}^{2} \end{array}\right.
⎩
⎨
⎧y1=a0+a1x1+a2x12y2=a0+a1x2+a2x22y3=a0+a1x3+a2x32
考虑线性代数
y
⃗
=
A
a
⃗
\vec y=A\vec a
y=Aa,即
(
y
1
y
2
y
3
)
⏟
y
⃗
=
(
1
x
1
x
1
2
1
x
2
x
2
2
1
x
3
x
3
2
)
⏟
A
(
a
0
a
1
a
2
)
⏟
a
⃗
\underbrace{\left(\begin{array}{l} y_{1} \\ y_{2} \\ y_{3} \end{array}\right)}_{\vec{y}}=\underbrace{\left(\begin{array}{lll} 1 & x_{1} & x_{1}^{2} \\ 1 & x_{2} & x_{2}^{2} \\ 1 & x_{3} & x_{3}^{2} \end{array}\right)}_{A} \underbrace{\left(\begin{array}{c} a_{0} \\ a_{1} \\ a_{2} \end{array}\right)}_{\vec{a}}
y
y1y2y3
=A
111x1x2x3x12x22x32
a
a0a1a2
这个行列式
∣
A
∣
|A|
∣A∣就是范德蒙行列式,解得为
(
x
3
−
x
1
)
(
x
3
−
x
2
)
(
x
2
−
x
1
)
(x_3-x_1)(x_3-x_2)(x_2-x_1)
(x3−x1)(x3−x2)(x2−x1),点不一样,行列式自然不为0,那就只有一个唯一解。
三个点只能唯一的确定一个二次多项式,不管它是如何组合出来的。
基本方案
假设要分发的秘密为
S
S
S,将其拆为
n
n
n份,需要大于等于
t
t
t份才能恢复秘密。也就是
(
n
,
t
)
(n,t)
(n,t)。
方案大致分为初始化,秘密分发,秘密恢复三个步骤
初始化
选取
n
n
n个不同的元素去标识子秘密持有人(参与者)并公开。
秘密分发
随机选取
t
−
1
t-1
t−1个元素
a
1
⋯
a
t
−
1
a_1\cdots a_{t-1}
a1⋯at−1,和原始的秘密构造多项式
f
(
x
)
=
S
+
a
1
x
+
a
2
x
2
+
⋯
+
a
t
−
1
x
t
−
1
f(x)=S+a_1x+a_2x^2+\cdots+a_{t-1}x^{t-1}
f(x)=S+a1x+a2x2+⋯+at−1xt−1
接着分别(为了更便于理解,实际上
x
x
x是可以由每个成员自行随机选择的)令
x
=
1
,
2
⋯
,
n
x=1,2\cdots,n
x=1,2⋯,n计算
f
(
x
)
f(x)
f(x),即得到子秘密
S
i
=
f
(
x
i
)
(
i
=
1
,
⋯
,
n
)
S_i = f(x_i) \quad(i=1,\cdots,n)
Si=f(xi)(i=1,⋯,n)(如果
x
x
x是随机选择的,那么得到子秘密也是随机的)
然后一般由一个可信的第三方(Dealer),分配给
n
n
n个成员。
秘密恢复
t
t
t个成员拿出他们分到的秘密,组成点
(
1
,
S
1
)
,
⋯
,
(
t
,
S
t
)
(1,S_1),\cdots,(t,S_t)
(1,S1),⋯,(t,St)共
t
t
t个点,然后使用拉格朗日插值公式得到一个唯一的
t
−
1
t-1
t−1次多项式
f
(
x
)
=
∑
i
=
1
t
S
i
ℓ
j
(
x
)
=
∑
i
=
1
t
S
i
∏
i
=
0
,
i
≠
j
k
x
−
x
i
x
j
−
x
i
\begin{aligned} f(x)&=\sum_{i=1}^tS_i \ell_j(x)\\ &=\sum_{i=1}^tS_i\prod_{{i}=0, {i} \neq {j}}^{{k}} \frac{{x}-{x}_{{i}}}{{x}_{{j}}-{x}_{{i}}} \end{aligned}
f(x)=i=1∑tSiℓj(x)=i=1∑tSii=0,i=j∏kxj−xix−xi
该方案中,相当于
n
n
n个成员从
t
−
1
t-1
t−1次多项式上取到了
n
n
n个点,所以恢复出这个多项式需要
t
t
t个点就够了。
可验证的秘密共享
上述方案是不安全的,假设
- Dealer作恶,发送给成员的密钥分片并不能恢复出一致的密钥
- 成员作恶,在恢复阶段发送的分片是错误的,这样恢复的密钥也是错误的;
为了解决这个问题,诞生了可验证的秘密共享。
Feldman VSS
基于shamir方案,增加了承诺验证,是常用的方案。
秘密分发
Dealer随机选择计算一个
t
−
1
t-1
t−1阶多项式,显然需要
t
t
t个参与者才能恢复出原来的秘密。
S
S
S是秘密值。
f
(
x
)
=
S
+
a
1
x
+
a
2
x
2
+
⋯
+
a
t
−
1
x
t
−
1
f(x)=S+a_1x+a_2x^2+\cdots+a_{t-1}x^{t-1}
f(x)=S+a1x+a2x2+⋯+at−1xt−1
然后就是和shamir方案一样,Dealer计算出
n
n
n个
t
−
1
t-1
t−1阶的多项式,也就是随机选择
n
n
n个x轴坐标(可以是1~n),带入多项式得到子秘密
S
i
=
f
(
x
i
)
S_i=f(x_i)
Si=f(xi),然后将它通过加密通道发送给参与成员,这样每个成员都有一个坐标
(
x
i
,
S
i
)
(x_i,S_i)
(xi,Si),这样凑够
t
t
t个就可以恢复出来原来的多项式。
承诺生成
g
g
g为循环群
G
G
G的生成元。
Dealer生成承诺:
c
0
=
g
S
,
c
1
=
g
a
1
,
⋯
,
c
t
=
g
a
t
−
1
c_0=g^S,c_1=g^{a_1},\cdots,c_t=g^{a_{t-1}}
c0=gS,c1=ga1,⋯,ct=gat−1共
t
t
t个承诺。(基于离散对数难题),这组值需要广播出去。
承诺验证
每个参与者可以验证自己收到的秘密,若
g
f
(
x
i
)
=
g
S
+
a
1
i
+
a
2
i
2
⋯
+
a
t
i
t
−
1
=
c
0
c
1
i
c
2
i
2
⋯
c
t
i
t
−
1
\begin{aligned} g^{f(x_i)}&=g^{S+a_1i+a_2{i^2} \cdots+a_t{i^{t-1}}}\\ &=c_0c_1^ic_2^{i^2}\cdots c_t^{i^{t-1}} \end{aligned}
gf(xi)=gS+a1i+a2i2⋯+atit−1=c0c1ic2i2⋯ctit−1则代表验证成功,即Dealer没有作恶。
秘密恢复
具体恢复方法和shamir的一样,在Dealer计算出了
S
S
S后,需要验证一下
c
0
=
g
S
c_0=g^S
c0=gS是否成立。若成立则证明成员没有作恶。
Pedersen VSS
对比Feldman的更加安全,多出了一个多项式。
g
g
g为循环群
G
G
G的生成元,
h
h
h是
G
G
G中一个元素。
秘密分发
Dealer随机选择两个多项式
f
(
x
)
=
S
+
a
1
x
+
a
2
x
2
+
⋯
a
t
−
1
x
t
−
1
q
(
x
)
=
b
0
+
b
1
x
+
b
2
x
2
+
⋯
b
t
−
1
x
t
−
1
\begin{array}{l} f(x)=S+a_{1} x+a_{2} x^{2}+\cdots a_{t-1} x^{t-1} \\ q(x)=b_{0}+b_{1} x+b_{2} x^{2}+\cdots b_{t-1} x^{t-1} \end{array}
f(x)=S+a1x+a2x2+⋯at−1xt−1q(x)=b0+b1x+b2x2+⋯bt−1xt−1
f
(
x
)
f(x)
f(x)也就是前面feldman开始随机计算出的一个多项式。
接着计算出
S
i
=
(
f
(
i
)
,
q
(
i
)
)
S_i=(f(i),q(i))
Si=(f(i),q(i)),一共
n
n
n个并分发给参与者
承诺生成
Dealer公开
c
i
=
g
a
i
h
b
i
c_i=g^{a_i}h^{b_i}
ci=gaihbi,广播出去
承诺验证
参与者验证
g
f
(
i
)
h
q
(
i
)
=
c
0
c
1
i
c
2
i
2
⋯
c
t
−
1
i
t
−
1
g^{f(i)} h^{q(i)}=c_{0} c_{1}^{i} c_{2}^{i^{2}} \cdots c_{t-1}^{i^{t-1}}
gf(i)hq(i)=c0c1ic2i2⋯ct−1it−1
成立就通过。
秘密恢复
和前面的一样。
参考
秘密共享技术
拉格朗日插值法
趣说密码学(五)秘密共享方案——shamir,中国剩余定理,Brickell和Blakley
可验证秘密共享
可验证秘密共享-维基百科
Feldman方案
秘密共享与可验证秘密共享