FlagYard - Challenge Writeup
FlagYard - Challenge Writeup
Challenge Summary
This challenge presents a cryptographic puzzle based on the Diffie-Hellman key exchange setup
with modifications. The flag is encrypted using a small prime-based modular arithmetic, where the
main task is to recover the flag from provided cryptographic outputs. The challenge specifically
exploits the weakness in the construction of the hint value, which combines the secret flag raised
to a power with a XOR operation against a value derived from a small 8-bit random integer.
The vulnerability lies in the fact that the random integer is only 8 bits, making it feasible to brute-
force all possible values, recover the intermediate encrypted flag, and then solve for the flag using
modular arithmetic. Additionally, the smoothness of the prime group's order further simplifies the
potential to solve the discrete logarithm problem directly.
Learning Outcomes
● Understanding the weaknesses in cryptographic protocols that use small random values.
● Learning how to brute-force cryptographic keys when the key space is small.
● Gaining experience in solving discrete logarithm problems using modular arithmetic.
● Recognizing the importance of group order in cryptographic security and how smooth
orders can be exploited.
● Practical experience with Python's Crypto.Util.number module for handling large
integers and modular arithmetic.
This challenge is designed to reinforce the understanding of cryptographic vulnerabilities and the
practical application of number theory in breaking cryptographic systems.
2
FlagYard | Challenge Writeup
Solution
Summary of the Steps in Python Code:
from Crypto.Util.number import bytes_to_long, long_to_bytes, inverse
import random
# Provided values
p = 2**521 - 1
g = 3
h =
4032754735786959608993479828796037537696909683855161211524481832813601
9295570051803189794738412847161664976444067074795518901183546879003577
96448890587768319
hint =
4996271902668750386408967583218439425362940880833289971997165550999614
7989727319042067616849674645887443959775922317585878695666811814084058
27905235411423930
def eightBitBlock(num):
return '0'*(8-log2Int(num))+bin(num)[2:]
# Solve for m
d = inverse(7, p-1)
m = pow(possible_m7, d, p)
# Check if it matches h
if pow(g, m, p) == h:
flag = long_to_bytes(m).decode()
print("Flag:", flag)
break
3
FlagYard | Challenge Writeup
• Since r is an 8-bit number, it has only 256 possible values. We can brute-force through
each possible value of r to reconstruct secretNum using the function provided in the
challenge:
def log2Int(num):
s = 0
while num >= 1:
num /= 2
s += 1
return s
def eightBitBlock(num):
return '0'*(8-log2Int(num))+bin(num)[2:]
4
FlagYard | Challenge Writeup
d = inverse(7, p-1)
m = pow(possible_m7, d, p)
• Validate each candidate for m by checking if it satisfies the equation gm mod p =h:
if pow(g, m, p) == h:
# Flag found
flag = long_to_bytes(m).decode()
break
Conclusion:
The challenge can be solved by either brute-forcing the small random value used in the
construction of secretNum or by employing a direct cryptographic attack using group
properties. Both methods should lead to the correct recovery of the flag
FlagY{418c8886e081dcc8d18c0586136a1e63}.