Skip to main content

【NSS每日一题】[SWPU 2020]happy

摘要:通过解两个包含p和q的方程,利用最大公约数求出素数p和q。先化简方程,建立关于p的一元二次方程并求解,再计算q。最后用RSA私钥d解密得到flag{happy_rsa_1}。关键步骤包括代数化简、解方程、求逆元和模幂运算。

2 min read
【NSS每日一题】[SWPU 2020]happy 封面

【NSS每日一题】[SWPU 2020]happy 配图 1

题目附件:

('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),计算关键点:

  1. 计算判别式 Δ = (A+B)² - 4*B² = (A+B-2B)(A+B+2B) = (A-B)(A+3B);
  2. 计算 Δ 的平方根(因 p 是整数,Δ 必为完全平方数);
  3. 代入求根公式得到 p(取正整数解,且为素数)。

步骤 3:由 p 求 q

得到 p 后,代入方程 2 q*p*(1+p) = B,直接解出 q:q = B / [p*(1+p)](验证:q 需为素数,且代入方程 1 需成立)

步骤 4:计算私钥 d 并解密

  1. 计算欧拉函数 φ(n) = (p-1)*(q-1)(n = p*q);
  2. 求 e 关于 φ(n) 的模逆元 d(即满足 e*d ≡ 1 mod φ(n)),可通过扩展欧几里得算法实现;
  3. 解密:m = pow(c, d, n)(c 是给定的密文,pow 函数高效计算大数模幂)。

三、基础注意事项

  1. 大数计算:所有数值都是极大整数,需用支持大整数的语言(如 Python)计算,Python 天然支持任意精度大整数,无需担心溢出;
  2. 素数验证:求解出的 p、q 需验证是否为素数(可通过简单的素性测试,如米勒 - 拉宾测试);
  3. 模逆元求解:若 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}

相关文章

全部文章 →