Key generation
p # prime number q # prime number n # modulus n = p * q totien(n) = (p - 1) * (q - 1) e # public key exponent 1 < e < totien(n) and gcd(e, n) = 1 d # private key exponent # Method 1 d = gmpy.invert(e, totien(n)) # Method 2 def egcd(a, b): if a == 0: return (b, 0, 1) else: g, y, x = egcd(b % a, a) return (g, x - (b // a) * y, y) def modinv(a, m): g, x, y = egcd(a, m) if g != 1: return None # modular inverse does not exist else: return x % m d = modinv(e, totien(n)) # Method 3 d = 1 while True: if (e * d - 1) % totien_n == 0: print d break else: d += 1 (e, n) # public key (d, n) # private key
Example
p = 61 q = 53 n = 53 * 61 = 3233 totien(3233) = (53 - 1) * (61 - 1) = 3120 e = 17 d = modinv(e, totien(3233)) = 2753 (17, 3233) # public key (2753, 3233) # private key m = 65 # message c # ciphertext
Encryption
c = m**e % n = pow(m, e, n) c = 65**17 % 3233 = pow(65, 17, 3233) = 2790
Decryption
m = c**d % n = pow(c, d, n) m = 2790**2753 % 3233 = pow (2790, 2753, 3233) = 65 # CRT (to speed up calculation) dp = d % (p - 1) = 2753 % (61 - 1) = 53 dq = d % (q - 1) = 2753 % (53 - 1) = 49 qinv = modinv(q, p) = modinv(53, 61) = 38 m1 = c**dp % p = 2790**53 % 61 = 4 m2 = c**dq % q = 2790**49 % 53 = 12 h = (qinv * (m1 - m2)) % p = (38 * (4 - 12)) % 61 = 1 m = m2 + (h * q) = 12 + (1 * 53)= 65
References
https://en.wikipedia.org/wiki/RSA_(cryptosystem)
https://en.wikipedia.org/wiki/Chinese_remainder_theorem
https://factordb.com
No comments:
Post a Comment