Fermat素性检验算法

文章目录

  • 题目
  • 环境
  • 方案设计
    • 背景
    • 原理
    • 算法步骤
  • 方案实现
    • 流程图
    • 主要函数
    • 代码
      • C语言
      • python
    • 测试用例
    • 注意问题
  • 说明

题目

给定奇整数m≥3和安全参数k=5,判断m是否为合数或有1-1/2^k 概率为素数。

环境

Windows10,MinGW-W64-builds-4.3.5,miracl 7.0.1

方案设计

背景

Fermat 小定理

原理

  1. 给定素数p,a∈Z,则有a(p-1)≡1(mod p);
  2. 奇整数m,若任取一整数2≤a≤m-2,(a,m)= 1,使得a(m-1)≡1 (mod m),则m至少有1/2的概率为素数。

算法步骤

给定奇整数m≥3和安全参数k=5
(1) 随机选取整数a,2≤a≤m-2
(2) 计算g=(a, m),如果g =1,转(3);否则,跳出,m为合数
(3) 计算r =a(m-1)(mod m),如果r=1,m可能是素数,转(1);否则,跳出,m为合数
(4) 重复上述过程k次,如果每次得到m可能为素数,则m为素数的概率为 1 − 1 2 k 1- \frac1{2^k} 12k1

方案实现

流程图

Fermat素性检验算法_第1张图片

主要函数

  • bigrand(big w, big x),产生一个小于w的随机数x
  • powmod(big x, big y, big z, big w) 求w =x^y(mod z)
  • egcd(big x, big y, big z)求最x, y大公约数z=gcd(x, y)
  • compare(a, b),如果a>b,函数返回值为1;如果a=b,函数返回值为0;如果a

代码

C语言

#include"miracl.h"
#include

int main(){
	FILE *fp;
    int i=0;
    //m_4=m-4;a is a random number and 2<=a
    big m,r,g,a,b,m_4;

    miracl *mip = mirsys(4000,10);
    
    m = mirvar(0);
	m_4 = mirvar(0);
    r = mirvar(0);
    g = mirvar(0);
    a = mirvar(0);

    b = mirvar(1);//big 1
	
    
    fp = fopen("data.txt", "r+");
    mip->IOBASE = 10;

    cinnum(m, fp);
    fclose(fp);
/*
	if(isprime(m)){
		printf("x\n");
	}
*/
    for(i=0;i<5;i++){
        //make sure 2<=a
		decr(m, 4, m_4);//m_4=m-4
        bigrand(m_4, a);
		incr(a, 2, a);//a=a+2

        decr(m, 1, g);//g=m-1
        powmod(a, g, m, r);
        egcd(a, m, g);
		//b=1
        if(mr_compare(g, b)||mr_compare(b, r)){
            break;
        }
    }
    cotnum(m, stdout);
	i==5?puts("INPUT number is prime\n"):puts("INPUT number is NOT prime\n");

    mirexit();
    return 0;
}

python

#求两个数的最大公约数
def gcd(a,b):
    if b==0: return a
    else: return gcd(b, a%b)
#素性检验
def is_prime(num, k=7):
    for _ in range(k):
        a=random.randrange(2,num-2)
        if gcd(a, num)!=1:
            return False
        if pow(a,num-1,num)!=1:
            return False
    return True

测试用例

100位长大素数

2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550077

大素数网站中有10到100 位数的大素数。

注意问题

(1)算法要求随机数2≤a≤m-2,所以产生随机数a的时候,先用bigrand(a,m-4)产生一个数a,使得0≤a≤m-4,然后再把加2,得到2≤a≤m-2。
(2)大数需要用compare()函数比较大小,不能直接用a==b。

说明

课程作业,仅作记录

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