RSA
本文最后更新于:2024年7月2日 下午
公钥密码体制
保密 + 认证
RSA
RSA算法是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman于1977年发明,并以他们的姓氏首字母命名。RSA算法基于大数分解的难题,即分解两个大素数乘积的难度,这是RSA算法的安全基础。
主要步骤
1.密钥生成
- 选择两个大质数p和q。
- 计算n = p * q,n是加密密钥。
- 计算欧拉函数φ(n) = (p-1) * (q-1)。
- 选择一个小于φ(n)的整数e,使得e和φ(n)互质(即它们的最大公约数为1)。
- 计算d,使得e * d ≡ 1 (mod φ(n))。d是解密密钥。
2.密钥分发
- 公开n和e,作为公钥。
- 保密d,作为私钥。
3.加密
- 使用公钥(n和e)进行加密。
- 选择明文消息m(0 < m < n)。
- 计算密文c = m^e (mod n)。
4.解密
- 使用私钥(n和d)进行解密。
- 计算明文m = c^d (mod n)。
素性检验
试除法
(Trial Division)是一种简单但效率较低的素数检验方法。它通过尝试将给定的数n除以所有小于等于n的质数来判断n是否为素数。如果n可以被任何一个这样的质数整除,那么n就不是素数。如果n不能被任何一个这样的质数整除,那么n可能是素数。
试除法的步骤如下:
- 选择一个质数p,p可以是从2开始的任意质数。
- 计算n除以p的余数r。
- 如果r等于0,则n不是素数。
- 如果r不等于0,选择下一个质数p+1,重复步骤2和3。
- 如果对所有小于等于√n的质数p,n都不能被整除,那么n可能是素数。
这种方法的时间复杂度是O(n^1/2),因为它需要尝试所有小于等于√n的质数。因此,对于非常大的数,试除法非常慢。此外,试除法对于某些合数可能会产生假阳性,即错误地判断合数为素数。
在实际应用中,试除法通常用于较小的数或者作为其他更高效素性检验方法的辅助。对于较大的数,通常会使用米勒-拉宾素性检验等更高效的概率性方法。
示例
1 |
|
在这个例子中,is_prime
函数用于执行试除法。它首先检查n是否小于等于1,如果是,则返回False。然后,它检查n是否小于等于3,如果是,则返回True。接下来,它检查n是否可以被2整除,如果是,则返回False。最后,它通过循环检查n是否可以被所有小于等于n的奇数整除。如果n不能被任何一个这样的数整除,那么它可能是素数。
米勒-拉宾素性检验
(Miller-Rabin Primality Test)是一种概率性素性检验算法,用于判断一个数是否为素数。该算法基于一个称为费马小定理的数学原理,并经过优化,使其具有较高的效率和较低的错误率。
米勒-拉宾素性检验的基本步骤如下:
- 选择一个随机数a,a是2到n-2之间的整数。
- 计算r = n - 1,然后找到r的欧几里得算法除数d,满足d * 2^r ≡ 1 (mod n)。
- 计算x = a^d (mod n)。
- 如果x = 1或x = n-1,则n可能是素数。
- 对于k = 0到s-1,执行以下步骤:
- 将r除以2,得到r_i = r / 2^i。
- 计算x = x^2 (mod n)。
- 如果x = 1,则n是合数。
- 如果x = n-1,则继续下一次迭代。
- 如果x^r_i ≡ -1 (mod n),则n是合数。
- 如果所有迭代都没有发现n是合数,则n是素数。
其中,s是测试的迭代次数,s越大,错误率越低。
示例
1 |
|
在这个例子中,miller_rabin
函数用于执行米勒-拉宾素性检验。我们选择了一个随机数a,并进行了s次迭代。如果n通过了所有迭代,则我们认为是素数。如果n没有通过所有迭代,我们仍然不能确定它是合数,因为我们使用的是概率性测试。
快速模幂算法
(Fast Modular Exponentiation)是一种用于计算大数模幂运算的算法,其时间复杂度为O(log n),其中n是指数的大小。这种算法特别适用于RSA加密算法中的密钥生成和加密过程。
快速模幂算法的基本思想是将指数n分解为二进制形式,并利用模运算的性质来简化计算。
具体步骤如下:
- 初始化:
- 设置结果
result = 1
。 - 设置底数
base = base
。 - 设置模数
modulus = modulus
。
- 设置结果
- 二进制分解:
- 将指数n转换为二进制形式,并计算其长度
bit_length = len(bin(n)) - 2
。
- 将指数n转换为二进制形式,并计算其长度
- 循环计算:
- 循环
i = 0
到bit_length - 1
。 - 在每次迭代中,将
result
乘以result
(即result = result * result mod modulus
)。 - 如果
n & (1 << i)
等于1(即二进制位的值为1),则将base
乘以result
(即result = base * result mod modulus
)。
- 循环
- 返回结果:
- 循环结束后,
result
将是base^n mod modulus
的结果。
快速模幂算法的一个关键优化是使用模平方来减少乘法运算。这样可以避免在每次迭代中都需要进行乘法运算,从而显著提高算法的效率。
- 循环结束后,
示例
1 |
|
在这个例子中,fast_mod_pow
函数用于计算 base^exponent mod modulus
。我们首先将指数转换为二进制形式,然后使用循环和模平方来计算结果。最后,我们打印出计算结果。
扩展欧几里得算法
扩展欧几里得算法(Extended Euclidean Algorithm)是欧几里得算法的一个变体,它不仅找到两个整数a和b的最大公约数gcd(a, b),还找到一组整数x和y,使得等式ax + by = gcd(a, b)成立。这组整数x和y被称为扩展欧几里得算法的解。
扩展欧几里得算法的基本步骤如下:
- 如果a等于0,那么gcd(a, b)就是b,x是0,y是1。
- 如果b等于0,那么gcd(a, b)就是a,x是1,y是0。
- 否则,计算gcd(b, a % b),并设x1、y1为x和y的值。
- 设置新的a为原来的b,新的b为x1,新的x为y1,新的y为x - (a // b) * y1。
- 重复步骤3和4,直到b为0。
扩展欧几里得算法的时间复杂度是O(log(min(a, b))),因为每一步都减半了b的大小。
示例
1 |
|
在这个例子中,extended_euclidean
函数用于计算 gcd(a, b)
以及满足等式 ax + by = gcd(a, b)
的整数x和y。我们首先检查a是否等于0,如果是,则返回b和相应的x、y值。否则,我们递归地调用扩展欧几里得算法,直到b为0。最后,我们打印出gcd、x和y的值。
RSA代码实现
1 |
|