(cequiv FLAG^{2^{30}+3} ~~ (mod~~n))
给定(c)和(n),(n)为两接近的素数乘积,求(FLAG)
(RSA):
- 寻找两个质数(p),(q),令(n=p*q)
- 计算欧拉函数(varphi(n)=(p-1)*(q-1))
- 寻找公钥(e),满足(1< e < varphi(n))且(e)与(n)互质
- 计算私钥(d),(e*dequiv 1 ~~ (mod ~~ varphi(n)))
若(c)为密文,(m)为明文
加密:(c=m^e ~ mod ~ n)
解密:(m=c^d ~ mod ~ n)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mul(ll u, ll v, ll p) {
return (u * v - ll((long double)u * v / p) * p + p) % p;
}
ll qpow(ll x, ll y, ll mod) {
ll ans = 1;
for (; y; y >>= 1, x = mul(x, x, mod))
if (y & 1) ans = mul(ans, x, mod);
return ans;
}
ll extend_gcd(ll a, ll b, ll &x, ll &y) {
if (a == 0 && b == 0) return -1;
if (!b) {
x = 1, y = 0;
return a;
}
ll d = extend_gcd(b, a % b, y, x);
y -= a / b * x;
return d;
}
ll inv(ll a, ll n) {
ll x, y;
ll d = extend_gcd(a, n, x, y);
if (d == 1) return (x % n + n) % n;
return -1;
}
int main() {
int t;
ll n, c;
scanf("%d", &t);
for (int _ = 1; _ <= t; _++) {
scanf("%lld%lld", &n, &c);
ll qn = sqrt(n), q, p;
while (1) {
if (n % qn == 0) {
q = qn;
p = n / q;
break;
}
qn--;
}
ll phi = (q - 1) * (p - 1);
ll d = inv(1073741827ll, phi);
printf("Case %d: %lld
", _, qpow(c, d, n));
}
return 0;
}