Shamir 门限方案|秘密共享|拉格朗日插值|密码学

门限秘密分割

秘密s被分成n份毫无相关的部分信息,每一部分信息称为一个子密钥,由一个参与者持有,只有至少拥有k份子密钥时才能恢复出秘密s,这种方案为(k, n)-秘密分割门限方案k称为方案的门限值

Shamir门限方案就是一种门限秘密分割方案,他是基于拉格朗日插值公式的

子密钥生成算法

  • 秘密为S
  • 取大素数p
  • 确定n,作为子密钥的持有者的数量
  • 确定k,作为门限值
  • 1p的有限域中随机取k-1个数,记做 a 1 , a 2 , . . . a k − 1 a_1,a_2,...a_{k-1} a1,a2,...ak1,作为k-1次多项式f(x)的非常数项的系数
  • 写出多项式为 f ( x ) = S + a 1 x + a 2 x + . . . + a k − 1 x k − 1 f(x)= S +a_1x+a_2x +...+a_{k-1}x^{k-1} f(x)=S+a1x+a2x+...+ak1xk1,共n项,S是秘密,作为常数项放在多项式内
  • n个持有者记做 P 1 , P 2 , . . . . P n P_1,P_2,....P_{n} P1,P2,....Pn P i P_i Pi分到的子密钥为 f ( i ) f(i) f(i)
  • 销毁多项式

复原秘密

复原秘密至少需要 k 个子密钥

利用 f ( x ) = ∑ j = 1 k f ( i j ) ∏ l = 1 , l ! = j k x − i l i j − i l m o d p f(x)=\sum_{j=1}^{k}{f(i_{j}) \prod_{l=1,l!=j}^{k}{\frac{x-i_l}{i_j-i_l}}}modp f(x)=j=1kf(ij)l=1,l!=jkijilxilmodp

而我们如果只需要计算秘密,就只需要将x=0带入,得到的数就是所需要的秘密

在这里插入图片描述

  • 63
    点赞
  • 174
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Shamir门限方案是一种秘密分享方案,它可以将一个秘密S分成n个部分,其中只有k个部分可以重组得到原始秘密,k的值小于n。下面是Shamir门限方案的Python实现: ```python import random def generate_shares(s, k, n, p): """ 生成Shamir门限方案的秘密分享 :param s: 原始秘密 :param k: 重组秘密所需的部分数量 :param n: 总的分享数量 :param p: 素数 :return: 一个包含n个元素的列表,其中每个元素都是一个二元组(x, y),表示(x, f(x))的点 """ if k > n: raise ValueError("k must be less than or equal to n") # 生成多项式f(x) = a0 + a1*x + ... + ak-1*x^(k-1),其中a0 = s coefficients = [s] + [random.randint(1, p - 1) for _ in range(k - 1)] def f(x): """ 计算f(x) """ result = 0 for i, coeff in enumerate(coefficients): result += coeff * pow(x, i, p) return result % p # 生成n个分享 points = [(i, f(i)) for i in range(1, n + 1)] return points def recover_secret(shares): """ 恢复秘密 :param shares: 一个包含k个或更多元素的列表,其中每个元素都是一个二元组(x, y),表示(x, f(x))的点 :return: 原始秘密 """ k = len(shares) if k == 0: raise ValueError("shares list must not be empty") # 计算所有可能的多项式的值 p = shares[0][1].bit_length() - 1 x_values, y_values = zip(*shares) secrets = [] for i in range(k): xi, yi = shares[i] numerator = denominator = 1 for j in range(k): if i == j: continue xj, yj = shares[j] numerator *= -xj denominator *= xi - xj coefficient = numerator * pow(denominator, -1, p) % p secrets.append((coefficient, yi)) # 求出f(0),即原始秘密 result = 0 for coeff, yi in secrets: result += coeff * yi return result % p ``` 在这个实现中,`generate_shares`函数接受一个原始秘密`s`,需要重组秘密的部分数量`k`,总分享数量`n`和一个素数`p`,然后返回一个包含n个二元组的列表,其中每个二元组表示一个分享点(x, f(x))。`recover_secret`函数接受一个包含k个或更多元素的分享点列表,然后返回原始秘密。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值