from binascii import crc32 import os import secrets import sys from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives.hashes import Hash, SHA256 from cryptography.hazmat.primitives.padding import PKCS7
defsend_authenticated(key, used_nonces, message): nonce = secrets.token_bytes(4) while nonce in used_nonces: nonce = secrets.token_bytes(4) used_nonces.add(nonce)
tag = mac(key, nonce + message.encode()) print(message) print(f'Note: This message was sent over an authenticated channel. Its tag is {tag.hex()} with nonce {nonce.hex()}.')
defencrypt(key_parts, message): iv = secrets.token_bytes(16)
hasher = Hash(SHA256()) for part in key_parts: hasher.update(part) key = hasher.finalize()
send_authenticated(mac_key, used_nonces, f'Here is the flag: {encrypt(enc_key_parts, flag).hex()}')
enc_key_parts_checksums = list(map(lambda kp: crc32(kp), enc_key_parts)) enc_key_parts = None send_authenticated(mac_key, used_nonces, 'I have forgotten my key :(\nBut here are 4 congnitive reminders of my key:') send_authenticated(mac_key, used_nonces, str(enc_key_parts_checksums))
try: print('Please remind me of my key:') part1 = bytes.fromhex(input('Part 1 (hex): ')) part2 = bytes.fromhex(input('Part 2 (hex): ')) part3 = bytes.fromhex(input('Part 3 (hex): ')) part4 = bytes.fromhex(input('Part 4 (hex): ')) print('This is an authenticated channel!') nonce = bytes.fromhex(input('Please provide your nonce (hex): ')) tag = bytes.fromhex(input('Please provide the tag of the concatenation of the nonce and the 4 parts (hex): ')) except ValueError: print('Invalid hex!') sys.exit(1)
iflen(nonce) != 4: print('Nonce must be 4 bytes long!') sys.exit(1) if nonce in used_nonces: print('Nonces must not be reused!') sys.exit(1) ifnot secrets.compare_digest(mac(mac_key, nonce + part1 + part2 + part3 + part4), tag): print('Invalid tag!') sys.exit(1) if crc32(part1) != enc_key_parts_checksums[0] or crc32(part2) != enc_key_parts_checksums[1] or crc32(part3) != enc_key_parts_checksums[2] or crc32(part4) != enc_key_parts_checksums[3]: print('I cannot remember it!') sys.exit(1) enc_key_parts = [part1, part2, part3, part4] send_authenticated(mac_key, used_nonces, f'Thanks for reminding me! Here is a reward: {encrypt(enc_key_parts, flag).hex()}')
#!/usr/bin/env python from base64 import b64encode from math import gcd, lcm from pathlib import Path from os import environ, urandom
from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PublicKey import RSA from Crypto.Random.random import getrandbits, randrange from Crypto.Util.number import getPrime, inverse, size
FLAG = environ["FLAG"]
defEEA(a, b): if b == 0: return (a, 1, 0) g, s, t = EEA(b, a % b) return (g, t, s - (a // b) * t)
defCRT(r1, r2, m1, m2): g, k1, k2 = EEA(m1, m2) assert (r2 - r1) % g == 0, "CRT not possible" m = lcm(m1, m2) r = (r1 + m1 * k1 * (r2 - r1) // g) % m return r, m
# The sacret texts mentioned this problem # - but not its solution. Can you solve it?
d, m = CRT(dp, dq, p - 1, q - 1) d += randrange(0, φ // m) * m
e = inverse(d, φ) return RSA.construct((N, e, d, p, q))
file = Path("./key") try: with file.open("rb") as f: rsa_key = RSA.import_key(f.read()) except: rsa_key = generate_key() with file.open("wb") as f: f.write(rsa_key.export_key())
R = Zmod(N) P = PolynomialRing(R, 'x') x = P.gen()
D = 2**20 r = R.random_element()
# 预计算 u_i = r^(e * i * D) uu = r ** (e * D) uv = 1 / uu u = [(uv := uv * uu) for _ inrange(D)] # 等价于:u = [r ** (e * i * D) for i in range(D)]
# 构造 f(x) = ∏_{j=0}^{D-1} (r^{e*j} * x - r) fu = r**e fv = 1 / fu f = prod((fv := fv * fu) * x - r for _ inrange(D)) # 等价:f = prod((r ** (e * j)) * x - r for j in range(D))
# 构造多点求值用的乘积树 M M = [[x - ui for ui in u]] whilelen(M[-1]) > 2: M.append([M[-1][i] * M[-1][i + 1] for i inrange(0, len(M[-1]), 2)]) M.reverse()