def Rational_LLL(M, impl="auto"): """ Calculate LLL-reduced Matrix on Rational Field Args: M : A matrix impl : LLL Implementation (default: auto) You can select implementation: auto, fplll, parigp or gap Return: LLL-reduced Matrix Matrix Element Format: (num, denom) """ from scryptos.math import gcd g = None for i in xrange(len(M)): for j in xrange(len(M[i])): if isinstance(M[i][j], (int, long)): continue if M[i][j][1] == 1: continue if g is None: g = M[i][j][1] else: g = gcd(g, M[i][j][1]) for i in xrange(len(M)): for j in xrange(len(M[i])): if isinstance(M[i][j], (int, long)): M[i][j] = M[i][j] * g else: M[i][j] = M[i][j][0] * (g/M[i][j][1]) B = LLL(M) for i in xrange(len(B)): for j in xrange(len(B[i])): p, q = (B[i][j], g) p, q = (p / gcd(p, q), q / gcd(p, q)) if q == 1: B[i][j] = p else: B[i][j] = (p, q) return B
def fault_crt_signature(rsa, m, sig): """ Attack to RSA: Boneh, DeMillo and Lipton's CRT-Fault Attack This attack is Known-Plaintext-Attack Args: rsa : RSA Object m : plaintext message sig : Faulted signature of `m` Return: Recovered RSA Private Key corresponding to `rsa` """ from scryptos.math import gcd from scryptos.crypto.RSA import RSA p = gcd((pow(sig, rsa.e, rsa.n) - m) % rsa.n, rsa.n) if 1 < p < rsa.n and rsa.n % p == 0: return RSA(rsa.e, rsa.n, p)
def modulus_fault_crt(rsa, fault_sigs, r=50): """ Attack to RSA: Brier et al.'s Modulus Fault Attack Args: rsa : RSA Object fault_sigs : Fault Signatures (len(fault_sigs) >= 5) r : Tweakable Iteration Range Return: Recovered RSA Private Key Reference : https://eprint.iacr.org/2011/388.pdf """ from scryptos.math import gcd, vector_add, vector_sub, vector_scalarmult, vector_norm_i, Orthogonal_Lattice from scryptos.crypto import RSA ITERATION_RANGE = xrange(-r, r + 1) assert len(fault_sigs) >= 5 l = len(fault_sigs) # calculate v^\perp B = Orthogonal_Lattice([fault_sigs]) assert len(B) == l - 1 # calculate L'^\perp B2 = Orthogonal_Lattice(B[:l - 2]) assert len(B2) == 2 # enumerate u, v x, y = B2 for a in ITERATION_RANGE: if int(vector_norm_i(a * x)**2) >= l * rsa.n: continue for b in ITERATION_RANGE: z = vector_add(vector_scalarmult(a, x), vector_scalarmult(b, y)) if int(vector_norm_i(z)**2) >= l * rsa.n: continue for c in (vector_sub(fault_sigs, z)): g = gcd(c, rsa.n) if 1 < g < rsa.n: #print "FACTOR", g p = g q = rsa.n / g return RSA(rsa.e, rsa.n, p, q)