xd信息安全数学基础密码学实验-2 中国剩余定理

it2023-08-09  63

文章目录

一、基础知识原理二、算法实现1.环境2.Miracl库函数说明3.主要代码 三、总结


上一篇fermat素性检测算法的文章请跳转到: https://blog.csdn.net/Koz_0/article/details/109177491

一、基础知识原理

基础知识上课老师都讲了,也有相关的ppt,这里就不多说了。 但是我个人觉得这个逆元的概念比较有趣。 其基本思想和解方程组差不多,但这里是同余方程组。

visio流程图如下图所示:

二、算法实现

1.环境

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

2.Miracl库函数说明

此部分主要列举了一些用到的函数,因为是大整数,所以对于一般的“=”赋值或者“*”乘法都无法实现,需要用函数实现。

1、 miracl *mip = mirsys(10000,10); //初始化10的五次方 mip->IOBASE = 10; //设置 10进制 2、 x = mirvar(0); //初始化 //给x赋值大整数0 3cinnum(m,fp);//从文件中读取一个数 4bigrand(x,a);//生成随机数 //a<x=m-1 5egcd(a,m,g);//求a和m的最大公约数 //g = (a,m) 6powmod(a,x,m,r);//模幂运算, //r=ax (mod m) 7cotnum(m,stdout)//把大整数m打印到终端 8multiply(mj[i],m, m); //m = m * mi 9divide(x, y, z) //z = x / y //也可以求模值 divide(x,y,z) //x = x mod y 10xgcd(Mj[i], mj[i], Mj_contrary[i], Mj_contrary[i], Mj_contrary[i]); //计算mj的逆 xgcd(x,p,z,z,z); //z = x^-1 mod p => z*x = 1 (mod p)

3.主要代码

这里就不多说什么了,算法比较简单,难点是其中库函数的运用。 代码中也有注释,不懂的可以私信我。 P.S.我的代码里面那块注释我也没有什么好方法来实现,如果有大佬有什么好方法希望能指明方向。 代码如下:

#include<stdio.h> #include<math.h> #include"miracl.h" int main() { int j = 0; int i = 0; FILE *fd; int k = 3; miracl *mip = mirsys(1000, 10);//初始化10的五次方 //mip->IOBASE = 10; //设置 10进制 big a[3], mj[3], Mj[3], Mj_contrary[3]; big m, res; big temp, one; big nok; m = mirvar(1); one = mirvar(1); res = mirvar(0); temp = mirvar(0); nok = mirvar(1); for (i=0;i<k;i++) { a[i] = mirvar(0); mj[i] = mirvar(0); Mj[i] = mirvar(0); Mj_contrary[i] = mirvar(0); } fd = fopen("2.txt","r"); if(fd == NULL) { printf("Error!"); return 0; } for (i=0;i<k;i++) { cinnum(a[i],fd); } for (i=0;i<k;i++) { cinnum(mj[i],fd); } fclose(fd); for (i=0;i<k;i++){ //判断mi是否是互素的≡ for (j=i+1;j<k;j++) { egcd(mj[i], mj[j], temp); if (compare(one, temp)) { printf("mj不互素"); return 0; } } } /*没有办法把cotnum自带的换行取消掉,没法打印出来方程组 printf("同余方程组为:\n"); for(i=0;i<k;i++){ printf(" x≡ "); cotnum(a[i], stdout); printf(" ( mod "); cotnum(mj[i],stdout); printf(" )"); printf("\n"); } printf("\n"); */ for (i=0;i<k;i++){//m = m1*m2*m3 multiply(mj[i],m, m);//m = m * mi } for (i=0;i<k;i++) { copy(m, temp);// temp = m divide(temp, mj[i], Mj[i]);//求Mj = m / mj //divide(x, y, z) z = x / y //这里不能直接用m,因为divide也有取余的功能,会改变m的值 } for (i=0;i<k;i++){ xgcd(Mj[i], mj[i], Mj_contrary[i], Mj_contrary[i], Mj_contrary[i]);//计算mj的逆 //xgcd(x,p,z,z,z); z = x^-1 mod p => z*x = 1 (mod p) } for (i=0;i<k;i++) { multiply(Mj[i], Mj_contrary[i], Mj[i]); multiply(Mj[i], a[i], temp); divide(temp, m, nok); //求temp (mod m) //divide(x,y,z) =>x = x mod y add(res, temp, res); } divide(res, m, temp); printf("得到方程组的解为:\n"); printf("x = "); cotnum(res, stdout); mirkill(m); //释放内存 mirkill(one); mirkill(res); mirkill(m); mirkill(temp); /*好像加上不知道为什么会报错,就不加了,对结果无影响 mirkill(a[3]); mirkill(mj[3]); mirkill(Mj[3]); mirkill(Mj_contrary[3]); */ mirexit(); //清除MIRACL系统,释放所有的内部变量 getchar(); return 0; }

三、总结

这个是此课程的第二个实验。下一个实验我也会尽快上传的。

最新回复(0)