Skip to content

Instantly share code, notes, and snippets.

@c3l3si4n
Last active April 26, 2025 20:27
Show Gist options
  • Save c3l3si4n/3636041e03f42568138f2bc15e3c1cec to your computer and use it in GitHub Desktop.
Save c3l3si4n/3636041e03f42568138f2bc15e3c1cec to your computer and use it in GitHub Desktop.
obsidian ) cat output.txt
19970192951896076587357270489167937916618022198129516743091736664525698125224
78876026922201259108741049564691635166471597880603787944801336451046144103203
obsidian ) cat dist.py
from Crypto.Util.number import bytes_to_long
import os
def rot(n, r):
return (n >> r) | ((n << (256 - r) & (2**256 - 1)))
round_constants = [3, 141, 59, 26, 53, 58, 97, 93, 23, 84, 62, 64, 33, 83, 27, 9, 50, 28, 84, 197, 169, 39, 93, 75]
M = 2**256
def encrypt(key, block):
for i in range(24):
block = (block + key) % M
block = rot(block, round_constants[i])
return block
key = os.urandom(32)
key = bytes_to_long(key)
p1 = b'please like and subscribe!!!!!!!'
p2 = b'UMDCTF{REDACTED}'
assert(len(p1) <= 32)
assert(len(p2) <= 32)
c1 = encrypt(key, bytes_to_long(p1))
c2 = encrypt(key, bytes_to_long(p2))
print(c1)
print(c2)
obsidian )
obsidian ) python3 d.py
p1_long: 50850558227970268200447612605193929343733636240750802448491965554429981172001
D(0, c1): 60597284719542603656003344756756076243365397764852292883712797954871242269021
D(0, c2): 50139088373414202329671020440516854279153894391574297935895619289486386536897
Calculated p2_long: 40392361881841866874115288288954707379522132867472807500674786889045125439877
Calculated p2 (bytes): b'YMDCTFsdiamon\\_p\x89ckaxu_no_w\xe1i!!\x85'
Could not decode p2 bytes as ASCII.
obsidian ) cat d.py
from Crypto.Util.number import bytes_to_long, long_to_bytes
import os
# Constants from the challenge
M = 2**256
round_constants = [3, 141, 59, 26, 53, 58, 97, 93, 23, 84, 62, 64, 33, 83, 27, 9, 50, 28, 84, 197, 169, 39, 93, 75]
# --- Helper Functions ---
# Original right rotation (for reference, not strictly needed for solve)
def rot_right(n, r):
r = r % 256
return (n >> r) | ((n << (256 - r)) & (M - 1))
# Inverse rotation: Left rotation by r bits
def rot_left(n, r):
r = r % 256
return ((n << r) & (M - 1)) | (n >> (256 - r))
# Decryption function assuming key = 0
def decrypt_zero(ciphertext):
block = ciphertext
# Apply inverse operations in reverse order
for i in range(23, -1, -1):
# The encryption did rot_right(block + key, rc[i])
# To reverse just the rotation part (key=0): rot_left(block, rc[i])
block = rot_left(block, round_constants[i])
return block
# --- Known Values ---
p1_bytes = b'please like and subscribe!!!!!!!'
# Pad p1 to 32 bytes (256 bits) if necessary, although bytes_to_long handles it
# p1_bytes = p1_bytes.ljust(32, b'\0') # Not needed based on assert and bytes_to_long
c1 = 19970192951896076587357270489167937916618022198129516743091736664525698125224
c2 = 78876026922201259108741049564691635166471597880603787944801336451046144103203
# --- Calculations ---
# 1. Convert p1 to integer
p1_long = bytes_to_long(p1_bytes)
print(f"p1_long: {p1_long}")
# 2. Calculate D(0, c1)
d0_c1 = decrypt_zero(c1)
print(f"D(0, c1): {d0_c1}")
# 3. Calculate D(0, c2)
d0_c2 = decrypt_zero(c2)
print(f"D(0, c2): {d0_c2}")
# 4. Compute p2_long = (p1_long - D(0, c1) + D(0, c2)) mod M
p2_long = (p1_long - d0_c1 + d0_c2) % M
print(f"Calculated p2_long: {p2_long}")
# 5. Convert p2_long back to bytes
# The length might be slightly off if there were leading null bytes,
# long_to_bytes handles this.
p2_bytes = long_to_bytes(p2_long)
print(f"\nCalculated p2 (bytes): {p2_bytes}")
# Try decoding to see the flag
try:
flag = p2_bytes.decode('ascii')
# Remove potential null padding if exists
flag = flag.rstrip('\x00')
print(f"\nPotential Flag: {flag}")
except UnicodeDecodeError:
print("\nCould not decode p2 bytes as ASCII.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment