我正在试图弄清楚如何从头开始实施RSA加密(仅用于智力练习),我坚持这一点:
对于加密,c = m e mod n
现在,e通常是65537.m和n是1024位整数(例如128字节数组)。对于标准方法来说,这显然太大了。你会如何实现这个?
我在这里读了一些关于取幂的内容,但它并没有点击给我:
Wikipedia-Exponentiation by squaring
This Chapter(参见第14.85节)
感谢。
编辑:也发现了这个 - 这是我应该看的更多内容吗? Wikipedia- Modular Exponentiation
答案 0 :(得分:8)
通过平方来表示:
我们举一个例子。你想找到17 23 。请注意,23是二进制的10111
。让我们尝试从左到右构建它。
// a exponent in binary
a = 17 //17^1 1
a = a * a //17^2 10
a = a * a //17^4 100
a = a * 17 //17^5 101
a = a * a //17^10 1010
a = a * 17 //17^11 1011
a = a * a //17^22 10110
a = a * 17 //17^23 10111
当你平方时,你将指数加倍(向左移1位)。当您乘以m时,将1加到指数中。
如果你想减少模n
,你可以在每次乘法后做到(而不是把它留到最后,这会使数字变得非常大)。
65537是二进制的10000000000000001
,这使得所有这一切变得非常简单。这基本上是
a = m
repeat 16 times:
a = a * a
a = a mod n
a = a * m
a = a mod n
当然a,n和m是“大整数”。 a需要至少为2048位,因为它可以达到(n-1) 2 那么大。
答案 1 :(得分:3)
对于有效的算法,您需要在每个步骤后通过平方和重复应用mod
来组合取幂。
对于奇数 e ,它有:
m e mod n = m·m e-1 mod n
即使 e :
m e mod n =(m e / 2 mod n) 2 mod n
以 m 1 = m 作为基本情况,这定义了一种进行有效模幂运算的递归方法。
但是即使使用这样的算法,因为 m 和 n 会非常大,你仍然需要使用一个可以处理这样的整数的类型/库尺寸。
答案 2 :(得分:3)
result = 1 while e>0: if (e & 1) != 0: result = result * m result = result mod n m = m*m m = m mod n e = e>>1 return result
这将检查指数中从最低有效位开始的位。每次我们向上移动一点,它对应于m的功率加倍 - 因此我们移动e和平方m。如果指数在该位置具有1位,则结果仅获得m的乘积。所有乘法都需要减少mod n。
作为一个例子,考虑m ^ 13。 11 = 1101二进制。所以这与m ^ 8 * m ^ 4 * m相同。注意功率8,4,(不是2),1与比特1101相同。然后回想起m ^ 8 =(m ^ 4)^ 2和m ^ 4 =(m ^ 2)^ 2。
答案 3 :(得分:1)
如果您的bignum资料库计算g(x) = x mod 2^k
的速度比f(x) = x mod N
更快,因为N不能被2整除,请考虑使用Montgomery multiplication。当与模幂运算一起使用时,它避免了必须在每一步计算模N,你只需要在开始和结束时进行“蒙哥马利化”/“非蒙哥马利化”。