RSA中的中国剩余定理(CRT)和多素数(multi-prime)

RSA的中国剩余定理(CRT)和多素数(multi-prime)

写了个代码,方便计算大数运算:
git@github.com:mrpre/bn_tool.git
本片中的运算都可以使用这个工具进行计算。

传统方式计算RSA公钥私钥

RSA公钥私钥生成
两个大素数p,q,计算n = p*q
计算phi(n),因为p,q是素数,所以phi(n) = (p-1)*(q-1)
随机取与phi(n)互素的数e,计算其对于phi(n)的逆元。既,求d,使得d满足
d*e = 1 mod (phi(n))
(n,e)为公钥,(n,d)为私钥

使用公钥加密和使用私钥解密流程(传统方式):

计算
使用公钥加密:
若要加密明文m1,则需要计算c = m1^e mod n,c为密文。
使用私钥解密:
若要解密密文c,则需要计算 m2 = c ^d mod n,m2为明文,既,m2=m1

简介中国剩余定理:

p和q是互相独立的大素数,n为p*q,对于任意(m1, m2), (0<=m1< p, 0<=m2< p)
必然存在一个唯一的m ,0<=m< n
使得
m1 = m mod p
m2 = m mod q

所以换句话说,给定一个(m1,m2),其满足上述等式的m必定唯一存在。

所以解密rsa的流程c^d mod n,可以分解为 m1=c^d mod p以及m2=c^d mod q方程组,然后再计算m( m的计算方法见后面 )。
但是等式c^d mod p 或者 c^d mod q ,模数虽然从n降为p或q了,但是这个指数d还是较大,运算还是比较消耗性能。我们需要降低指数。

仔细看等式c^d mod p

 令 
 d = k(p-1) + r
 则
 c^d mod p
=c^(k(p-1) + r) mod p
=c^r * c^(k(p-1)) mod p
因为 c^(p-1) mod p = 1 (欧拉定理)
=c^r mod p

r是c除p-1的余数,即 r = d mod (p-1)

所以 c^d mod p可以降阶为 c^(d mod p-1) mod p
同理,c^d mod q可以降阶为 c^(d mod q-1) mod q

其中 dp = d mod p-1dq = d mod q-1 可以提前计算。

但是计算dp和dq可以更简单,就是分别计算e对p-1和q-1的逆。
这个(证明比较复杂,要是不懂的话,直接使用d mod p-1d mod q-1就行了)

使用公钥加密和使用私钥解密流程(中国剩余定理):
准备
首先,我们需要在在生成私钥公钥时,多生成几个数:
我们的d是e对phi(n)的逆元,我们现在需要另外2个逆元(分别是对(p-1)和(q-1)的),既
1:计算dp,使得dp*e = 1 mod(p-1)
2:计算dq,使得dq*e = 1 mod(q-1)
此外需要第三个元素,既q对p的逆元
3:计算qInv,使得qInv * q = 1 mod p
1 2 3 都作为私钥的一部分。

计算
使用公钥加密:
若要加密明文m,则需要计算c = m^e mod n,c为密文。
使用私钥解密:

1:m1=c^dp mod p
2:m2=c^dq mod q
3:h= (qInv*((m1 - m2)mod p)) mod p
4:m = m2 + h*q
m就是明文。

举例子:

p=137
q=131
n = 137*131=17947
计算phi(n) = 136*130=17680
取e=3,计算e对于phi(n)的逆 ,d = 11787

可以使用我的工具执行如下命令
./a.out mod_inv "03" "2E0B"
我这里使用了欧几里得算法求逆元,大家感兴趣可以细究
3*d = 1 mod 17680
3*d - 17680*x = 1
-17680 = -5893*3 - 11 d=-5893, x=-12 d=11787, x=2

若要加密明文 513

使用公钥加密和使用私钥解密流程(传统方式):
密文为 513 ^ 3 mod 17947 = 8363
(可以使用命令 ./a.out mod_exp "0201" "03" "461B")
若要解密密文8363,则需要计算8363^11787 mod 17947 = 513 ,解密成功。
(可以使用命令 ./a.out mod_exp "20AB" "2E0B" "461B")

使用公钥加密和使用私钥解密流程(中国剩余定理):
预先计算
dp = 91
dq = 87
qInv = 114

则解密c=8363,执行如下计算即可:

m1 = c^dp mod p = 102
m2 = c^dq mod q = 120
h  = (qInv*((m1 - m2)modp))mod p 
   = (114*(-18 mod 137)) mod 137 
   = 114*119 mod 137 
   = 3
m = m2 + h*q = 120 + 3*131 = 513

多素数

为了强调多素数这个特性,我们把上面举例的RSA证书称之为单素数证书(实际上没有这个称呼)。

公钥生成
p=137
q=131
r=127

计算n=p*q*r=2279269
计算phi(n)=136*130*126=2227680
取e=19,计算e对phi(n)的逆元。既,求d,使得d满足d*19= 1 mod phi(n)
d=351739
(可以使用命令 ./a.out mod_inv "13" "21FDE0")

公钥(2279269, 19)
私钥(2279269, 351739)

使用公钥加密和使用私钥解密(传统方式):
若要加密513,
513^19 mod 2279269 = 768924
(可以使用命令 ./a.out mod_exp "0201" "13" "22C765")
若要解密 768924,
768924^351739 mod 2279269 = 513
(可以使用命令 ./a.out mod_exp "0BBB9C" "055DFB" "22C765")

这样的计算和单素数证书一样。但是比较愚蠢,有多素数可以用,为什么不用呢?

使用公钥加密和使用私钥解密(多素数下中国剩余定理):
预先计算:
dp = 19^-1 mod 137-1 = 43
dq = 19^-1 mod 131-1 = 89
dr = 19^-1 mod 127-1 = 73

若要解密密文 768924,则先计算
1:m1=768924^43 mod 137 = 102
2:m2=768924^89 mod 131 = 120
3:m3=768924^73 mod 127 = 5

等式1与等式2连列方程组计算:

qInv = 114(预先算好)
h = (qInv*((m1 - m2)mod p)) mod p 
  = (114*(-18 mod 137) mod 137 ) mod 137
  = 3
m12 = m2 + h*q = 120 + 3*131 = 513

1与2的通用解为
513+k1*(131*137)
等式1和2合并后, 算上等式3,则问题转化为:

m1=513  p=17947
m2=5    q=127

计算q对p的逆 qInv = 10316

h = (10316*((513 - 5)mod 17947)) mod 17947
  = 4
m = 5 + 4*127 = 513

多素数证书的好处

为了达到相同长度的n,n可以被分解为多个小的素数;小的素数越多,p,q,r,….rn就的值就越小。使用中国剩余定理就越快速。

多素数证书

私钥是多素数的证书,就是多素数证书。。。。。
这里写图片描述

  • 24
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
RSA算法是一种公钥加密算法,它是由三个数构成的密钥,分别是公钥、私钥和模数。在C语言,我们可以使用大数库GMP来处理大数运算,实现RSA加解密。 中国剩余定理是一种用于加速RSA加解密的算法,它可以将RSA加解密过程分解成多个小的模数运算,从而提高运算速度。 下面是一个使用C语言和GMP库实现RSA加解密,并使用中国剩余定理优化的示例代码: ```c #include <stdio.h> #include <gmp.h> // 生成RSA密钥对 void generate_keys(mpz_t p, mpz_t q, mpz_t n, mpz_t e, mpz_t d) { mpz_t phi, tmp; mpz_inits(phi, tmp, NULL); // 生成p和q,要求它们是质数 mpz_nextprime(p, tmp); mpz_nextprime(q, tmp); // 计算n和phi(n) mpz_mul(n, p, q); mpz_sub_ui(p, p, 1); mpz_sub_ui(q, q, 1); mpz_mul(phi, p, q); // 选择公钥e,要求它和phi(n)互质 mpz_set_ui(e, 65537); while (mpz_gcd(tmp, e, phi) != 1) { mpz_add_ui(e, e, 2); } // 计算私钥d mpz_invert(d, e, phi); mpz_clears(phi, tmp, NULL); } // RSA加密 void rsa_encrypt(char *msg, mpz_t n, mpz_t e, mpz_t c) { mpz_t m; mpz_init(m); // 将文本消息转换成大数 mpz_set_str(m, msg, 256); // 加密 mpz_powm(c, m, e, n); mpz_clear(m); } // RSA解密 void rsa_decrypt(mpz_t c, mpz_t n, mpz_t d, char *msg) { mpz_t m; mpz_init(m); // 解密 mpz_powm(m, c, d, n); // 将大数转换成文本消息 mpz_get_str(msg, 256, m); mpz_clear(m); } // 使用中国剩余定理优化的RSA加密 void rsa_encrypt_crt(char *msg, mpz_t p, mpz_t q, mpz_t n, mpz_t e, mpz_t d, mpz_t c) { mpz_t m, mp, mq, yp, yq, tmp; mpz_inits(m, mp, mq, yp, yq, tmp, NULL); // 将文本消息转换成大数 mpz_set_str(m, msg, 256); // 计算mp、mq、yp、yq mpz_mod(mp, m, p); mpz_mod(mq, m, q); mpz_invert(yp, q, p); mpz_invert(yq, p, q); // 加密 mpz_powm(tmp, mp, e, p); mpz_powm(c, mq, e, q); mpz_sub(tmp, c, tmp); mpz_mul(tmp, tmp, yq); mpz_mul(tmp, tmp, p); mpz_add(c, tmp, tmp); mpz_clears(m, mp, mq, yp, yq, tmp, NULL); } // 使用中国剩余定理优化的RSA解密 void rsa_decrypt_crt(mpz_t c, mpz_t p, mpz_t q, mpz_t n, mpz_t d, char *msg) { mpz_t m, cp, cq, yp, yq, tmp; mpz_inits(m, cp, cq, yp, yq, tmp, NULL); // 计算cp、cq、yp、yq mpz_mod(cp, c, p); mpz_mod(cq, c, q); mpz_invert(yp, q, p); mpz_invert(yq, p, q); // 解密 mpz_powm(tmp, cp, d, p); mpz_powm(cq, cq, d, q); mpz_sub(tmp, cq, tmp); mpz_mul(tmp, tmp, yp); mpz_mul(tmp, tmp, p); mpz_add(m, tmp, tmp); // 将大数转换成文本消息 mpz_get_str(msg, 256, m); mpz_clears(m, cp, cq, yp, yq, tmp, NULL); } int main() { mpz_t p, q, n, e, d, c; char msg[1024], decrypted_msg[1024]; mpz_inits(p, q, n, e, d, c, NULL); // 生成RSA密钥对 generate_keys(p, q, n, e, d); // 输入要加密的文本消息 printf("Enter message to encrypt: "); scanf("%s", msg); // 加密 rsa_encrypt(msg, n, e, c); gmp_printf("Encrypted message: %Zx\n", c); // 解密 rsa_decrypt(c, n, d, decrypted_msg); printf("Decrypted message: %s\n", decrypted_msg); // 使用中国剩余定理优化的RSA加密 rsa_encrypt_crt(msg, p, q, n, e, d, c); gmp_printf("Encrypted message (CRT): %Zx\n", c); // 使用中国剩余定理优化的RSA解密 rsa_decrypt_crt(c, p, q, n, d, decrypted_msg); printf("Decrypted message (CRT): %s\n", decrypted_msg); mpz_clears(p, q, n, e, d, c, NULL); return 0; } ``` 在上面的示例代码,我们定义了`generate_keys`函数来生成RSA密钥对,`rsa_encrypt`和`rsa_decrypt`函数用于RSA加密和解密,`rsa_encrypt_crt`和`rsa_decrypt_crt`函数使用中国剩余定理优化了RSA加解密过程。在`main`函数,我们首先生成RSA密钥对,然后输入要加密的文本消息,进行RSA加解密和使用中国剩余定理优化的RSA加解密,并输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值