环境
- 编程语言:python
- 依赖包: math,galois,pypbc,numpy
- 环境:Ubuntu
- 编程软件:pycharm
代码
import math
import galois
import pypbc
import numpy as np
def get_random_value(q):
v = 0
v = pypbc.get_random(q)
while not v < q:
v = pypbc.get_random(q)
return v
def get_distinct_xlist(n,GF):
'''
生成自变量列表,保证不重复。
''' x_list=[GF(0)]
i = 1
while i <= n:
m_t = get_random_value(GF.order)
m = GF(m_t)
if(m not in x_list):
x_list.append(m)
i = i + 1
return x_list
def run_shamir_scheme(t, n, k, GF):
'''
:param t:门限值
:param n:参与者数量
:param k:秘密
:param q:素数
:param GF:伽罗华域
:return:秘密份额数值对
'''
k = GF(k)
x_list = [GF(0)]
A_list = [GF(0)]
share_pairs = []
x_list = get_distinct_xlist(n,GF)
for i in range(1, t):
A_i = get_random_value(GF.order)
A_list.append(GF(A_i))
for i in range(1, n + 1):
x = x_list[i]
polynomialSum = k
for j in range(1, t):
A_i = A_list[j]
exponent = np.power(x, j)
polynomialSum = polynomialSum + A_i * exponent
share_pairs.append([x,polynomialSum])
return share_pairs
def generateK(share_pairs,GF):
'''
恢复秘密
:param share_pairs: 秘密份额数值对
:param GF: 伽罗华域
:return: 恢复的秘密
''' res_sum = GF(0)
for i in range(0,len(share_pairs)):
polynomial_sum = GF(0)
l = GF(1)
n = GF(1)
for j in range(0,len(share_pairs)):
if(j == i):
continue
else:
l *= GF(0) - (share_pairs[j][0])
n *= share_pairs[i][0] - share_pairs[j][0]
polynomial_sum = share_pairs[i][1] * l *(GF(1) / n)
res_sum = res_sum + polynomial_sum
return res_sum
if __name__ == '__main__':
q_bit = 64
q = pypbc.get_random_prime(q_bit)
n = 10
t = 8
GF = galois.GF(q)
K = pypbc.get_random(q)
print(K)
share_pairs = run_shamir_scheme(t, n, K, GF)
print(share_pairs)
K_1 = generateK(share_pairs[0:t], GF)
print(K_1)
注意事项
- pypbc包的安装需要安装其余的依赖库。此处不列出。
- galois包主要用来实现伽罗华域以及其运算。大数的伽罗华域生成比较耗费时间,可以自行修改代码,使其在初始阶段生成一个足够大的GF,例如GF(2^256)。之后直接在该伽罗华域内运算即可。
- galois包的+=运算会出问题。我不知道为什么,找这个BUG花了我快一天时间。改用普通的运算。
- galois包支持numpy的运算。
- pypbc主要用于支持双线性映射。本处用于生成大素数。因为python的int范围受限,直接用random.randint会溢出。