素数测试算法是中间较快的一种,则N通过自由数A的测试

【SinGuLaRiTy-1003】 Copyright (c) SinGuLaRiTy 2017. All Rights
Reserved.

【SinGuLaRiTy-1003】 Copyright SinGuLaRiTy 2017. All Rights Reserved.

姓名:李浩然

背景

数论学家利用费马小定理研商出了两种素数测试方法,Miller-Rabbin
素数测试算法是里面较快的一种。

背景

数论学家利用费马小定理研讨出了多样素数测试办法,Miller-Rabbin
素数测试算法是内部较快的一种。

学号:16030410020

步骤

(1)总括奇数M,使得N=2^r * M + 1;

(2)选择随机数A<N;

(3)对于任意i<r,若A^(2^i*M) mod N = N – 1,则N通过自由数A的测试;

(4)或然,若A^M mod N = 1,则N通过自由数A的测试;

(5)让A取不一致的值对N举行行数十次测试(一般须求5~11遍,有较高需要的话能够进行20~贰十九次),若一切透过则判定N为素数;

步骤

总结奇数M,使得N=2^r * M + 1;

选择随机数A<N;

对此任意i<r,若A^ mod N = N – 1,则N通过任意数A的测试;

恐怕,若A^M mod N = 1,则N通过任意数A的测试;

让A取分裂的值对N举办行多次测试(一般须求5~1柒回,有较高须要的话能够进行20~26遍),若一切透过则判定N为素数;

转自:http://blog.csdn.net/Dreaming\_My\_Dreams/article/details/48469269(有删改)

概率

若N通过1遍测试,则N不是素数的可能率为25%;

若N通过 t 次测试,则N不是素数的可能率为1/( 4 ^ t );

实际,当 t = 5 时,N不是素数的可能率已为1/128,已经超(Jing Chao)越99.99%。

在实际应用中,可首先用300~500个小素数对N实行测试,以增加测试通过的可能率与算法的快慢。在肆意生成的素数中,选用的随机数最棒让
r = 0,则足以省去手续(3)的操作,进一步压缩判定时间。

概率

若N通过一遍测试,则N不是素数的可能率为1/4;

若N通过 t 次测试,则N不是素数的可能率为1/;

实则,当 t = 5 时,N不是素数的票房价值已为1/128,已经不止99.99%。

在骨子里运用中,可率先用300~500个小素数对N进行测试,以增强测试通过的可能率与算法的速度。在随心所欲变化的素数中,选取的随机数最棒让
r = 0,则足以省去手续的操作,进一步削减判定时间。

【嵌牛导读】:福睿斯SA是现阶段最有影响力和最常用的公钥加密算法,它亦可对抗到近年来停止已知的多数密码攻击,已被ISO推荐为公钥数据加密标准。Montgomery(Montgomery)幂模运算是非常快总括a^b%k的一种算法,是福睿斯SA加密算法的主导之一。明日,借助那篇文章,让我们了然一下那二种算法

代码

#include<cstdlib>
#include<ctime>
#include<cstdio>
using namespace std;
const int count=10;
int modular_exp(int a,int m,int n)
{
    if(m==0)
        return 1;
    if(m==1)
        return (a%n);
    long long w=modular_exp(a,m/2,n);
    w=w*w%n;
    if(m&1)
        w=w*a%n;
    return w;
} 
bool Miller_Rabin(int n)
{
    if(n==2)
        return true;
    for(int i=0;i<count;i++)
    {
        int a=rand()%(n-2)+2;
        if(modular_exp(a,n,n)!=a)
            return false;
    }
    return true;
}
int main()
{
    srand(time(NULL));
    int n;
    scanf("%d",&n);
    if(Miller_Rabin(n))
        printf("Probably a prime.");
    else
        printf("A composite.");
    printf("\n");
    return 0;
}

 

Time:2017-02-07

代码

#include<cstdlib>#include<ctime>#include<cstdio>using namespace std;const int count=10;int modular_exp(int a,int m,int n){    if(m==0)        return 1;    if(m==1)        return (a%n);    long long w=modular_exp(a,m/2,n);    w=w*w%n;    if(m&1)        w=w*a%n;    return w;} bool Miller_Rabin(int n){    if(n==2)        return true;    for(int i=0;i<count;i++)    {        int a=rand()%(n-2)+2;        if(modular_exp!=a)            return false;    }    return true;}int main(){    srand(time;    int n;    scanf("%d",&n);    if(Miller_Rabin        printf("Probably a prime.");    else        printf("A composite.");    printf("\n");    return 0;}

Time:2017-02-07

【嵌牛鼻子】:非对称秘钥、欧几里得方程、模幂运算、移位操作

【嵌牛提问】:路虎极光SA算法原理是怎么?蒙哥马利算法?那三种算法是怎么落到实处的?他们都有何样好处?

【嵌牛正文】:RSA应用

LacrosseSA首要用来PKI身份验证系统,详细说有数字证书、数字签名、数字签章、数字水印、数字信封等。近期最贴近生活的有的案例如:银行的u盾、银行卡的刷卡机、Tmall和12306的数字证书。别的未来乘机电子商务电子行政事务的铺开,登陆认证权限管理进一步贴近生活,PAJEROSA的空间特别大。

RSA 原理:

挑选七个不等的大素数p、q,并盘算N=p*q,选取小素数d,并总结e,使d*e %
(p-1)(q-1)=1,

对此任意A

若B=A**d % N

则A=B**e % N

可知d、e形成了非对称秘钥关系,加密者用公钥d加密,解密者可用私钥e解密,第二者固然拦截了密文B、公钥d和N,在不知道p、q的前提下,不能够推算出e,从而不可能赢得明文A。当N取一点都不小的值时,将其因式分解成p、q是万分拮据的,例如当N为1024
bit时,据分析,需利用价值数千万法郎的巨型电脑种类并费用一年的时日。

HavalSA 密钥的选拔和加解密进程都不行简单,在算法上海重机厂中之主要贯彻三个难题:

① 、怎么样处理大数运算

二 、如何求解同余方程 XY % M = 1

③ 、怎么着快捷实行模幂运算

四 、怎么样赢得大素数

实际上,在实现HighlanderSA
算法的进度中山大学家会发现后多少个难点不是各自独立的,它们互有关联,环环相套,相信届时你会发觉到:奥迪Q7SA算法是一种“精粹”的算法!

时局存款和储蓄:

大切诺基SA 正视庆大学数运算,近期主流福特ExplorerSA
算法都建立在102几人的气数运算之上。而当先六分之三的编写翻译器只可以协助到六15位的整数运算,即大家在运算中所使用的平头必须低于等于六拾几人,即:0xffffffffffffffff,相当于18446744073709551615,那远远达不到TucsonSA
的内需,于是必要特地建立大数运算库来化解这一题材。

最简便的法门是将时局当作数组实行拍卖,数组的各因素相当于天机每一位上的数字,经常选用最不难了然的十进制数字0—9。然后对“数字数组”编写加减乘除函数。不过那样做功能异常的低,因为二进制为10十八位的大数在十进制下也有三百多位,对于别的一种运算,都须求在五个有数百个因素的数组空间上屡次重循环,还要许多额外的上空存放计算的进退位标志及中等结果。其余,对于有些特殊的演算而言,选择二进制会使计量进程大大简化,而那种大数表示方法转化成二进制显明十三分辛勤,所以在一些实例中则索性选拔了二进制数组的艺术来记录大数,当然如此效能就更低了。

二个实惠的更正措施是将时局表示为三个n 进制数组,对于近年来的3一个人系统而言n
能够取值为2 的二十八次方,即 0x一千00000,假使将八个二进制为10贰十五人的命局

倒车成0x10000000进制,就变成了三十三位,而每壹人的取值范围不再是二进制的0—1或十进制的0—9,而是0-0xffffffff,我们恰好能够用三个30位的DWOGL450D
(如:无符号长整数,unsigned long)
类型来表示该值。所以1024人的天数就变成三个含有36个因素的
DWORD数组,而针对
DWO途观D数组进行各样运算所需的巡回规模至多三十一遍而已。而且0x一千00000
进制与二进制,对于电脑来说,大概是二遍事,转换万分不难。

比如说大数18446744073709551615,等于 0xffffffff
ffffffff,就一定于十进制的99:有两位,每位都以0xffffffff。而18446744073709551616等于0x0000000100000000 00000000,就一定于十进制的100:有4个人,第三位是1
,其余两位都是0
,如此等等。在实际上接纳中,“数字数组”的排列顺序采纳低位在前高位在后的点子,那样,大数A
就足以一本万利地用数学表明式来表示其值:

A=Sum[i=0 to n](A[i]*r**i),r=0x100000000,0<=A

任何整数运算最终都能分解成数字与数字之间的运算,在0x一千00000
进制下其“数字”最大达到0xffffffff,其数字与数字之间的运算,结果也势必超过了当下33个人系统的字长。在VC++中,存在三个__int64
类型能够拍卖陆拾个人的整数,所以不要担心这一题材,而在任何编写翻译系统中就算不存在63个人整形,就须求选拔更小的

进制格局来囤积大数,例如十三人的WOTiguanD类型能够用来代表0x一千0
进制。但功效更高的措施依然使用三十人的 DWO揽胜D类型,只不过将0x一千00000
进制改成0x五千0000进制,那样七个数字进行四则运算的最大结果为 0x3fffffff
*
0x3fffffff,小于0xffffffffffffff,能够用二个双精度浮点类型(double,51人有效数字)来存款和储蓄这一中级结果,只是无法大约地用高位低位来将中间结果拆分成三个“数字”。

时局加减乘除:

存在大数A、B和C,个中A>=B:

A=Sum[i=0 to p](A[i]*r**i)

B=Sum[i=0 to q](B[i]*r**i)

C=Sum[i=0 to n](C[i]*r**i)

r=0x100000000(32位),0<=A[i],B[i],C[i]=q(A[i],B[i],C[i]都是32位的数)

则当C=A+B、C=A-B、C=A*B时,大家都能够透过总计出C来获得C:

1.加法

C=A+B,显然C[i]不两次三番等于A[i]+B[i],因为A[i]+B[i]可能>0xffffffff,而C[i]必须<=0xffffffff,那时就须求进位,当然在总计C[i-1]时也或然发生了进位,所以总计C[i]时还要加上上次的进位值。假诺用贰个61个人变量result来记录和(六十五位是为乘法准备的,实际加减法只要3二个人即可),另3个三15位变量carry来记录进位(为啥要三九人?为乘法准备的,实际加减法进位唯有1),则有:

carry=0;

for(i=0;i<=p;i++) {//i从0到p 因为A>B

result=A[i]+B[i]+carry;

C[i]=result%0x一千00000 ;//从此间看result应该高于六十八个人,至少陆13个人

carry=result/0x100000000;

if(carry=0) n=p;

else n=p+1;

2.减法

C=A-B,同理C[i]不总是等于A[i]-B[i],因为A[i]-B[i]可能<0,而C[i]务必>=0,那时就须求借位,同样在计算C[i-1]时也可能发生了借位,所以计算C时还要减去上次的借位值:

carry=0

for(i=0;i<=p;i++) {//i从0到p 因为A>B

if((A[i]-B[i]-carry)>=0){

C[i]=A[i]-B[i]-carry;

carry=0;

}

else{

C[i]=0x100000000+A[i]-B[i]-carry;

carry=1;

}

}

n=p;

while (C[n]==0) n=n-1;//将眼下的0去掉

3.乘法

C=A*B,首先大家需求考察平时做乘法所用的“竖式总计”进程:

A3 A2 A1 A0

* B2 B1 B0


= A3B0 A2B0 A1B0 A0B0

+ A3B1 A2B1 A1B1 A0B1

+ A3B2 A2B2 A1B2 A0B2


=        C5     C4     C3    C2    C1     C0

能够综合出:C[i]=Sum[j=0 to
q](A[i-j]*B[j])(注意是C[i]),其中i-j必须>=0且<=p。

自然这一定论没有设想进位,即便总计A[i-j]*B[j]和Sum的时候都或然发生进位,分明那两种原因爆发的进位能够添加成二个进位值。最终可用如下算法完结乘法:

C = Sum[i= 0 to n](C[i]*r**i) =  Sum[i= 0 to n] ( Sum[j=0 to
q](A[i-j]*B[j]) 
*r**i).(那里的n=p+q-1,但当第n位的演算有进位时n应加1)

C也能够表示成 C= Sum[i= 0 to q](A*B[i] *r**i)

n=p+q-1

carry=0

for(i=0;i<=n;i++){

result=carry;

for(j=0;j<=q;j++){

if (0<=i-j<=p ){

result=result+A[i-j]*B[j];

C[i]=result%0x100000000;

carry=result/0x100000000;

}

}

}

if(carry!=0) {

n=n+1;

C[n]=carry

}

4.除法

对此C=A/B,由于不可能将B
对A“试商”,大家只好转换来B[q]对A[p]的试商来赢得一个好像值,所以不能直接通过总计C来博取C,只可以一步步逼近C。由于:

B*(A[p]/B[q]-1)*0x100000000**(p-q)

令:X=0,重复A=A-X*B,X=X+(A[p]/B[q]-1)*0x100000000**(p-q),(为什么?)直到A

则:X=A/B,且此时的A=A%B

留意对于自由大数A*0x100000000**k,都等价于将A 的数组中的各因素左移k
位,

不必总计;同样,A/0x一千00000**k则等价于右移。

欧几里得方程:

在哈弗SA 算法中,往往要在已知A、N的状态下,求 B,使得
(A*B)%N=1。即一对一于求解B、M都以未知数的二元1次不定方程 A*B-N*M=1
的微乎其微整数解。

而针对不定方程ax-by=c
的纤维整数解,古今中外都实行过详尽的钻研,西方有资深的欧几Reade算法,即辗转相除法,中华人民共和国有秦九韶的“大衍求一术”。事实上二元一回不定方程有整数解的充要条件是c为a、b的最大公约数。即当c=1时,a、b必须互质。而在EvoqueSA算法里由于公钥d为素数,素数与其它正整数互质,所以能够通

过欧几Reade方程来求解私钥e。

欧几Reade算法是一种递归算法,比较易于通晓:

例如:11x-49y=1,求x

(a) 11 x – 49 y = 1 49%11=5 ->

(b) 11 x – 5 y = 1 11%5 =1 ->

(c) x – 5 y = 1

令y=0 代入(c)得x=1

令x=1 代入(b)得y=2

令y=2 代入(a)得x=9

同理可选取递归算法求得任意
ax-by=1(a、b互质)的解。实际上通过分析归结将递归算法转换到非递归算法就改成了大衍求一术:

x=0,y=1

WHILE a!=0

i=y

y=x-y*a/b

x=i

i=a

a=b%a

b=i

IF x<0 x=x+b

RETURN x

模幂运算

模幂运算是LX570SA 的主干算法,最直白地决定了卡宴SA
算法的个性。针对高速模幂运算这一课题,西方现代地工学家建议了汪洋的缓解方案,日常都以先将幂模运算转化为乘模运算。

例如求D=C**15 % N,由于:a*b % n = (a % n)*(b % n) % n,所以:

C1 =C*C % N =C**2 % N

C2 =C1*C % N =C**3 % N

C3 =C2*C2 % N =C**6 % N

C4 =C3*C % N =C**7 % N

C5 =C4*C4 % N =C**14 % N

C6 =C5*C % N =C**15 % N

即:对于E=15的幂模运算可表明为四个乘模运算,总结分析以上措施能够窥见对于任意E,都可应用以下算法总括D=C**E
% N:

D=1

WHILE E>=0

IF E%2=0

C=C*C % N

E=E/2

ELSE

D=D*C % N

E=E-1

RETURN D

接轨分析会发现,要驾驭E 什么日期能整除
2,并不需求反复进行减一或除二的操作,只需验证E 的二进制各位是0 如故1
就足以了,从左至右或从右至左验证都足以,从左至右会更简短,设E=Sum[i=0
to n](E*2**i),0<=E<=1,则:

D=1

FOR i=n TO 0

D=D*D % N

IF E[i]=1 D=D*C % N

RETURN D

那样,模幂运算就转化成了一八种的模乘运算。

模乘运算

对此乘模运算 A*B%N,假设A、B都以102四个人的时局,先总计A*B,再%
N,就会时有发生20四十五个人的高级中学级结果,假如不使用动态内存分配技术就必须将命局定义中的数组空间增添一倍,那样会造成多量的浪费,因为在多数景况下不会用到那额外的一倍空间,而利用动态内存分配技术会使大数存款和储蓄失去三番五次性而使运算进度中的循

环操作变得特别繁琐。所以模乘运算的重点标准就是要幸免间接总结A*B。

设A=Sum[i=0 to k](A[i]*r**i),r=0x10000000,0<=A

C = A*B = Sum[i=0 to n](A*B*r**i) (应该为Sum[i= 0 to n] (
Sum[j=0 to q](A[i-j]*B[j])  *r**i),其中n=p+q-1)

可以用多少个循环来处理:

C=0;

FOR i=n to 0

C=C*r

C=C+A*B//A*B应该是Sum[j=0 to
q](A[i-j]*B[j]) 与上述的时局乘法实质是千篇一律的。

RETURN C

那般将贰个多位乘法转换来了一二种单位乘法和加法,由于:

a*b %n = (a%n * b%n) %n

a+b %n = (a%n + b%n) %n

所以,对于求C=A*B %N,大家完全能够在求C的经过中形成:

C=0;

FOR i=n to 0

C=C*r %N

C=C+A*B %N//A*B应该是Sum[j=0 to q](A[i-j]*B[j])

RETURN C

这样产生的最大中间结果是A*B
或C*r,都不当先1056(1024+32)位,空间代价会小得多,可是日子代价却加大了,因为求模的经过由一回成为了频仍。对于孤立的乘模运算而言那种时间换空间的贸易照旧值得的,可是对于频仍循环的乘模运算,那种代价就不也许经受,必须另寻出路。

Montgomery模乘要化解的题材:

{注:蒙哥马利模乘实际上是赶尽杀绝了这么1个难题,即不利用除法(用移动操作)而求得模乘运算的结果。时刻放在心上是模运算而且是命局运算的功底上的。例如:借使进制
奔驰G级=10  四个数(大数表示)23 =2*10^1+3*10^0  若求 23 * 10^-k  mod 5的值 
不选用乘法 大家能够动用上面包车型地铁法子 便是将 23+5*q 这时不影响模运算的结果
当23+5*q 是10的翻番时
就足以用运动操作除以10,一般k的值取23(大数)的位数(在进制兰德酷路泽的底子上)一向移位,最终剩下三个超过模5
小于2*5的数  在减去2个5 正是终极的结果了。那样求出的是23 * 10^-k mod
5 的结果,大家想求23 mod 5的结果只须求先将23*10^k mod 5 = Z即可  在去求
z*10^-k mod 5 即可 。其他进制同理。

•Montgomery约减表达式: Mon =(S+qM)/Sportage =
(S+qM)*1/君越  (S为 当中S表示被归约数,M表示模数,CR-V =
2^n(二进制情状下),n表示钦命0的个数。)。S+qM实际表示模M的S所在的剩余类的全数数•看做剩余类的运算:M(S)*M(1)
= M(S)*M(R)*M(R^(-1))所以Mon mod M = S*奔驰M级^(-1) mod M    
(所以想求S*凯雷德^(-1) mod M的值能够用Mon mod
M来测算,找到q使得S+qM是奥迪Q5的倍数,那样被除数就是整数了)•蒙哥马利乘法:Z
= X*Y*福特Explorer^(-1) mod
M•(奥迪Q7与M要互素,当汉兰达是2^n时,M是奇数即可)}Montgomery模乘器可用硬件达成,在合营软件达成PRADOSA运算,以加速运算速度。

Montgomery模乘(下列表述不是很不难驾驭,可以参考上边的注)

由于PRADOSA 的着力算法是模幂运算,模幂运算又一定于模乘运算的轮回,要拉长陆风X8SA
算法的频率,首要难题在于进步模乘运算的功用。不难发现,模乘进度中复杂度最高的环节是求模运算,因为壹回除法实际上包括了累累加法、减法和乘法,借使在算法中能够尽量减弱除法甚至幸免除法,则算法的功能会大大升高。

设A=Sum[i=0 to k](A[i]*2**i),0<=A<=1,则:

C= A*B = Sum[i=0 to k](A*B*2**i)//B应该是B=Sum[i=0 to
k](B[i]*2**i),0<=B<=1;C= A*B = Sum[i=0 to
k](A*B[i]*2**i)

可用循环处理为:

C=0

FOR i FROM k TO 0

C=C*2

C=C+A*B       //此处应为C=C+A*B[i]

RETURN C

若令 C’= A*B *2**(-k)则:{C’= C*2**(-k)=A*B *2**(-k)=Sum[i=0
to k](A*B[i]*2**(i-k)),}

C’= Sum[i=0 to k](A*B*2**(i-k))

用循环处理即:

C’=0

FOR i FROM 0 TO k

C’=C’+A*B

C’=C’/2

RETURN C’

通过这一算法求A*B*2**(-k)是不纯粹的,因为在循环中年老年是除以2都只怕有余数被放任了,然则足以经过这一算法求A*B*2**(-k)
%N的规范值,方法是在对C’除

2之前,让C’加上C'[0]*N。由于在LacrosseSA中N是八个素数的积,总是奇数,所以当C’是奇数时,C'[0]=1,C’+C'[0]*N
就是偶数,而当C’为偶数时C'[0]=0,C’+C'[0]*N仍旧偶数,这样C’/2
就不会有余数被扬弃。又因为C’+N %N = C’
%N,所以在总结进度中加多少次N,并不会影响结果的科学。能够将算法整理如下:

C’=0

FOR i FROM 0 TO k

C’=C’+A*B

C’=C’+C'[0]*N

C’=C’/2

IF C’>=N C’=C’-N

RETURN C’

由于在XC90SA中A、B总是小于N,又0<=A,C'[0]<=1,所以:

C’ = (C’+A*B+C'[0]*N)/2

C’ < (C’+2N)/2

2C’ < C’+2N

C’ < 2N

既然C’总是小于2N,所以求C’ %N
就可以很简单地在收尾循环后用叁回减法来成功,即在求A*B*2**(-k)
%N的长河中不要反复求模,达到了笔者们幸免做除法的目

的。当然,这一算法求得的是A*B*2**(-k) %N,而不是大家最初必要的A*B
%N。可是利用A*B*2**(-k)大家同样能够求得A**E %N。

设R=2**k %N,R’=2**(-k) %N,E=Sum[i=0 to n](E[i]*2**i):

A’=A*PRADO %N//这一步是怎么求的?

X=A’

FOR i FROM n TO 0

X=X*X*R’ %N

IF E[i]=1 X=X*A’*R’ %N

X=X*1*R’ %N

RETURN X

最初:

X = A*R %N,

千帆竞发循环时:

X = X*X*R’ %N

= A*R*A*R*R’ %N

= A**2*R %N

反复循环之后:

X = A**E*R %N

最后:

X = X*1*R’ %N

= A**E*R*R’ %N

= A**E %N

那般,大家最后实现了不含除法的模幂算法,这正是响当当的Montgomery算法,而X*Y*奥迪Q5′
%N 则被誉为“Montgomery模乘”。以上商量的是Montgomery模乘最简便,最容

易精通的二进制方式。Montgomery算法的核情感想在于将求A*B
%N转化为不须求频仍取模的A*B*RAV4′
%N,(移位即可,因为ENVISION是2^K,总之安德拉是与进制相关的数),但是使用二进制算法求10贰16位的A*B*Odyssey’
%N,供给循环102五次之多,小编么必然希望找到更实惠的总结A*B*R’ %N的算法。

考虑将A表示为随意的r进制:

A = Sum[i=0 to k](A*r**i) 0<=A<=r

咱俩须要获得的Montgomery乘积为:

C’= A*B*R’ %N R’=r**(-k)

则以下算法只好获得C’的近似值

C’=0

FOR i FROM 0 TO k

C’=C’+A*B

C’=C’/r

IF C’>=N C’=C’-N

RETURN C’

因为在循环中年老年是C’=C’/r 时,都恐怕有余数被放任。借使大家能够找到三个系数q,使得(C’ + A*B + q*N) %r =0,并将算法修改为:

C’=0

FOR i FROM 0 TO k

C’=C’+A*B+q*N

C’=C’/r

IF C’>=N C’=C’-N

RETURN C’

则C’的最后重临值正是A*B*Sportage’ %N的纯正值,所以关键在于求q。由于:

(C’ + A*B + q*N) %r =0

==> (C’ %r + A*B %r + q*N %r) %r =0

==> (C'[0] + A*B[0] + q*N[0]) %r =0

若令N[0]*N[0]’ %r =1,q=(C'[0]+A*B[0])*(r-N[0]’) %r,则:

(C'[0] + A*B[0] + q*N[0]) %r

= (C'[0]+A*B[0] – (C'[0]+A*B[0])*N[0]’*N[0]) %r) %r

= 0

于是乎大家得以得出r为任何值的Montgomery算法:

m=r-N[0]’

C’=0

FOR i FROM 0 TO k

q=(C'[0]+A*B[0])*m %r

C’=(C’+A*B+q*N)/r

IF C’>=N C’=C’-N

RETURN C’

若果令 r=0x一千00000,则 %r 和 /r
运算都会变得万分容易,在102贰位的运算中,循环次数k
不高于32,整个运算进程中最大的中等变量C’=(C’+A*B+q*N)

< 2*r*N < 10五二十位,算法效能就相当高了。唯一的额外负担是索要计算N[0]’,使N[0]*N[0]’ %r
=1,而这一难点前面已经用欧几Reade算法化解过了,而且在模幂运算转化成反复模乘运算时,N是固定值,所以N[0]’只必要总结贰回,负担并极小。

素数测试方法

数论学家利用费马小定理钻探出了多样素数测试方法,最近最快的算法是拉宾Miller测试算法,其经过如下:

(1)总括奇数M,使得N=(2**r)*M+1

(2)选择随机数A

(3)对于任意i

(4)或者,若A**M % N = 1,则N通过任意数A的测试

(5)让A取分化的值对N进行四回测试,若一切因此则判定N为素数

若N 通过3次测试,则N 不是素数的可能率为 四分一,若N 通过t 次测试,则N
不是素数的可能率为四分之一**t。事实上取t 为5 时,N 不是素数的可能率为 1/128,N
为素数的可能率已经超(英文名:jīng chāo)越99.99%。

在实质上采纳中,可率先用300—500个小素数对N
实行测试,以拉长拉宾Miller测试通过的票房价值,从而提升总体育项目测验试速度。而在变化随机素数时,选拔的随机数最佳让r=0,则可省去手续(3)
的测试,进一步提升测试速度。

素数测试是PRADOSA
选用秘钥的率先步,奇妙的是其主干运算与加解密时所需的运算完全一致:都是模幂运算。而模幂运算进程中中所须求解的欧几Reade方程又恰恰

多亏选拔密钥第2步所用的演算。可知整个大切诺基SA 算法具有一种一体化的和谐。