RSA 是一种经典的加密算法。它的基本加密过程如下。
首先生成两个质数 p,q 令 n=p⋅q 设 d 与(p-1) * (q-1) 互质,则可 找到 e 使得 d⋅e 除 (p−1)⋅(q−1) 的余数为 1.
n,d,e 组成了私钥,n,d 组成了公钥。
当使用公钥加密一个整数 X 时(小于 n ),计算 C=X^d mod n ,则 C 是加 密后的密文.
当收到密文 C 时,可使用私钥解开,计算公式为 X = C^e mod n.
例如,当 p=5,q=11,d=3 时,n=55,e=27.
若加密数字 24 ,得 24^3mod55=19 .
解密数字 19 ,得 19^27 mod 55=24.
现在你知道公钥中 n=1001733993063167141,d=212353.同时你截获了 别人发送的密文 C=20190324 请问,原文是多少?
题解:
只要求出e就可以算出原文。
先算出d,这个很好求。
让k=(p-1)*(q-1)。
然后由题推出:d*e=1(mod k).
d关于k的逆元就是e,所以题目转化为了求d的逆元。
由欧拉定理知,d的逆元为d^(ϕ(k)−1).
再根据公式X=C^e (modn) 求出.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fast_mul(ll p,ll q,ll mod){ //计算p*q
ll ret=0;
p%=mod; q%=mod;
while(q>0){
if(q&1)
ret=(ret+p)%mod;
q>>=1;
p=(p+p)%mod;
}
return ret;
}
ll pow_mod(ll a,ll p,ll mod){ //计算a^p
ll ret=1;
a%=mod;
while(p>0){
if(p&1)
ret=fast_mul(ret,a,mod);
p>>=1;
a=fast_mul(a,a,mod);
}
return ret;
}
ll euler_phi(ll n){
ll m=sqrt(n+0.5);
ll ans=n;
for(int i=2;i<=m;i++)
if(n%i==0){
ans=ans/i*(i-1);
while(n%i==0) n/=i;
}
if(n>1) ans=ans/n*(n-1);
return ans;
}
ll get_zhishu(ll x){
for(int i=2;i<=x;i++){
if(x%i==0)
return i;
}
}
int main(){
ll n=1001733993063167141;
ll d=212353;
ll C=20190324;
ll p=get_zhishu(n);
printf("p的值为%lld\n",p);
ll q=n/p;
printf("q的值为%lld\n",q);
ll k=(p-1)*(q-1);
printf("k的值为%lld\n",k);
ll ans=euler_phi(k);
printf("phi(k)的值为%lld\n",ans);
ll e=pow_mod(d,ans-1,k);
printf("e的值为%lld\n",e);
printf("C^e的值为%lld",pow_mod(C,e,n));
}