现代密码学实验4 Miller-Rabin算法

赞赏码 & 联系方式 & 个人闲话

【实验名称】Miller-Rabin算法

 

【实验目的】

1、理解Miller-Rabin算法的数学原理;

2、通过实验掌握Miller-Rabin素数判定的算法。

 

【实验原理】

Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重要的地位。

基本原理:令n表示一个整数,假设存在整数x和y满足x2 ≡ y2(mod n),但x≠ ±y(mod n),那么n是合数。而且gcd(x-y,n)给出了n的一个非平凡因子。

Miller-Rabin素数判定: (n-1=2km,m为奇数),如果对所有的r∈[0,k-1],若am mod n≠1且a^(2^r m) mod n≠-1,则n是合数。

现代密码学实验4 Miller-Rabin算法_第1张图片

【实验内容】

实验内容: 编程实现Miller-Rabin素数判定算法,并判断23456789是否是素数?

代码:(代码解释见代码中注释)

//现代密码学实验4  Miller_Rabin算法
#include
#include 
#include 
#include
#define LL long long

//幂次运算,含模运算,防止溢出
LL My_Pow(LL a, LL m, LL input)
{
	LL result = 1;
	for (int i = 0; i < m; i++)
	{
		result = (result*a) % input;
	}
	return result;
}

//Miller_Rabin算法
int Miller_Rabin(LL input)
{
	if (input == 2 || input == 3)
	{
		//2、3特判为素数
		return 1;
	}
	else if (input % 2 == 0 || input == 1)
	{
		//偶数和1特判为非素数
		return -1;
	}
	else
	{
		int ji = 0;
		LL b;
		LL m = input - 1;
		//计算k,即ji
		while (m % 2 == 0)
		{
			m = m / 2;
			ji++;
		}
		srand(time(NULL));
		LL a = 0;
		//随机取a
		while (a <= 1)
		{
			a = rand() % (input - 1);
		}
		b = My_Pow(a, m, input);
		//若b0=1或-1
		if (b == 1 || b == input - 1)
		{
			return 1;
		}
		else
		{
			double r = 0;
			for (r = 0;; )
			{
				//循环直到r

运行演示:

现代密码学实验4 Miller-Rabin算法_第2张图片

 

【小结或讨论】

这次算法比起上次的AES可以说是简单很多了,只是完成RSA算法的一部分——用于素数判断的Miller-Rabin算法。这次的实验让我重新认识了素数判定,原本我只知道那种遍历到基础算法,没想到还可以根据费马小定理来进行这种概率性素数判断,感到十分新鲜。

坦诚地说,虽然算法并不复杂,但是其背后的数学原理确实是有些晦涩难懂的。书中在这提出了一个新的“基本定理”和信息安全数学基础中的“费马小定理”,并把其结合成Miller-Rabin素数判定算法。这一块书上写的的解释和证明,我觉得略微简略了一点,看起来比较费劲,特别是第一个b0和第二个b1的mod n的结果判断比较难懂,两者一个都用了费马小定理,另一个“1”时用的是基本定理、“-1”时用的是费马小定理。但是只要把解释看懂了,整个算法也就比较明白了。

看懂了后,在算法实现的过程中我觉得还有两个小坑吧。一个当然就是幂次运算的溢出,由于C语言的模运算%限制必须要是整型,而整型最大的就是long long型,这对于大数幂次运算是远远不够的,所以我自己写了个My_Pow幂次运算,每次乘法都mod n这样就能解决溢出问题;其次还有一个就是算法中mod运算结果-1应该是n-1,因为按My_Pow算的话保持数是正数,那么在模运算中-1也就等于n-1了,这是我觉得要注意的两点。

你可能感兴趣的:(现代密码学)