RSA加密解密的核心--快速幂取模算法原理

RSA的加密规则:m^e≡c(mod n),即c=m^e%n

RSA的解密规则:c^d≡m(mod n),即m=c^d%n

其中:m为明文,c为密文,ed≡1(mod φ(n)),(n,e)构成公钥,(n,d)构成私钥

撇除密钥的生成,RSA加密解密的核心就一个:快速幂取模算法

快速幂取模算法类似于快速幂算法,但要复杂一点。

//递归法
function quick1($a, $b, $c)
{
    if($b==1) return $a % $c;
    $temp = quick1($a, $b>>1, $c);
    return ($b&1)==0?($temp*$temp)%$c:($temp*$temp*$a)%$c;
}

//蒙哥马利法
function quick2($a, $b, $c)
{
    $ans = 1;
    $a = $a % $c;
    while($b != 0)
    {
        if(($b & 1) ==1)
        {
            $ans = ($ans * $a) % $c;
        }
        $b>>=1;
        $a = ($a * $a) % $c;
    }
    return $ans;
}

算法原理

先了解两条模运算性质:

  • 递归法原理

当b为偶数时:


当b为奇数时

经过以上推导,高次幂的求模降为低次幂的求模了,而降幂的规律,不管b的奇偶,刚好符合二进制移位,并且最终都会降到易于求解的1次幂,即a mod c。

  • 蒙哥马利法原理(递推)

b可用以下二进制形式表示

那么

结合前面模的积运算性质,则有

又令

则有

bn只有0、1两个取值,所以

再令

则有

综上所述:An为所求目标,可通过An-1递推求得,递推中还需Kn,而Kn和bn有关,当bn=0,Kn=1;当bn=1,Kn=Tn,Tn也可以通过Tn-1递推求得。

递推初始条件

这里之所以是T1而非T0,是因为T0无实际意义,而且需要开方,不方便计算。至于改变后迭代的变化参看后面的代码。

下面看代码

int quick(int a,int b,int c) 
{
    //An,初始值A0
    int A=1;
    //Tn,初始值T1
    T=a%c;
    while(b!=0) 
    { 
        //这个if是判断目前最右边的一位bn是不是1
        //如果是1,那么Kn=Tn直接用Tn递推,具体看上面原理
        //如果是0,那么Kn=1,考虑到An-1是小于c的,所以An = (An-1*Kn)%c = An-1,就是说可以不用更新An了
        if(b&1) {
            A = ( A * T ) % c;
        }
        //二进制位移,再结合if条件的位与运算,相当于从右到左读取位b1 b2 b3 b4等等       
        b>>=1;
        //更新Tn,供下一轮计算An使用
        //本来应该在An之前计算的,但由于初始值是T1开始的,所以先用再算
        //因为b的二进制的任何位置是都有可能为1的,所以我们需要一直计算Tn,不能放到if里面
        //另外观察代码可知,局部变量a只在第二行处用到,为减少空间分配,文章开头及网上的一些实现方法,用a替换了T
        T=(T*T)%c;
    }   
    return A;
}

 

参考文章:https://blog.csdn.net/qq_36760780/article/details/80092665

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值