实验过程
编写程序调用gmpy.2的大素数生成算法,生成不同的素数。
import gmpy2
# 创建随机数生成器的状态
rs = gmpy2.random_state()
# 生成大素数
def create_prime():
p = gmpy2.mpz_urandomb(rs, 1024) # 随机生成一个0~2^1024的数
while not gmpy2.is_prime(p): # 判断生成的数是否是素数
p = gmpy2.mpz_urandomb(rs, 1024)
return p
编写RSA程序,在程序中调用大素数生成算法生成需要的素数。
# 生成RSA公钥和私钥
def generate_keypair():
# 调用素数生成函数生成两个素数
p = create_prime()
q = create_prime()
# p=2357
# q=2551
n = p * q # 计算模数
# print(n)
phi = (p - 1) * (q - 1) # 计算Euler函数值
e = gmpy2.next_prime(gmpy2.mpz(65537)) # 选择公钥e (通常选择65537)
# print(e)
# e=3674911
pub_key = (n, e)
print(f'生成的公钥为:({n},{e})')
d = gmpy2.invert(e, phi) # 计算私钥d
print('生成的私钥为:', d)
# 返回公钥和私钥
return pub_key, d
用较小的x<1,000,000,000尝试采用传统方法计算模指数,即
的方法。
# 传统方法计算模指数
def mod_exp(base, exp, modulus):
result = 1
for _ in range(exp):
result = (result * base) % modulus
return result
base = 5234673
exp = 3674911
modulus = 6012707
result = mod_exp(base, exp, modulus)
print(f'模指数计算结果为(传统方式):{result}')
尝试用模运算的快速算法计算模指数(称为重复平方相乘法),即将指数写成二进制的形式,如果b=35,可以写成b=1000011,则
x = 5234673 # 密文
y = 3674911 # 指数
m = 6012707 # 模
result = 1
while y > 0:
if y % 2 == 1:
result = (result * x) % m
x = (x * x) % m
y = y // 2
print("Result:", result)
最后,利用快速模指数运算法实现RSA加密与解密算法。
完整代码如下:
import gmpy2
# 创建随机数生成器的状态
rs = gmpy2.random_state()
# 生成大素数
def create_prime():
p = gmpy2.mpz_urandomb(rs, 100) # 随机生成一个数
while not gmpy2.is_prime(p): # 判断生成的数是否是素数
p = gmpy2.mpz_urandomb(rs, 100)
return p
# 生成RSA公钥和私钥
def generate_keypair():
# 调用素数生成函数生成两个素数
p = create_prime()
q = create_prime()
print(f'生成的大素数(即p、q)为:{p}、{q}')
# p=2357
# q=2551
n = p * q # 计算模数
# print(n)
phi = (p - 1) * (q - 1) # 计算Euler函数值
e = gmpy2.next_prime(gmpy2.mpz(65537)) # 选择公钥e (通常选择65537)
# print(e)
# e=3674911
pub_key = (n, e)
print(f'生成的公钥为:({n},{e})')
d = gmpy2.invert(e, phi) # 计算私钥d
print('生成的私钥为:', d)
# 返回公钥和私钥
return n, e, d
# 快速模指数运算
def mod_exp(base, exp, modulus):
result = 1
while exp > 0:
if exp % 2 == 1:
result = (result * base) % modulus
base = (base * base) % modulus
exp = exp // 2
return result
# RSA加解密
def rsa_encrypt(message, public_key, modulus):
return mod_exp(message, public_key, modulus)
def rsa_decrypt(ciphertext, private_key, modulus):
return mod_exp(ciphertext, private_key, modulus)
def main():
modulus, public_key, private_key = generate_keypair()
plaintext = int(input("请输入要加密的明文: "))
cipher = rsa_encrypt(plaintext, public_key, modulus)
print(f'明文:{plaintext}')
print(f'加密的结果为:{cipher}')
message = rsa_decrypt(cipher, private_key, modulus)
print(f'密文:{cipher}')
print(f'解密的结果为:{message}')
if __name__ == "__main__":
main()
运行结果
要判断编写的程序是否正确,可以使用已知正确的算法求出结果进行验证,例如用gmpy2库进行运算,与自己得出的结果比较。
import gmpy2
number1 = gmpy2.mpz(930171431646201037747253461007)
number2 = gmpy2.mpz(696068596238208926722796423131)
# 使用gmpy2库计算两个大数相乘
result_gmpy2 = number1 * number2
print(f'gmpy2计算得到的结果为:{result_gmpy2}')
# 使用自己实现的代码计算两个大数相乘
result_custom = 647463122686856263479122264333657511736515464117119781352917
# 比较结果是否一致
if result_gmpy2 == result_custom:
print('结果正确!')
else:
print('结果错误!')
可以检验程序的正确性。