基于 t 维空间中点的确定的(t, n)门限秘密共享
其原理基于三维空间中,两个互不平行的面相交于一条直线,三个互不平行的面相交于一个唯一确定的点。
那么,(t, n)门限秘密共享就可以看作将秘密信息映射为三维空间中某一点(此处的 t 设为3),随机选取n个互不平行的平面。当已知n个平面中的任意两个平面时无法确定出该点,满足当选取任意 t-1 个秘密信息碎片时,无法恢复秘密信息。
对于 (t, n) 门限秘密共享,只需将其扩展到 t 维即可。即在 t 维空间中任意选取一个点作为秘密信息,并过该点任意选取 n 个互不平行的超平面,将这些超平面方程的系数和常数项作为秘密信息碎片。恢复时,只需将 t 个超平面方程联立求解线性方程组即可。
缺点是,当 t 值较大时,幂运算的次数也较高,所以运算缓慢,效率不高。
# 密钥分割函数 将秘密信息k分割为n个信息
def secretSplit(secret, t, n):
# 在t维空间中确定一个点,将秘密信息编码到这个点的坐标当中
# 简单采用重复构造
point = []
for i in range(t):
point.append(secret)
# 构造过该点的n个面,且两两不平行
# 面的方程为: A(a - a0) + B(b - b0) + ... + T(t - t0) = 0
# 系数矩阵
factor = np.zeros([n, t])
# 常数
Num = np.zeros([1, n])
for i in range(n):
tag = 1
while tag == 1:
tag = 0
# 随机生成t个系数
random.seed(time.time())
list = range(1, 2 * t)
num = random.sample(list, t)
# 常数项
N = 0
# 系数
F = np.zeros([1, t])
for j in range(t):
N = N + num[j] * point[j]
F[0, j] = num[j]
# 判断是否两两平行
for k in range(i):
temp = F[0, 0] / factor[k][0]
flag = 0
for l in range(1, t):
if F[0, l]/factor[k][l] == temp:
flag = flag + 1
# 平行
if flag == t - 1:
tag = 1
break
Num[0, i] = N
for j in range(t):
factor[i][j] = F[0, j]
print("%d个方程系数矩阵为:"%(n))
print(factor)
print("%d个方程常数矩阵为:"%(n))
print(Num)
return factor, Num
# 解线性方程组使用的库
from scipy import linalg
# 秘密信息恢复
def secretRecover(factor, Num):
# 少于t个面
if factor.shape[0] < factor.shape[1]:
print("平面个数少于%d,无法恢复"%(factor.shape[1]))
elif factor.shape[0] == factor.shape[1]:
Num = Num.reshape(factor.shape[1], 1)
point = linalg.solve(factor, Num)
point = point.reshape(1, factor.shape[1])
print("恢复秘密信息为:")
print(point)
else:
F = np.zeros([factor.shape[1], factor.shape[1]])
N = np.zeros([1, factor.shape[1]])
random.seed(time.time())
list = range(0, factor.shape[0])
num = random.sample(list, factor.shape[1])
for i in range(factor.shape[1]):
F[i] = factor[num[i]]
N[0, i] = Num[0, num[i]]
N = N.reshape(factor.shape[1], 1)
point = linalg.solve(F, N)
point = point.reshape(1, factor.shape[1])
print("恢复秘密信息为:")
print(point)
运行结果: