对于RSA算法的一些理解

……来自 @百度作业帮
RSA中,e*d=1(mod(p-1)(q-1))中为什么是mod(p-1)(q-1)而不是mod pq ?

答:
用a表示加密前的信息,b表示加密后的信息,c表示用另一对密钥解密后所得的信息,那么:
对明文加密后得b≡a^e mod(p*q);

然后再用另一对密钥解密b得c≡b^d≡(a^e)^d=a^(e*d) mod(p*q);

现在还是不能确定是否有a=c,即a^(e*d)≡ a mod(p*q)(解密后得信息与加密前的一样)

但是如果我们让e*d=1 mod(p-1)(q-1); 即 e*d = k(p-1)(q-1)+1;

那么c≡a^(e*d)=a^(k(p-1)(q-1)+1) ≡ a mod(p*q);

(根据欧拉定理:a^((p-1)(q-1))≡1 mod(p*q))

在限制0≤ a,c<p*q的情况下,a=c

如果a不与p*q互素,也有相同的结论.
//上面所说 就是在 e*d=1 mod(p-1)(q-1)时,使得 a^(e*d)≡ a mod(p*q)

//
下面是来自 @宫藏嘉辈 类似的证明,可能看起来更清晰些
http://www.cnblogs.com/zhtxwd/archive/2012/02/09/2344154.html

RSA定理证明:

定理:设p,q是不同的素数,n=pq记φ(n)=(p-1)(q-1),如果e,d是与φ(n)互素 的两个正整数(e,d<φ(n)),
并满足 ed≡1(mod φ(n)), 则对于每个整数x,都有x^ed≡x(mod n)。

分析:为了证明x^ed≡x(mod n),只要证明φ(n)是x^ed-x的因数即可。又因为n=pq,而p,q都是素数,
故只要证明p和q都是xed-x的因数即可,即

x^ed≡x(mod p) (1)

x^ed≡x(mod q) (2)

证明:证明式1,若p是x的因数则式1必然成立

若p不是x的因数,则由ed≡1(mod φ(n))得ed-1=k(p-1)(q-1),k为任意整数。

则x^ed=x^(k(p-1)(q-1)+1) = x * (x^(p-1))^k(q-1)

根据费马小定理因为x与p互素所以x^(p-1) ≡1(mod p)

所以x^ed≡x * 1^k(q-1) ≡x(mod p)

同理可证x^ed≡x(mod q)

例题:
题解来自 @芋智波佐助
http://blog.csdn.net/u011686226/article/details/38960211

URAL 1141. RSA Attack
题意:给你e n c 并且有m^e = c(mod n) 求 m
思路: RSA算法

过程大致是
1.发送的信息是m
2.随机选择两个质数 p和q, n = q*p, n的欧拉函数值φ(n)= (p-1)*(q-1)
3.选择一个与φ(n)互质的并且小于φ(n)的数e, 计算c = m^e(mod n)
4.发送c
5解密 求e的逆元d 逆元就是2个数乘一下在mod一个数等于1 这里就是e*d = 1(mod φ(n))
(求逆元用扩展欧几里德)
6.计算c^d(mod n) 就是m

下面是我自己写的:(其实还是套的模板QAQ)

//URAL 1141
//Time: 15MS
//Memory: 652 KB

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long int LL;
const int MAXN =  32010;

int phi[MAXN],prime[MAXN],cnt_p;
int flag_p[MAXN];
//线性欧拉函数
void getphi()
{
   cnt_p = 0;

   memset(flag_p,0,sizeof(flag_p)); //0为素数
   flag_p[0] = 1;
   flag_p[1] = 1;

   phi[0] = 0;
   phi[1] = 0;//???

   for(int i=2; i<MAXN; ++i)
   {//cout<<"xxx"<<endl;
       if(!flag_p[i]) { prime[cnt_p++] = i; phi[i] = i-1; }

       for(int j=0; j<cnt_p && i*prime[j]<MAXN; ++j)
       {
           flag_p[i*prime[j]] = 1;

           if(!(i%prime[j])) { phi[i*prime[j]] = phi[i]*prime[j]; break;}
             else phi[i*prime[j]] = phi[i]*(prime[j]-1);  //若p为素数,则pih[p] = p-1;

       }
   }
   return ;
}

//快速幂
LL quike_mod(LL a,LL b,LL M)
{
    LL ans = 1;
    while(b)
    {
     if(b&1)
     {
        ans = (ans*a)%M;
        --b;
     }
    b = b/2;
    a = ((a%M)*(a%M))%M;

    }

 return ans;
}

//扩展欧几里得
LL ex_gcd(LL a,LL b,LL &x,LL &y)
{
    if(b==0)
    {
        x = 1;
        y = 0;
        //return ;
        return a;
    }

    //LL ans = ex_gcd(b,a%b,x,y);
    LL ans = ex_gcd(b,a%b,x,y);
    LL temp = x;
    x = y;
    y = temp - (a/b) * y;
    return ans;  ///ans是最大公约数
}

//求方程解,逆元等...
//方程:  a*x + b*y = c
LL niyuan(LL a,LL b,LL c)
{
    LL x,y;
    LL gcd=ex_gcd(a,b,x,y);
    if(c%gcd!=0) return -1;
    x*=c/gcd;
    b/=gcd;
    if(b<0) b=-b;
    LL ans=x%b;
    if(ans<=0) ans+=b;
    return ans;
}

int main()
{
    //ss();
    getphi();   ///因为 n=p*q, 且p,q都是素数;那么n的欧拉函数 = (p-1)*(q-1);

    LL e,n,c;
    int T;
    scanf("%d",&T);
    while(T--)
    {
       scanf("%I64d%I64d%I64d",&e,&n,&c);

    //e关于对phi[n]取模的逆元
       LL d = niyuan(e, phi[n], 1);
       LL m = quike_mod(c, d, n);

       printf("%lld\n",m);

    }

    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值