对于已有为数不多的匿名秘密共享方案,为了保证方案的匿名特性,作者们都积极从秘密分配规则上入手,探寻新的构造方法,但成效不佳。本文中,我们不走传统路线,而是基于 Shamir秘密共享,引入安全多方计算技术,实现了任意门限参数的匿名秘密共享。建议的方案既能保证任意 t 个参与者协作可以正确恢复 秘密( t 为门限值),又能保证不泄露参与者的隐私输入,即不泄露任何有关参与者共享份额的信息。
首先介绍shamir秘密共享
这里简单说明一下为什么能解密成功,因为你在秘密分发协议的第三步构成了一个多项式,后面密钥的分发就是通过这个多项式实现的,然后将多项式经过的点进行分发,秘密恢复的过程中就只将t个秘密的二维点进行拉格朗日插值进行恢复,就可以将原本的多项式恢复,然后带入x=0即可得到秘密,而对于数量不足的参与者,是无法恢复到原来的多项式,就会得到错误的秘密。而对于超过t个参与者,我们随机选取t个就可以实现。
import random
import math
# 输⼊p, w, t, s 程序⼊⼝
def runCode(predefineData):
p = 0
w = 0
t = 0
s = 0
if not predefineData:
tempstr = input("输⼊素数(p)\n")
p = int(tempstr)
p = testPrimality(p)
w = input("输⼊持有⼦密钥的⼈数\n")
t = input("请输⼊门限⼈数\n")
if(int(w)>=int(t)):
print("建⽴ (" + str(t) + ", " + str(w) + ")门限密钥")
s = input("输⼊你的主密钥(s))
s = int(s)
print("secret:",s)else:
print("门限值⼤于拥有密钥的⼈数")
runCode([])
predefineData = [w,t,p,s]else:
w = predefineData[0]
t = predefineData[1]
p = predefineData[2]
s = predefineData[3]
generatesubKey(t,w,s,p) # ⽣成⼦密钥
generateMainKey(s,p,t) # 求解主密钥# ⽣成⼦密钥def generatesubKey(t_str,w_str,s,p):
a_j=[0] # 存放多项式系数列表
x_i=[0] # 多项式x取值列表
t = int(t_str)
w = int(w_str)
x_i = randomList(1,w,w,True) # 获取x 不相同
a_j = randomList(1,5,t-1,False) # 多项式参数
x_i.sort() # 升序排列x
print("x_i:",x_i)
print("a_j:",a_j)
subKey = {} #⼦密钥字典for i in range(0,w):
polynomialSum = s; #多项式求和
x = x_i[i]for j in range(0,t-1):
a = a_j[j]
polynomialSum += (a*math.pow(x,j+1))
regsubK = polynomialSum % p # 得到其中⼀个⼦密钥
subKey[x] = int(regsubK) # 添加到密钥字典# print(subKey)# 处理输出多项式字符串
polynomialStr = "f(x) = ("+str(s)+" + "for i in range(0,t-1):
polynomialStr += str(a_j[i])+"x^"+str(i+1)+" + "
polynomialStr = "".join(list(polynomialStr)[:-3])
polynomialStr += ") mod("+str(p)+")"
print("表达式:",polynomialStr)
print("⽣成的密钥:\n")# 打印⼦密钥for key,value in subKey.items():
print("("+str(key)+","+str(value)+")")return subKey# 获取⼦密钥def getSubset(t):
print("\n输⼊⼤于"+t+"组密钥进⾏解密")
Subset_RAWstr = input("\n获取⼦密钥\n请输⼊x值\n")
Subset_str = Subset_RAWstr.split()
Subset = {}
Subset_mm = input("请输⼊x对应的⼦密钥\n")
Subset_mm = Subset_mm.split()
ind = 0for ID in Subset_str:try:
ID = int(ID)
Subset_mm[ind] = int(Subset_mm[ind])
Subset[ID] = Subset_mm[ind]
ind = ind +1except:
print("Error in list entered, try again")
Subset = getSubset(t)#ADD RECURSIVE FUNCTIONreturn Subset# ⽣成主密钥def generateMainKey(s,p,t):
x_list = []
y_list = []
subSet = getSubset(t) # 输⼊密钥
recoveredS = 0# 遍历输⼊密钥字典⽣成x yfor key,value in subSet.items():
x_list.append(key)
y_list.append(value)
print("("+str(key)+","+str(value)+")")# ⽣成解密表达式 for i in range(0,len(x_list)):
x_i = x_list[i]
temp_j = 1for j in range(0,len(x_list)):if(j!=i):
x_j = x_list[j]
temp_one = float(x_j)/(x_j-x_i)
temp_j = temp_j * temp_one# print("("+str(x_i)+","+str(y_list[i])+"):",y_list[i] * temp_j)
recoveredS += y_list[i] * temp_j# print("recoveredS ",recoveredS)
recoveredS = int(round(recoveredS)) # 四舍五⼊ int
recoveredS = recoveredS % p
print("密钥值为: ",recoveredS)if recoveredS == s:
print("解密成功\n")else:
print("解密失败\n")
resp = input("是否再次解密?\n")if resp.upper() == "Y":
generateMainKey(s,p,t)else:pass
print("OVER\n")return recoveredS# 检测素数def testPrimality(p):
temp = p;
p = math.sqrt(p)
p = int(p)for i in range(2, (p+1)):
f = temp / iif(f.is_integer()):
newP = input("Enter prime number")
newP = int(newP)
newP = testPrimality(newP)
temp = newPbreakreturn temp# 得到⼀个随机数 state: true 不重复 false 可以重复def getRandomNum(xlist, start, stop, state): # x_subi = []
x = random.randint(start, stop)if state is True:if not x in xlist:return xelse:
x = getRandomNum(xlist,start, stop, state)return xelse:return x# 得到随机列表 state: true 不重复 false 可以重复def randomList(start,stop,length,state):if le
length=int(length)
start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
random_list = []for i in range(length):
num = getRandomNum(random_list,start, stop, state)
random_list.append(num)return random_list# runCode(["5","3",11,5])
runCode([])
演示成功:
输⼊素数(p)
11
输⼊持有⼦密钥的⼈数
5
请输⼊门限⼈数
3
建⽴ (3, 5)门限密钥
输⼊你的主密钥(s)10
secret: 10
x_i: [1, 2, 3, 4, 5]
a_j: [1, 1]
表达式:f(x) = (10 + 1x^1 + 1x^2) mod(11)
⽣成的密钥:
(1,1)
(2,5)
(3,0)
(4,8)
(5,7)
输⼊⼤于3组密钥进⾏解密
获取⼦密钥
请输⼊x值
1 2 3
请输⼊x对应的⼦密钥
1 5 0
(1,1)
(2,5)
(3,0)
密钥值为: 10
解密成功
接下来的协议均是在半诚实模型下完成的。
利用安全两方点积协议、安全两方求积协议、安全两方求差协议、茫然传输来实现匿名门限秘密共享方案。
则有f(0)=s1+s2+……+st mod q
这里实现的匿名性就是对于每个秘密的输入xi,通过公式的变化,将秘密下方进行了不同的除法,但是有一个问题就是我们还是需要进行每个人的输入进行一定的计算后才能获取到特定的vi,这样子的方法只能用于密钥分发完之后,无法进行第二次重新的密钥分发,也就是说,我们的密钥分发和解密都是固定的,只能初始化设置之后,后面只能一直沿用这个密钥,会造成个别人进行密钥的窃取,从而造成一定的经济损失。