numpy Python中的RSA实现

nafvub8i  于 2023-03-23  发布在  Python
关注(0)|答案(2)|浏览(158)

我试图实现RSA密码,这是我到目前为止的工作:

import numpy as np

def solve_diophantine_eqn(a: int, b: int, d: int):
    '''
    Solving ax + by = d, where a, b and d are given. \\
    Solving for x and y, where d is multiple of gcd(a, b)
    '''
    d_sol_gcd, d_sol_0 = apply_extended_euclidean(np.array((a, 1, 0)), np.array((b, 0, 1)))
    if d == 0:
        return d_sol_0[1], d_sol_0[2]
    return d_sol_gcd[1:] * d // d_sol_gcd[0]

def apply_extended_euclidean(a: np.ndarray, b: np.ndarray, d = 1):
    '''
    Solving ax + by = d, where a, b and d are given \\
    Solving for x and y, where d is multiple of gcd(a, b) \\
    Default case stopping at d = 0, because 0 is multiple of every integer
    '''
    if b[0] < d:
        return a, b
    q = a[0] // b[0]
    return apply_extended_euclidean(b, a - q*b, d)

# print(apply_extended_euclidean(np.array((12, 1, 0)), np.array((8, 0, 1))))
# x, y = solve_diophysis_eqn(12, 8, 0)
# print(x, y)

message = 7
p = 11                                      # Select any large prime p
q = 7                                       # Select any large prime q
n = p * q                                   # Let large natural number n be p*q
t_n = (p-1)*(q-1)                           # theta(n) is euler totient of n
e = t_n - 1                                 # e is coprime with theta(n)
d, _ = solve_diophantine_eqn(e, t_n, 1)     # Solve equation e*d + theta(n) * y = 1
d = d % t_n                                 # If d < 0, make d positive
print(d)
public_key = (e, n)
private_key = (d, n)
print(public_key)
print(private_key)
plaintext = message
print(plaintext)
ciphertext = plaintext ** d % n
print(ciphertext)
recievedtext = ciphertext ** e % n
print(recievedtext)

输出为:

59
(59, 77)
(59, 77)
7
43
63

奇怪的是,当使用计算器时,* C = M^d mod n * 的输出是63. x1c 0d1x即使当我单步执行程序时,当所有值都正确时,它仍然给出不正确的答案。
我不明白。有人能解释一下这是怎么回事吗?
先谢了!

jogvjijk

jogvjijk1#

尝试使用pow函数求幂

代替

ciphertext = plaintext ** d % n

尝试

ciphertext = pow(plaintext, int(d), n)

并对解密执行相同的操作。

使用大数和模时,pow优于**

它不是简单地先求幂再求模,而是边求幂边求模,这样可以避免错误。

35g0bw71

35g0bw712#

好吧,多亏了@Eureka的回答,我意识到正在使用的d实际上是一个numpy.intc,这把答案搞砸了。
d转换为int工作,并建议使用pow函数,正确的代码如下:

import numpy as np

def solve_diophantine_eqn(a: int, b: int, d: int):
    '''
    Solving ax + by = d, where a, b and d are given. \\
    Solving for x and y, where d is multiple of gcd(a, b)
    '''
    d_sol_gcd, d_sol_0 = apply_extended_euclidean(np.array((a, 1, 0)), np.array((b, 0, 1)))
    if d == 0:
        return d_sol_0[1], d_sol_0[2]
    return d_sol_gcd[1:] * d // d_sol_gcd[0]

def apply_extended_euclidean(a: np.ndarray, b: np.ndarray, d = 1):
    '''
    Solving ax + by = d, where a, b and d are given \\
    Solving for x and y, where d is multiple of gcd(a, b) \\
    Default case stopping at d = 0, because 0 is multiple of every integer
    '''
    if b[0] < d:
        return a, b
    q = a[0] // b[0]
    return apply_extended_euclidean(b, a - q*b, d)

# print(apply_extended_euclidean(np.array((12, 1, 0)), np.array((8, 0, 1))))
# x, y = solve_diophysis_eqn(12, 8, 0)
# print(x, y)

message = 7
p = 11                                      # Select any large prime p
q = 7                                       # Select any large prime q
n = p * q                                   # Let large natural number n be p*q
t_n = (p-1)*(q-1)                           # theta(n) is euler totient of n
e = t_n - 1                                 # e is coprime with theta(n)
d, _ = solve_diophantine_eqn(e, t_n, 1)       # Solve equation e*d + theta(n) * y = 1
d = d % t_n                                 # If d < 0, make d positive
print(d)
public_key = (e, n)
private_key = (d, n)
print(public_key)
print(private_key)
plaintext = message
print(plaintext)
ciphertext = pow(plaintext, int(d), n)
print(ciphertext)
recievedtext = pow(ciphertext, e, n)
print(recievedtext)

相关问题