信息安全导论 实验三 Shamir门限方案的秘钥分享(不要求支持大数)

本文详细介绍了Shamir门限方案在密钥分割与恢复中的应用,阐述了秘密共享体制的重要性和工作原理。通过实例展示了如何基于LaGrange插值公式进行密钥分割,并利用逆元计算进行解密。该方案确保了只有达到门限值数量的参与者才能恢复原始秘密,增强了安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、实验目的与原理

通过基于Shamir门限方案的密钥分割及恢复的演示,理解密钥分割的重要性,理解密钥分割的基本原理和作用,掌握基于Shamir门限方案的密钥分割软件的使用。

秘密共享体制为将秘密分给多人掌管提供了可能。例如重要场所的通行、遗嘱的生效等都必须由两人或多人同时参与才能生效,这时都需要将秘密分给多人掌管并同时参与才能恢复。在实际应用中,秘密共享的要求多种多样、形形色色,每一种解决问题的方案都可成为一种体制。1979年,Shamir在提出秘密分享思想的同时,利用拉格朗日插值多项式理论设计出了一个具体的(t,n)秘密分享方案。1979年以后,人们通过对秘密共享问题的分析研究,构建出了许多类型的秘密共享体制。具有代表性和一般性的除了有Shamir提出的(t,n)门限体制,还有Blakley提出的矢量体制,Asmuth和Bloom提出的同余类体制,Karnin提出的矩阵法体制等。

一般地,一个由秘密分发者D和参与者P1,P2,…,Pn构成的(t,n)秘密分享体制包含下面两个协议:

(1) 秘密分发协议:在这个协议中,秘密分发者D在n个参与者中分享秘密s,每个参与者Pi获得一个碎片si,i=1,2,…,n。

(2) 秘密重构协议:在这个协议中,任意不少于t个参与者一起合作,以自己的碎片为输入,重构原秘密s。

一个安全的(t,n)秘密分享体制必须同时提供两个性质:一方面,任意t个参与者通过提供自己的碎片能够协作地恢复出原秘密s;另一方面,任意少于t个参与者即便拥有自己的碎片也无法计算关于原秘密s的任何信息。一般称这里的t为门限值。

Shamir提出的基于LaGrange插值公式的密钥分存思想是,利用有限域GF(p)上的t-1次多项式

h(x)= at- 1xt- 1+ … + a1x+ a0 mod p (1)

构造秘密共享的(t,n)门限体制。其中,所选的随机素数p要大于最大可能的秘密数S和参与者总数n,并且公开;S=h(0)=a0,而at-1,at-2,… ,a1为选用的随机系数,这些都需要保密,在生成n个秘密份额之后即可销毁。通过计算多项式h(x)对n个不同xi的取值就给出每个人的秘密份额:

Si= h(xi)mod p,i= 1,2,3,… ,n (2)

每一(xi,Si)对就是曲线h上的一个点,可看作是用户的标识符。由于任意t个点都可唯一地确定相应的t- 1次多项式,所以,秘密S可以从t个秘密份额重构。给定任意t个秘密份额Si1,Si2,… ,Sit,由LaGrange插值公式重构的多项式为

具体步骤如下。如图所示

 

其中需要使用到逆元计算。

 关于逆元,可以参看逆元(数论中的倒数)_淼润淽涵的博客-优快云博客其中有些例子不够完善,请谨慎选取,小心验证。

具体例子:

n=5, t=3, p=17; 随机选取K=13,a1=10,a2=2;

于是有

 解密的时候选取  (1 8)(2 7) (5 11)来解密

 上面的例子每个倒数都计算了一次逆元。

输入

大素数p

子秘钥总数n

门限值t

输出

设置的密钥与恢复的密钥的差值

输入样例1

1006000813
10
3

输出样例1

0

代码:(有参考)

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
public class Main {
    //定义基本常量
    private static long k,x1,x2,x3,x4,x5;
    //定义一个类
    static class Point {
        public long x,y;
        //类的初始化
        public Point(long x, long y) {
            this.x = x;
            this.y = y;
        }
    }
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //分别输入大素数p,子密钥总数n,门限值t
        long p,n,t,key=0,con,mod;
        p = scan.nextInt();
        n = scan.nextInt();
        t = scan.nextInt();
        //获得随机数
        Random random = new Random();
        //获得1到50的随机数
        k = random.nextInt(50) + 1;
        //获得1到20之间的随机数
        x1 = random.nextInt(20) + 1;
        x2 = random.nextInt(2) + 1;

        //获取点,为后面进行密钥计算做准备
        //使用循环对应一个曲线,将曲线上的一个点当做是用户的标识符
        //每个点可以确定t-1个多项式
        Long[] arr = new Long[(int) n + 1];
        for (int i = 1; i <= n; i++) {
            long y = (k + x1 * i + x2 * i * i) % p;
            arr[i] = y;
        }
        List<Long> points=Arrays.asList(arr);

        boolean[] boo = new boolean[(int) n + 1];
        Point[] pointlist = new Point[(int)t];
        for (int i = 0; i < t; i++) {
            while (true) {
                int x = random.nextInt((int)n) + 1;
                if (!boo[x]) {
                    boo[x] = true;
                    pointlist[i] = new Point(x, points.get(x));
                    break;
                }
            }
        }
        List<Point> list = Arrays.asList(pointlist);
        //解密过程,解密的过程需要选取门限值个数的不重复的点
        //恢复密钥过程,里面调用了费马定理函数,解密过程调用费马函数进行循环的逆元计算
        for (int i = 0; i < list.size(); i++) {
            Point point = list.get(i);
            long val = point.y;
            for (int j = 0; j < list.size(); j++) {
                if (i == j) {
                    continue;
                }
                val *= list.get(j).x;
                val %= p;
                mod =ol(point.x - list.get(j).x,p-2,p);
                val *= mod;
                val %= p;
            }
            key += val;
            key %= p;
        }
        con = key - k;
        System.out.println(con);
    }

    //费马定理函数,用于求解逆元
    static long ol(long a, long b, long c) {
        long t = 1;
        long temp = a % c;
        while (b != 0) {
            if ((b & 1) != 0) t = t * temp % c;
            temp = temp * temp % c;
            b >>= 1;
        }
        if (t < 0) {
            return t + c;
        } else {
            return t;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

stearm210

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

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

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

打赏作者

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

抵扣说明:

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

余额充值