def lcm_multi(numbers): """ Calculate lcm for the list of numbers :param numbers: list of numbers :return: lcm(a,b,c,d,...) """ return multiply(numbers) / gcd_multi(numbers)
def get_fi_distinct_primes(primes): """ Get Euler totient for list of pairwise co-prime numbers :param primes: list of co-prime numbers :return: fi(n) = (p-1)(q-1)... """ return multiply((p - 1) for p in primes)
def prepare_values(): prefix = bytes_to_long("X: ") factors, _ = factor(prefix) random.shuffle(factors) base1 = multiply(factors[:len(factors) / 2]) base2 = multiply(factors[len(factors) / 2:]) assert base1 * base2 == prefix shift = 5 x = base1 * 256**shift + 0 y = base2 * 256**shift + 0 z = base1 * 256**shift + 1 v = base2 * 256**shift + 1 A = x * y B = z * v C = x * v D = y * z assert (A * B == C * D == x * y * z * v) for x in [A, B, C, D]: assert (long_to_bytes(x)[:3] == 'X: ') assert (len(long_to_bytes(x)) < 16) return A, B, C, D
def factor_worker(data): flag, i, primes = data factors, residue = factor_p(flag, primes) print('factors', i, factors) for potential_exp in subsets(factors): if len(potential_exp) == 0: continue exp = multiply(potential_exp) bits = recover_bits(flag, exp) if bits is not None: data = int("".join(map(str, bits[::-1])), 2) data = long_to_bytes(data) if "IHDR" in data and "PNG" in data: print("FOUND!", i, flag, data) save_png(data, i, exp) return data
def solve_crt(residue_and_moduli): """ Solve CRT for given modular residues and modulus values, eg: x = 1 mod 3 x = 2 mod 4 x = 3 mod 5 x = 58 residue_and_moduli = [(1,3), (2,4), (3,5)] :param residue_and_moduli: list of pairs with (modular residue mod n, n) :return: x """ residues, moduli = zip(*residue_and_moduli) N = multiply(moduli) Nxs = [N // n for n in moduli] ds = [modinv(N // n, n) for n in moduli] mults = [r * Nx * d for r, Nx, d in zip(residues, Nxs, ds)] return reduce(lambda x, y: x + y, mults) % N
def modular_sqrt_composite(c, factors): """ Calculates modular square root of composite value for given all modulus factors For a = b^2 mod p*q*r*m... calculates b :param c: residue :param factors: list of modulus prime factors :return: all potential root values """ n = multiply(factors) roots = [[(modular_sqrt(c, x), x), (x - modular_sqrt(c, x), x)] for x in factors] solutions = [] for x in itertools.product(*roots): solution = solve_crt(list(x)) solutions.append(solution) assert solution**2 % n == c return solutions
def paillier_decrypt(c, factors, g): """ Decrypt data using Paillier Cryptosystem Actually it's the same as Damgard Jurik with s=1 :param c: ciphertext :param factors: prime factors :param g: random public integer g :return: decrypted data as long """ def L(u, n): return int((u - 1) // n) lbd = lcm_multi([p - 1 for p in factors]) n = multiply(factors) x = L(pow(g, lbd, n * n), n) mi = int(modinv(x, n)) m = L(pow(c, lbd, n * n), n) * pow(mi, 1, n) return m % n
def combine_signatures(signatures, N): return multiply(signatures) % N