Writeups
4 challengeStep by step solutions. Exploit Implementation code included.
- ECCMedium
From Dusk Till Dawn Finals - 2k26 - KKEEYYS
Using linear system to bypass blindings and generate a valid Schnorr ECC signature
def add_key(key: str, value: int, comm: Point, init=False) -> Point: r = hash_to_scalar(f"blinding_{key}_{value}".encode()) coeffs = [ hash_to_scalar(f"{'init' if init else 'key'}_{key}_{i}".encode()) for i in range(256) ] points = [value * c * B[i] for i, c in enumerate(coeffs)] delta = sum(points, Gr * r) return comm + delta def verify_signature(comm: Point, message: bytes, sig: Tuple[int, int]): (s, e) = sig r_v = s * Gr + e * comm e_v = hash_to_scalar(message + (r_v.x).to_bytes(32, "big") + (r_v.y).to_bytes(32, "big")) return e_v == eFrom Dusk Till Dawn Finals 2026 - latticeMedium
CH - LWE 2 - Too Many Errors
Using lattices to search the error vector
a = [] for i in range(len(FLAG)): a.append(self.rand.randint(0, q - 1)) e = self.rand.randint(-1, 1) self.rand.seed(getrandbits(32)) if self.rand.randint(0, 1): a[self.rand.randint(0, len(a) - 1)] = self.rand.randint(0, q - 1) b = 0 for (i, j) in zip(a, FLAG): b += i * j b += e b %= q return {"a": a, "b": b}CryptoHack - LWE 2 - 2026 - latticeMedium
HTB - Noise Codex
Using lattices to solve Approximate Common Divisor Problem
def inscribe_noise(self, message: str): bits = "".join(f"{ord(c):08b}" for c in message) ciphertext = [] anchor = getPrime(1024) for bit in bits: b = int(bit) distortion = random.randint(self.anchor, self.anchor**2) entropy = random.randint(2**256, 2**512) c = self.anchor * distortion + 2 * entropy + b ciphertext.append(c) return ciphertextHTB 2026 - latticeMedium
Brunner CTF 2k26 - Shredded Recipe
Solving linear systems with lattices
x = bytes_to_long(flag[0::3]) y = bytes_to_long(flag[1::3]) z = bytes_to_long(flag[2::3]) a, b, c = (random.randint(2, p) for _ in range(3)) d = (a*x + b*y + c*z) % p print(a, b, c, d)
Brunner CTF 2026
No Writeup for this category.