用Python实现 Shamir 的秘密共享方案
秘密共享方案用于通过将秘密分成片段(股份)在多个参与者(股东)之间分配秘密值。这样做的方式是防止单个股东对原始秘密有任何有用的知识。检索原始秘密的唯一方法是合并分配给参与者的共享。因此,秘密的控制是分布式的。这些方案是阈值密码系统的示例,其中涉及多方之间的秘密划分,使得多方(超过某个阈值数)必须合作重建秘密。
一般来说,一个秘密可以分成n股(对于n名股东),其中,成功重建至少需要t , (t < n)股。这种方案被称为 (t, n) 共享方案。从n 个参与者中,任何大小大于或等于t的股东子集都可以重新生成秘密。重要的是,即使有任何k (k < t)共享,也不会学习到有关原始秘密的新信息。
沙米尔秘密分享
Shamir Secret Sharing ( SSS ) 是由以色列著名密码学家Adi Shamir创建的秘密共享方案中最受欢迎的实现之一,他也为 RSA 算法的发明做出了贡献。 SSS 允许将秘密分成任意数量的份额并允许任意阈值(只要它小于参与者总数)。 SSS 基于多项式插值的数学概念,该概念指出,可以根据已知位于曲线上的 t 个或更多点的知识来重建 t-1 次多项式。
例如,要重建一条 1 次曲线(一条直线),我们需要至少 2 个点位于该直线上。相反,如果可用的唯一点的数量小于 (degree-of-curve + 1),则在数学上重建曲线是不可行的。可以想象有无限可能的直线可以由二维空间中的一个点形成。
SSS 背后的动机
通过将秘密嵌入多项式,可以应用多项式插值的概念来生成秘密共享方案。 p次的一般多项式可以表示如下:
在 P(x) 的表达式中,值 a_{1}、a_{2}、a_{3}、…、a_{n} 表示多项式的系数。因此,多项式的构造需要选择这些系数。请注意,实际上没有任何值被替换为x;多项式中的每一项都充当“占位符”来存储系数值。
一旦生成多项式,我们基本上可以仅通过位于曲线上的p+1个点来表示曲线。这遵循多项式插值原理。例如,如果我们可以访问至少 5 个位于其上的独特点,则可以重建 4 次曲线。为此,我们可以运行拉格朗日插值或任何其他类似的插值机制。
因此,如果我们将秘密值隐藏在这样一个多项式中,并使用曲线上的各个点作为共享,我们就会得到一个秘密共享方案。更准确地说,为了建立一个(t, n)秘密共享方案,我们可以构造一个t-1 次的多项式,并在曲线上选择n个点作为共享,这样只有在合并t或更多共享时才会重新生成多项式。秘密值 ( s ) 隐藏在多项式的常数项(0 次项的系数或曲线的 y 截距)中,只有在曲线重建成功后才能获得。
使用的算法
Shamir's Secret Sharing 使用多项式插值原理在以下两个阶段进行阈值共享:
第一阶段:股票的产生
此阶段涉及系统的设置以及共享的生成。
- 确定参与者数量(n)和阈值(t)的值以确保某些秘密值(s)
- 通过选择多项式的随机系数,构造一个次数为t-1的随机多项式P(x) 。将多项式中的常数项(零度项的系数)设置为等于秘密值s
- 要生成n股,随机选择多项式P(x)上的n个点
- 在参与者之间分配上一步中选择的坐标。这些充当系统中的份额
第二阶段:秘密的重构
为了重建秘密,至少需要t个参与者来集中他们的份额。
- 收集t股或更多股
- 使用插值算法从份额中重建多项式P'(x) 。拉格朗日插值是这种算法的一个例子
- 确定x = 0的重构多项式的值,即计算P'(0) 。该值揭示了恰好是原始秘密的多项式的常数项。因此,秘密被重建
下面是实现。
Python3
import random
from math import ceil
from decimal import Decimal
FIELD_SIZE = 10**5
def reconstruct_secret(shares):
"""
Combines individual shares (points on graph)
using Lagranges interpolation.
`shares` is a list of points (x, y) belonging to a
polynomial with a constant of our key.
"""
sums = 0
prod_arr = []
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))
def polynom(x, coefficients):
"""
This generates a single point on the graph of given polynomial
in `x`. The polynomial is given by the list of `coefficients`.
"""
point = 0
# Loop through reversed list, so that indices from enumerate match the
# actual coefficient indices
for coefficient_index, coefficient_value in enumerate(coefficients[::-1]):
point += x ** coefficient_index * coefficient_value
return point
def coeff(t, secret):
"""
Randomly generate a list of coefficients for a polynomial with
degree of `t` - 1, whose constant is `secret`.
For example with a 3rd degree coefficient like this:
3x^3 + 4x^2 + 18x + 554
554 is the secret, and the polynomial degree + 1 is
how many points are needed to recover this secret.
(in this case it's 4 points).
"""
coeff = [random.randrange(0, FIELD_SIZE) for _ in range(t - 1)]
coeff.append(secret)
return coeff
def generate_shares(n, m, secret):
"""
Split given `secret` into `n` shares with minimum threshold
of `m` shares to recover this `secret`, using SSS algorithm.
"""
coefficients = coeff(m, secret)
shares = []
for i in range(1, n+1):
x = random.randrange(1, FIELD_SIZE)
shares.append((x, polynom(x, coefficients)))
return shares
# 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)}')
输出:
Original Secret: 1234
Shares: (79761, 4753361900938), (67842, 3439017561016), (42323, 1338629004828), (68237, 3479175081966), (32818, 804981007208)
Combining shares: (32818, 804981007208), (79761, 4753361900938), (68237, 3479175081966)
Reconstructed secret: 1234
实际应用
秘密共享方案广泛用于需要分布式而不是集中式信任的密码系统。使用秘密共享的现实世界场景的突出示例包括:
- 比特币基于阈值的签名
- 安全多方计算
- 具有多方计算的私有机器学习
- 密码管理