信息安全基础综合实验-中国剩余定理

本文介绍了一个基于Miracl库的中国剩余定理实验项目,旨在帮助学生掌握密码学中的重要数学工具。实验通过编程实现了中国剩余定理,并详细记录了实验过程、原理及代码实现。

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

最近没有什么事情,打算把之前的作业整理一下发出来,有需要的学弟学妹们可以参考一下。
相关:某电的密码学实验,信安专业必选实验


实验题目:中国剩余定理

实验目的

(包括实验环境、实现目标等等)
实验环境:
Windows 10
Visual studio 2017
Miracl库

实验目标:
1.通过算法编程,熟悉使用miracl库的基本函数操作
2.通过编程实现中国剩余定理,加深对于中国剩余定理的理解与运用
3.体会密码学与数论的紧密联系
4.提高逻辑思维能力

方案设计

2.1背景
一千多年前的《孙子算经》中,有这样一道算术题:“今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?”按照今天的话来说:个数除以三余二,除以五余三,除以七余二,求这个数。《孙子算经》给出了一个非常有效的巧妙解法。术曰:“三、三数之剩二,置一百四十;五、五数之剩三,置六十三;七、七数之剩二,置三十,并之,得二百三十三。以二百一十减之,即得。凡三、三数之剩一,则置七十;五、五数之剩一,则置二十一;七、七数之剩一,则置十五。一百六以上,一百五减之,即得。
后来流传的《孙子歌》中所说“七十稀”、“廿一枝”和“正半月”,就是暗指这三个关键的数字。《孙子算经》没有说明这三个数的来历。实际上,它们具有如下特性:也就是说,这三个数可以从最小公倍数M=3×5×7=105中各约去模数3、5、7后,再分别乘以整数2、1、1而得到。假令k1=2,K2=1,K3=1,那么整数Ki(i=1,2,3)的选取使所得到的三数70、21、15被相应模数相除的时候余数都是1。由此出发,立即可以推出,在余数是R1、R2、R3的情况下的情况。应用上述推理,可以完全类似地把孙子算法推广到一般情形:设有一数N,分别被两两互素的几个数a1,a2,…,an相除得余数R1,R2,…,Rn,即N≡Ri(mod ai)(i=1,2,…,n),只需求出一组数K,使满足1(mod ai)(i=1,2,…,n),那么适合已给一次同余组的最小正数解是P是整数,M=a1×a2×…×an),就是现代数论中著名的剩余定理。
2.2原理
在这里插入图片描述2.3 原理证明
在这里插入图片描述2.4算法步骤
在这里插入图片描述

方案实现

3.1 算法流程图
在这里插入图片描述3.2 主要函数
(1)mirsys()
函数原型:miracl *mirsys(nd,nb)
参数类型:int nd,nb
功能:初始化MIRACL系统,该函数必须在调用MIRACL库函数之前先执行,函数的返回值是是一个miracl实例指针,通过它可以访问所有实例变量,如果没有足够的内存来创建实例,则为NULL
Eg: miracl *mip=mirsys(500,10);
意思是定义的这些变量最大长度都是500位(这个位是后面进制的位数),输入、输出、运算用的进制都是10进制。
(2)mirvar()
函数原型:flash mirvar(iv)
参数类型:int iv
功能:通过为big/flash变量保留适当数量的内存位置来初始化该变量。这个内存可以通过随后调用mirkill函数来释放, 在程序中,每个big型变量都必须赋初始值,否则会出错。
(3)cinnum()
函数原型:int cinnum(x,f)
参数类型:big x; FILE *f
功能:从键盘或文件中输入一个big类型变量,以实例变量IOBASE的当前值作为数。从键盘输入时,将f指定为stdin,否则指定为其他打开文件的描述符。
(4)cotnum()
函数原型:int cotnum(x,f)
参数类型:big/flash x;FILE *f
功能:将当前分配给实例变量IOBASE的值作为基数,输出一个big/flash的变量到屏幕或文件中参数一个big/flash x和一个文件描述符f。如果f是stdout,则输出到屏幕,否则输出到用描述符f打开的文件。

(5)egcd()
函数原型:int egcd(x,y,z)
参数类型:big x,y,z;
功能:用来计算两个大数的最大公约数, 即z=gcd(x,y)。
(6)mr_compare()
函数原型:int mr_compare(x,y)
参数类型:big x; big y
函数功能:比较两个大数的大小
返回值:x>y时返回+1, x=y时返回0, x<y时返回-1 在这里需要注意的是,mr_compare()函数比较的是两个big类型的数,此函数的返回值是int型的+1和-1。
(7)multiply()
函数原型:void multiply(x,y,z)
参数类型:big x,y,z
功能:计算两个大数的乘积,即z=x*y。
(8)xgcd()
函数原型:int xgcd(x,y,xd,yd,z)
参数类型: big x,y,xd,yd,z;
功能: 计算两个大数的扩展最大公约数,也可以用来计算模逆,这个函数比mad函数运算速度稍慢。z=gcd(x,y)=x.xd+y.yd,在此算法实现中,我选择此函数来进行模逆运算。
(9)add()
函数原型:void add(x,y,z)
参数类型:big x,y,z
功能:计算两个大数的和,即z=x+y。
(10)powmod()
函数原型:void powmod(x,y,z,w)
参数类型:big x,y,z,w;
功能:用来进行模幂运算,用表达式表示为w=x^y mod z。

3.3算法实现的代码

#include<stdlib.h>
#include "miracl.h"
#define MAXSIZE 100

int main()
{
	miracl *mip = mirsys(5000, 160); //初始化miracl系统
	mip->IOBASE = 10;
	FILE *fp;
	char fname[MAXSIZE];//存放文件名称的数组
	big a1, a2, a3, m1, m2, m3, e1, e2, e3, one, Ma, Mb, Mc, Ma1, Mb1, Mc1, fu, x, m;
	a1 = mirvar(0);//初始化参数
	a2 = mirvar(0);
	a3 = mirvar(0);
	m1 = mirvar(0);
	m2 = mirvar(0);
	m3 = mirvar(0);
	e1 = mirvar(0);
	e2 = mirvar(0);
	e3 = mirvar(0);
	one = mirvar(1);
	fu = mirvar(-1);
	x = mirvar(0);
	m = mirvar(0);
	Ma = mirvar(0);
	Mb = mirvar(0);
	Mc = mirvar(0);
	Ma1 = mirvar(0);
	Mb1= mirvar(0);
	Mc1= mirvar(0);
	printf("please input the path of file: ");
	scanf("%s", fname);
	fp = fopen(fname, "r+");
	if (fp == NULL)
	{
		printf("File open error!");
		return 0;
	}
	else
	{//读入数据
		cinnum(a1, fp);
		cinnum(a2, fp);
		cinnum(a3, fp);
		cinnum(m1, fp);
		cinnum(m2, fp);
		cinnum(m3, fp);
	}
	fclose(fp);
	//数字读取完毕,输出到屏幕上
	printf("a1 = "); 
	cotnum(a1, stdout);
	printf("a2 = ");
	cotnum(a2, stdout);
	printf("a3 = ");
	cotnum(a3, stdout);
	printf("m1 = ");
	cotnum(m1, stdout);
	printf("m2 = ");
	cotnum(m2, stdout);
	printf("m3 = ");
	cotnum(m3, stdout);
	//判断mi是否互素
	egcd(m1, m2, e1);//e1=gcd(m1,m2)
	egcd(m1, m3, e2);
	egcd(m2, m3, e3);
	if (mr_compare(e1, one) == 0 && mr_compare(e2, one) == 0 && mr_compare(e3, one) == 0)
	{
		//计算M1 M2 M3
		multiply(m2, m3, Ma);//Ma=m2*m3
		multiply(m1, m3, Mb);
		multiply(m1, m2, Mc);

		//计算M1^-1  M2^-1 M3^-1
		xgcd(Ma, m1, Ma1, Ma1, Ma1);
		xgcd(Mb, m2, Mb1, Mb1, Mb1);
		xgcd(Mc, m3, Mc1, Mc1, Mc1);

		//计算X=M1M1^-1a1+M2M2^-1a2+M3^-1a3
		multiply(Ma, Ma1, e1);//e1=Ma*Ma^-1
		multiply(e1, a1, e1);//e1=Ma*Ma^-1*a1

		multiply(Mb, Mb1, e2);//e1=Mb*Mb^-1
		multiply(e2, a2, e2);//e1=Mb*Mb^-1*a2

		multiply(Mc, Mc1, e3);//e1=Mc*Mc^-1
		multiply(e3, a3, e3);//e1=Mc*Mc^-1*a3

		add(e1, e2, x);//x=e1+e2
		add(x, e3, x);//x=e1+e2+e3

		multiply(m1, m2, m);
		multiply(m, m3, m);//m=m1*m2*m3
		powmod(x, one, m, x);//x = x的一次方 mod m

		printf("\nX = ");
		cotnum(x, stdout);
		printf("\nmod ");
		cotnum(m, stdout);
	}
	else
	{
		printf("\n(由于mi不互素)不能直接利用中国剩余定理!");
	}
	mirexit();// 清除MIRACL系统,释放所有内部变量
	return 0;
}  

数据分析

通过测试老师验收时所给的数据,来验证编写算法代码的正确性
在这里插入图片描述
在这里插入图片描述

通过多组实验数据验证,可以确定程序的正确性没有问题,在同余方程组有解时,可以将其对应的解x计算出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值