存在作弊者的 (t,n) 秘密共享方案

存在作弊者的 (t,n) 秘密共享方案

Tip:本文仅根据个人理解进行论文复现,可能存在错误,具体原理详见原论文。
jupyter文件链接:存在作弊者的 (t,n) 秘密共享方案.ipynb
提取码:iahh

1.问题背景

(t,n) 门限秘密共享方案

       密码学中一组参与者的授权子集共同作用才能恢复出秘密的信息保护技术。在 ( t , n ) (t,n) (t,n) 门限秘密共享方案中,一个秘密 s s s 由分发者分发给 n n n 个参与者 p 1 , p 2 , . . . , p n p_1,p_2, ... ,p_n p1,p2,...,pn。当由t个或更多参与者时,可以恢复秘密信息 s s s ,而 t − 1 t-1 t1 个或者更少的参与者无法恢复秘密信息 s s s 。秘密共享能有效地防止系统外敌人的攻击和系统内用户的背叛。常见的 ( t , n ) (t,n) (t,n) 秘密共享方案有 S h a m m i r Shammir Shammir 秘密共享[1] A s m u t h − B l o o m Asmuth-Bloom AsmuthBloom 秘密共享[2]等。

存在作弊者的 (t,n) 秘密共享方案

       作弊问题是传统秘密共享方案中的一个重要问题。秘密共享计划中的作弊场景最早由 T o m p a Tompa Tompa W o l l Woll Woll 提出[3]。他们考虑了一些不诚实的参与者(作弊者)在重建秘密时汇集假秘密碎片的情况。这样,作弊者就可以完全找回一个秘密 s s s,而诚实的参与者只能找回一个伪造的秘密 s , s^, s,。如果将作弊者成功作弊的概率被限制在指定的概率内,即使作弊者是无限强大的,门限方案也被认为是无条件防止作弊的。作弊者的检测和识别对于实现秘密的公平重建非常重要。

2.问题介绍

作弊可检测的秘密共享

       在作弊检测方案中,诚实用户可以检测到作弊行为,但不能识别作弊行为。 M c E l i e s s McEliess McEliess S a r w a t e Sarwate Sarwate [4]证明了 S h a m i r Shamir Shamir 的方案本身具有检测作弊的能力。任何一组最多包含 t t t 个作弊者的 k + 2 t k+2t k+2t 个参与者都可以检测到谁在作弊。他们也能获得正确的秘密 s s s。然而,这个方案需要超过 k k k 个参与者来检测谁是作弊者。

作弊可识别的秘密共享

       作弊识别方案为解决诚实用户不仅可以检测到作弊行为,还可以识别作弊用户的作弊问题提供了更强的技术支持。 M c E l i e s s McEliess McEliess S a r w a t e Sarwate Sarwate [[4]]证明了 S h a m i r Shamir Shamir 的方案本身具有检测作弊的能力。任何一组最多包含 k k k 个作弊者的 t + 2 k t+2k t+2k 个参与者可以检测到谁在作弊。同时也能获得正确的秘密信息 s s s。但是,这个方案需要超过 t t t 个参与者来识别作弊者是谁。

鲁棒性秘密共享

       健壮性的秘密共享方案即使重建时使用包含错误碎片的碎片集合,也能恢复正确的秘密信息。

3.攻击方案

假设存在以下三种攻击方案:
攻击1: 作弊者可以是不小心错误地提交碎片的诚实用户,也可以是不诚实的,他们在没有任何合作的情况下提交伪造的秘密信息碎片。此攻击的每个伪造碎片只是一个随机整数,与其他份额完全独立。
攻击2: 作弊者是不诚实的用户,他们故意修改自己的碎片,以愚弄诚实的用户。在这种类型的攻击中,我们假设所有用户同步释放他们的碎片。因此,作弊者只能在秘密重构之前相互协作找出他们伪造的碎片,但在知道诚实用户的股票后不能修改他们的碎片(即假设所有碎片都必须同时公开)。在此假设下,只有当作弊者的数量大于或等于阈值t时,作弊者才能成功实施欺骗诚实用户的攻击。
攻击3: 作弊者是不诚实的用户,他们故意修改自己的碎片,以愚弄诚实的股东。在这种类型的攻击中,我们假设所有用户都异步公开他们的碎片。由于用户一次只发行一个碎片,所以作弊者的最佳选择是在所有诚实的用户公开后再公开碎片。作弊者可以相应地修改他们的碎片。这是最坏的情况。

4.解决方案与分析

作弊可检测的秘密共享

方案一

        L e i n H a r n Lein Harn LeinHarn L e i n H a r n Lein Harn LeinHarn 提出了一种基于 S h a m m i r Shammir Shammir 门限方案的作弊检测算法[5]。在 S h a m m i r Shammir Shammir 门限方案中,通过拉格朗日插值法恢复秘密信息 s s s。如果有超过 t t t 个的碎片,并且没有伪造的碎片,对于 t t t 个碎片的所有组合,都应该重构一个相容的多项式。作弊检测是通过检测所有重构秘密中不一致的多项式(或秘密)来确定的。但是,作弊者可以合作构造他们的伪造碎片,欺骗诚实的参与者,使他们相信伪造的秘密才是真正的秘密。

  • 算法如下:
    • I n p u t : t , n , J , ( s J 1 , s J 2 , . . . , s J k ) Input:t,n,J,(s_{J_1},s_{J_2},...,s_{J_k}) Input:t,n,J,(sJ1,sJ2,...,sJk) (其中 J J J 是参与恢复的用户集合, s J i s_{J_i} sJi 是秘密碎片)
    • 1.计算 j j j 个点 ( i , s J 1 ) , ( i , s J 2 ) , . . . , ( i , s J j ) (i,s_{J_1}),(i,s_{J_2}),...,(i,s_{J_j}) (i,sJ1),(i,sJ2),...,(i,sJj) 的拉格朗日插值多项式 F ( x ) F(x) F(x)。令 d = F ( x ) d=F(x) d=F(x) 的次数。
    • 2.如果 d = t − 1 d=t-1 d=t1 , 则 s = F ( 0 ) s=F(0) s=F(0) ;否则存在作弊者。
    • O u t p u t : Output: Output: 不存在作弊者,恢复的秘密是 s s s ;否则存在作弊者。

       检测算法基本原理为:采用拉格朗日插值算法重构多项式时,如果参与重构的点都是真实的,那么最后的多项式次数一定等于秘密信息划分时选取的多项式的次数,为 t − 1 t-1 t1。前 t t t 个参与者恢复的多项式次数一定等于 t − 1 t-1 t1。超出 t t t 个参与者参与恢复时,如果是真实的,那么多项式一定包含了该点,所以不会引起次数的变化。一旦参与恢复的点中存在一个伪造点,就会使重构的多项式改变,次数加一。所以可以通过此法检测作弊者的存在。

       该检测算法的前提是有超过门限t的参与者进行恢复秘密信息。但当只有t个参与者且其中存在作弊者时,无法进行检测。这是因为此时不论存在作弊者,必然会增加维度,但由于仅存在 t t t 个参与者,所以无法通过冗余的参与者进行检测。

       实现代码见附录.1

方案二

       刘等人[10]提出了一个新的线性 ( t , n ) (t,n) (tn) 秘密共享方案,该方案在 O K S OKS OKS 假设下具有欺骗检测功能。因为在 O K S OKS OKS 假设下, t − 1 t-1 t1 个欺骗者不知道秘密的信息,这与 ( t , n ) (t,n) (tn) 秘密共享的定义是一致的。该方案是在 S h a m i r Shamir Shamir 方案的基础上提出的,当只有一个诚实的参与者时,可以检测到其他 t − 1 t-1 t1 个作弊者的作弊行为。

  • 方案如下:
    • 秘密信息分发:
      • 1. 分发中心在 G F ( P ) GF(P) GF(P) 上选择一个 ( t − 1 ) (t-1) (t1) 阶随机多项式,
        f ( x ) = s + a 1 ∗ x + . . . + a t − 1 ∗ x t − 1 f(x)=s+a_1*x+...+a_{t-1}*x^{t-1} f(x)=s+a1x+...+at1xt1
      • 2. 分发中心在 G F ( P ) GF(P) GF(P) 上选择一个随机数 r r r 和一个 ( t − 1 ) (t-1) (t1) 阶多项式,
        g ( x ) = b 0 + b 1 ∗ x + . . . + b t − 1 ∗ x t − 1 g(x)=b_0+b_1*x+...+b_{t-1}*x^{t-1} g(x)=b0+b1x+...+bt1xt1
        满足 r s + b 0 = 0 rs+b_0=0 rs+b0=0 r a 1 + b 1 = 0 ra_1+b_1=0 ra1+b1=0
      • 3. 分发中心计算秘密碎片 v i = ( m i , d i ) v_i=(m_i,d_i) vi=(mi,di) i = 1 , 2 , . . . , n i=1,2,...,n i=1,2,...,n,其中 m i = f ( i ) m_i=f(i) mi=f(i) d i = g ( i ) d_i=g(i) di=g(i)
    • 秘密信息恢复:
      • 1. 根据拉格朗日插值法,通过秘密碎片 ( 1 , m 1 ) , ( 2 , m 2 ) , . . . , ( t , m t ) (1,m_1),(2,m_2),...,(t,m_t) (1,m1),(2,m2),...,(t,mt) ( 1 , d 1 ) , ( 2 , d 2 ) , . . . , ( t , d t ) (1,d_1),(2,d_2),...,(t,d_t) (1,d1),(2,d2),...,(t,dt) 分别恢复 f ( x ) f(x) f(x) g ( x ) g(x) g(x)
      • 2. a 0 , a 1 , b 0 , b 1 a_0,a_1,b_0,b_1 a0,a1,b0,b1 分别是 x 0 x^0 x0 x x x f ( x ) f(x) f(x) g ( x ) g(x) g(x) 中的系数。如果存在满足 r a 0 + b 0 = 0 ra_0+b_0=0 ra0+b0=0 r a 1 + b 1 = 0 ra_1+b_1=0 ra1+b1=0 r ∈ Z p r\in Z_p rZp,则输出 s = f ( 0 ) s=f(0) s=f(0)。否则, f ( 0 ) f(0) f(0) 为无效秘密,检测到作弊,输出 ⊥ ⊥

       完美性证明:

       方案中,秘密 s s s 利用 S h a m i r Shamir Shamir 原有的 ( t , n ) (t,n) (tn) 秘密共享方案被分成 n n n 份,显然方案中的 t t t 份或更多份可以重构秘密 s s s。接下来仅需证明 t − 1 t-1 t1 个用户不能获取任何有关秘密 s s s 的信息即可。
       假设: m ∗ ( k ) m^*(k) m(k) 是随机选择的第 k k k 个碎片,那么 k − 1 k-1 k1 个股东重构 k − 1 k-1 k1 次多项式 f i ( x ) f_i(x) fi(x) a 0 , a 1 a_0,a_1 a0,a1 f i ( x ) f_i(x) fi(x) 中的相应系数。可以把 b 0 , b 1 , . . . , b k – 1 b_0,b_1,...,b_{k–1} b0b1,...,bk1 r ′ r' r 作为 k + 1 k+1 k+1 个未知数,建立关于这些未知数的方程: g 0 ( i ) = d i , i = 1 , 2 , . . . , k – 1 g_0(i)=d_i,i=1,2,...,k–1 g0(i)=dii=1,2,...,k1 r ′ a 0 ′ + b 0 ′ = 0 , r ′ a 1 ′ + b 1 ′ = 1 r'{a_0}'+{b_0}'=0,r'{a_1}'+{b_1}'=1 ra0+b0=0,ra1+b1=1。使用穷举法尝试第 k k k 个碎片时,得到 Z p Z_p Zp 中的每一个值的概率是相同的。因此 t − 1 t-1 t1 个用户不能获取任何有关秘密 s s s 的信息。

       可检测性:

       作弊者无法知道原始多项式 f ( x ) f(x) f(x) g ( x ) g(x) g(x),即不能获取 m i m_i mi d i d_i di 之间的关系。作弊者改变其中的某一个,但无法根据生成规则改变另一个值。所以在重构时,恢复出的两个多项式之间不会满足原始多项式之间的关系,即验证错误。当参与重构的 t t t 个用户中存在最多 t − 1 t-1 t1 个作弊者时,均能检测出来。

       实现代码见附录.4

作弊可识别的秘密共享

方案一

        K a o r u Kaoru Kaoru K U R O S A W A KUROSAWA KUROSAWA 提出了一种可识别的 t − t- t作弊者秘密共享方案[6]。该方案基于线性纠错码和正交数组设计。使用强度为 t + 1 t+1 t+1 的正交数组作为无条件安全的认证码,并将其与 S h a m i r Shamir Shamir ( k , n ) (k,n) (kn) 门限方案和 M c E l i e s s McEliess McEliess S a r w a t e Sarwate Sarwate 提出的线性码[4]相结合。

  • 假设最多有 t t t 个作弊者,定义的模型如下:

    • 完备性:任何一组参与者包含至少 k k k 个诚实的参与者。
    • 可靠性:不小于 k k k 个参与者的子集都可以确定秘密信息的任何部分。
    • 可检测性:如果 k k k 或更多的参与者公开他们的碎片,存在可以高概率地检测谁是作弊者的图灵机 M M M
  • 方案如下:

    • 1. 分发中心 D D D 生成秘密碎片 v i = ( α i , β i , γ i ) v_i=(\alpha_i,\beta_i,\gamma_i) vi=(αi,βi,γi), i = 1 , 2 , . . . , n . i=1,2,...,n. i=1,2,...,n. S h a m i r Shamir Shamir 的方案一样, D D D G F ( P ) GF(P) GF(P) 上选择一个 ( k − 1 ) (k-1) (k1) 阶随机多项式,
      f ( x ) = s + a 1 ∗ x + . . . + a k − 1 ∗ x k − 1 f(x)=s+a_1*x+...+a_{k-1}*x^{k-1} f(x)=s+a1x+...+ak1xk1
      α i = f ( i ) \alpha_i = f(i) αi=f(i) i = 1 , 2 , . . , n . i=1,2,..,n. i=1,2,..,n.
    • 2. O A ( t + 1 , n p , q ) OA(t+1,np,q) OA(t+1,np,q) 为正交数组(假设公开), q q q 为素数次方。 D D D 选择一个随机数 e e e,使得 1 ≤ e ≤ q t + 1 1 \le e \le q^{t+1} 1eqt+1 。设 β i \beta_i βi O A ( t + 1 , n p , q ) OA(t+1,np,q) OA(t+1,np,q) 的第 e e e 行和第 ( i − 1 ) p + α i t h (i-1)p + \alpha_i th (i1)p+αith 列元素。
    • 3. D D D G F ( q t + 1 ) GF(q_{t+1}) GF(qt+1) 上随机选择 t t t 阶多项式,
      g ( x ) = e + b 1 ∗ x + . . . + b t ∗ x t g(x)=e+b_1*x+...+b_t*x^t g(x)=e+b1x+...+btxt
      γ i = g ( i ) \gamma_i=g(i) γi=g(i), i = 1 , 2 , . . . , n . i=1,2,...,n. i=1,2,...,n.
方案二

       刘等人提出了一种基于二元多项式的作弊者可识别秘密共享方案[7]。每个用户的碎片是由对称的二元多项式生成的,作弊识别仅基于二元多项式的对称性和插值多项式的线性度。第一种算法可以从 m m m 个参与秘密重构的用户中识别出作弊者,第二个算法可以在其余 n − m n−m nm 个未参与秘密重构的用户的协作下获得更强的作弊识别能力。

方案如下:

  • 秘密信息分发:
    • 1. 分发中心 D D D x x x y y y 中都选择 k − 1 k-1 k1 次的对称二元多项式 F ( x , y ) ∈ G F ( q ) [ X , Y ] F(x,y)∈GF_{(q)}[X,Y] F(xy)GF(q)[XY],秘密 s s s 被隐藏在常数项 s = F ( 0 , 0 ) s=F(0,0) s=F(00) 中。
    • 2. 分发中心 D D D 计算 n n n 个多项式份额 f i ( y ) = F ( i , y ) f_i(y)=F(i,y) fi(y)=F(iy) i = 1 , 2 , . . . , n i=1,2,...,n i=1,2,...,n,并将每个多项式碎片 f i ( y ) f_i(y) fi(y) 发送给用户 P i P_i Pi
  • 秘密信息恢复:
    • 假设有 m ( m ≥ k ) m(m\ge k) m(mk) 个参与者参与秘密信息恢复。

    • 算法一

      • 1. 所有 m m m 个参与者选取两个随机整数 d 1 , d 2 > n d_1,d_2>n d1d2>n,每个参与者 P i P_i Pi i ∈ [ 1 , m ] i∈[1,m] i[1m] 分别计算他的秘密碎片 v i = f i ( 0 ) v_i=f_i(0) vi=fi(0) 和两个检测份额 e i , 1 = f i ( d 1 ) , e i , 2 = f i ( d 2 ) e_{i,1}=f_i(d_1),e_{i,2}=f_i(d_2) ei1=fi(d1)ei2=fi(d2)
      • 2. 所有 m m m 个参与者一起发布他们的秘密共享和两个检测共享。分别计算 v 1 , v 2 , . . . , v m {v_1,v_2,...,v_m} v1,v2,...,vm e 1 , 1 , e 2 , 1 , . . . , e m , 1 {e_{1,1},e_{2,1},...,e_{m,1}} e1,1,e2,1,...,em,1 e 1 , 2 , e 2 , 2 , . . . , e m , 2 {e_{1,2},e_{2,2},...,e_{m,2}} e1,2,e2,2,...,em,2 上的插值多项式 g 0 ( x ) g_0(x) g0(x) g d 1 ( x ) g_{d_1}(x) gd1(x) g d 2 ( x ) g_{d_2}(x) gd2(x)
      • 3. 如果三个多项式 g 0 ( x ) g_0(x) g0(x) g d 1 ( 1 ) g_{d_1}(1) gd1(1) g d 2 ( x ) g_{d_2}(x) gd2(x) 的次数最多为 k − 1 k-1 k1。同时 g d 1 ( d 2 ) = g d 2 ( d 1 ) g_{d_1}(d_2)=g_{d_2}(d_1) gd1(d2)=gd2(d1) g d 1 ( 0 ) = g 0 ( d 1 ) g_{d_1}(0)=g_0(d_1) gd1(0)=g0(d1) g d 2 ( 0 ) = g 0 ( d 2 ) g_{d_2}(0)=g_0(d_2) gd2(0)=g0(d2)。则秘密信息 s = g 0 ( 0 ) s=g_0(0) s=g0(0),输出秘密信息 s s s,算法结束。
      • 4. 如果不满足 s t e p 3 step 3 step3,则表明存在作弊者,需要将其识别出来。所有 m m m 个用参与者公布他们的多项式份额 f i ( y ) f_i(y) fi(y) i = 1 , 2 , . . . , m i=1,2,...,m i=1,2,...,m。所有这 m m m 个参与者使用以下规则相互投票:
        • (1)如果 f i ( j ) = f j ( i ) f_i(j)=f_j(i) fi(j)=fj(i) P i P_i Pi P j P_j Pj 相互投票;
        • (2)如果 f i ( j ) ≠ f j ( i ) f_i(j)\ne f_j(i) fi(j)=fj(i) P i P_i Pi P j P_j Pj 不相互投票。
      • 5. V i V_i Vi 表示参与者 P i P_i Pi s t e p 4 step 4 step4 之后的投票。任何获得少于 T = m + k − 5 2 T={m+k−5\over 2} T=2m+k5 票 $(V_i<T) $的参与者 P i P_i Pi 都被识别为作弊者。设 L L L 是所有作弊者的集合,如果 m − ∣ L ∣ ≥ k m−|L|≥k mLk,则由诚实用户的秘密份额重构秘密 s s s,输出 ( s , L ) (s,L) (sL);否则输出 ( ⊥ , L ) (⊥,L) (L)
    • 算法二

      • 1. m ( m ≥ k ) m(m≥k) m(mk) 个参与者公布他们的多项式碎片 f i ( y ) f_i(y) fi(y) i = 1 , 2 , . . . , m i=1,2,...,m i=1,2,...,m。所有这 m m m 个用户使用以下规则相互投票:
        • (1)如果 f i ( j ) = f j ( i ) f_i(j)=f_j(i) fi(j)=fj(i) P i P_i Pi P j P_j Pj 相互投票;
        • (2)如果 f i ( j ) ≠ f j ( i ) f_i(j)\ne f_j(i) fi(j)=fj(i) P i P_i Pi P j P_j Pj 不相互投票。
      • 2. 如果没个参与者都获得 m − 1 m-1 m1 票,则从 m m m 个秘密共享 v i = f i ( 0 ) v_i=f_i(0) vi=fi(0) i = 1 , 2 , . . . , m i=1,2,...,m i=1,2,...,m 中的任取 k k k 个重建秘密 s s s。输出 ( s , ∅ ) (s,∅) (s);否则转到 s t e p 3 step 3 step3 识别作弊者。
      • 3. 发布 m m m 个多项式碎片 f ∣ i ( y ) f|_i(y) fi(y) i = 1 , 2 , . . . , m i=1,2,...,m i=1,2,...,m 给其他 n − m n−m nm 个用户 P m + 1 , P m + 2 , . . . , P n P_{m+1},P_{m+2},...,P_n Pm+1,Pm+2,...,Pn。每个用户 P i , i ∈ [ m + 1 , n ] P_i,i∈[m+1,n] Pii[m+1n] 按以下规则投票给 P 1 , P 2 , . . . , P m P_1,P_2,...,P_m P1,P2,...,Pm
        • (1)如果 f j ( i ) = f i ( j ) , j ∈ [ m + 1 , n ] , i ∈ [ 1 , m ] f_j(i)=f_i(j),j∈[m+1,n],i∈[1,m] fj(i)=fi(j)j[m+1n]i[1m] P j P_j Pj 投票给 P i P_i Pi
        • (2)否则 P j P_j Pj 不投票给 P i P_i Pi

      V i V_i Vi P i P_i Pi 的选票, i = 1 , 2 , . . . , m i=1,2,...,m i=1,2,...,m,将 s t e p 1 step 1 step1 s t e p 3 step 3 step3 中的选票加在一起。如果 V i < T = n + k − 3 2 V_i<T={{n+k−3}\over 2} Vi<T=2n+k3,则 P i P_i Pi 被识别为作弊者。

方案二完美性证明:

       设 g 0 ( x ) = F ( x , 0 ) g_0(x)=F(x,0) g0(x)=F(x0),显然 g 0 ( x ) g_0(x) g0(x) 的次数为 k − 1 k-1 k1,秘密 s s s s = F ( 0 , 0 ) = g 0 ( 0 ) s=F(0,0)=g_0(0) s=F(00)=g0(0)。此外,每个用户 P i P_i Pi 具有秘密碎片 v i = f i ( 0 ) = F ( i , 0 ) v_i=f_i(0)=F(i,0) vi=fi(0)=F(i0) i = 1 , 2 , . . . , n i=1,2,...,n i=1,2,...,n,易得秘密碎片 v i v_i vi g 0 ( x ) g_0(x) g0(x) 产生的碎片,即 v i = F ( i , 0 ) = g 0 ( i ) v_i=F(i,0)=g_0(i) vi=F(i0)=g0(i)。这与 S h a m i r Shamir Shamir ( k , n ) (k,n) (kn) 秘密共享方案是一致的。因此,方案是一个完美的 ( k , n ) (k,n) (kn) 门限方案。

方案二作弊检测和识别能力分析:

       · 如果作弊人数 t t t 满足 t ≤ m − k + 2 t≤m−k+2 tmk+2,则算法一可以检测到作弊。

        s t e p 2 step 2 step2 中, t t t 个作弊者发布虚假秘密碎片 v i ∗ ≠ v i v_i^*\ne vi vi=vi。结果表明, m m m 个公开秘密碎片上的插值多项式 g 0 ( x ) g_0(x) g0(x) 不等于原来的 g 0 ( x ) = F ( x , 0 ) g_0(x)=F(x,0) g0(x)=F(x0)。只有当 g 0 ( x ) g_0(x) g0(x) 的次数最多为 k − 1 k−1 k1 g 0 ( d 1 ) = g d 1 ( 0 ) g_0(d_1)=g_{d_1}(0) g0(d1)=gd1(0) g 0 ( d 2 ) = g d 2 ( 0 ) g_0(d_2)=g_{d_2}(0) g0(d2)=gd2(0) 时,欺骗才能成功。如果作弊者随机发布他们的假秘密共享,即攻击1,作弊就很容易被发现。假设这些作弊者勾结在一起(攻击2),他们可以如下伪造他们的假秘密文件。在不失一般性的情况下, P 1 , P 2 , . . . , P t P_1,P_2,...,P_t P1,P2,...,Pt 是作弊者, P t + 1 , P t + 2 , . . . , P m P_{t+1},P_{t+2},...,P_m Pt+1,Pt+2,...,Pm 是诚实的参与者。作弊者生成一个 k − 1 k-1 k1 次多项式 g 0 , ( x ) ≠ 0 g_0^,(x)\ne 0 g0,(x)=0,满足 g 0 , ( t + 1 ) = g 0 , ( t + 2 ) = , . . . , = g 0 , ( m ) = 0 g_0^,(t+1)=g_0^,(t+2)=,...,=g_0^,(m)=0 g0,(t+1)=g0,(t+2)=,...,=g0,(m)=0,且 g 0 , ( d 1 ) = 0 g_0^,(d_1)=0 g0,(d1)=0 g 0 , ( d 2 ) = 0 g_0^,(d_2)=0 g0,(d2)=0。每个作弊者 P i P_i Pi 伪造一个伪秘密碎片 v i ∗ = v i + g 0 , ( i ) v_i^*=v_i+g_0^,(i) vi=vi+g0,(i) i = 1 , 2 , . . . , t i=1,2,...,t i=1,2,...,t。因此, v 1 ∗ , v 2 ∗ , … , v t ∗ , v t + 1 , v t + 2 , . . . , v m v_1^*,v_2^*,…,v_t^*,v_{t+1},v_{t+2},...,v_m v1,v2,,vt,vt+1,vt+2,...,vm 上的插值多项式是 g 0 ∗ ( x ) = g 0 ( x ) + g 0 , ( x ) g^∗_0(x)=g_0(x)+g^,_0(x) g0(x)=g0(x)+g0,(x)。因为 g 0 , ( d 1 ) = g 0 , ( d 2 ) = 0 g_0^,(d_1)=g_0^,(d_2)=0 g0,(d1)=g0,(d2)=0,所以有 g 0 ∗ ( d 1 ) = g d 1 ( 0 ) g^∗_0(d_1)=g_{d_1}(0) g0(d1)=gd1(0) g 0 ∗ ( d 2 ) = g d 2 ( 0 ) g^∗_0(d_2)=g_{d_2}(0) g0(d2)=gd2(0)。所以通过发布伪造秘密碎片 v i ∗ , i = 1 , 2 , . . . , t v^∗_i,i=1,2,...,t vi,i=1,2,...,t 成功作弊。但是,只有当 m − t + 2 ≤ k − 1 m−t+2≤k−1 mt+2k1 时,这种方法才有效,否则不存在满足 g 0 , ( t + 1 ) = g 0 , ( t + 2 ) = , . . . , = g 0 , ( m ) 0 g_0^,(t+1)=g_0^,(t+2)=,...,=g_0^,(m)0 g0,(t+1)=g0,(t+2)=,...,=g0,(m)0,且 g 0 , ( d 1 ) = 0 , g 0 , ( d 2 ) = 0 g_0^,(d_1)=0,g_0^,(d_2)=0 g0,(d1)=0g0,(d2)=0

       · 如果作弊人数 t t t 满足 t < m − k + 3 2 t<{{m−k+3}\over 2} t<2mk+3,则算法一可以识别出作弊者。

       在 s t e p 3 step 3 step3 中,每个作弊者最多只能得到 k + t − 4 k+t−4 k+t4 个票,设 f i ∗ ( y ) ≠ f i ( y ) f^∗_i(y)\ne f_i(y) fi(y)=fi(y) 是作弊者 P i P_i Pi 的伪造多项式碎片。 f i ∗ ( y ) f^∗_i(y) fi(y) 应与 s t e p 2 step 2 step2 中公布的 E i , 1 , E i , 2 , v ∗ i Ei,1,Ei,2,v∗i Ei1Ei2vi一致。根据k−一次多项式的性质,f∗i(Y)至多可满足k−3个其他插值点f∗i(J)=fj(I),j?=i,其中pj

       算法一在公布多项式份额之前公布检测碎片的目的是,作弊者不能随意地伪造他们的伪多项式碎片,伪多项式碎片 f i ∗ ( y ) f^∗_i(y) fi(y) 必须与他们公布的秘密碎片和检测碎片一致。在算法一中,如果 t < m − k + 3 2 t<{{m−k+3}\over 2} t<2mk+3,则可以识别作弊者。这种识别作弊者的能力与参数 m m m k k k 有关,当更多的用户参与秘密重构时,相应地可以识别出更多的作弊者。

       算法一的局限性在于,当参与秘密重构的用户数 m m m 接近 k k k 时,识别欺骗者的能力将减弱。例如,当 m = k m=k m=k m = k + 1 m=k+1 m=k+1 时,算法一只能识别1个作弊者。因此,在算法一中,如果每个用户计算并发布 u > 2 u>2 u>2 个检测碎片,则可通过 t < m − k + u + 1 2 t<{{m−k+u+1}\over 2} t<2mk+u+1来增强作弊识别能力。

       · 如果 t < k t<k t<k,则可以使用算法二来检测作弊。

       令 P 1 , P 2 , . . . , P t P_1,P_2,...,P_t P1,P2,...,Pt 是作弊者, P t + 1 , P t + 2 , . . . , P M P_{t+1},P_{t+2},...,P_M Pt+1,Pt+2,...,PM 都是诚实的用户。在算法二中,作弊者发布伪多项式碎片 f i ∗ ( y ) f^∗_i(y) fi(y) i = 1 , 2 , . . . t i=1,2,...t i=1,2,...t。如果 t ≥ k t≥k tk,他们可以在秘密重构之前计算其他诚实用户多项式份额 f i ( y ) f_i(y) fi(y) i = t + 1 , t + 2 , . . . , m i=t+1,t+2,...,m i=t+1,t+2,...,m ,则可以生成另一个 k − 1 k−1 k1 次对称多项式 F ∗ ( x , y ) ≠ F ( x , y ) F^∗(x,y)\ne F(x,y) F(x,y)=F(x,y),它满足 f i ( y ) = F ∗ ( i , y ) f_i(y)=F^∗(i,y) fi(y)=F(i,y) i = t + 1 , t + 2 , . . . , m i=t+1,t+2,...,m i=t+1,t+2,...,m,并公布伪造的多项式碎片 f ∗ i ( y ) = F ∗ ( i , y ) f^∗i(y)=F^∗(i,y) fi(y)=F(i,y) i = 1 , 2 , . . . t i=1,2,...t i=1,2,...t。这样,所有 m m m 个用户都可以获得 m − 1 m−1 m1 票,作弊成功。但是,当 t < k t<k t<k 时,作弊者不能预先得到其他诚实用户的多项式碎片,欺骗成功只能通过猜测诚实用户的多项式碎片,概率最大为 1 q 1\over q q1。此外,在防作弊秘密共享方案中,满足 t < k t<k t<k 的作弊个数是一种共识。算法二可以检测来自任何 k − 1 个 k−1个 k1 或更少的作弊者的作弊行为。当算法二检测到作弊时,其他 n − m n−m nm 个用户参与作弊识别,他们只需投票给 m m m 个用户,而不公开他们的多项式碎片。

       · 如果 t < n − k + 1 2 t<{{n−k+1}\over 2} t<2nk+1,则算法二可以识别出所有 t t t 个作弊者。

       · 算法一算法二的选择可以根据应用中的不同要求来决定。例如,如果 m > > k m>>k m>>k,则算法一较好,因为当 m > k m>k m>k 时,算法一在不涉及其他 n − m n−m nm 个用户的情况下具有较强的作弊识别能力 t < m − k + 3 2 t<{{m−k+3}\over 2} t<2mk+3;如果 m m m 接近 k k k,则可以选择算法二来识别作弊,其能力为 t < n − k + 1 2 t<{{n−k+1}\over 2} t<2nk+1,与 m m m 无关。

       实现代码见附录.2

鲁棒性秘密共享

        R o y Roy Roy 等人设计了一个简单的 t − o u t − o f − n t-out-of-n toutofn 秘密共享方案,只要 t < n 2 t<{n\over 2} t<2n,它就可以在 t t t 个作弊参与者存在的情况下重构秘密,概率最高为 δ δ δ [8]。通过应用 C a r p e n t i e r i Carpentieri Carpentieri 设计的 " a u t h e n t i c a t i o n "authentication "authentication t a g tag tag c o m p r e s s i o n " compression" compression" 技术改善了鲁棒性秘密共享方案的共享大小。

       消息鉴别码 ( M A C ) (MAC) (MAC):在不假设任何计算困难的情况下验证消息的完整性。

        R e e d − S o l o m o n Reed-Solomon ReedSolomon c o d e code code:令 ( a 0 , . . . , a t ) ∈ F t + 1 (a_0,...,a_t)∈F^{t+1} (a0,...,at)Ft+1 且多项式 f ( x ) = a 0 + a 1 x + . . . + a t x t f(x)=a_0+a_1x+...+a_tx^t f(x)=a0+a1x+...+atxt 的最高次数为 t t t C = ( f ( x 1 ) , f ( x 2 ) , . . . , f ( x n ) ) C=(f(x_1),f(x_2),...,f(x_n)) C=(f(x1),f(x2),...,f(xn)) 是消息 ( a 0 , . . . , a t ) (a_0,...,a_t) (a0,...,at) 的纠错码。 R e e d − S o l o m o n Reed-Solomon ReedSolomon c o d e code code 最多可以修正 e e e 个错误符号,即 n n n 个求值点 f ( x i ) ( 1 ≤ i ≤ n ) f(x_i)(1≤i≤n) f(xi)(1in) 中的 e e e 个被修改时,当且仅当 n ≥ t + 1 + 2 e n≥t+1+2e nt+1+2e ,多项式(消息)可以唯一确定。这里使用 B e r l e k a m p − W e l c h Berlekamp-Welch BerlekampWelch 算法[9]

        ( t , δ ) (t,δ) (t,δ) 鲁棒秘密共享方案:存在一组 n n n 个参与者,记为 P = P= P={ P 1 , P 2 , . . . , P n P_1,P_2,...,P_n P1,P2,...,Pn} 以及两个特殊参与者分发者 ( D ) (D) (D)和重构者 ( R ) (R) (R)。分享阶段,攻击者最多可以破坏 t t t 个参与者的碎片。重构阶段,重构者在最多可能有 t t t 个碎片被破坏的情况下,恢复正确的秘密信息 s s s 的概率最大为 δ δ δ

       敌手模型:默认分发者 ( D ) (D) (D)和重构者 ( R ) (R) (R)是诚实的,且秘密碎片的传输是安全的。假设攻击者 ( A ) (A) (A)在计算上是无限的、快速的、自适应的,且最多可以破坏 t < n 2 t<{n\over 2} t<2n 个参与者的碎片。

方案如下:

  • 初始化:
    • α i ∈ F 2 m \alpha_i \in F_{2^m} αiF2m {0} 是公开且固定的。且 α i \alpha_i αi F 2 q F_{2^q} F2q 中是非零且互不相同的。
  • 秘密信息分发:
    • 分发者 ( D ) (D) (D)随机选取一个最高次数为 t t t 的多项式 f ( x ) ∈ F 2 q [ X ] f(x)∈F_{2^q}[X] f(x)F2q[X] f ( 0 ) = s f(0)=s f(0)=s 是秘密信息。依次计算 f ( α i ) = s i f(\alpha_i) = s_i f(αi)=si i = 1 , 2 , . . . , n i=1,2,...,n i=1,2,...,n
    • 如果 q < m q<m q<m,令 l = m q l={m\over q} l=qm s j = s j , 1 ∣ ∣ . . . ∣ ∣ s j , l s_j=s_{j,1}||...||s_{j,l} sj=sj,1...sj,l。分发者 ( D ) (D) (D)随机选取 d i , 1 , . . . , d i , t d_{i,1},...,d_{i,t} di,1,...,di,t g i , j g_{i,j} gi,j。计算
      b i , j = { g i , j s j + ∑ k = 1 t α i k d j , k , f o r   q   ≥   m ∑ k = 1 l g i , j k s j , k + ∑ k = 1 t α i k d j , k , f o r   q   <   m b_{i,j}= \begin{cases} g_{i,j}s_j+\sum_{k=1}^t\alpha_i^kd_{j,k}, &for\ q\ \ge\ m\\ \sum_{k=1}^l{g_{i,j}^k}s_{j,k}+\sum_{k=1}^t\alpha_i^kd_{j,k}, &for\ q\ \lt\ m \end{cases} bi,j={gi,jsj+k=1tαikdj,k,k=1lgi,jksj,k+k=1tαikdj,k,for q  mfor q < m
      j = 1 , . . . , i − 1 , i + 1 , . . . , n j=1,...,i-1,i+1,...,n j=1,...,i1,i+1,...,n i = 1 , . . . , n i=1,...,n i=1,...,n
    • 分发者 ( D ) (D) (D)给每个参与者 P i P_i Pi分发秘密碎片
      S i = ( s i , d i , 1 , . . . , d i , t , g i , 1 , . . . , g i , i − 1 , g i , i + 1 , . . . , g i , n , b i , 1 , . . . , b i , i − 1 , b i , i + 1 , . . . , b i , n ) S_i=(s_i,d_{i,1},...,d_{i,t},g_{i,1},...,g_{i,i-1},g_{i,i+1},...,g_{i,n},b_{i,1},...,b_{i,i-1},b_{i,i+1},...,b_{i,n}) Si=(si,di,1,...,di,t,gi,1,...,gi,i1,gi,i+1,...,gi,n,bi,1,...,bi,i1,bi,i+1,...,bi,n)
  • 秘密信息恢复:
    • 每个参与者 P i P_i Pi发送 ( s i ′ , d i , 1 ′ , . . . , d i , t ′ ) ({s_i}',{d_{i,1}}',...,{d_{i,t}}') (si,di,1,...,di,t) 给重构者 R R R
    • 每个参与者 P i P_i Pi发送 ( g i , 1 ′ , . . . , g i , i − 1 ′ , g i , i + 1 ′ , . . . , , g i , n ′ , b i , 1 ′ , . . . , b i , i − 1 ′ , b i , i + 1 ′ , . . . , b i , n ′ ) ({g_{i,1}}',...,{g_{i,i-1}}',{g_{i,i+1}}',...,,{g_{i,n}}',{b_{i,1}}',...,{b_{i,i-1}}',{b_{i,i+1}}',...,{b_{i,n}}') (gi,1,...,gi,i1,gi,i+1,...,,gi,n,bi,1,...,bi,i1,bi,i+1,...,bi,n) 给重构者 R R R
    • 声明一个数组 v v v,如果 P i P_i Pi 的身份验证标记被 P j P_j Pj 接受, v i , j = 1 v_{i,j}=1 vi,j=1 i , j ∈ i,j∈ i,j{ 1 , 2.... , n 1, 2....,n 1,2....,n};否则, v i , j = 0 v_{i,j}=0 vi,j=0
    • 重构者 ( R ) (R) (R)计算最大集合 L ⊆ L\subseteq L{ 1 , 2 , . . . , n 1,2,...,n 1,2,...,n}, L L L 满足
      ∀ i ∈ I : ∣ ∀ i∈I:| iI:{ j ∈ I ∣ v i j = 1 j∈I|v_{ij}=1 jIvij=1} ∣ = ∑ j ∈ I v i j ≥ t + 1. |=\sum_{j∈I}v_{ij}≥t+1. =jIvijt+1.
      显然 L L L 包含了所有诚实的参与者。令 e = ∣ L ∣ − ( t + 1 ) e=|L|-(t+1) e=L(t+1) L L L 中作弊者的最大数量。
    • 使用 R e e d − S o l o m o n Reed-Solomon ReedSolomon c o d e code code 的纠错算法( B e r l e k a m p − W e l c h Berlekamp-Welch BerlekampWelch 算法[9]),重构者 R R R 计算得到一个最高次数为 t t t 的多项式 f ( x ) ∈ F 2 m [ X ] f(x)∈F_{2^m}[X] f(x)F2m[X],使得 L L L 中至少 ( t + 1 ) + e 2 (t + 1) + {e\over 2} (t+1)+2e 个参与者 P i P_i Pi 满足 f ( α i ) = s i ′ f(\alpha_i)={s_i}' f(αi)=si
      • 如果不存在这样的多项式,就输出 ⊥ ⊥
      • 否则输出 s = f ( 0 ) s=f(0) s=f(0)

       在所提出的方案中,可在作弊概率和碎片大小之间权衡。因此,在自然约束下,参数可灵活设置。 q q q 可以小于或大于 m m m

完美性证明:

       攻击者 A A A在共享阶段控制任何 t t t 个参与者的碎片,都不会得到关于秘密信息 s s s 的任何信息。

       假设前 t t t 个参与者 P i , . . . , P t P_i,...,P_t Pi,...,Pt 被修改。根据拉格朗日插值公式, t + 1 t+1 t+1 个参与者可以完全重构一个 t t t 次多项式。再选取一个 s i s_i si,假定 i = t + 1 i=t+1 i=t+1。估计通过 ( g i , t + 1 , b i , t + 1 ) (g_{i,t+1}, b_{i,t+1}) (gi,t+1,bi,t+1) 用于每个 P i P_i Pi s t + 1 s_{t+1} st+1

        ( q ≥ m ) : (q≥m): (qm):

       对所有的 i ∈ L i∈L iL

b i , t + 1 = g i , t + 1 s t + 1 + α i d t + 1 , 1 + α i 2 d t + 1 , 2 + . . . + α i t d t + 1 , t b_{i,t+1}=g_{i,t+1}s_{t+1}+α_id_{t+1,1}+α^2_id_{t+1,2}+...+α^t_id_{t+1,t} bi,t+1=gi,t+1st+1+αidt+1,1+αi2dt+1,2+...+αitdt+1,t

       所以,
b i , t + 1 − g i , t + 1 s t + 1 = α i d t + 1 , 1 + α i 2 d t + 1 , 2 + . . . + α i t d t + 1 , t b_{i,t+1}-g_{i,t+1}s_{t+1}=α_id_{t+1,1}+α^2_id_{t+1,2}+...+α^t_id_{t+1,t} bi,t+1gi,t+1st+1=αidt+1,1+αi2dt+1,2+...+αitdt+1,t

       显然,对于 s t + 1 s_{t+1} st+1 的所有可能值,线性系统是一致的。可以得出结论,攻击者 A A A可以猜出正确的 s t + 1 s_{t+1} st+1 的概率最多为 1 2 m 1\over 2^m 2m1

        ( q < m ) : (q<m): (q<m):

       对所有的 i ∈ L i∈L iL
b i , t + 1 = ∑ k = 1 l g i , t + 1 k s t + 1 , k + ∑ k = 1 t α i k d t + 1 , k b_{i,t+1}=\sum_{k=1}^lg_{i,t+1}^ks_{t+1,k}+\sum_{k=1}^t\alpha_i^kd_{t+1,k} bi,t+1=k=1lgi,t+1kst+1,k+k=1tαikdt+1,k

       所以,
b i , t + 1 − ∑ k = 1 l g i , t + 1 k s t + 1 , k = ∑ k = 1 t α i k d t + 1 , k b_{i,t+1}-\sum_{k=1}^lg_{i,t+1}^ks_{t+1,k}=\sum_{k=1}^t\alpha_i^kd_{t+1,k} bi,t+1k=1lgi,t+1kst+1,k=k=1tαikdt+1,k

       对于任何固定值 s t + 1 = s t + 1 , 1 ∣ ∣ . . . ∣ ∣ s t + 1 , l s_{t+1}=s_{t+1,1}||...||s_{t+1,l} st+1=st+1,1...st+1,l,可以使用与情况1 ( q ≥ m ) (q≥m) (qm) 中相同的参数来证明攻击者 A A A正确猜测 s t + 1 s_{t+1} st+1 的概率最多为 1 2 m 1\over 2^m 2m1

鲁棒性:

       对于任何正整数 t t t,使得 n = 2 t + 1 n=2t+1 n=2t+1,所提出的构造形式为 ( t , δ ) (t,δ) (t,δ)鲁棒秘密共享方案,用于 n n n 个参与者共享秘密。同时,
δ ≤ e ( ( t + 1 ) ϵ ) ( t + 1 ) 2 δ≤e^{((t + 1)\epsilon)^{(t+1)\over 2}} δe((t+1)ϵ)2(t+1)

ϵ = { 1 2 q , f o r   q   ≥   m l 2 q , f o r   q   <   m \epsilon= \begin{cases} 1\over 2^q, &for\ q\ \ge\ m\\ l\over 2^q, &for\ q\ \lt\ m \end{cases} ϵ={2q,12q,lfor q  mfor q < m

       实现代码见 附录.3

5.实验结果及分析

作弊可检测的秘密共享

方案一:

       基本实验参数:

sntp f ( x ) f(x) f(x)(此处为方便演示固定,实际可随机选取)
128519 5 ∗ x 4 + 7 ∗ x 3 + 9 ∗ x 2 + 5 ∗ x + 12 5*x^4 + 7*x^3 + 9*x^2 + 5*x + 12 5x4+7x3+9x2+5x+12

       秘密分发如下:

P 1 P_1 P1 P 2 P_2 P2 P 3 P_3 P3 P 4 P_4 P4 P 5 P_5 P5 P 6 P_6 P6 P p 7 Pp_7 Pp7 P 8 P_8 P8
( 1 , 0 ) (1, 0) (1,0) ( 2 , 4 ) (2, 4) (2,4) ( 3 , 18 ) (3, 18) (3,18) ( 4 , 4 ) (4, 4) (4,4) ( 5 , 6 ) (5, 6) (5,6) ( 6 , 17 ) (6, 17) (6,17) ( 7 , 17 ) (7, 17) (7,17) ( 8 , 11 ) (8, 11) (8,11)

       模拟作弊者:

Cheater S r c Src Src T a r Tar Tar
P 2 P_2 P2 ( 2 , 4 ) (2, 4) (2,4) ( 2 , 5 ) (2, 5) (2,5)
P 8 P_8 P8 ( 8 , 11 ) (8, 11) (8,11) ( 2 , 12 ) (2, 12) (2,12)

       作弊者检测与秘密信息恢复:

UsersCheater f ′ ( x ) f'(x) f(x) DegreeCheater DetectionSecret
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6 P 2 : ( 2 , 5 ) P_2:(2, 5) P2:(2,5) 5 > t − 1 5>t-1 5>t1 Y e s Yes Yes N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 8 P_8 P8 P 2 : ( 2 , 5 ) P_2:(2, 5) P2:(2,5), P 8 : ( 8 , 12 ) P_8:(8, 12) P8:(8,12) 5 > t − 1 5>t-1 5>t1 Y e s Yes Yes N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5 P 2 : ( 2 , 5 ) P_2:(2, 5) P2:(2,5) 4 = t − 1 4=t-1 4=t1 N o No No 2 2 2
P 1 P_1 P1, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6, P 7 P_7 P7 N o n e None None 4 = t − 1 4=t-1 4=t1 N o No No 12 12 12
P 1 P_1 P1, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6 N o n e None None 5 > t − 1 5>t-1 5>t1 N o No No 12 12 12
P 1 P_1 P1, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5 N o n e None None 4 = t − 1 4=t-1 4=t1 N o No No N o n e None None

       当参与恢复的用户数小于门限 t t t 时,无法恢复秘密信息。当参与恢复的用户中含有作弊者且用户数大于门限 t t t 时,可以检测出作弊者的存在。当参与恢复的用户中含有作弊者且用户数不大于门限 t t t 时,不能检测出作弊者的存在。

方案二:

       基本实验参数:

sntp f ( x ) f(x) f(x)(此处为方便演示固定,实际可随机选取) g ( x ) g(x) g(x)(此处为方便演示固定,实际可随机选取)
128519 x 4 + 6 ∗ x 3 + 7 ∗ x 2 + 18 ∗ x + 12 x^4 + 6*x^3 + 7*x^2 + 18*x + 12 x4+6x3+7x2+18x+12 13 ∗ x 4 + 11 ∗ x 3 + 5 ∗ x 2 + 7 ∗ x + 11 13*x^4 + 11*x^3 + 5*x^2 + 7*x + 11 13x4+11x3+5x2+7x+11

       秘密分发如下:

P 1 P_1 P1 P 2 P_2 P2 P 3 P_3 P3 P 4 P_4 P4 P 5 P_5 P5 P 6 P_6 P6 P p 7 Pp_7 Pp7 P 8 P_8 P8
( 1 , 6 , 9 ) (1, 6, 9) (1,6,9) ( 2 , 7 , 18 ) (2, 7, 18) (2,7,18) ( 3 , 11 , 2 ) (3, 11, 2) (3,11,2) ( 4 , 0 , 9 ) (4, 0, 9) (4,0,9) ( 5 , 18 , 0 ) (5, 18, 0) (5,18,0) ( 6 , 0 , 1 ) (6, 0, 1) (6,0,1) ( 7 , 0 , 8 ) (7, 0, 8) (7,0,8) ( 8 , 1 , 6 ) (8, 1, 6) (8,1,6)

       模拟作弊者:

Cheater S r c Src Src T a r Tar Tar
P 2 P_2 P2 ( 2 , 7 , 18 ) (2, 7, 18) (2,7,18) ( 2 , 7 , 0 ) (2, 7, 0) (2,7,0)
P 8 P_8 P8 ( 8 , 1 , 6 ) (8, 1, 6) (8,1,6) ( 2 , 1 , 7 ) (2, 1, 7) (2,1,7)

       作弊者检测与秘密信息恢复:

UsersCheaterCheater DetectionSecret
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6 P 2 : ( 2 , 7 , 18 ) P_2:(2, 7, 18) P2:(2,7,18) Y e s Yes Yes N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 8 P_8 P8 P 2 : ( 2 , 7 , 18 ) P_2:(2, 7, 18) P2:(2,7,18), P 8 : ( 8 , 1 , 6 ) P_8:(8, 1, 6) P8:(8,1,6) Y e s Yes Yes N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5 P 2 : ( 2 , 7 , 18 ) P_2:(2, 7, 18) P2:(2,7,18) Y e s Yes Yes N o n e None None
P 1 P_1 P1, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6 P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6 Y e s Yes Yes N o n e None None
P 1 P_1 P1, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6, P 7 P_7 P7 N o n e None None N o No No 12 12 12
P 1 P_1 P1, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6 N o n e None None N o No No 12 12 12
P 1 P_1 P1, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5 N o n e None None N o No No N o n e None None

       当参与恢复的用户数小于门限 t t t 时,无法恢复秘密信息。当参与恢复的用户中含有作弊者且作弊者数小于 t − 1 t-1 t1 时,可以检测出作弊者的存在。相比方案一,可检测的下限更低,最少 t t t 个用户就可以进行检测。

作弊可识别的秘密共享

       基本实验参数:

sntp F ( x , y ) F(x,y) F(x,y)(此处为方便演示固定,实际可随机选取)
139523 − 4 ∗ x 4 ∗ y 4 + 2 ∗ x 4 ∗ y 3 + 2 ∗ x 3 ∗ y 4 − 4 ∗ x 4 ∗ y 2 − x 3 ∗ y 3 − 4 ∗ x 2 ∗ y 4 − 10 ∗ x 4 ∗ y − 9 ∗ x 3 ∗ y 2 − 9 ∗ x 2 ∗ y 3 − 10 ∗ x ∗ y 4 − 5 ∗ x 4 + 10 ∗ x 3 ∗ y + 6 ∗ x 2 ∗ y 2 + 10 ∗ x ∗ y 3 − 5 ∗ y 4 − 2 ∗ x 3 + 5 ∗ x 2 ∗ y + 5 ∗ x ∗ y 2 − 2 ∗ y 3 + 4 ∗ x 2 + 9 ∗ x ∗ y + 4 ∗ y 2 + 7 ∗ x + 7 ∗ y − 10 -4*x^4*y^4 + 2*x^4*y^3 + 2*x^3*y^4 - 4*x^4*y^2 - x^3*y^3 - 4*x^2*y^4 - 10*x^4*y - 9*x^3*y^2 - 9*x^2*y^3 - 10*x*y^4 - 5*x^4 + 10*x^3*y + 6*x^2*y^2 + 10*x*y^3 - 5*y^4 - 2*x^3 + 5*x^2*y + 5*x*y^2 - 2*y^3 + 4*x^2 + 9*x*y + 4*y^2 + 7*x + 7*y - 10 4x4y4+2x4y3+2x3y44x4y2x3y34x2y410x4y9x3y29x2y310xy45x4+10x3y+6x2y2+10xy35y42x3+5x2y+5xy22y3+4x2+9xy+4y2+7x+7y10

       秘密分发如下:

UserShare
P 1 P_1 P1 ( 1 , 2 ∗ y 4 + 2 ∗ y 2 − 2 ∗ y − 6 ) (1, 2*y^4 + 2*y^2 - 2*y - 6) (1,2y4+2y22y6)
P 2 P_2 P2 ( 2 , 3 ∗ y 4 + 6 ∗ y 3 − 6 ∗ y 2 + 11 ∗ y − 7 ) (2, 3*y^4 + 6*y^3 - 6*y^2 + 11*y - 7) (2,3y4+6y36y2+11y7)
P 3 P_3 P3 ( 3 , 4 ∗ y 4 − 10 ∗ y 3 − 11 ∗ y 2 − y + 2 ) (3, 4*y^4 - 10*y^3 - 11*y^2 - y + 2) (3,4y410y311y2y+2)
P 4 P_4 P4 ( 4 , 7 ∗ y 4 − 3 ∗ y 3 − 8 ∗ y 2 − 3 ∗ y + 8 ) (4, 7*y^4 - 3*y^3 - 8*y^2 - 3*y + 8) (4,7y43y38y23y+8)
P 5 P_5 P5 ( 5 , 10 ∗ y 4 + 5 ∗ y 3 + 4 ∗ y 2 + 7 ∗ y − 7 ) (5, 10*y^4 + 5*y^3 + 4*y^2 + 7*y - 7) (5,10y4+5y3+4y2+7y7)
P 6 P_6 P6 ( 6 , 7 ∗ y 4 − 6 ∗ y 3 − y 2 − 2 ∗ y + 3 ) (6, 7*y^4 - 6*y^3 - y^2 - 2*y + 3) (6,7y46y3y22y+3)
P 7 P_7 P7 ( 7 , 7 ∗ y 4 − 6 ∗ y 3 − y 2 − 2 ∗ y + 3 ) (7, 7*y^4 - 6*y^3 - y^2 - 2*y + 3) (7,7y46y3y22y+3)
P 8 P_8 P8 ( 8 , 7 ∗ y 4 − 6 ∗ y 3 − y 2 − 2 ∗ y + 3 ) (8, 7*y^4 - 6*y^3 - y^2 - 2*y + 3) (8,7y46y3y22y+3)
P 9 P_9 P9 ( 9 , 7 ∗ y 4 − 6 ∗ y 3 − y 2 − 2 ∗ y + 3 ) (9,7*y^4 - 6*y^3 - y^2 - 2*y + 3) (9,7y46y3y22y+3)

       模拟作弊者:

Cheater S r c Src Src T a r Tar Tar
P 2 P_2 P2 ( 2 , 3 ∗ y 4 + 6 ∗ y 3 − 6 ∗ y 2 + 11 ∗ y − 7 ) (2, 3*y^4 + 6*y^3 - 6*y^2 + 11*y - 7) (2,3y4+6y36y2+11y7) ( 2 , 3 ∗ y 4 + 6 ∗ y 3 − 6 ∗ y 2 + 11 ∗ y − 6 ) (2, 3*y^4 + 6*y^3 - 6*y^2 + 11*y - 6) (2,3y4+6y36y2+11y6)
P 3 P_3 P3 ( 3 , 4 ∗ y 4 − 10 ∗ y 3 − 11 ∗ y 2 − y + 2 ) (3, 4*y^4 - 10*y^3 - 11*y^2 - y + 2) (3,4y410y311y2y+2) ( 3 , 4 ∗ y 4 − 10 ∗ y 3 − 11 ∗ y 2 − y + 3 ) (3, 4*y^4 - 10*y^3 - 11*y^2 - y + 3) (3,4y410y311y2y+3)

       作弊者检测识别与秘密信息恢复:

UsersCheaterAlgorithmCheater DetectionCheater RecognitionSecret
P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6, P 7 P_7 P7, P 8 P_8 P8, P 9 P_9 P9Algorithm 1 P 3 P_3 P3 Y e s Yes Yes P 3 P_3 P3 13 13 13
P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6, P 7 P_7 P7, P 8 P_8 P8, P 9 P_9 P9Algorithm 2 P 3 P_3 P3 Y e s Yes Yes P 3 P_3 P3 13 13 13
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 8 P_8 P8, P 9 P_9 P9Algorithm 1 P 2 P_2 P2, P 3 P_3 P3 Y e s Yes Yes P 2 P_2 P2, P 3 P_3 P3 13 13 13
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 8 P_8 P8, P 9 P_9 P9Algorithm 2 P 2 P_2 P2, P 3 P_3 P3 Y e s Yes Yes P 2 P_2 P2, P 3 P_3 P3 13 13 13
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 8 P_8 P8Algorithm 1 P 2 P_2 P2, P 3 P_3 P3 Y e s Yes Yes P 2 P_2 P2, P 3 P_3 P3 N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 8 P_8 P8Algorithm 2 P 2 P_2 P2, P 3 P_3 P3 Y e s Yes Yes P 2 P_2 P2, P 3 P_3 P3 N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5Algorithm 1 P 2 P_2 P2, P 3 P_3 P3 Y e s Yes Yes N o n e None None N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5Algorithm 2 P 2 P_2 P2, P 3 P_3 P3 Y e s Yes Yes P 2 P_2 P2, P 3 P_3 P3 N o n e None None
P 1 P_1 P1, P 7 P_7 P7, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6Algorithm 1 N o n e None None N o No No N o n e None None 13 13 13
P 1 P_1 P1, P 7 P_7 P7, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6Algorithm 2 N o n e None None N o No No N o n e None None 13 13 13
P 1 P_1 P1, P 2 P_2 P2, P 4 P_4 P4, P 5 P_5 P5Algorithm 1 N o n e None None N o No No N o n e None None N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 4 P_4 P4, P 5 P_5 P5Algorithm 2 N o n e None None N o No No N o n e None None N o n e None None

       当参与恢复的用户数小于门限 t t t 时,算法1和算法2均无法恢复秘密信息。当参与恢复的用户中含有作弊者且用户数大于门限 t t t 时,算法1和算法2均可以检测出作弊者的存在。当参与恢复的用户中含有作弊者且作弊用户数 k < m − t + 3 2 k<{{m−t+3}\over 2} k<2mt+3 时,算法1无法识别具体的作弊者,但算法2可以。当识别出作弊者,且去除作弊者后的参与恢复用户数大于等于门限 t t t,则可以恢复秘密信息,否则不能。

鲁棒性秘密共享

       基本实验参数:

sntp f ( x ) f(x) f(x)(此处为方便演示固定,实际可随机选取)
127517 16 ∗ x 4 + 15 ∗ x 3 + 16 ∗ x 2 + 12 16*x^4 + 15*x^3 + 16*x^2 + 12 16x4+15x3+16x2+12

       秘密分发如下:

UserShare sShare S = ( s i , d i , 1 , . . . , d i , t , g i , 1 , . . . , g i , i − 1 , g i , i + 1 , . . . , g i , n , b i , 1 , . . . , b i , i − 1 , b i , i + 1 , . . . , b i , n ) S=(s_i,d_{i,1},...,d_{i,t},g_{i,1},...,g_{i,i-1},g_{i,i+1},...,g_{i,n},b_{i,1},...,b_{i,i-1},b_{i,i+1},...,b_{i,n}) S=(si,di,1,...,di,t,gi,1,...,gi,i1,gi,i+1,...,gi,n,bi,1,...,bi,i1,bi,i+1,...,bi,n)
P 1 P_1 P1 ( 1 , 8 ) (1, 8) (1,8) [ 8 , [ 4 , 1 , 15 , 5 , 0 ] , [ 11 , 0 , 13 , 12 , 11 , 3 ] , [ 133 , 39 , 68 , 197 , 224 , 32 ] ] [8, [4, 1, 15, 5, 0], [11, 0, 13, 12, 11, 3], [133, 39, 68, 197, 224, 32]] [8,[4,1,15,5,0],[11,0,13,12,11,3],[133,39,68,197,224,32]]
P 2 P_2 P2 ( 2 , 10 ) (2, 10) (2,10) [ 10 , [ 10 , 1 , 2 , 10 , 0 ] , [ 0 , 2 , 8 , 0 , 10 , 14 ] , [ 106 , 151 , 166 , 146 , 334 , 96 ] ] [10, [10, 1, 2, 10, 0], [0, 2, 8, 0, 10, 14], [106, 151, 166, 146, 334, 96]] [10,[10,1,2,10,0],[0,2,8,0,10,14],[106,151,166,146,334,96]]
P 3 P_3 P3 ( 3 , 4 ) (3, 4) (3,4) [ 4 , [ 9 , 13 , 7 , 10 , 0 ] , [ 7 , 9 , 10 , 2 , 15 , 13 ] , [ 333 , 391 , 457 , 423 , 692 , 140 ] ] [4, [9, 13, 7, 10, 0], [7, 9, 10, 2, 15, 13], [333, 391, 457, 423, 692, 140]] [4,[9,13,7,10,0],[7,9,10,2,15,13],[333,391,457,423,692,140]]
P 4 P_4 P4 ( 4 , 3 ) (4, 3) (4,3) [ 3 , [ 4 , 9 , 2 , 14 , 0 ] , [ 14 , 5 , 4 , 11 , 8 , 5 ] , [ 680 , 736 , 829 , 1003 , 1070 , 196 ] ] [3, [4, 9, 2, 14, 0], [14, 5, 4, 11, 8, 5], [680, 736, 829, 1003, 1070, 196]] [3,[4,9,2,14,0],[14,5,4,11,8,5],[680,736,829,1003,1070,196]]
P 5 P_5 P5 ( 5 , 13 ) (5, 13) (5,13) [ 13 , [ 16 , 7 , 7 , 11 , 0 ] , [ 5 , 5 , 11 , 10 , 0 , 10 ] , [ 1049 , 1365 , 1543 , 1879 , 1704 , 356 ] ] [13, [16, 7, 7, 11, 0], [5, 5, 11, 10, 0, 10], [1049, 1365, 1543, 1879, 1704, 356]] [13,[16,7,7,11,0],[5,5,11,10,0,10],[1049,1365,1543,1879,1704,356]]
P 6 P_6 P6 ( 6 , 16 ) (6, 16) (6,16) [ 13 , [ 16 , 7 , 7 , 11 , 0 ] , [ 5 , 5 , 11 , 10 , 0 , 10 ] , [ 1049 , 1365 , 1543 , 1879 , 1704 , 356 ] ] [13, [16, 7, 7, 11, 0], [5, 5, 11, 10, 0, 10], [1049, 1365, 1543, 1879, 1704, 356]] [13,[16,7,7,11,0],[5,5,11,10,0,10],[1049,1365,1543,1879,1704,356]]
P 7 P_7 P7 ( 7 , 4 ) (7, 4) (7,4) [ 4 , [ 16 , 0 , 2 , 2 , 0 ] , [ 16 , 5 , 12 , 14 , 1 , 3 ] , [ 2589 , 3595 , 3921 , 5009 , 4194 , 4332 ] ] [4, [16, 0, 2, 2, 0], [16, 5, 12, 14, 1, 3], [2589, 3595, 3921, 5009, 4194, 4332]] [4,[16,0,2,2,0],[16,5,12,14,1,3],[2589,3595,3921,5009,4194,4332]]

       模拟作弊者:

Cheater S r c Src Src T a r Tar Tar
P 2 P_2 P2 ( 2 , 10 ) (2, 10) (2,10) ( 2 , 11 ) (2, 11) (2,11)
P 3 P_3 P3 ( 3 , 4 ) (3, 4) (3,4) ( 3 , 5 ) (3, 5) (3,5)

       鲁棒性秘密信息恢复:

UsersCheater E p Ep Ep Q p Qp Qp P p Pp PpSecret
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6, P 7 P_7 P7 P 2 P_2 P2 x + 15 x + 15 x+15 16 ∗ x 5 + 3 ∗ x 3 + 2 ∗ x 2 + 12 ∗ x + 10 16*x^5 + 3*x^3 + 2*x^2 + 12*x + 10 16x5+3x3+2x2+12x+10$16x^4 + 15x^3 + 16*x^2 + 12
$ 12 12 12
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6, P 7 P_7 P7 P 2 P_2 P2, P 3 P_3 P3(作弊数 ≥ m − t + 1 2 \ge{{m-t+1}\over 2} 2mt+1) N o n e None None N o n e None None N o n e None None N o n e None None
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5, P 6 P_6 P6, P 7 P_7 P7 N o n e None None x + 15 x + 15 x+15 16 ∗ x 5 + 3 ∗ x 3 + 2 ∗ x 2 + 12 ∗ x + 10 16*x^5 + 3*x^3 + 2*x^2 + 12*x + 10 16x5+3x3+2x2+12x+10$16x^4 + 15x^3 + 16*x^2 + 12
$ 12 12 12
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4, P 5 P_5 P5 N o n e None None N o n e None None N o n e None None 16 ∗ x 4 + 15 ∗ x 3 + 16 ∗ x 2 + 12 16*x^4 + 15*x^3 + 16*x^2 + 12 16x4+15x3+16x2+12 12 12 12
P 1 P_1 P1, P 2 P_2 P2, P 3 P_3 P3, P 4 P_4 P4 N o n e None None N o n e None None N o n e None None N o n e None None N o n e None None

       当参与恢复的用户数小于门限 t t t 时,无法恢复秘密信息。当参与恢复的用户数大于门限 t t t,且其中包含的作弊者数 < m − t + 1 2 <{{m-t+1}\over 2} <2mt+1 时,可以恢复秘密信息,否则不能。

6.总结

       作弊可检测的秘密共享方案一中,虽然作弊者被发现的概率很高,但他们获得了秘密,而其他参与者却没有获得关于该秘密的信息。同时需要至少 t + 1 t+1 t+1 个用户才能检测。

       作弊可检测的秘密共享方案二中,最少只需要 t t t 个用户就可以检测作弊者,且最多可以检测 t − 1 t-1 t1 个作弊者

       作弊可识别的秘密共享方案二中,第一个算法可以通过 m m m 个参与秘密重构的用户来识别作弊者,第二个算法可以在其余 n − m n−m nm 个未参与秘密重构的用户的协作下实现更强的作弊识别能力。该方案的欺诈识别仅基于二元多项式的对称性和插值多项式的线性,不包含份额中的任何冗余信息。这两种算法在识别作弊者的能力方面都是有效的。

       鲁棒性秘密共享方案中,共享碎片的大小有所改进。

引用

[1] A Shamir, How to share a secret. Commun. ACM. 22(11), 612–613 (1979).
[2] K. Kaya et al.Threshold cryptography based on asmuth-bloom secret sharing Inf. Sci. (Ny) (2007)
[3] Tompa, M., Woll, H. How to share a secret with cheaters. J. Cryptology 1, 133–138 (1989)
[4]  R.J.McEliece and D.V.Sarwate, On sharing secrets and Reed-Solomon codes,Comm.ACM, 24(1981), pp.583-584.
[5] Harn, L., Lin, C. Detection and identification of cheaters in (t, n) secret sharing scheme. Des. Codes Cryptogr. 52, 15–24 (2009).
[6] Kurosawa K., Obana S., Ogata W. (1995) t-Cheater Identifiable (k, n) Threshold Secret Sharing Schemes. In: Coppersmith D. (eds) Advances in Cryptology — CRYPT0’ 95. CRYPTO 1995. 
[7] Liu, Yanxiao; Yang, Chingnung; Wang, Yichuan; Zhu, Lei; Ji, Wenjiang (2018). Cheating identifiable secret sharing scheme using symmetric bivariate polynomial. Information Sciences, 453(), 21–29. 
[8] Roy, P. S., Adhikari, A., Xu, R., Morozov, K., & Sakurai, K. (2014). An Efficient Robust Secret Sharing Scheme with Optimal Cheater Resiliency. Lecture Notes in Computer Science, 47–58.
[9] Berlekamp, E.R., Welch, L.R.: Error correction of algebraic block codes. U.S. Patent Number 4, 633.470 (1986)
[10] Y. Liu, “Linear (k, n ) secret sharing scheme with cheating detection,” Security and Communication Networks, vol. 9, no. 13, pp. 2115–2121, 2016.

附录.1

# -------------------------------------------------------------------------
# 作弊者可检测秘密共享方案
# -------------------------------------------------------------------------
# 秘密信息划分函数
# 参数s:秘密信息
# 参数n:划分个数
# 参数t:门限
# 参数p:模数
# -------------------------------------------------------------------------
def ShareGen(s, n, t, p):
    # 随机生成多项式系数,n-1次,模p
    factor = []
    S = []
    for i in range(t - 1):
        factor.append(ZZ.random_element(0, p))
    factor.append(s)
    print("多项式系数:",factor)
    factor.reverse()
    # 定义在环Zp上的多项式
    R.<x> = Zmod(p)[]
    f = R(factor)
    print("多项式为:", f)
    # 计算n个秘密碎片
    for i in range(n):
        temp = []
        num = s
        temp.append(i+1)
        # 计算多项式的值 f(i)
        temp.append(f(i+1))
        S.append(temp)
    
    print("秘密信息划分为:", S)
    return S

# -------------------------------------------------------------------------
# 作弊者检测和秘密信息恢复函数 
# 参数S:秘密信息碎片列表
# 参数t:门限
# 参数p:模数
# -------------------------------------------------------------------------
def Detection_Reconstruct(S, t, p):
    if len(S) < t:
        print("参与恢复的碎片数量少于门限{0},无法恢复!".format(t))
    else:
        secret = 0
        # 定义在环Zp上的多项式
        R.<x> = Zmod(p)[]
        f = R([0])
        # 拉格朗日插值法
        for i in range(len(S)):
            temp = []
            num1, num2 = 1, 1
            temp.extend(S[:i])
            temp.extend(S[i+1:])

            g1 = R([1])
            g2 = R([1])
            
            for j in range(len(temp)):
                g1 = (g1 * (x - temp[j][0]))
                g2 = (g2 * (S[i][0] - temp[j][0]))
            g = int(g2(0))
            f = (f + S[i][1] * g1 * inverse_mod(g, p))

        print("重构多项式为:", f)
        print("次数为:", R(f).degree())
        # 判断多项式次数
        if R(f).degree() == t - 1:
            secret = f(0)
            print("恢复的秘密信息为:", secret)
            return secret
        else:
            print("警告!检测到作弊者,恢复秘密失败!")
            return -1

# -------------------------------------------------------------------------
# 测试
# -------------------------------------------------------------------------
S = ShareGen(12, 8, 5, 19)
# 正常情况
s = Detection_Reconstruct(S[:5], 5, 19)
# 攻击
# 作弊者修改 [1,y+1]
S[1][1] = S[1][1] + 1
# S[2][1] = S[2][1] + 1
s = Detection_Reconstruct(S[:6], 5, 19)

附录.2

# -------------------------------------------------------------------------
# 作弊者可检测识别秘密共享方案
# -------------------------------------------------------------------------
# 秘密划分函数
# 参数s:秘密信息
# 参数n:划分个数
# 参数t:门限
# 参数p:模数
# -------------------------------------------------------------------------
def ShareGen(s, n, t, p):
    S = []
    # 定义在环Zp上的多项式
    R.<x,y> = GF(p)[]
    # 此处默认,分发中心D可自主选择(保密)
    f = 7*x + 4*x^2 + 21*x^3 + 18*x^4 + 7*y + 9*x*y + 5*x^2*y + 10*x^3*y + 13*x^4*y + 4*y^2 + 5*x*y^2 + 6*x^2*y^2 + 14*x^3*y^2 + 19*x^4*y^2 + 21*y^3 +\
    10*x*y^3 + 14*x^2*y^3 + 22*x^3*y^3 + 2*x^4*y^3 + 18*y^4 + 13*x*y^4 + 19*x^2*y^4 + 2*x^3*y^4 + 19*x^4*y^4
    f = f + s
    print("二元多项式为:", f)
    # 计算n个秘密碎片
    print("秘密信息划分为:")
    for i in range(n):
        temp = []
        num = s
        temp.append(i+1)
        # 计算多项式的值 f(i)
        temp.append(f(i+1,y))
        S.append(temp)
        print(f(i+1,y))
    
    return S

# -------------------------------------------------------------------------
# 作弊者检测识别和秘密信息恢复函数 
# 参数S:多项式碎片列表
# 参数t:门限
# 参数p:模数
# 参数v: 秘密碎片
# 参数e1: 检测碎片
# 参数e2: 检测碎片
# 参数d1: 随机整数
# 参数d2: 随机整数
# -------------------------------------------------------------------------
# 算法1
# -------------------------------------------------------------------------
def Detection_Reconstruct1(S, v, e1, e2, t, n, p, d1, d2):
    print("算法一:")
    if len(S) < t:
        print("参与恢复的碎片数量少于门限{0},无法恢复!".format(t))
    else:
        # 秘密信息
        secret = 0
        R.<x> = Zmod(p)[]
        
        # Step 2
        # 拉格朗日插值法 v
        g0 = R([0])
        for i in range(len(v)):
            temp = []
            num1, num2 = 1, 1
            temp.extend(v[:i])
            temp.extend(v[i+1:])

            h1 = R([1])
            h2 = R([1])
            
            for j in range(len(temp)):
                h1 = (h1 * (x - temp[j][0]))
                h2 = (h2 * (v[i][0] - temp[j][0]))
            h = int(h2(0))
            g0 = (g0 + v[i][1] * h1 * inverse_mod(h, p))

        print("重构多项式g0为:", g0)
        
        # 拉格朗日插值法 e1
        g1 = R([0])
        for i in range(len(e1)):
            temp = []
            num1, num2 = 1, 1
            temp.extend(e1[:i])
            temp.extend(e1[i+1:])

            h1 = R([1])
            h2 = R([1])
            
            for j in range(len(temp)):
                h1 = (h1 * (x - temp[j][0]))
                h2 = (h2 * (e1[i][0] - temp[j][0]))
            h = int(h2(0))
            g1 = (g1 + e1[i][1] * h1 * inverse_mod(h, p))

        print("重构多项式g1为:", g1)
        
        # 拉格朗日插值法 e2
        g2 = R([0])
        for i in range(len(e2)):
            temp = []
            num1, num2 = 1, 1
            temp.extend(e2[:i])
            temp.extend(e2[i+1:])

            h1 = R([1])
            h2 = R([1])
            
            for j in range(len(temp)):
                h1 = (h1 * (x - temp[j][0]))
                h2 = (h2 * (e2[i][0] - temp[j][0]))
            h = int(h2(0))
            g2 = (g2 + e2[i][1] * h1 * inverse_mod(h, p))

        print("重构多项式g2为:", g2)
        
        # Step 3
        if g0.degree() == t-1 and g1.degree() == t-1 and g2.degree() == t-1:
            # print(g1(d2),g2(d1),g1(0),g2(0),g0(d2))
            if g1(d2) == g2(d1) and g1(0) == g0(d1) and g2(0) == g0(d2):
                secret = g0(0)
                print("未检测到作弊者!")
                print("恢复的秘密信息为:", secret)
        else:
            # Step 4
            # 票数 V
            V = []
            # 作弊者列表
            L = []
            # 诚实用户
            H = []
            for i in range(len(v)):
                V.append([v[i][0], 0])
            for i in range(len(v)):
                for j in range(i + 1, len(v)):
                    # print(S[i][0],S[j][0],S[i][1](S[i][0],S[j][0]),S[j][1](S[j][0],S[i][0]))
                    if S[i][1](S[i][0],S[j][0]) == S[j][1](S[j][0],S[i][0]):
                        V[i][1] = V[i][1] + 1
                        V[j][1] = V[j][1] + 1
            
            for i in range(len(v)):
                if V[i][1] < float((len(v) + t - 5) / 2):
                    # 作弊者
                    L.append(V[i][0])
                else:
                    # 诚实用户
                    H.append(v[i])
            
            print("存在作弊者,识别到的作弊者为:", L)
            
            # 重构秘密信息 secret
            if len(v) - len(L) >= t:
                # 拉格朗日插值法
                f = R([0])
                for i in range(len(H)):
                    temp = []
                    num1, num2 = 1, 1
                    temp.extend(H[:i])
                    temp.extend(H[i+1:])

                    g1 = R([1])
                    g2 = R([1])

                    for j in range(len(temp)):
                        g1 = (g1 * (x - temp[j][0]))
                        g2 = (g2 * (H[i][0] - temp[j][0]))
                    g = int(g2(0))
                    f = (f + H[i][1] * g1 * inverse_mod(g, p))
                secret = f(0)
                print("重构多项式为:", f)
                print("恢复的秘密信息为:", secret)
            else:
                print("诚实用户数不足,无法恢复秘密信息!")

# -------------------------------------------------------------------------
# 算法2
# -------------------------------------------------------------------------
def Detection_Reconstruct2(S_other, S, v, t, p):
    print("算法二:")
    if len(S) < t:
        print("参与恢复的碎片数量少于门限{0},无法恢复!".format(t))
    else:
        secret = 0
        R.<x> = Zmod(p)[]
        
        # Step 1
        # 票数 V
        V = []
        # 作弊者列表
        L = []
        # 诚实用户
        H = []
        for i in range(len(S)):
            V.append([S[i][0], 0])
        for i in range(len(S)):
            for j in range(i + 1, len(S)):
                # print(S[i][1](S[i][0],j+1) , S[j][1](S[j][0],i+1))
                if S[i][1](S[i][0],S[j][0]) == S[j][1](S[j][0],S[i][0]):
                    V[i][1] = V[i][1] + 1
                    V[j][1] = V[j][1] + 1
        flag = 1
        for i in range(len(S)):
            if V[i][1] != len(S) - 1:
                flag = 0
                break
        if flag == 1:
            # Step 2
            print("不存在作弊者!")
            # 重构秘密信息 secret
            # 拉格朗日插值法
            f = R([0])
            vv = v[:t]
            for i in range(t):
                temp = []
                num1, num2 = 1, 1
                temp.extend(vv[:i])
                temp.extend(vv[i+1:])
                    
                g1 = R([1])
                g2 = R([1])
                    
                for j in range(len(temp)):
                    g1 = (g1 * (x - temp[j][0]))
                    g2 = (g2 * (vv[i][0] - temp[j][0]))
                g = int(g2(0))
                f = (f + vv[i][1] * g1 * inverse_mod(g, p))
            secret = f(0)
            print("重构多项式为:", f)
            print("恢复的秘密信息为:", secret)
        else:
            # Step 3
            # 识别作弊者
            # n - m 个用户投票
            for i in range(len(S_other)):
                for j in range(len(S)):
                    
                    if S_other[i][1](S_other[i][0],S[j][0]) == S[j][1](S[j][0],S_other[i][0]):
                        V[j][1] = V[j][1] + 1
            for i in range(len(S)):
                if V[i][1] < float((n + t - 3) / 2):
                    # 作弊者
                    L.append(V[i][0])
                else:
                    # 诚实用户
                    H.append(v[i])
            
            print("存在作弊者,识别到的作弊者为:", L)
            # 重构秘密信息 secret
            if len(v) - len(L) >= t:
                # 拉格朗日插值法
                f = R([0])
                for i in range(len(H)):
                    temp = []
                    num1, num2 = 1, 1
                    temp.extend(H[:i])
                    temp.extend(H[i+1:])

                    g1 = R([1])
                    g2 = R([1])

                    for j in range(len(temp)):
                        g1 = (g1 * (x - temp[j][0]))
                        g2 = (g2 * (H[i][0] - temp[j][0]))
                    g = int(g2(0))
                    f = (f + H[i][1] * g1 * inverse_mod(g, p))
                secret = f(0)
                print("重构多项式为:", f)
                print("恢复的秘密信息为:", secret)
                
            else:
                print("诚实用户数不足,无法恢复秘密信息!")
                
                
# -------------------------------------------------------------------------
# 测试
# -------------------------------------------------------------------------
t = 5
n = 9
p = 23
secret =13

S = ShareGen(secret, n, t, p)

# 攻击
# 伪造一个碎片 [1, f1()] 改为 [1, f1()+1]

S[2][1] = S[2][1]+1

# 秘密碎片
v = []
# 检测碎片
e1 = []
e2 = []
        
# 定义在环Zp上的多项式
R.<x,y> = GF(p)[]
# 生成两个随机数 d1,d2 >n
d1 = ZZ.random_element(n, n*n)
d2 = ZZ.random_element(n, n*n)

# 计算秘密碎片 v 检测碎片 e1,e2
for i in range(len(S)):
    f = S[i][1]
    v.append([S[i][0],f(S[i][0],0)])
    e1.append([S[i][0],f(S[i][0],d1)])
    e2.append([S[i][0],f(S[i][0],d2)])

# 参与重构的用户
m = 6
# 算法一
Detection_Reconstruct1(S[2:], v[2:], e1[2:], e2[2:], t, n, p, d1, d2)
# 算法二
# 攻击
S_other = S[:2]
S = S[2:]
Detection_Reconstruct2(S_other, S, v[2:], t, p)

附录.3

# -------------------------------------------------------------------------
# 鲁棒秘密共享方案
# -------------------------------------------------------------------------
# 秘密划分函数
# 参数s:秘密信息
# 参数n:划分个数
# 参数t:门限
# 参数p:模数
# -------------------------------------------------------------------------
import numpy as np

def ShareGen(s, n, t, p):
    # 此处默认参与者序号从1开始以此增加到n
    # 随机选取最高次数为 t-1 的多项式,模p
    factor = []
    S = []
    SS = []
    for i in range(t - 1):
        factor.append(ZZ.random_element(0, p))
    factor.append(s)
    print("多项式系数:",factor)
    factor.reverse()
    # 定义在环Zp上的多项式
    R.<x> = Zmod(p)[]
    f = R(factor)
    print("多项式为:", f)
    # 计算n个秘密碎片
    for i in range(n):
        temp = []
        num = s
        temp.append(i+1)
        # 计算多项式的值 f(i)
        temp.append(f(i+1))
        S.append(temp)
    
    print("秘密信息划分为:", S)
    
    # p<s
    g = np.zeros((n, n))
    d = np.zeros((n, t))
    b = np.zeros((n, n))
    # 随机选取 d
    for i in range(n):
        for k in range(t-1):
            d[i][k] = ZZ.random_element(0, p)
    for i in range(n):
        for j in range(n-1):
            if j >= i:
                j = j+1
            # 随机选取 g
            g[i][j] = ZZ.random_element(0, p)
            
            if p < s:
                l = s/p
                s_j = []
                # 十进制转二进制
                s_bin = bin(S[j][1])
                s_bin = s_bin[2:]
                ls = list(s_bin)
                ls.reverse()
                # 计算 s_j
                s_j = []
                for k in range(l*len(bin(p)[2:])-len(l)):
                    ls.append('0')
                ls.reverse()
                for k in range(l):
                    s_j.append(int("".join(l[k*len(bin(p)[2:]):(k+1)*len(bin(p)[2:])]),2))
                
                # 计算 b
                sum_1, sum_2 = 0, 0
                
                for k in range(l):
                    sum_1 = sum_1 + g[i][j]^k*s_j[k]
                for k in range(t-1):
                    sum_2 = sum_2 + S[i][0]^k*d[j][k]
                    
                b[i][j] = sum_1 +sum_2
            else:
                # 计算 b
                sum_1 = 0
                
                for k in range(t-1):
                    sum_1 = sum_1 + S[i][0]^k*d[j][k]
                
                b[i][j] = g[i][j]*int(S[j][1]) + int(sum_1)
        
        g_temp = list(g[i])[:i]
        g_temp.extend(list(g[i])[i+1:])
        b_temp = list(b[i])[:i]
        b_temp.extend(list(b[i])[i+1:])
        SS.append([[i+1],[S[i][1], list(d[i]), g_temp, b_temp]])
        
    print("秘密信息划分为:", SS)
    return SS

# -------------------------------------------------------------------------
# 秘密信息恢复函数 
# 参数S:多项式碎片列表
# 参数t:门限
# 参数p:模数
# 参数l:l=m/p
# -------------------------------------------------------------------------
def Reconstruct(S, t, n, l, p):
    s = [0]*len(S)
    g = np.zeros((n, n))
    d = np.zeros((n, t))
    b = np.zeros((n, n))
    b_ver = np.zeros((n, n)) 
    # 秘密碎片第一部分 s,d
    for i in range(len(S)):
        s[i] = S[i][1][0]
        # print(np.array(S[1][1]))
        d[i] = np.array(S[i][1][1])
        
    # 秘密碎片第二部分 g,b
    for i in range(len(S)):
        temp = S[i][1][2][:i]
        temp.append(0)
        temp.extend(S[i][1][2][i:])
        g[i] = np.array(temp)
        
        temp = S[i][1][3][:i]
        temp.append(0)
        temp.extend(S[i][1][3][i:])
        b[i] = np.array(temp)
    
    # 验证数组 v
    v = np.zeros((n, n))
    # 计算 b'
    for i in range(len(S)):
        for j in range(len(S)-1):
            if j >= i:
                j = j+1
            # p<m
            if l>1:
                # 计算 b'
                sum_1, sum_2 = 0, 0
                
                for k in range(l):
                    sum_1 = sum_1 + g[i][j]^k*s_j[k]
                for k in range(t-1):
                    sum_2 = sum_2 + S[i][0]^k*d[j][k]
                    
                b_ver[i][j] = int(sum_1) + int(sum_2)
            else:
                # 计算 b'
                sum_1 = 0
                
                for k in range(t-1):
                    sum_1 = sum_1 + S[i][0][0]^k*d[j][k]
                b_ver[i][j] = int(g[i][j])*int(s[j]) + int(sum_1)
    
    # 验证
    for i in range(len(S)):
        for j in range(len(S)-1):
            if j >= i:
                j = j+1
            if b_ver[i][j] == b[i][j]:
                v[i][j] = 1
    print("验证数组为:\n", v)
    
    # 计算满足条件的最大集合 I
    I = []
    for i in range(len(S)):
        sum_vi = 0
        for j in range(len(S)-1):
            if j >= i:
                j = j+1
            sum_vi = sum_vi + v[i][j]
        if sum_vi >= t:
            I.append([S[i][0][0],S[i][1][0]])
    e = (len(I)-t)//2

    if e > 0:
        print("作弊者数量最大为:", e)

        # 使用 Reed−Solomon code 的纠错算法重构秘密信息
        # Berlekamp-Welch算法
        for m in range(1, e+1):
            print("假设错误个数为:", m)
            E, Q = np.zeros((len(I),m+1)), np.zeros((len(I),m+t))
            for i in range(len(I)):
                for j in range(m+1):
                    E[i][j] = int(I[i][1]*(I[i][0]^j))
                for k in range(m+t):
                    Q[i][k] = int(I[i][0]^k)

            b_temp = [[0] * m + [1] + [0] * (m+t)]
            slv = np.append(E, (-1)*Q, axis=1)
            slv = np.append(slv,b_temp,axis=0)

            slv = matrix(Zmod(p), len(I)+1, 2*m+t+1, slv)
            b_temp = [0] * (len(I))
            b_temp.append(1)
            b_temp = matrix(Zmod(p), len(I)+1, 1, b_temp)
            try:
                X = slv.solve_right(b_temp)
            except Exception:
                print("错误个数有误,无法恢复!")
                continue
            Q,E = [],[]
            for i in range(m+1):
                E.append(X[i,0])
            for i in range(m+1,2*m+t+1):
                Q.append(X[i,0])

            R.<x> = Zmod(p)[]
            Ep = R(E)
            Qp = R(Q)
            Pp = Qp/Ep
            print("恢复的多项式:")
            print("Ep:", Ep)
            print("Qp:", Qp)
            if Qp % Ep == 0:
                print("Pp:", Pp)
                print("恢复的秘密信息为:", Pp(0))
                return Pp(0)
            else:
                print("多项式无法重构!")
                return -1
    else:
        R.<x> = Zmod(p)[]
        f = R([0])
        # 拉格朗日插值法
        if len(I) >= t:
            for i in range(len(I)):
                temp = []
                num1, num2 = 1, 1
                temp.extend(I[:i])
                temp.extend(I[i+1:])

                g1 = R([1])
                g2 = R([1])

                for j in range(len(temp)):
                    g1 = (g1 * (x - temp[j][0]))
                    g2 = (g2 * (I[i][0] - temp[j][0]))
                g = int(g2(0))
                f = (f + I[i][1] * g1 * inverse_mod(g, p))

            print("重构多项式为:", f)
            print("恢复的秘密信息为:", f(0))
            return f(0)
        else:
            print("通过验证的参与者数量少于门限t,无法恢复秘密信息s!")
            return -1
    
    
# -------------------------------------------------------------------------
# 测试
# -------------------------------------------------------------------------
s=12
n=7
t=5
p=17
S = ShareGen(s, n, t, p)
# 改变一个碎片
S[1][1][0] = (S[1][1][0]+1)%p
# S[2][1][0] = S[2][1][0]+1
Reconstruct(S, t, n, 1, p)
# 改变两个碎片
S[2][1][0] = (S[2][1][0]+1)%p
# S[2][1][0] = S[2][1][0]+1
Reconstruct(S, t, n, 1, p)

附录.4

# -------------------------------------------------------------------------
# 作弊者可检测秘密共享方案
# -------------------------------------------------------------------------
# 秘密信息划分函数
# 参数s:秘密信息
# 参数n:划分个数
# 参数t:门限
# 参数p:模数
# -------------------------------------------------------------------------
def ShareGen(s, n, t, p):
    # 随机生成多项式系数,n-1次,模p
    factor = []
    S = []
    for i in range(t - 1):
        factor.append(ZZ.random_element(0, p))
    factor.append(s)
    print("多项式系数:",factor)
    factor.reverse()
    # 定义在环Zp上的多项式
    R.<x> = Zmod(p)[]
    f = R(factor)
    # 计算多项式 g
    a0 = factor[0]
    a1 = factor[1]
    # 随机数r
    r = ZZ.random_element(1, p)
    print("随机数为:", r)
    
    b0 = p - (r*a0)%p
    b1 = p - (r*a1)%p
    factor = []
    for i in range(t - 2):
        factor.append(ZZ.random_element(0, p))
        
    factor.append(b1)
    factor.append(b0)    
    factor.reverse()
    g = R(factor)
    
    print("多项式为f:", f)
    print("多项式为g:", g)
    
    # 计算n个秘密碎片
    for i in range(n):
        temp = []
        num = s
        temp.append(i+1)
        # 计算多项式的值 f(i)
        temp.append(f(i+1))
        temp.append(g(i+1))
        S.append(temp)
        
    print("秘密信息划分为:", S)
    return S

# -------------------------------------------------------------------------
# 作弊者检测和秘密信息恢复函数 
# 参数S:秘密信息碎片列表
# 参数t:门限
# 参数p:模数
# -------------------------------------------------------------------------
def Detection_Reconstruct(S, t, p):
    if len(S) < t:
        print("参与恢复的碎片数量少于门限{0},无法恢复!".format(t))
    else:
        secret = 0
        # 定义在环Zp上的多项式
        R.<x> = Zmod(p)[]
        f = R([0])
        g = R([0])
        # 拉格朗日插值法
        for i in range(len(S)):
            temp = []
            num1, num2 = 1, 1
            temp.extend(S[:i])
            temp.extend(S[i+1:])

            g1 = R([1])
            g2 = R([1])
            
            for j in range(len(temp)):
                g1 = (g1 * (x - temp[j][0]))
                g2 = (g2 * (S[i][0] - temp[j][0]))
            g_int = int(g2(0))
            f = (f + S[i][1] * g1 * inverse_mod(g_int, p))
        
                # 拉格朗日插值法
        for i in range(len(S)):
            temp = []
            num1, num2 = 1, 1
            temp.extend(S[:i])
            temp.extend(S[i+1:])

            g1 = R([1])
            g2 = R([1])
            
            for j in range(len(temp)):
                g1 = (g1 * (x - temp[j][0]))
                g2 = (g2 * (S[i][0] - temp[j][0]))
            g_int = int(g2(0))
            g = (g + S[i][2] * g1 * inverse_mod(g_int, p))
        
        print("重构多项式f为:", f)
        print("重构多项式g为:", g)
        
        a0 = int(str(f).split("+")[-1])
        if str(f).split("+")[-2][-2] != "x":
            a1 = 0
        else:
            if str(f).split("+")[-2].split("*")[0] == " ":
                a1 = 1
            else:
                a1 = int(str(f).split("+")[-2].split("*")[0])
        
        b0 = int(str(g).split("+")[-1])
        if str(g).split("+")[-2][-2] != "x":
            b1 = 0
        else:
            if str(g).split("+")[-2].split("*")[0] == " ":
                b1 = 1
            else:
                b1 = int(str(g).split("+")[-2].split("*")[0])
        
        for i in range(p):
            if (i*a0+b0)%p == 0 and (i*a1+b1)%p == 0:
                print("未检测到作弊者!恢复的秘密信息为:", f(0))
                return f(0)
        
        print("检测到作弊者!恢复失败!")
        return -1
            
        
# -------------------------------------------------------------------------
# 测试
# -------------------------------------------------------------------------
S = ShareGen(12, 8, 5, 19)
# 正常情况
s = Detection_Reconstruct(S[:5], 5, 19)
# 攻击
# 作弊者修改 [1,y+1]
S[1][1] = S[1][1] + 1
# S[2][1] = S[2][1] + 1
s = Detection_Reconstruct(S[:6], 5, 19)
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

PlanetRT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值