如何为巨大的数字实现c = m ^ e mod n?

时间:2010-07-07 00:24:51

标签: math encryption cryptography biginteger bignum

我正在试图弄清楚如何从头开始实施RSA加密(仅用于智力练习),我坚持这一点:

对于加密,c = m e mod n

现在,e通常是65537.m和n是1024位整数(例如128字节数组)。对于标准方法来说,这显然太大了。你会如何实现这个?

我在这里读了一些关于取幂的内容,但它并没有点击给我:

Wikipedia-Exponentiation by squaring

This Chapter(参见第14.85节)

感谢。

编辑:也发现了这个 - 这是我应该看的更多内容吗? Wikipedia- Modular Exponentiation

4 个答案:

答案 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,你只需要在开始和结束时进行“蒙哥马利化”/“非蒙哥马利化”。