CRT优化RSA
RSA 作为世界上使用最为流行的公钥密码算法,被广泛应用在数据加密和数字签名上。
为了提高加密和签名验证的效率,一般会将RSA的加密指数(一般是公钥位数)设置的较小,一般为 65537 ,而解密或签名效率却不能够简单的通过减小私钥的长度来实现,因为过短的私钥将直接导致安全问题。
于是乎,基于中国剩余定理(Chinese Remainder Theorem,简称 CRT)的 RSA 加速方案被提出。以RSA加解密为例,本文将首先讲解 RSA 基本原理,再介绍中国剩余理论和费马小定理,最后介绍 RSA-CRT算法。
RSA算法
RSA 包括密钥生成算法、加密算法和签名算法。
密钥生成
加解密
签名与验签
CRT
Garner's formulax
(x1, x2)
(参考:H. Garner. The Residue Number System. IRE Transactions on Electronic Computers, EC-8 (6), pp. 140 – 147, June 1959.),对于\(x_1 = x(mod p)\)和\(x_2=x(mod q)\):\(x=x_2 + h.q\)
\(h=(x_1-x_2)(q^{-1}mod p) mod p\)
欧拉定理和费马小定理
RSA-CRT
- \(d = d(mod p-1)+k(p-1)\),这个如何实现?
- 求出\(m_q\)和\(m_p\)后,就可以基于CRT求出\(m\)。
举例
## RSA加解密
p = 137, q = 131, n = 137.131 = 17947, e = 3, d = 11787.
私钥(n,d),公钥(n,e)
m = 513
加密:c = 5133 mod n = 8363
解密:m'=c^d mod n = 513
## RSA-CRT加解密
dP = d mod (p-1) = 11787 mod 136 = 91
dQ = d mod (q-1) = 11787 mod 130 = 87
qInv = q^{-1} mod p = 131-1 mod 137 = 114
m1 = cdP mod p = 836391 mod 137 = 102
m2 = cdQ mod q = 836387 mod 131 = 120
h = qInv.(m1 - m2) mod p = 114.(102-120+137) mod 137 = 3
m = m2 + h.q = 120 + 3.131 = 513.
程序
import time
def chinese_remainder_theorem(c, d, p, q):
dp = d % (p - 1)
dq = d % (q - 1)
q_inv = modinv(q, p) # calculates the inverse
m1 = pow(c % p, dp, p)
m2 = pow(c % q, dq, q)
h = q_inv * (m1 - m2) % p
m = m2 + h * q
return m
def modinv(e, phi): # function used to calculate modular inverse
d = 0
x1 = 0
x2 = 1
y1 = 1
temp_phi = phi
while e > 0: # extended euclidean algorithm
temp1 = temp_phi // e
temp2 = temp_phi - temp1 * e
temp_phi = e
e = temp2
x = x2 - temp1 * x1
y = d - temp1 * y1
x2 = x1
x1 = x
d = y1
y1 = y
if temp_phi == 1:
return d + phi
def gcd(a, h): # function used to calculate the GCD
temp = 0
while (1):
temp = a % h
if (temp == 0):
return h
a = h
h = temp
start_time = time.time()
# p and q are 1024 bit primes. Tested using Miller Rabbin algorithm from Question 2
p = 137
q = 131
n = p*q
e = 3
phi = (p-1)*(q-1)
d = modinv(e, phi)
msg = 513
print("Message data = ", msg)
c = pow(msg, e, n) # encryption c = (msg ^ e) % n
print("Encrypted data = ", c)
# decryption using chinese remainder theorem
decrypted_msg = chinese_remainder_theorem(c, d, p, q)
print("Original Message Sent = ", decrypted_msg)
end_time = time.time()
elapsed_time = end_time - start_time
print("Time taken for RSA with CRT: {:.6f} seconds".format(elapsed_time))