from winpwn import * from hashlib import sha256 from struct import pack, unpack from Crypto.Cipher import ARC4 context.log_level = "debug"
e, Ns =
p = remote('127.0.0.1', 10001) p.recvuntil('message:') p.sendline('LordRiot')
# get target key = sha256('LordRiot'.encode()).digest()[:16] E = ARC4.new(key) target = 0 for i in range(64): target ^= unpack('Q', E.encrypt(pack('Q', 0)))[0] print(target)
# use sage get ans ''' from sage.all import * candidate = [pow(3, e, N) % (1 << 64) for N in Ns] I = GF(2) _matrix = [[] for _ in range(64)] for i in range(64): _matrix[i] = [int(bit) for bit in bin(candidate[i])[2:].rjust(64, '0')] _matrix = matrix(I, _matrix) target_vec = [int(bit) for bit in bin(target)[2:].rjust(64, '0')] target_vec = matrix(I, target_vec) ans = _matrix.solve_left(target_vec) print('ans =', list(res[0])) ''' ans = [0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1]
# io to get flag print(len(ans)) for i in range(64): p.recvuntil('x') if ans[i] == 1: p.sendline('3') else: p.sendline('0') p.recvuntil('v:') p.sendline('1') p.interactive()
Simple Curve
这个题涉及到概念 hyperelliptic curve,具体的理论我在Way to Crypto中已添加,此处不做赘述,这篇wp讲的很好,推荐一看。
defpartial_oracle_attack(c, e, n, enc): nbits = n.bit_length() decimal.getcontext().prec = nbits low = decimal.Decimal(0) high = decimal.Decimal(n) for i in tqdm(range(nbits)): c = (c * pow(2, e, n)) % n if oracle(c) == 0: high = (low + high) / 2 else: low = (low + high) / 2 if i % 8 == 0: flag = enc ^ int(high) print(long_to_bytes(flag)[:i // 8]) return int(high)
k1 = partial_oracle_attack(x0 ^ x1, e, n, k1_flag)
import string import random from fractions import Fraction as frac
flag_min = 48 flag_max = 125
defre_me(fini): res = '' den, num = fini[0], fini[1] reducer = 0 while num != 0: char = int(den / num) res += chr(char) tmp = frac(den, num) - char reducer += 1 den, num = tmp.denominator * reducer, tmp.numerator
return res
defre_you(fini): res = '' den, num = fini[0], fini[1] reducer = -1 while num != 0: char = abs(round(den / num)) res += chr(char) tmp = frac(den, num) - char reducer *= -1 den, num = tmp.denominator * reducer, tmp.numerator return res
defre_us(fini): res = '' den, num = fini[0], fini[1] while num != 0: char = abs(round(den / num)) res += chr(char) tmp = frac(den, num) - char den, num = tmp.denominator, tmp.numerator return res
defget_phi_a(index, return_list=False): primes = [] for i in tqdm(range(4, index+1)): tmp = strip(b(i)) if isPrime(tmp): primes.append(tmp) else: factors = get_factor_list(tmp) for factor in factors: primes.append(factor)
if return_list: return set(primes)
phi = 2 factor_dict = {} for key in primes: factor_dict[key] = factor_dict.get(key, 0) + 1 for key in factor_dict.keys(): if factor_dict[key] == 1: phi *= int(key) - 1 else: phi *= int(key) - 1 phi *= pow(key, factor_dict[key]-1) return phi
factors_list = list(get_phi_a(606, True)) print(len(factors_list)) e = 0x10001 + 2 for prime in itertools.combinations(factors_list, 2): p = prime[0] q = prime[1] n = p * q phi = (p-1) * (q-1) m = pow(enc, inverse(e, phi), n) flag = long_to_bytes(m) ifb'CCTF'in flag: print(flag) break
# calc the bound bound = 0 for i in range(9): bound += (2**64 * (5 - abs(i - 4)))**2
# construct the Lattice M = matrix(ZZ, 10, 10) x = 3 ** 66 balance = 2 ** int(iroot(int(bound), int(2))[0]).bit_length() for i in range(9): M[i, i] = 1 M[i, 9] = (x ** (8-i)) * balance
M[9, 9] = n * balance L = M.LLL()[0]
P.<y> = PolynomialRing(ZZ) f = 0 for i in range(9): f += int(L[i]) * (y**(8-i))
factors = f.factor() a = list(factors[0][0]) b = list(factors[1][0])
defrecover_random_prime(tmp): total = 0 for i in range(5): total += x ** i * tmp[i] fac = str(factor(total)).split(" * ") return int(fac[-1])
p = recover_random_prime(a) q = recover_random_prime(b) assert n == p * q e = 127 d = inverse(e, (p-1) * (q-1)) result = [] for c in enc: result.append(pow(c, d, n))
from Crypto.Util.number import * from gmpy2 import * from sage.modules.free_module_integer import IntegerLattice import numpy as np
enc = n =
# factor n
# calc the bound bound = 0 for i in range(9): bound += (2**64 * (5 - abs(i - 4)))**2
# construct the Lattice M = matrix(ZZ, 10, 10) x = 3 ** 66 balance = 2 ** int(iroot(int(bound), int(2))[0]).bit_length() for i in range(9): M[i, i] = 1 M[i, 9] = (x ** (8-i)) * balance
M[9, 9] = n * balance L = M.LLL()[0]
P.<y> = PolynomialRing(ZZ) f = 0 for i in range(9): f += int(L[i]) * (y**(8-i))
factors = f.factor() a = list(factors[0][0]) b = list(factors[1][0])
defrecover_random_prime(tmp): total = 0 for i in range(5): total += x ** i * tmp[i] fac = str(factor(total)).split(" * ") return int(fac[-1])
p = recover_random_prime(a) q = recover_random_prime(b) assert n == p * q print('got factors')
e = 127 d = inverse(e, (p - 1) * (q - 1)) result = [] for c in enc: result.append(pow(c, d, n))
# recover LWE A = np.ndarray.tolist(np.load('A.npy')) module = 152989197224467
defCVP(lattice, target): gram = lattice.gram_schmidt()[0] t = target for i in reversed(range(lattice.nrows())): c = ((t * gram[i]) / (gram[i] * gram[i])).round() t -= lattice[i] * c return target - t