秘密共享原理与实现

毕业设计里用到了一些密码学的知识,在博客做个记录。

秘密共享

秘密共享(Secret Sharing),如其名,是一种用来共享秘密的技术。理解这个技术,首先需要把意义搞清楚,然后了解技术实现原理,最后用工具实现一个demo。

共享的意义

一个秘密信息,必然有其最初的持有者,也即发布者。发布者具有秘密的使用权和共享权,即他有权利将秘密分享给别人。但这里存在一个问题:如何保证这个共享过程是安全的?
传统的方法,是加密。如对称加密,双方用约定的密钥进行加密解密通信——但也有一个问题:如何安全传递密钥?总是需要有一个最初“绝对安全”的信道。非对称加密解决了这个矛盾,发布方自己生成公私钥对,通过公开公钥,用私钥加密、公钥解密,无需事先约定。
非对称加密解决了绝大部分加密的问题,目前广泛应用的RSA就是明证。但其实它依赖了一个潜在假设(虽然这个假设很接近现实):公开环境是一个诚实信道,它不会篡改发布的共享信息。否则,中间人攻击就会破获秘密。
假设这样一个场景:发布者A与接受者B之间存在N条独立信道,在不清楚各信道信任度和稳定度的情况下,A如何将信息发送给B?秘密共享应运而生。它通过某种方法将秘密拆分,从N个信道同时发送,即使有信道存在恶意者,也无法恢复秘密。
在实际应用中,秘密共享常用于密钥的分布式存储,将一个密钥拆分后多地存储,分散风险,等到需要用的时候再聚合到一起。

共享原理

形式化定义如下:
S ( s , t , n ) → { ⟨ s 0 ⟩ , ⟨ s 1 ⟩ , . . . , ⟨ s n ⟩ } S(s,t,n)\rightarrow{\langle s_0\rangle,\langle s_1\rangle,...,\langle s_n\rangle} S(s,t,n)s0,s1,...,sn
其中s表示需要拆分的秘密,t表示恢复门限,n为拆分数目。
存在恢复函数 R R R,对于任意 m ≥ t m\ge t mt R ( ⟨ s 0 ⟩ , ⟨ s 1 ⟩ , . . . , ⟨ s m ⟩ ) → s R(\langle s_0\rangle,\langle s_1\rangle,...,\langle s_m\rangle)\rightarrow s R(s0,s1,...,sm)s

shamir算法

shamir是一种秘密共享的实现1,利用了拉格朗日插值公式2。详细原理见参考文献。
下面补充一个shamir算法的有用的性质:加同态。
已知已有两个用于秘密共享的多项式 f ( x ) = a 0 + a 1 x + . . + a n x n f(x)=a_0+a_1x+..+a_nx^n f(x)=a0+a1x+..+anxn g ( x ) = b 0 + b 1 x + . . + b n x n g(x)=b_0+b_1x+..+b_nx^n g(x)=b0+b1x+..+bnxn以及素数 p p p。通过秘密共享分享的分片形式是 ( x , f ( x ) m o d   p ) (x, f(x)mod\ p) (x,f(x)mod p) ( x , g ( x ) m o d   p ) (x, g(x)mod\ p) (x,g(x)mod p)
将分片中的多项式结果求和,得到 ( x , f ( x ) + g ( x ) m o d      p ) (x, f(x)+g(x)\mod\ p) (x,f(x)+g(x)mod p)
根据shamir算法中的定义, a 0 a_0 a0 b 0 b_0 b0是原秘密。因此通过恢复算法对求和后的分片进行恢复,将会得到 a 0 + b 0 a_0+b_0 a0+b0。这就实现了秘密求和。在双方求和的情况下,没有意义,但在参与者数目大于等于3时,就会有用。
下面的demo将会演示这个过程。

实现应用

github上有对shamir算法的实现3,这里直接借用实现一个拆分求和后恢复的过程。

from secretsharing import secret_int_to_points, points_to_secret_int
from secretsharing import primes
p = primes.get_large_enough_prime([100000])

n_frac = 3
n_rcvr = 2

// 拆分
def ss(n):
	return secret_int_to_points(n, n_rcvr, n_frac, p)

// 恢复
def recover(s):
	return points_to_secret_int(s, p)

// 对秘密求和
def secret_sum(s1, s2):
	return [(i+1, (s1[i][1]+s2[i][1])%p) for i in range(3)]



>>> sh = seret_sum(ss(123),ss(234))
>>> recover(sh)
357

后记

本来写了一堆原理,结果没保存点了发布,发现已经掉线,全没了,心累。算了,参考文献里写的也很详细了。


  1. shamir算法介绍 ↩︎

  2. 拉格朗日插值法 ↩︎

  3. https://github.com/blockstack/secret-sharing ↩︎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值