AlpacaHack Round 12 (Crypto) writeup & upsolve
概要
2025年7月6日に開催されたAlpacaHackのwriteupです。
諸用があり、1時間だけ参加でしたが1問解けたのは良いところ。
一方で、変な計算ミスで時間を浪費してしまったので、落ち着いて問題に取り組むのは課題と感じました。
ということで、以下writeup。
RSARSARSARSARSARSA
You don't have to say it again and again...
from math import gcd
import os
from Crypto.Util.number import getPrime, bytes_to_long
e = 19
while True:
p = getPrime(2048)
q = getPrime(2048)
if gcd((p - 1) * (q - 1), e) == 1:
break
n = p * q
flag = os.environ.get("FLAG", "Alpaca{**** REDACTED ****}")
assert len(flag) == 26 and flag.startswith("Alpaca{") and flag.endswith("}")
m = bytes_to_long((flag * 1337).encode())
c = pow(m, e, n)
print(f"{n = }")
print(f"{e = }")
print(f"{c = }")
方針)
-
をN倍していることから、乗法の準同型性を用いる{\rm flag}({\rm bytes}) -
が比較的小さいため、Low Public-Exponent Attackを用いるe
問題と予想。
2.についての補足
正確には、
assert len(flag) == 26 and flag.startswith("Alpaca{") and flag.endswith("}")
より、
具体的には、
であるため、
を計算し、
簡単のため、
m = bytes_to_long((flag * 2).encode())
の状況を考える。
つまり、
となる。
同様に、今回は、1337倍しているので
であるため、
が求められ、
solve.py
from Crypto.Util.number import long_to_bytes
from gmpy2 import iroot
n = 434245275129793896913302623186216967500119715299127153234221039838158526818290666891561167619572507897277032319251523352710966722158326513857889678449160348496647427753832233179173745189495799707833020232209447520485615893168704144655033371807912826948460011240258726843346618328839282439390863464375320181495406806870462330735361196286553150480225927729088313551861682406252457739974850015509783430978939475350707211461876140420181118923743456062581297038004651412953310377554877499792225388059857865550418697212704277742826280689987165702071346542831836616149138379224837551040036947064990027047482745931141458056028719767845142490618375017582275824317241572815337810658684051187938258804346960781372035972758516593800419459342799854863845667715099378564373594732798224797622583907677749880918106223965727445907355069025939554400938193579295415911074889648122298896605189398591684277376327938718166279159875826993866460251900514487349848332991005775574378131897581182876147580659857596204121970624162722935263271888969020482566142620134100258216288390250174699829806817678453601913377347867137739622906815272561714188564065071077762169177825466514512198167566882661748389120146622447920498988341055543170346944366105037929197965527
e = 19
c = 78338816976998323261765735600063671710448529902850366859501110834174319629348492230679353792803618614020892663940158627385470036549819116375194598599193512981265682997072278631964394686243958989105159463105190885437258093111178664394786430767942639437287236999171486583513816766766869843448941665224796216610702708658300011987744401747551989248270799179750556330952646223694000679475842632497149402602469848595868051660228892506097962300820851000134370939783634534516434054009303981106884637932006844265722691022870174977860945699441650254771777451995160642261482879537396171107016491225773397809485749640163676209732235156461483660111845782227127763086286553520914359194795617080980736767821995556156173267185240945707717461037831992544868933876015548419376861213017988005848033349136839971120363078490938026883354839573512645985195570831018461470031329716026531550172207332072481279548470657090575709419245114386419567236219816237412255505882075283974654569995321334498673793010812162088796252555619242463561750801895032793870706949913548310632113206159695535952422316840587214237406730422405058644629458566515378607614900910335034732797410592671297941526063690060922625005949094383664832255082556088451940780657576420871470920836
x = ((256**26)**1337-1)//(256**26-1)
x_inv = pow(x,-e,n)
m2 = (c*x_inv)%n
m, tf = iroot(m2, e)
if tf:
print(long_to_bytes(m).decode())
その他
upsolveするよん。お楽しみに。
Discussion