! Pollard-Rho - CQOI2016密钥破解

学习博客


此题主要是将N分解成p*q,使用Pollard-Rho算法

我的理解并不是很深入,还有加油

把测试样本在模N的意义下乘起来,再对N做gcd,为了避免在环上停留太久,每127次就做一次gcd

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
	while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
	return f==1?x:-x;
}
#define ll __int128
int gcd(int x,int y){
	return y==0?x:gcd(y,x%y);
}
inline int ksm(int x,int r,int mod){
	int ret=1;
	for(int i=0;(1ll<<i)<=r;i++){
		if((r>>i)&1)ret=(ll)ret*x%mod;
		x=(ll)x*x%mod;
	}
	return ret;
}
inline bool MR(int x,int p){
	int k=x-1,cur;
	while(k){
		cur=ksm(p,k,x);
		if(cur!=1&&cur!=x-1)return 0;
		if((k&1)||cur==x-1)return 1;
		k>>=1;
	}
	return 1;
}
inline bool prime(int x){
	if(x==46856248255981ll||x<2)return 0;
	if(x==2||x==3||x==7||x==61||x==24251)return 1;
	return MR(x,2)&&MR(x,61);
}
inline int f(int x,int c,int mod){
	return ((ll)x*x+c)%mod;
} 
inline int PR(int x){
	for(int w=1,val,s,t=0,c=rand()%(x-1)+1,d;;w<<=1){
		s=t;val=1;
		for(int i=1;i<=w;i++){
			t=f(t,c,x);
			val=(ll)val*abs(t-s)%x;
			if(i%127==0){
				d=gcd(val,x);
				if(d>1)return d;
			}
		}
		d=gcd(val,x);
		if(d>1)return d;
	}
}
void exgcd(int a,int b,int &x,int &y){
	if(!b){x=1;y=0;return;}
	exgcd(b,a%b,x,y);
	int t=y;y=x-a/b*y;x=t;
}
signed main(){
	srand(time(0));
	int e,n,c,p,r,d;
	e=read();n=read();c=read();
	p=PR(n);
	r=(p-1)*(n/p-1);
	exgcd(e,r,d,p);
	d=(d%r+r)%r;
	n=ksm(c,d,n);
	cout<<d<<" "<<n<<"\n";
	return (0-0);
}

猜你喜欢

转载自www.cnblogs.com/aurora2004/p/12572267.html