q = getMyPrime(256)
n = p*q
e = 65537
m = bytes_to_long(flag)
c = pow(m, e, n)
print(f’n = {n}‘)
print(f’e = {e}’)
print(f’c = {c}')
‘’’
n = 53763529836257082401813045869248978487210852880716446938539970599235060144454914000042178896730979463959004404421520555831136502171902051936080825853063287829
e = 65537
c = 50368170865606429432907125510556310647510431461588875539696416879298699197677994843344925466156992948241894107250131926237473102312181031875514294014181272618
‘’’
1.random模块中的choice()函数用于在一个序列(列表,元组或字符串中随机选择一个元素并返回
2.sieve_base是由前10000的素数组成的列表,里面最大的数是104729,是在Crypto.Util.number中
那么现在的问题就是如何分解n,使用工具果然分不开,好吧不会了,搜索了一下(搜索引擎是强大的),看了一下网上的wp
这是一道p-1光滑题
光滑数:一个数n可以被分解为若干小质数的乘积,则称n为光滑数。
B-Smooth数**😗*若一个光滑数中最大的质数因子 <= B, 则称其为B-Smooth数。
即 n = ,则称n是b−Smooth数
(p1,p2,……,pn两两互不相同)
利用的是费马小定理:
若b为一个素数,则任意一个与b互质的整数a,有a^(b-1) mod b ≡ 1
拓展结论:a ^k(b-1) mod b ≡1(k为正整数)
推导:
a ^k(b-1) mod b
=(a^(b-1) )^k mod b
=(a^(b-1) mod b * a^(b-1) mod b *……*a^(b-1) mod b) mod b
总共k个
=1
那么对于这道题:
(p-1)和(q-1)都是sieve_base列表中若干个素数的乘积,即**(p-1)和(q-1)均为光滑数**
那么p-1=p1*p2*…*pn
设有一个B,使其满足p-1=p1*p2*…*pn,pn<=B,则p-1是B-Smooth数
由质因数分解的原理:任何一个正整数N都可以表示为质数因子的乘积,即因数分解的意思
有:B!=1*2*3*…*p1…*pn*…=k*p1*p2*…*pn=k*(p-1)
那么由费马定理有:a ^ k*(p-1)≡1 mod p 即 a ^ B! =1 mod p 即 a ^ B! -1≡ k*p
那么很显然 a ^ B! - 1 是 p 的倍数
因为n= p * q ,那么很显然n也是p的倍数
则gcd(2 ^ B! - 1 , n) = p,就可以求到p
而B!是不知道的,于是递推计算
解密代码:
from Crypto.Util.number import *
from gmpy2 import *
from bytes import *
n = 53763529836257082401813045869248978487210852880716446938539970599235060144454914000042178896730979463959004404421520555831136502171902051936080825853063287829
e = 65537
c = 50368170865606429432907125510556310647510431461588875539696416879298699197677994843344925466156992948241894107250131926237473102312181031875514294014181272618
def Pollards_p_1(N):
a = 2 # 为了快速计算以及满足费马小定理条件
n = 2 # 从1开始没必要
while (True):
a = pow(a, n, N) # 递推计算a^B!
p = gcd(a - 1, N) # 尝试计算p
if p != 1 and p != N: # 满足要求则返回