xd信息安全数学基础密码学实验-3 基于中国剩余定理的秘密共享方案


上一篇中国剩余定理的文章请跳转到:
https://blog.csdn.net/Koz_0/article/details/109177491

一、基础知识原理

基础知识上课老师都讲了,也有相关的ppt,这里就不多说了。
而且也没人看对吧,都只想着看代码了。
这个题的难点估计就是找这个di数组了,因为这个di数组是随机生成的,
而且有递增、互素、N>K>M这三个条件,所以比较难以搞定。
其基本思想其实和剩余定理差不多。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

二、算法实现

1.环境

使用的是vc 6++ 和miracl大整数库。
miracl整数库的配置可以自行去百度一下,应该也有不少。我这里提供一下miracl整数库的配置资源吧。见链接:
如果在配置的时候有什么问题可以私信或者评论,我会尽力而为的。
链接:http@@s://p@@an.baidu.c@@om/s/1HKP-v0OFQIPyZmMjRSPFJw
提取码:jops (把@删除掉就是完整链接)

2.di数组生成说明

这里面,因为秘密是500位的,而且是分成五个子秘密,恢复需要三个子秘密,所以di随机数只要设定成100-200位的,并且相互互素就可以。
我用的是167位,有一个hxd跟我说这个di的位数最好满足
(500/t + 500/t-1)/2,
算了一下,166或者167都可以,大家可以直接用。

3.主要代码

代码如下:

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include"miracl.h"
#define n 5
#define t 3
#define secnum 500
big d[n],k[n];

int compbig(int x){
	int i;
	big one = mirvar(1);
	big temp = mirvar(0);
	int result = 1;
	for (i = 0; i < x; i++)
	{
			egcd(d[x], d[i], temp);//求最大公约数
			if (compare(temp, one) != 0)
			{
				result = 0;
			}
	
	}
	mirkill(temp);
	mirkill(one);
	return result;

}

int find_d(big key)
{
	int coprime(int x);
	int i;
	int res = 1;
	int j;
	big one;
	big temp;
	big N,M,K;
	N = mirvar(1);
	M = mirvar(1);
	K = mirvar(1);
	one = mirvar(1);
	temp = mirvar(0);
	bigdig(167,10,d[0]);
	//先生成一个随机数,然后再循环生成随机数,判断是否互素
	for(i=1;i<n;i++){
		bigdig(167,10,d[i]);
		if(compbig(i)==0){//
				i--;
			}
	}
	//冒泡排序
	for(i=0; i<5; i++){
		for(j=0; j<5-i-1; j++){
            if(compare(d[j],d[j+1])==1){//d[j]>d[j+1]
                copy(d[j],temp);//temp = d[j]
                copy(d[j+1],d[j]);
                copy(temp,d[j+1]);
            }
        }
    }
	
	printf("findi---2\n");
	for(i=0;i<3;i++){
		multiply(d[i],N,N);
	}
	for(i=3;i<5;i++){
		multiply(d[i],M,M);
	}
	printf("findi---3");
	copy(key,K);
	if((compare(N,K)==1)&&(compare(N,M)==1)&&(compare(k,M)==1))
	//if(compare(N,K)compare(K,M))
		res = 0;
	else 
		res = 1;
	return res;
}

int main()
{
	FILE *fp;
	miracl *mip = mirsys(10000, 10);//初始化10的五次方
	//mip->IOBASE = 10;  //设置 10进制
    int j = 0;
	int i = 0;
	int cordi = 1;
	int numseq[5];
    big secret;
    big res;
	big temp, one;
	big m = mirvar(1);//m是di连乘的乘积
	big Mit[5];//Mi
	big Mit_1[5];//Mi的逆
	big g1[5];//中间变量,计算Mi*Mi的逆*ai(a1即Ki)
	//key = mirvar(1);
	one = mirvar(1);
	res = mirvar(0);
	temp = mirvar(0);
	secret = mirvar(1);

	for (i=0;i<n;i++) {
		d[i] = mirvar(0);
		k[i] = mirvar(0);
	}
    fp = fopen("3.txt","r");
	if (fp == NULL)
	{
		printf("FILE ERROR\n");
		return 0;
	}
	cinnum(secret, fp);
    cotnum(secret, stdout);
	//为了能够满足N>K>M
	while(cordi){
		cordi = find_d(secret);//找到合法的di数组
		printf("2\n");
	}

	for(i=0;i<n;i++){
		//ki = k mod(di)
		printf("\n");
		printf("第%d个di和ki的值为:\n",i+1);
		copy(secret,temp);
		printf("\n------------------------------------------------------------------\n");
		printf("\n");
		cotnum(d[i],stdout);
		divide(temp,d[i],d[i]);
		copy(temp,k[i]);
		//printf("\n------------------------------------------------------------------\n");
		printf("\n");
		cotnum(k[i],stdout);
		printf("\n------------------------------------------------------------------\n");
	}
	
	//中国剩余定理
	printf("选择3个子秘密,输入序号1-5\n");

	for (i = 0; i < t; i++)
	{
		scanf("%d", &numseq[i]);
		numseq[i]--;//
	}

	//初始化
	for (i = 0; i < n; i++)
	{
		Mit[i] = mirvar(0);
		Mit_1[i] = mirvar(0);
		g1[i] = mirvar(0);
	}
	
	//m=d[numseq[i]]连乘
	for (i = 0; i < t; i++)
	{
		multiply(m, d[numseq[i]], m);
	}

	//计算Mi
	for (i = 0; i < t; i++)
	{
		fdiv(m, d[numseq[i]], Mit[i]);//除法
	}

	//计算Mi的逆
	for (i = 0; i < t; i++)
	{
		xgcd(Mit[i], d[numseq[i]], Mit_1[i], Mit_1[i], Mit_1[i]);//求逆运算
	}

	for (i = 0; i < t; i++)
	{
		multiply(Mit[i], Mit_1[i], g1[i]);
		multiply(g1[i], k[numseq[i]], g1[i]);
	}

	//求和
	for (i = 0; i < t; i++)
	{
		add(res, g1[i], res);
	}
	powmod(res, one, m, res);// 模一次

	printf("秘密是 : \n");
	printf("------------------------------------------------------------------\n");
	cotnum(res, stdout);
	printf("------------------------------------------------------------------\n");

	mirexit(); //清除MIRACL系统,释放所有的内部变量
	getchar();
	return 0;
}

三、总结

这个是此课程的第三个实验。
这几天牙疼,无心学习,所以才拖到周五。

  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值