在Python中使用numpy加密

hpxqektj  于 2023-08-05  发布在  Python
关注(0)|答案(3)|浏览(145)

我正在使用Anaconda Navigator的Jupyter Notebook。我正在尝试加密(RSA算法)一个二维NumPy数组。使用dtype=np.float128时,显示AttributeError: module 'numpy' has no attribute 'float128'
Bmatrix是:
[[ 13 109 207 307 416][ 11 24 122 224 333] [ 15 32 53 155 268] [ 4 17 37 68 191]] <class 'numpy.ndarray'>

encrypted_matrix = np.mod(np.power(Bmatrix, 17, dtype=np.float64), 703)
print(encrypted_matrix)

字符串
[[153. 142. 445. 120. 28.] [ 11. 296 567 125 128.] [ 53. 612 216 166 511.] [366. 459 365 21 360.] [176. 106、564、378。560.]]
预期的输出:[[153 394 162 81 534] [535 167 560 545 218] [64 612 582 166 629] [698 459 451 127 181] [176 161 37 216 191]]

vuktfyat

vuktfyat1#

官方页面:
https://numpy.org/doc/stable/user/basics.types.html
我引述如下:NumPy没有提供比C的long double更精确的类型;特别是,128位IEEE四精度数据类型(FORTRAN的真实的 *16)不可用。
你将不得不使用另一种解决方法,把它放在264位浮点数中。

a0zr77ik

a0zr77ik2#

两种解决方案。
一个是不要使用numpy,因为numpy的数量是有限的。所以只要用python的int就可以了(也就是大int)

# That's your matrix. But I had to add all the comas myself. That is painful. 
# Please, next time, post a minimal reproducible example. You get less help
# when you make the life of people who might help you more difficult
B=[[ 96, 205, 325, 460, 599], [ 13, 109, 207, 307, 416], [ 11, 24, 122, 224, 333], [ 15, 32, 53, 155, 268], [ 4, 17, 37, 68, 191]]

Bpow17 = [[x**17 for x in line] for line in B]
Bpow17mod703 = [[x%703 for x in line] for line in Bpow17]

# Or, in one line
Res=[[(x**17)%703 for x in line] for line in B]

字符串
或者,如果你坚持使用numpy,那么你必须确保你永远不会溢出int的大小。(如果使用浮点数,溢出甚至更容易,即使它采用另一种形式。这并不是说你完全溢出,因为最大值比相同大小的int类型大得多。但是,当价值上升时,准确性就会下降。直到精度甚至不能确保整数值的程度。而且float64能够编码的确切整数的数量低于你可以用int64编码的确切整数的数量。因此,当你需要精确的int值时,不要仅仅因为理论上的最大值更大而使用float。这不是,在你的情况下,权衡“更大的价值,以换取更小的准确性”。是“更大的价值,以换取它不工作”。
但即使使用int,**17也会溢出。
所以诀窍是永远不要直接计算96**17 % 703这样的值。
模运算的技巧是a*b≡c[703]当且仅当a'≡a[703]b'≡b[703]a'*c'≡c[703]
例如1051*2344%703232。但1051%7033482344%703235。所以348*235%703也是232
所以,同样的结果。但操作是用较小的值完成的。因此溢出的风险较小(在直接情况下,它使用2463544中间结果,如果之前计算%703,则更大的中间结果为81780)
实际上,用numpy,你可以计算出

B=np.array([[ 96, 205, 325, 460, 599], [ 13, 109, 207, 307, 416], [ 11, 24, 122, 224, 333], [ 15, 32, 53, 155, 268], [ 4, 17, 37, 68, 191]], dtype=np.uint32)
# Note: I could skip the dtype since by default, numpy would create a `int64` array. 
# But I prefer explicit. Plus, I use `int32` to further demontrate how this avoid
# yet even easier overflow

B2=B**2%703
B4=B2**2%703
B8=B4**2%703
B16=B8**2%703
B17=B16*B%703


结果是预期的结果。
您可以将其推广到其他值

def powmod(M, p, m):
   if p==1: return M%m
   X=powmod(M, p//2, m)
   if p%2:
      return X*X*M%m
   else:
      return X*X%m

pkbketx9

pkbketx93#

我将添加另一个解决方案,而不提供代码:研究 * 模运算 *。注意,模乘法已经不需要执行全乘法。你知道这一点是因为你可以计算(625 x 3405)% 10 = 5而不需要接触大部分数字。RSA中使用的模幂运算也有类似的技巧。这些类型的函数不会将值扩展到比模数更高的值。

相关问题