def merkle_hellman_modulo(c, pub, modulo): """ Attack to Knapsack Cipher: Lattice Attack with Modulus Args: c : Ciphertext pub : Public key list modulo : Modulo Return: Plaintext """ from scryptos.math import modinv, LLL import random mat = [] pub = pub + [c] for x in xrange(len(pub)): mat += [[0] * x + [1] + [0] * (len(pub) - x - 1) + [pub[x]]] mat += [[0] * (len(pub)) + [modulo]] ml = LLL(mat) # find shortest vector(a.k.a. plaintext) for x in ml: if x[-1] == 0: if x[-2] != -1: if x[-2] == 1: return [(y * modinv(-1, modulo)) % modulo for y in x[:-2]] return [(y * modinv(x[-2], modulo)) % modulo for y in x[:-2]] else: return x[:-2]
def common_modulus(rsa1, rsa2, c1, c2): """ Attack to RSA: Common Modulus Attack Args: rsa1 : RSA Object 1 rsa2 : RSA Object 2 c1 : ciphertext encrypted by `rsa1` c2 : ciphertext encrypted by `rsa2` Return: plaintext message """ from scryptos.math import egcd, modinv from scryptos.crypto import Ciphertext assert rsa1.n == rsa2.n if isinstance(c1, Ciphertext): c1 = c1.v if isinstance(c2, Ciphertext): c2 = c2.v a, b, g = egcd(rsa1.e, rsa2.e) if a < 0: c1 = modinv(c1, rsa1.n) a *= -1 if b < 0: c2 = modinv(c2, rsa2.n) b *= -1 return (pow(c1, a, rsa1.n) * pow(c2, b, rsa2.n)) % rsa1.n
def crack_lcg(a, b, c, modulo): """ Cracking LCG: from 3 Random integers Args: a : random integer 1 b : random integer 2 c : random integer 3 modulo : Modulus Parameter Return: Tuple of LCG Parameter, as (A, B) """ from scryptos.math import modinv A = (((b - c) % modulo) * modinv((a - b) % modulo, modulo)) % modulo B = (b - A * a) % modulo return (A, B)
def crack_mt19937_using_index_difference(mA, mB, idxA, idxB): """ Attack to MT19937 : Guess initial state and seed cracking Args: mA : A generated random value 1 mB : A generated random value 2 idxA : An index of `mA` idxB : An index of `mB` Return: Seed Candidates See: Scrapbox [Mersenne Twister] """ from scryptos.math import modinv from scryptos.crypto import mt19937 assert (idxA + 397) % 624 == idxB # untempering mA_ = mt19937.untempering(mA) mB_ = mt19937.untempering(mB) res = [] y_ = (mA_ ^ mB_) # Guess LSB for lsb in [0, 1]: y = y_ if lsb == 1: y ^= mt19937.MATRIX_A y = (y << 1) & 0xffffffff if lsb == 1: y |= 1 # Guess MSB of mt[idxA] and mt[idxA+1] invMult = modinv(0x6c078965, mt19937.MOD) for msb_mA in [0, 1]: for msb_mC in [0, 1]: mC = y ^ (msb_mA << 31) ^ (msb_mC << 31) x = mC for i in range(idxA + 1, 0, -1): x = ((x - i) * invMult) % mt19937.MOD x = x ^ (x >> 30) res += [x] ret = set() for seed in res: mt = mt19937(seed=seed) rand = [mt.next() for _ in range(max(idxA, idxB) + 1)] if mA in rand and mB in rand: ret.add(seed) return sorted(map(int, ret))