概述
Shamir原理参见
分析
1.随机生成最高m - 1次的多项式
2.获取f(x)的值
3.随机生成n份shares
4.根据m份shares重构出secret(拉格朗日插值)
5.测试函数
source code
import random
from math import ceil
from decimal import Decimal
FIELD_SIZE = 10 ** 5
def coeff(t, secret):
"""
生成最高次为t - 1次的多项式,其中常数项是secret
"""
# 保证第一项不为0
coeff = [random.randrange(1, FIELD_SIZE)]
# 后面t - 2系数项可为0
if t > 3:
coeff += [random.randrange(0, FIELD_SIZE) for _ in range(t - 2)]
# 加入常数项
coeff.append(secret)
return coeff
def polynom(x, coefficients):
"""
获取f(x)的值
"""
point = 0
# coeff从左到右是高次到低次的(使用enumerate表示指数)
for coefficient_index, coefficient_value in enumerate(coefficients[::-1]):
point += x ** coefficient_index * coefficient_value
return point
def generate_shares(n, m, secret):
"""
将秘密分成n份,只需要m份就可以复原(也就是阈值,函数的最高次数 + 1)
"""
coefficient = coeff(m, secret)
shares = []
for i in range(1, n + 1):
x = random.randrange(1, FIELD_SIZE)
shares.append((x, polynom(x, coefficient)))
return shares
def reconstruct_secret(shares):
"""
利用拉格朗日插值法(已知m个秘密)还原并得到secret(f(0))
"""
sums = 0
for j, share_j in enumerate(shares):
xj, yj = share_j
prod = Decimal(1)
for i, share_i in enumerate(shares):
xi, _ = share_i
if i != j:
prod *= Decimal(Decimal(xi) / (xi - xj))
prod *= yj
sums += Decimal(prod)
return int(round(Decimal(sums), 0))
# Driver code
if __name__ == '__main__':
# (3,5) sharing scheme
t, n = 3, 5
secret = 1234
print(f'Original Secret: {secret}')
# Phase I: Generation of shares
shares = generate_shares(n, t, secret)
print(f'Shares: {", ".join(str(share) for share in shares)}')
# Phase II: Secret Reconstruction
# Picking t shares randomly for
# reconstruction
pool = random.sample(shares, t)
print(f'Combining shares: {", ".join(str(share) for share in pool)}')
print(f'Reconstructed secret: {reconstruct_secret(pool)}')
最终结果
总结
这是门限(n,t)Shamir秘密分享
用了多项式理论
在区块链的多方签名有所应用
20221003 bug修复
- 由于filed_size过大可能存在超大数溢出的可能,后面可以取MOD进行解决,由于涉及除法,因此需考虑到逆元
- x的取值需要保证不同
- 下面修改filed_size为100,可以在一定概率上支持t = 50的情况
import random
from math import ceil
from decimal import Decimal
FIELD_SIZE = 10 ** 2
MOD = 9999999987
def coeff(t, secret):
"""
生成最高次为t - 1次的多项式,其中常数项是secret
"""
# 保证第一项不为0
coeff = [random.randrange(1, FIELD_SIZE)]
# 后面t - 2系数项可为0
if t > 3:
coeff += [random.randrange(0, FIELD_SIZE) for _ in range(t - 2)]
# 加入常数项
coeff.append(secret)
return coeff
def polynom(x, coefficients):
"""
获取f(x)的值
"""
point = 0
# coeff从左到右是高次到低次的(使用enumerate表示指数)
for coefficient_index, coefficient_value in enumerate(coefficients[::-1]):
point += x ** coefficient_index * coefficient_value
return point
def generate_shares(n, m, secret):
"""
将秘密分成n份,只需要m份就可以复原(也就是阈值,函数的最高次数 + 1)
"""
coefficient = coeff(m, secret)
shares = []
xs = random.sample(range(0, FIELD_SIZE), n)
for i in range(1, n + 1):
x = xs[i - 1]
shares.append((x, polynom(x, coefficient)))
return shares
def reconstruct_secret(shares):
"""
利用拉格朗日插值法(已知m个秘密)还原并得到secret(f(0))
"""
sums = 0
for j, share_j in enumerate(shares):
xj, yj = share_j
prod = Decimal(1)
for i, share_i in enumerate(shares):
xi, _ = share_i
if i != j:
#print(Decimal(Decimal(xi) / (xi - xj)))
prod *= Decimal(Decimal(xi) / (xi - xj))
#print(yj)
prod *= yj
sums += Decimal(prod)
print(sums)
return int(round(Decimal(sums), 0))
# Driver code
if __name__ == '__main__':
# (3,5) sharing scheme
t, n = 50, 100
secret = 1234
print(f'Original Secret: {secret}')
# Phase I: Generation of shares
shares = generate_shares(n, t, secret)
print(f'Shares: {", ".join(str(share) for share in shares)}')
# Phase II: Secret Reconstruction
# Picking t shares randomly for
# reconstruction
pool = random.sample(shares, t)
print(f'Combining shares: {", ".join(str(share) for share in pool)}')
print(f'Reconstructed secret: {reconstruct_secret(pool)}')
最后
以上就是不安玫瑰为你收集整理的【密码学】Shamir秘密分享python实现的全部内容,希望文章能够帮你解决【密码学】Shamir秘密分享python实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复