学习shamir秘密分享

学习,shamir,秘密,分享 · 浏览次数 : 9

小编点评

**1979 年 Shamir 的秘密共享方案** 1979 年 Shamir 提出了基于拉格朗日插值多项式的秘密共享方案,该方案用于在多个地方存储和共享一个秘密。 **方案步骤:** **秘密分享(分段):** 1. 创建一个元项式,其中多项式有 r 个变量。 2. 从 r 个随机数中选择 r 个数,构造一个 r-1 次一元多项式。 3. 将这 r 个子秘密发送给 r 个不同的人。 **秘密重构:** 1. 收集大于 r 个子秘密。 2. 使用拉格朗日插值算法从这些子秘密中重建一个元项式。 3. 从元项式的系数中确定秘密。 **实验程序:** 链接到一个 Python 代码,该代码实现 Shamir 的秘密共享方案。 **结果:** 该方案允许多个人从一个秘密中恢复另一个秘密。 **重要点:** * 每个人的接收量不相同,取决于方案中使用的子秘密数量。 * 每个人的接收数量必须大于或等于秘密的长度。 * 该方案仅在秘密长度超过或等于 r 的情况下才具有安全性。

正文

介绍

1979年Shamir在下文提出基于拉格朗日插值多项式的\((r,n)\)秘密共享方案(\(0<r \leq n\)。秘密拥有者通过构建一元多项式将秘密分为\(n\)份,接收方收集大于等于\(r\)份的子秘密即可重构多项式恢复秘密。

image-20231008225008047

方案

\((r,n)\)秘密共享方案分为秘密分享和秘密重构两步:

  • 秘密分享

假设有一个秘密\(M\),取\(r-1\)个随机数\(d_1,d_2,...,d_{r-1}\),构造一个\(r-1\)次一元多项式\(w(x)=M+d_1x+d_2x^2+...+d_{r-1}x^{r-1}\)

\(x\)\((1,...,n)\),计算出\(n\)个子秘密\((x,w(x))\),将这\(n\)个子秘密发送给\(n\)个不同的人。

  • 秘密重构

当有不少于\(r\)个不同的子秘密聚在一起时,根据拉格朗日插值,可以唯一插值出一个\(r-1\)次多项式,即:

image-20231008230805785

也可以看作是:\(w(x)=M+d_1x+d_2x^2+...+d_{r-1}x^{r-1}\),另\(x=0\),就可以得到秘密\(M=w(0)\)

实验

程序来自:https://github.com/apachecn/geeksforgeeks-python-zh/blob/master/docs/implementing-shamirs-secret-sharing-scheme-in-python.md

import random
from decimal import Decimal

FIELD_SIZE = 10**5  # GF域大小

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

    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: (85479, 169064248999330), (64655, 96725154480594), (47701, 52649409201294), (99941, 231110282437614), (93923, 204115595277642)
Combining shares: (47701, 52649409201294), (64655, 96725154480594), (99941, 231110282437614)
Reconstructed secret: 1234

总结

秘密共享方案广泛应用于要求信任分布式而不是集中式的密码系统中。使用秘密共享的真实场景的突出例子包括:

  • 基于阈值的比特币签名
  • 安全多方计算
  • 具有多方计算的私有机器学习
  • 密码管理

与学习shamir秘密分享相似的内容:

学习shamir秘密分享

介绍 1979年Shamir在下文提出基于拉格朗日插值多项式的\((r,n)\)秘密共享方案(\(0

比特比较

学习&&转载文章: 【隐私计算笔谈】MPC系列专题(二):模型和Shamir秘密共享机制 【隐私计算笔谈】MPC系列专题(十一):共享随机数和比特分享 【隐私计算笔谈】MPC系列专题(十二):比特比较 【隐私计算笔谈】MPC系列专题(十三):比特分解【这部分没看懂,欢迎交流~】 通过共享随机数来实现

KD-Tree 学习笔记

学习资料: 1.B站 - 一只叫小花的猫 2.语雀 - 双愚:kdtree 3.B站视频:学习kdtree的前置知识:KNN算法 KD树简介与背景 k-d树,是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索。关于kd树的背景,它主要是一种解决特征点匹配问题的算法,kd树就是一种高维

学习.NET 8 MiniApis入门

介绍篇 什么是MiniApis? MiniApis的特点和优势 MiniApis的应用场景 环境搭建 系统要求 安装MiniApis 配置开发环境 基础概念 MiniApis架构概述 关键术语解释(如Endpoint、Handler等) MiniApis与其他API框架的对比 第一个MiniApis

yolov1-yolov5 网络结构&正负样本筛选&损失计算

学习yolo系列,最重要的,最核心的就是网络模型、正负样本匹配、损失函数等三个方面。本篇汇总了yolov1-yolov5等5个版本的相关知识点,主要看点是在yolo框架搭建。初学者可以通过相关篇章搭建自己的知识点框架,然后再深入各个知识点,就像攻克一个又一个山头。当大部分的知识点都了然于胸,yolo...

【内存管理】页面分配机制

前言 Linux内核中是如何分配出页面的,如果我们站在CPU的角度去看这个问题,CPU能分配出来的页面是以物理页面为单位的。也就是我们计算机中常讲的分页机制。本文就看下Linux内核是如何管理,释放和分配这些物理页面的。 伙伴算法 伙伴系统的定义 大家都知道,Linux内核的页面分配器的基本算法是基

【操作系统】页表映射

页表的一些术语 现在Linux内核中支持四级页表的映射,我们先看下内核中关于页表的一些术语: 全局目录项,PGD(Page Global Directory) 上级目录项,PUD(Page Upper Directory) 中间目录项,PMD(Page Middle Directory) 页表项,(

【简写Mybatis-02】注册机的实现以及SqlSession处理

学习源码一定一定不要太关注代码的编写,而是注意代码实现思想:通过设问方式来体现代码中的思想;方法:5W+1H

Android Media Framework(一)OpenMAX Spec阅读与框架简介

学习开源代码最快的方式是先阅读它的文档,再查看它的头文件,最后研读代码实现并进行编译调试。Android早期引入OpenMAX IL作为使用音视频编解码器的标准接口,了解Android Media框架的底层运行原理要从OMX IL开始。在这一节,我们将阅读整理OpenMAX IL Spec中的介绍和

【操作系统】内存管理概述

目录内存管理硬件结构早期内存的使用方法分段分页逻辑地址,线性地址(intel架构)虚拟地址物理地址结构图虚拟地址到物理地址的转换内存管理总览系统调用vm_area_struct缺页中断伙伴系统slab分配器页面回收反向映射KSMhuge page页迁移内存规整OOM内存管理的一些数据结构线性映射st