毕业设计里用到了一些密码学的知识,在博客做个记录。
秘密共享
秘密共享(Secret Sharing),如其名,是一种用来共享秘密的技术。理解这个技术,首先需要把意义搞清楚,然后了解技术实现原理,最后用工具实现一个demo。
共享的意义
一个秘密信息,必然有其最初的持有者,也即发布者。发布者具有秘密的使用权和共享权,即他有权利将秘密分享给别人。但这里存在一个问题:如何保证这个共享过程是安全的?
传统的方法,是加密。如对称加密,双方用约定的密钥进行加密解密通信——但也有一个问题:如何安全传递密钥?总是需要有一个最初“绝对安全”的信道。非对称加密解决了这个矛盾,发布方自己生成公私钥对,通过公开公钥,用私钥加密、公钥解密,无需事先约定。
非对称加密解决了绝大部分加密的问题,目前广泛应用的RSA就是明证。但其实它依赖了一个潜在假设(虽然这个假设很接近现实):公开环境是一个诚实信道,它不会篡改发布的共享信息。否则,中间人攻击就会破获秘密。
假设这样一个场景:发布者A与接受者B之间存在N条独立信道,在不清楚各信道信任度和稳定度的情况下,A如何将信息发送给B?秘密共享应运而生。它通过某种方法将秘密拆分,从N个信道同时发送,即使有信道存在恶意者,也无法恢复秘密。
在实际应用中,秘密共享常用于密钥的分布式存储,将一个密钥拆分后多地存储,分散风险,等到需要用的时候再聚合到一起。
共享原理
形式化定义如下:
其中s表示需要拆分的秘密,t表示恢复门限,n为拆分数目。
存在恢复函数,对于任意有。
shamir算法
shamir是一种秘密共享的实现1,利用了拉格朗日插值公式2。详细原理见参考文献。
下面补充一个shamir算法的有用的性质:加同态。
已知已有两个用于秘密共享的多项式、以及素数。通过秘密共享分享的分片形式是,。
将分片中的多项式结果求和,得到。
根据shamir算法中的定义, 是原秘密。因此通过恢复算法对求和后的分片进行恢复,将会得到。这就实现了秘密求和。在双方求和的情况下,没有意义,但在参与者数目大于等于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
后记
本来写了一堆原理,结果没保存点了发布,发现已经掉线,全没了,心累。算了,参考文献里写的也很详细了。
https://github.com/blockstack/secret-sharing ↩︎