記信安實驗(一):Fermat 素性檢驗算法


前言:在密碼學中很多地方都需要素數,很多庫直接提供檢驗是否是素數的函數,該文章通過Fermat 素性檢驗算法實現素數檢驗(C語言)。

一、實驗內容

給定奇整數m大於等於3和安全參數k,判斷m是否為合數,或者有(1-1/2^k)概率為素數。

二、實驗環境

(1). Windows7

(2). VC ++ 6.0

(3). Miracl_5.5.4

三、實驗原理:

1.Fermat 小定理:給定素數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的概率為素數。

四、實驗涉及的相關函數

1. mirsys()

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

功能說明:初始化MIRACL系統

2. mirvar()

函數原型:flash mirvar(iv)

功能說明:通過為其保留適量的內存位置倆初始化大/閃存變量。

3. bigrand()

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

功能說明:產生一個小於w的大隨機數,x<w

4. egcd()

函數原型:int egcd(big x,big y,big z)

功能說明:計算兩個數的最大公約數,z=gcd(x,y)

5. powmod()

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

功能說明:模冥運算,w=x^y mod z

6. mirkill()

函數原型: void mirkill(x)

功能說明:通過將其歸零並釋放其內存來安全的殺死大/閃存數字。

7. compare()

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

功能說明:比較兩個數大小,x>y時返回+1,x=y時返回0,x<y時返回 -1。

五、算法步驟

Fermat素性檢驗算法:給定奇整數m>=3和安全參數k=6(這里我取6)

(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 #include"miracl.h"
 2 #include<stdio.h>
 3 int main (){
 4       FILE *fp;
 5       int i=0,k=4;
 6       big m,a,b,c,d,e;   //定義大整數變量
 7       miracl *mip=mirsys(10000,10); //初始化MIRACL系統,初始化10000位的十進制數
 8       mip->IOBASE=10;  //控制輸入輸出的進制,這里輸入和輸出變量使用的都是十進制
 9       m=mirvar(0);   //初始化大整數變量
10       a=mirvar(0);
11       b=mirvar(0);
12       c=mirvar(0);
13       d=mirvar(0);
14       e=mirvar(1);   //big 1
15       fp=fopen("驗收數據例子.txt","r"); //以讀的方式打開文件
16       if(fp==NULL){
17       printf("找不到指定文件,無法打開!");}
18       else
19       {
20       cinnum(m,fp);  //從文件中讀取大整數並放入大整數變量m中
21       fclose(fp);  
22       decr(m,1,b);    //大整數變量減去int型整數,這里相當於b=m-1
23       for (i=0;i<k;i++){       
24           while(compare(a,e)!=1)  // 產生一個小於b的大數隨機數a,並且使2<=a<=m-2
25           {bigrand(b,a);}  
26           egcd(a,m,d);   //計算兩個大數a和m的最大公約數d
27           if(!compare(d,e)){     //判斷d是否為1,即m和a是否互為質數,不等於1則跳出,判斷出m為合數
28               powmod(a,b,m,c);  //模冥運算,c=a^b mod(m)
29               if(!compare(c,e))   //判斷c是否等於1,不等於1則跳出,判斷出出m為合數
30               {
31                   if(i==(k-1))
32                   {printf("m有93.75%的可能性為素數!");}  //如果每次循環都得到可能是素數的結論,則最后打印出結果
33               }
34               else{printf("m為合數!");
35                     break;}
36     
37           }
38           else {printf("m為合數!");
39                  break;}
40       }
41       mirkill(m);  //釋放內存大數所占的內存
42       mirkill(a);
43       mirkill(b);
44       mirkill(c);
45       mirkill(d);
46       mirkill(e);
47       }
48       mirexit(); //清除MIRACL系統,釋放所有的內部變量
49       return 0;
50 }

注:其中需要在源文件和頭文件中加入miracl庫的相應文件。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM