蓝桥杯 2019 RSA加密 (快速幂 快速乘 欧拉定理 乘法逆)

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));	
	
} 


 

发布了57 篇原创文章 · 获赞 58 · 访问量 606

猜你喜欢

转载自blog.csdn.net/weixin_43568895/article/details/103980462