大二下学期选修了密码学,学了公钥密码,刚好碰到这个题,就写个博客记录一下
RSA算法介绍:
两个大素数p,q (保密的,选定的)
n=p*q (n是公开的)
Φ(n)=(p−1)(q−1) (即 ,欧拉函数:小于n且与n互素的数的个数)
e满足gcd( Φ(n),e )=1; (1<e<Φ(n)) ,就是e与Φ(n)互质。
d*e≡1(mod Φ(n)),即d和e的积模 Φ(n)余1 ( d是e模 Φ(n)的乘法逆元,扩展欧几里得算法可求 );
私钥为{d,n},公钥为{e,n}
(RSA是非对称加密算法,基于大数分解,n一般而言有1024~2048比特,当然就这道题而言只是熟悉一下流程,n不会那么大,但是计算中间过程还是爆 long long ,具体代码见下方)
加密:
密文:C=M^e(mod n) ,
明文:M=C^d(mod n) ,
下面举个简单的例子:
p=3,q=11,e=7,明文M=5,求密文?
解:
n=p*q=3*11=33
Φ(n)=(3-1)*(11-1)=20
7*d=1(mod 20),所以d可以为3
私钥={3,20},公钥={7,20}
密文C=5^7(mod 33)=14
(转换为明文验证:M=14^3 (mod 33)=5,正确)
题目大意:
n=p*q
p,q为素数
d与(p-1)*(q-1)互素
(d*e)%((p-1)*(q-1))=1
c=x^d%n
x=c^e%n
给定d,c,n
求x
用素数筛求出p,q ;再用欧几里得验证是否满足互素条件,快速幂直接乘会爆longlong,所以要用快速乘+快速幂
Python代码如下:
p=891234941
q=1123984201
n=1001733993063167141
c=20190324
d=212353
for i in range(1,500000): #枚举因子 d*e%((p-1)*(q-1))=1 (((q-1)*(p-1))*yz+1) %d =0
if(((p-1)*(q-1)*i+1)%d==0):
e=((p-1)*(q-1)*i+1)//212353
print(((p-1)*(q-1)*i+1)//d)
break
def quick_mod(a,b,c):
a=a%c
ans=1
while b!=0:
if b&1:
ans=(ans*a)%c
b>>=1
a=(a*a)%c
return ans
x=quick_mod(c,e,n) #x=c^e%n 579706994112328949
print(x)
print(quick_mod(x,d,n)) #c=x^d%n
c++解法可以看我的另一篇博客:
https://blog.csdn.net/weixin_43107805/article/details/89525061