![【NSS每日一题】[SWPU 2020]happy 配图 1](/posts/nssmei-ri-yi-ti-swpu-2020-happy/images/image-01_hu_567c8827f69d4517.webp)
题目附件:
('c=', '0x7a7e031f14f6b6c3292d11a41161d2491ce8bcdc67ef1baa9eL')
('e=', '0x872a335')
#q + q*p^3 =1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586
#qp + q *p^2 = 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594
题目分析:
第一步:提取公因子简化方程
- 方程 1 提取
q:q*(1 + p³) = A(记大数 A 为方程 1 右侧值) - 方程 2 提取
q*p:q*p*(1 + p) = B(记大数 B 为方程 2 右侧值)
**第二步:利用代数公式化简 1+p³**代数公式:1 + p³ = (1 + p)(p² - p + 1),代入方程 1:q*(1 + p)*(p² - p + 1) = A
第三步:用方程 1 除以方程 2,消去公共项将化简后的方程 1 ÷ 方程 2:[q*(1+p)*(p²-p+1)] / [q*p*(1+p)] = A / B约去 q*(1+p)(q、p 是素数,不为 0),得到:(p² - p + 1) / p = A / B进一步整理:p² - p + 1 = (A/B)*p``p² - p*(1 + A/B) + 1 = 0(或更简单的形式:B*(p² - p + 1) = A*p → B*p² - (A+B)*p + B = 0)
步骤 2:求解一元二次方程得到 p
上述整理后得到关于 p 的一元二次方程:B*p² - (A+B)*p + B = 0根据一元二次方程求根公式 p = [ (A+B) ± √((A+B)² - 4*B*B) ] / (2*B),计算关键点:
- 计算判别式
Δ = (A+B)² - 4*B² = (A+B-2B)(A+B+2B) = (A-B)(A+3B); - 计算
Δ的平方根(因p是整数,Δ必为完全平方数); - 代入求根公式得到
p(取正整数解,且为素数)。
步骤 3:由 p 求 q
得到 p 后,代入方程 2 q*p*(1+p) = B,直接解出 q:q = B / [p*(1+p)](验证:q 需为素数,且代入方程 1 需成立)
步骤 4:计算私钥 d 并解密
- 计算欧拉函数
φ(n) = (p-1)*(q-1)(n = p*q); - 求
e关于φ(n)的模逆元d(即满足e*d ≡ 1 mod φ(n)),可通过扩展欧几里得算法实现; - 解密:
m = pow(c, d, n)(c是给定的密文,pow函数高效计算大数模幂)。
三、基础注意事项
- 大数计算:所有数值都是极大整数,需用支持大整数的语言(如 Python)计算,Python 天然支持任意精度大整数,无需担心溢出;
- 素数验证:求解出的
p、q需验证是否为素数(可通过简单的素性测试,如米勒 - 拉宾测试); - 模逆元求解:若
e和φ(n)不互质,说明计算有误(RSA 中e需与φ(n)互质)。
解题:
根据附件可知需要求出p,q,一看就是需要求公约数的,用到的原理
hint1 = q + qp^3 = (1+p^3)q = q(1+p)(p^2-p+1)
hint2 = qp + qp^2 = q(1+p)p
gcd(hint1,hint2) = q(1+p)
p = hint2 / q(1+p)
q = gift // (p+1)
得到p,q后根据欧拉定理,解题代码如下:
from Crypto.Util.number import *
from gmpy2 import *
c=0x7a7e031f14f6b6c3292d11a41161d2491ce8bcdc67ef1baa9e
e=0x872a335
#q + q*p^3 =1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586
#qp + q *p^2 = 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594
hint1 = 1285367317452089980789441829580397855321901891350429414413655782431779727560841427444135440068248152908241981758331600586
hint2 = 1109691832903289208389283296592510864729403914873734836011311325874120780079555500202475594
gift = gcd(hint1,hint2)
p = hint2//gift
q = gift // (p+1)
n= p*q
phi = (p-1)*(q-1)
d = invert(e, phi)
flag = pow(c, d, n)
print(long_to_bytes(flag))
Flag
flag{happy_rsa_1}
![【NSS每日一题】[SWPU 2020]happy 封面](/posts/nssmei-ri-yi-ti-swpu-2020-happy/images/cover.png)