蓝桥杯rsa解密

需要知识点

快速乘、快速加、扩展欧几里得原理

模板

快速乘

ll qkc(ll a,ll b){
	ll ans = 0;
	while(b)
	{
		if(b&1) ans = (ans+a)%n;
		a=(a+a)%n;
		b /=2;
	}
	return ans;
}

快速幂

ll qkm(ll a,ll b){
	ll ans = 1;
	while(b)
	{
		if(b&1) ans =qkc(ans,a);
		a = qkc(a,a);
		b/=2;
	}
	return ans;
}

扩展欧几里德

ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(!b)
	{
		x=1,y=0;
		return a;
	}
	ll d = exgcd(b,a%b,y,x);
	y -= a/b*x;
	return d;
}

解题

题目
题目没有限制是那两个素数,所以硬筛两个p,q即可,令b = (q-1)*(p-1)
已知b,a(即d) 可得方程 de mod b = 1 => de -k*b = 1;
用扩展欧几里得可求二元一次方程的可行解,可求得e = x,k = y
x可能小于0,用b余一下e = (x+b)%b,这样才能用于指数
结果即是c的e次方余n
题解代码

//by InsiApple
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i,n,m) for(int i=(n);i<=(m);i++)
#define per(i,n,m) for(int i=(m);i>=(n);i--)
#define all(a) a.begin(), a.end()
#define pw(x) (1ll<<(x))
#define endl "\n"
#define Mod 100000000
const int N = 1e6+10;
ll n=1001733993063167141;
ll d=212353;
ll C=20190324;
ll p,q,e;
	
ll qkc(ll a,ll b){
	ll ans = 0;
	while(b)
	{
		if(b&1) ans = (ans+a)%n;
		a=(a+a)%n;
		b /=2;
	}
	return ans;
}
ll qkm(ll a,ll b){
	ll ans = 1;
	while(b)
	{
		if(b&1) ans =qkc(ans,a);
		a = qkc(a,a);
		b/=2;
	}
	return ans;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
	if(!b)
	{
		x=1,y=0;
		return a;
	}
	ll d = exgcd(b,a%b,y,x);
	y -= a/b*x;
	return d;
}




int main(){
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    for(q = 2;q<n;q++)
		if(n%q==0){
			p = n/q;
			break;
			
		}
	ll k = (p-1)*(q-1);
	ll x,y;
		exgcd(d,(p-1)*(q-1),x,y);
		q = (p-1)*(q-1);
		x = (x+q)%q;
		//cout<<x<<endl;
		cout<<qkm(C,x);
	
	
    return 0;
}
posted @ 2022-03-13 20:54  InsiApple  阅读(98)  评论(0编辑  收藏  举报