←
$ Crypto: Insane Curves
Flag: BITSCTF{7h15_15_w4y_2_63nu5_6n6}Challenge
- Title:
Insane Curves - Category:
Crypto - Given files:
description.txt,val.txt - Flag format:
BITSCTF{...}
Given Data
val.txt provides:
- Prime field modulus
p - Degree-6 hyperelliptic polynomial coefficients
f_coeffs - Jacobian points in Mumford form:
G = (G_u, G_v),Q = (Q_u, Q_v) enc_flag(32-byte hex string)
Key Weakness
The intended hardness is a DLP on a genus-2 Jacobian: Q = dG.
But the base point sits in a very weak smooth-order subgroup:
((p+1) * G) = 0- Hence
ord(G) | (p+1) - And
p+1is fully smooth:
2^23 * 3^14 * 5^8 * 7^4 * 11^10 * 13^10 * 17^9 * 19^6 * 23^5 * 29 * 31^4This makes Pohlig-Hellman practical and recovers d.
Discrete Log Recovery
Using Pohlig-Hellman on each prime-power factor, CRT gives:
d = 91527621348541142496688581834442276703691715094599257862319082414424378704170Verification:
d * G == Q # TrueEncryption Mistake
The ciphertext is not AES-based. It is XOR with a SHA-256 digest of the decimal secret:
keystream = sha256(str(d).encode()).digest()
flag = bytes.fromhex(enc_flag) XOR keystreamRecovered plaintext:
BITSCTF{7h15_15_w4y_2_63nu5_6n6}Minimal Repro Script
from hashlib import sha256
enc = bytes.fromhex("f6ca1f88bdb8e8dda17861b91704523f914564888c7138c24a3ab98902c10de5")
d = 91527621348541142496688581834442276703691715094599257862319082414424378704170
ks = sha256(str(d).encode()).digest()
flag = bytes(a ^ b for a, b in zip(enc, ks))
print(flag.decode())