信息安全基础综合实验总共包含有二大块的内容,分为小组作业(小组作业有四项任务,为Fermat素性检验算法、中国剩余定理、密钥分配以及SM3的实现)和个人作业(SM2加密算法的实现),我也会分别通过五篇博客来分别记录。先进行小组作业,等把小组作业的四次做完之后,就可以对Miracl库的使用基本上掌握了。

俗话说的好,要做实验,肯定要先搭建环境,环境两小时,实验五分钟。而实验所需要的环境就是把miracl库添加进来即可。首先编译miracl包,参加我同学W的这个博客:https://blog.csdn.net/Baron_wu/article/details/83151473,里面讲述了如何生成所需要的miracl.lib,如果搞不定的话,那就来问我索取吧(邮箱联系308904186@qq.com);得到了这个包之后,那环境就算是完成了90%了,下面是在Visual Studio中调用此库即可,过程可以继续参考我这个同学W的另外一篇博客:https://blog.csdn.net/Baron_wu/article/details/83177251。通过这两个步骤后,就可以很开心的去编程吧!顺便感谢一下这个同学W,为什么他的出镜率这么高呢,因为我们两个是一组的,当时为了能够成功地调用Miracl库也是费了一番心思。

那下面就切入正题,看看如何通过Miracl库来实现Fermat素性检验算法。因为这是第一篇的博客嘛,除了对Fermat素性检验的介绍之外,对于一些Miracl库中的函数也会有一个很简单的介绍。

一、实验目的

在前面的四次小实验中,对我们的考察难度不是很大,四个小实验对我们提出来的要求是,通过完成验证四个定理的过程,让我们能够相比较才学习信息安全数学基础与现代密码学时,能更加详细的了解关于这四个定理的内容。第一次的实验是使用Fermat素性检验算法(这是一个概率性算法),来判断从文本文件中输入进去的大整数是不是一个素数。在平时我们接触到的C语言结构中,最大的表示数值是unsigned int型数据,其最大可以表示数据,也就是八个字节的大小,即使是这样,对于我们信息安全实验来说,这样的数据类型长度是远远不够的。在实验中,我们需要用到miracl函数库,它定义了两种新的数据类型——表示大整数的big类型和表示有理数的flash(short for floating-slash)类型。通过本次实验,可以让我们熟悉miracl库中的一些基本操作函数,将Fermat素性检验算法在实验中展示出来。

二、方案设计

2.1 Fermat素性检验

也就是说,要判断一个奇整数是不是素数(如果这个数是偶数那肯定就不是素数了),我们可以通过随机选取同m互为质数的一个整数a(如果m和a不互质的话,那么m也肯定不是素数),判断m和a是否满足费马小定理,如果满足的话,m就会以不低于的概率是一个素数。对于这个定理的证明,我也去网上查找了相关的资料,但是依旧对这个定理的证明不是特别的了解,等到以后能力提升再来读懂此定理的证明,也不在报告里附上此定理的证明了。

下面是Fermat素性检验算法的步骤,这儿我用一张图来阐明Fermat素性检验算法的原理:

2.2 关于Fermat素性检验算法单身的背景以及Carmichael数

人们自然会想,如果考虑了所有小于n的底数a,出错的概率是否就可以降到0呢?没想到的是,居然就有这样的合数,它可以通过所有a的测试。第一个发现这样极端的伪素数,他把它们称作Carmichael数。你一定会以为这样的数一定很大。错。第一个Carmichael数小得惊人,仅仅是一个三位数,561。前10亿个自然数中Carmichael数也有600个之多。Carmichael数的存在说明,我们还需要继续加强素性判断的算法。

比如说,1105就是一个Carmichael数,对于用Fermat素性检验算法来判断1105(十六进制下表示是451)是不是质数,得出的结果是1105能够以98.4375的概率成为一个素数。所以这点很直观的体现出了Fermat素性检验是一个概率性算法。

三、方案实现

3.1算法流程图

3.2 主要函数的介绍

   引入了miracl库后,其中定义了两种新的数据类型——表示大整数的big类型和表示有理数的flash(short for floating-slash)类型,因此随之也引入了能够操作big类型和flash类型的操作函数。整体上来说,完成实验所需要的语言是C语言,但是在其中一些关键地方的操作上,我们需要使用库中自己定义的函数,将这些函数的功能了解后,基本上写出Fermat素性检验算法就没有什么问题了。在miracl_5.5.4中,附带着一个manual.doc文件供我们参考,里面有所有函数的定义以及如何使用等,这个文件对于我们了解如何使用miracl库有非常重要的作用。

3.2.1 mirsys()

函数原型: miracl *mirsys(int nd, int nb);

功能说明: 初始化当前程序线程的MIRACL系统,如下所述,必须在尝试使用任何其他MIRACL例程之前调用:

(1)初始化错误跟踪机制。

(2)从nd和nb计算用于每个大/闪存号的计算机字数。

(3)初始化了16个大的工作变量(其中4个为双倍长度)。

(4)某些实例变量被赋予默认初始值。

(5)通过调用irand(0L)启动随机数发生器。

这个函数的返回值是是一个miracl实例指针,通过它可以访问所有实例变量,如果没有足够的内存来创建实例,则为NULL。

操作实例是miracl *mip=mirsys(500,10),意思是我定义的这些变量最大长度都是500位(这个位是后面进制的位数),输入、输出、运算用的进制都是10进制。

3.2.2 实例变量IOBASE

IOBASE是用于控制输入和输出的进制问题的,可以在程序中随意更改, 必须大于或等于2且小于或等于256。使用实例是像这样的:mip->IOBASE=16,这样子输入的变量和输出的变量所使用的进制都是十六进制。

3.2.3 mirvar()

函数原型:flash mirvar(iv)

功能说明:通过为其保留适当数量的内存位置来初始化大/闪存变量,可以通过对函数mirkill()的后续调用来释放该存储器。并且在程序中,每个big型变量都必须赋初始值,否则会出错。

例如上面的这段代码是用来演示没有初始化big型变量带来的错误,如果没有初始化变量,在compile和build阶段系统都会告诉我们没有警告,没有错误,但是一旦执行可执行文件后,系统就会崩溃。出错信息如下:

3.2.4 decr()

函数原型:void decr(x,n,z)

big x,z;

int n;

这个函数实现的功能是对一个big型的变量x减去一个int型的值后得出的big型数据,例如我们在Fermat素性检验算法中,产生的随机数范围在2至m-2中,如果我们需要得出m-2的话,有两种途径:第一,如果将减去的2视作为int类型的话,直接相减是不可行的,相当于是big型减去int型,需要用到这个函数,即decr(m,2,y),返回的结果是big y=m-2;第二,如果将2作为大数来看待的话,就需要先用negify()函数取2的复数,再使用add()函数得到m-2的结果。

3.2.5 bigrand()&bigdig()

函数原型: void bigrand(big w, big x);

功能说明: 使用内置的随机数发生器,产生一个小于w的大数随机数,x<w

函数原型: void bigdig(int n, int b, big x);

功能说明: 产生一个指定长度的进制的随机数,该函数使用内置的随机数发生器,初始化种子调用irand函数。

这两个函数都是可以生成随机数的,但是它们的功能确实略有差异的。bigrand()是产生一个小于w的大数随机数,x<w,如果w是一个十位的十进制数,那么x可能是一个十位的十进制数,只有九位的十进制数,也可能使只有一位的十进制数;bigdig()是产生一个指定长度的进制的随机数,比如说指定了产生一个十位的十进制数,那么这个函数就会严格的产生一个十位的十进制数。

上面的截图是我测试的bigdig()这个函数,为了验证这个函数是产生一个指定长度的进制的随机数,我在这里只让它生成二位十进制数,并且循环随机生成一千次(这种情况下,从概率角度来说,0-100这些数每个数出现的次数都能平均在10次左右),从输出的结果中看,只会产生10-99这个区间内的数,不会产生01、05这样的一位十进制数,证明了bigdig()只会产生指定长度的进制的随机数。

下面的截图是我测试的bigrand()这个函数的功能,和上面测试的原理是一样的,在这次的输出结果中,可以看到不仅仅有二位十进制数字,还有一位十进制数字,证明了bigrand()是产生一个小于给定数值的大数随机数。

在Fermat素性检验算法中,每轮的算法使用到的底数a是在2至m-2这些数中随机选取一个数作为底数,然后进行下面的算法,因此,在每轮中随机选取出的随机数必须是表现出完全的随机性。因此对于随机函数的选择是十分有必要的,在这里我选择的是bigrand()。

3.2.6 compare()

函数原型: int compare(big x, big y);

功能说明: 比较两个大数的大小。

返回值: x>y时返回+1, x=y时返回0, x<y时返回-1。在这里需要注意的是,compare()函数比较的是两个big类型的数,此函数的返回值是int型的+1和-1。

3.2.7 egcd()

函数原型:   int egcd(bigx, big y, big z);

功能说明:计算两个大数的最大公约数,z=gcd(x,y)。

3.2.8 powmod()

函数原型: void powmod(big x, big y,big z, big w);

功能说明: 模幂运算。

3.2.9 mirkill()

函数原型:void mirkill(x)      big x;

功能说明:通过将其归零并释放其内存来安全地杀死大/闪存数字。

3.2.10 mirexit()

函数原型: void mirexit();

功能说明: 清除MIRACL系统,释放所有内部变量。

3.3 算法实现的主要代码

#include "miracl.h"
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define round 6
int Fermatjdu_prime(big obj);
main()
{FILE *fp;big obj;miracl *mip = mirsys(1500, 16);//定义的这些变量最大长度都是5000位(这个位是后面进制的位数),输入、输出、运算用的进制都是16进制。mip->IOBASE = 16;obj=mirvar(0);   //初始化变量obj,obj是输入的需要判断是否为素数的大数if((fp=fopen("data.txt","r+"))==NULL){printf("Open the file failure...\n");exit(0);} //判断文件是否能够正确打开while(!feof(fp)){    //检测文件结束符cinnum(obj, fp); //从文件中读取一个数字进入,并将其强制转化为十六进制表的大数objcotnum(obj, stdout); //向屏幕上输出一个大数objif (Fermatjdu_prime(obj))printf("This number has a %6.4f%% probability of being a prime number.\n", 100 * (1 - pow(0.5, round)));elseprintf("This number is 100%% definitely a Composite number! \n");}fclose(fp);mirkill(obj);  //释放大数obj所占用的空间mirexit();     //清楚miracl系统
}int Fermatjdu_prime(big obj)
{
big radn,trans,mgcd,trans1,r,num1,num2,cons;
int i,j;
miracl *mip = mirsys(1500, 16);
mip->IOBASE=16;
radn=mirvar(0);//对函数中使用到的big型变量进行初始化
trans=mirvar(0);
mgcd=mirvar(0);
trans1=mirvar(0);
r=mirvar(0);
num1=mirvar(1);
num2=mirvar(2);
cons=mirvar(0);
i=0;
j=0;
decr(obj,2,trans);    //trans=obj-2
decr(obj,1,trans1);   //trans=obj-1
srand((unsigned int)time(NULL));
for(i=0;i<round;i++)
{bigrand(obj,radn); //生成所需要的随机数egcd(radn,obj,mgcd);  //计算obj和生成的随机数的最大公因数if(!compare(mgcd,num1))  //判断obj和随机数是否互素,它们的最大公因数如果不是1的话,compare函数将会返回1,不满足条件{powmod(radn,trans1,obj,r);  //计算 ,如果r=1,则obj可能是素数,进入下一个if语句if(!compare(r,num1))  j++  //j是判断因子,如果一个数能够满足在当前的轮数下,满足上述的算法,则j能够计数;如果j不等于轮数,那么这个数就不是素数;}
}if(j==round)return 1;else return 0;mirkill(obj);
mirkill(radn);
mirkill(trans);
mirkill(trans1);
mirkill(r);
mirkill(mgcd);
}

四、数据分析

在这部分的数据分析时,还未给老师验收,这部分测试的数据是我自己生成的数。这些数据是我借鉴的一个同学用python脚本写出来的,生成的时候是按一个合数一个素数进行生成的,用写成的算法跑了一下之后,和预期是一样的,用Fermat素性检验算法能够把里面所有的合数都检测出来,里面所有的素数都能够以概率98.4375%确定(轮数是六轮,当然这些数都是自己生成的素数,所以可以判断写出的程序没有问题)。

此外,在查阅资料的过程中,有这样的一种数的存在,即Carmichael数,我用自己的程序也跑了一下,确实这种数对于Fermat素性检验算法来说无法识别。

五、总结

在本次上机实验中,主要需要我们解决的问题有两个方面:一方面是实验环境的搭建,另外一方面是对miracl库中的函数需要一定的熟悉度。我们组在环境的搭建上采用了两条路线,一条是Win10系统+编译器是Visual Studio,另外一条的环境就是和实验室一样的Win7系统+编译器是Visual C++ 6.0。最初拿到实验任务,首先想到的肯定是网上搜索一翻资料看看如何配置这样的环境,在网上看到的一个比较靠谱的教程是叫我们将miracl.h、mirdef.h以及ms32.lib添加到工程下面,miracl.h、mirdef.h这两个文件直接可以在/include文件夹下找到,但是找不到ms32.lib这个链接库,所以我们就去CSDN上下载了一个别人编译过的链接库,但是装入到工程下面后,经过一些简单的调试却出错:告诉我们连接不到这个库,所以从网上下载的ms32.lib是不完善的库。所以我们决定自己编译一下静态链接库。

信息安全基础综合实验之Fermat素性检验算法(通过调用miracl大数库来实现)相关推荐

  1. c语言编fermat素数检验,记信安实验(一):Fermat 素性检验算法

    前言:在密码学中很多地方都需要素数,很多库直接提供检验是否是素数的函数,该文章通过Fermat 素性检验算法实现素数检验(C语言). 一.实验内容 给定奇整数m大于等于3和安全参数k,判断m是否为合数 ...

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

    最近没有什么事情,打算把之前的作业整理一下发出来,有需要的学弟学妹们可以参考一下. 相关:某电的密码学实验,信安专业必选实验 实验题目:中国剩余定理 实验目的 (包括实验环境.实现目标等等) 实验环境 ...

  3. 武汉理工大学计算机网,武汉理工大学计算机基础综合实验

    [实例简介] 武汉理工大学软件工程专业计算机基础综合实验(c实验),计费管理系统.基本功能加部分扩展功能实现,经过验收合格. [实例截图] [核心代码] 计算机基础综合实验 └── AMS ├── A ...

  4. 网络工程师课程---7、网络通信综合实验(做网络基础综合实验 用什么软件)...

    网络工程师课程---7.网络通信综合实验(做网络基础综合实验 用什么软件) 一.总结 一句话总结: cisco packet ['pækɪt]  tracer ['treɪsə] packet 英 [ ...

  5. 素数一套:Miller-Rabin 素性检验算法Pollard-Rho算法线性筛——Upside down primesDivisions

    部分目录 Solved 94 / 304 K Gym 100753K Upside down primes 高效判断素数 快速幂取模 继续 Miller-Rabin 素性检验算法 Unsolved 6 ...

  6. 初等数论--同余--Fermat素性检测算法(为什么每次概率改变1/2)

    初等数论--同余--Fermat素性检测算法(为什么每次概率改变1/2) 为什么每次概率改变1/2 博主是初学初等数论(整除+同余+原根),本意是想整理一些较难理解的定理.算法,加深记忆也方便日后查找 ...

  7. 计算机基础综合实验项目报告模板,计算机基础实验报告模板.doc

    实验项目名称 Windows 基本操作 实验日期 实验目的 1. 掌握Windows系统中鼠标.键盘的使用 2. 掌握Windows系统桌面.窗口.对话框.菜单等基本操作 3. 了解Windows文件 ...

  8. 计算机科学基础word实验一,大学计算机基础综合实验实验报告 参考模板(1)

    马克思主义认识论中的实践观 教 学 设 计 [教学目的与要求] 让学生了解与掌握什么问题,提高对什么问题的认识,有什 ... 2017届一轮复习 字音字形训练(全国) 1.下列各组词语中加点字的读音, ...

  9. 初等数论--同余--MILLER-RABIN素性检测算法优化

    初等数论--同余--MILLER-RABIN素性检测算法优化 Euler theorem.Fermat's little theorem Primality Test: Fermat.MILLER-R ...

最新文章

  1. 微软发布企业安全进度报告 云应用安全服务即将面世
  2. 6. Git 开启匿名访问
  3. 萤石云官方Demo下载并二次开发 QT5.12.10
  4. 企业运维实践-Nginx使用geoip2模块并利用MaxMind的GeoIP2数据库实现处理不同国家或城市的访问最佳实践指南...
  5. C++ Opencv安装学习笔记
  6. 天池比赛二手车预测Task2-数据分析
  7. 汇编中 rep指令 和 stos指令ollydbg图解
  8. ARM芯片学习内容规划及ARM开发环境的搭建
  9. 网线传输速度测试_千兆网络的速度测试
  10. npm学习(十七)之node_modules中的bin文件夹
  11. feign 实现签名、服务地址动态切换
  12. 计算机毕业设计ssm基于微信的的高校起床协会管理61rmm系统+程序+源码+lw+远程部署
  13. 国产28nm制程光刻机突破在即,助力国产芯片
  14. 工厂模式--大侠,您要预定金疮药还是黑玉断续膏?
  15. 【作用域、自由变量】
  16. Python爬取豆瓣短评
  17. python 课后习题:项目二数据分析之《冰与火之歌》全五卷人物关系图
  18. 适合小白的PPT基本操作
  19. ps人像精修教程——去除皱纹
  20. Android so库文件的区节section修复代码分析

热门文章

  1. 小P学区块链(一):区块链到底是什么?该如何去学习
  2. 软工实践第六次作业——团队选题报告
  3. NPDP产品经理认证:产品创新的六种类型
  4. 巨头扎堆的人脸识别红海市场,新玩家如何破局?
  5. 请描述计算机硬件故障检测工具的使用,电脑硬件故障检测工具(SyvirPC) v3.00免费版...
  6. 蓝牙室内定位技术方案有什么优势?
  7. 2021-3-26 米斯特安全团队视频笔记二(含PHP)
  8. 一步一个脚印,QAD助力CAPP走出信息化进阶之路
  9. 开发周期节省50%以上!EasyV数字孪生技术赋能区域综合能源数智“大脑”建设
  10. YY:真的猛公司 敢动腾讯的奶酪