Path: blob/master/Public Key/RSA/fault_attack.sage
336 views
# This file contains an implementation of a fault attack on RSA-CRT signatures12def generate_params(target_bitlen=1024, e=65537):3p = random_prime(2^target_bitlen//2, proof=False)4q = random_prime(2^target_bitlen//2, proof=False)56N = p * q7d = inverse_mod(e, (p - 1) * (q - 1))8dp = d % (p - 1)9dq = d % (q - 1)1011qinv = inverse_mod(q, p)12pinv = inverse_mod(p, q)13return N, p, q, dp, dq, e, qinv, pinv141516# Signature method that flips a random bit in dq with probability error_prob1718def sign(m, N, p, q, e, dp, dq, qinv, pinv, error_prob=1):19s1 = Integer(pow(m, dp, p))20s2 = Integer(pow(m, dq, q))2122if random() > 1 - error_prob:23s2 ^^= 2 ^ randint(2, 512)2425s = (s1 * q * qinv) + (s2 * p * pinv) % N2627return s2829# The attacker will already know m1 since he's trying to obtain signatures for them30# With sufficently high probability, gcd(s1 - m1, N) will reveal one of the factors of N31def factor_n(s1, e, m1, N):32p = 133q = gcd(s1^e - m1, N)34if q != 1:35p = N // q3637return p, q3839def test():40N, p, q, dp, dq, e, qinv, pinv = generate_params()41m1 = randint(0, 2^512)4243# Waaaaaaaaayy too many parameters for a simple function, will definitely simplify44# In the near future4546s1 = sign(m1, N, p, q, e, dp, dq, qinv, pinv)4748p, q = factor_n(s1, e, m1, N)4950if p != N and q != N:51print("[x] Obtained factors for N!")52print(p, q)5354if __name__ == "__main__":55test()56575859