The basic idea of RSA is as follows:
Classification Programming Techniques
1. Generation of Public and Private Keys:
(1) Randomly select two large prime numbers p and q, and construct n = p*q;
(2) Calculate the Euler function φ(n) = (p-1) * (q-1);
(3) Randomly select e such that gcd(e, φ(n)) = 1, i.e., e is coprime with φ(n), where gcd refers to finding the greatest common divisor;
(4) Calculate d such that e*d ≡ 1 (mod φ(n)), i.e., d is the multiplicative inverse of e.
2. Encryption Process:
(1) The plaintext m to be encrypted, m < n; (Modular arithmetic is used, if m is greater than n, the subsequent operations will not hold, so when the message is larger than n, it should be encrypted in blocks);
(2) The ciphertext c is generated as ( c = m^e \mod (n) ).
3. Decryption
>
( c^d \mod (n) = (m^e)^d \mod (n) = m^{(d*e)} \mod (n) );
3. Decryption
\( c^d \mod (n) = (m^e)^d \mod (n) = m^{(d*e)} \mod (n) \);
Why can it be decrypted?
>
Euler's theorem is used (which is actually a generalization of Fermat's Little Theorem)
( a^φ(n) \equiv 1 \mod (n) ),
Further generalized: ( a^{(φ(n)*k)} \equiv 1 \mod (n) ),
Obtaining ( a^{(φ(n)k+1)} \equiv a \mod (n) )
Note that ed ≡ 1 mod φ(N), i.e.: ed = 1 + k*φ(N).
Therefore, ( M^{(de)} \mod N = M^1 + k φ(N) \mod N = M )
4. Code is as follows
Example
#coding=utf-8
#__author__ = 'ralph'
import random
def extendedGCD(a, b):
#a*xi + b*yi = ri
if b == 0:
return (1, 0, a)
#a*x1 + b*y1 = a
x1 = 1
y1 = 0
#a*x2 + b*y2 = b
x2 = 0
y2 = 1
while b != 0:
q = a / b
#ri = r(i-2) % r(i-1)
r = a % b
a = b
b = r
#xi = x(i-2) - q*x(i-1)
x = x1 - q*x2
x1 = x2
x2 = x
#yi = y(i-2) - q*y(i-1)
y = y1 - q*y2
y1 = y2
y2 = y
return(x1, y1, a)
def computeD(fn, e):
(x, y, r) = extendedGCD(fn, e)
#y maybe < 0, so convert it
if y < 0:
return fn + y
return y
def keyGeneration(p,q,e):
#generate public key and private key
n = p * q
fn = (p-1) * (q-1)
d = computeD(fn, e)
return (d,n)
p_v = int(raw_input('Please enter the value of p (decimal)\n'))
q_v = int(raw_input('Please enter the value of q (decimal)\n'))
e_v = int(raw_input('Please enter the value of e (decimal)\n'))
c_v = int(raw_input('Please enter the value of ciphertext c (decimal)\n'))
(d,n) = keyGeneration(p_v,q_v,e_v) #generate d and n
m = pow(c_v,d,n)
print ("The obtained plaintext m is: "+str(m))