Shamir门限分割方案 python

Shamir门限分割方案

Shamir门限分割方案是一种基于数学方法的密钥分割技术,它允许将一个密钥分割成多个部分,其中任意集合中的k个部分可以重新组合成原始密钥。这种方案可以用于实现分布式密钥管理和安全多方计算。

generate_shares_shamir函数接受三个参数:

  • secret:要分享的秘密值。
  • n:总共要生成的分享数量。
  • k:恢复秘密所需的最小分享数量。
  • prime:用于生成多项式的素数(如果未提供,则随机生成)。

函数的主要逻辑是生成一个包含n个分享的列表shares。在每次循环中,首先生成一个随机系数列表coefficients,然后使用这些系数计算分享的值。最后,返回生成的分享列表和素数。

在程序的最后部分,使用示例中的secret_shamirn_shamirk_shamir参数调用generate_shares_shamir函数,并将生成的分享列表打印出来。然后,使用recover_secret_shamir函数从部分分享中恢复秘密,并将恢复的秘密值打印出来。

Shamir门限分割方案的安全性取决于秘密和分享数量的选择,以及分享的随机性。在实际应用中,需要确保秘密和分享数量的选择是足够大的值,以防止攻击者破解生成的分享。

代码部分:

from sympy import randprime, mod_inverse
import random

def generate_shares_shamir(secret, n, k, prime=None):
    """
    生成秘密分享的函数(Shamir's 秘密共享方案)
    :param secret: 要分享的秘密值
    :param n: 总共要生成的分享数量
    :param k: 恢复秘密所需的最小分享数量
    :param prime: 用于生成多项式的素数(如果未提供,则随机生成)
    :return: 生成的分享列表
    """
    if prime is None:
        prime = randprime(2**127, 2**128)  # 随机选择一个素数
    coefficients = [secret] + [random.randint(1, prime - 1) for _ in range(k - 1)]  # 生成 k 个随机系数
    shares = []
    for i in range(1, n + 1):
        share = sum((coefficients[j] * i**j) % prime for j in range(k)) % prime
        shares.append((i, share))
    return shares, prime

def recover_secret_shamir(shares, prime):
    """
    恢复秘密的函数(Shamir's 秘密共享方案)
    :param shares: 分享列表
    :param prime: 用于生成多项式的素数
    :return: 恢复的秘密值
    """
    x = [share[0] for share in shares]
    y = [share[1] for share in shares]
    secret = 0
    for i in range(len(x)):
        numerator, denominator = 1, 1
        for j in range(len(x)):
            if i != j:
                numerator = (numerator * -x[j]) % prime
                denominator = (denominator * (x[i] - x[j])) % prime
        lagrange = (y[i] * mod_inverse(denominator, prime) * numerator) % prime
        secret = (secret + lagrange) % prime
    return secret

# 输入
secret_shamir = "123abc"  # 要分享的秘密值
n_shamir = 5  # 总共要生成的分享数量
k_shamir = 3  # 恢复秘密所需的最小分享数量

# 生成分享
shares_shamir, prime_shamir = generate_shares_shamir(int.from_bytes(secret_shamir.encode(), 'big'), n_shamir, k_shamir)
print("Generated shares (Shamir's):", shares_shamir)  # 打印生成的分享

# 恢复秘密
recovered_secret_shamir = recover_secret_shamir(shares_shamir[:k_shamir], prime_shamir)  # 从部分分享中恢复秘密
print("Recovered secret (Shamir's):", bytes.fromhex(hex(recovered_secret_shamir)[2:]).decode('utf-8'))  # 打印恢复的秘密值

实验结果:

Generated shares (Shamir's): 
[(1, 251016269231287306291163047880048203059), 
(2, 189757478496317825575377239648440243192), 
(3, 75642021324164959982155086402090127867), 
(4, 168088291243902111641009045146231718533), 
(5, 207677894726455878422426658875631153741)]
Recovered secret (Shamir's): 123abc

Process finished with exit code 0

个人博客 qinquanquan.com

  • 24
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
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个或更多元素的分享点列表,然后返回原始秘密。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qinquanquan_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值