如何对大量数字实现 c=m^e mod n?
我试图弄清楚如何从头开始实现 RSA 加密(只是为了智力练习),但我坚持这一点:
对于加密,c = me mod n
现在,e通常是 65537。m 和 n 是 1024 位整数(例如 128 字节数组)。这对于标准方法来说显然太大了。你会如何实施这个?
我在这里读了一些关于幂的内容,但它只是不适合我:
本章(参见第 14.85 节)
谢谢。
编辑:还发现了这个 - 这是我应该看的吗? 维基百科-模幂
I'm trying to figure out how to implement RSA crypto from scratch (just for the intellectual exercise), and i'm stuck on this point:
For encryption, c = me mod n
Now, e is normally 65537. m and n are 1024-bit integers (eg 128-byte arrays). This is obviously too big for standard methods. How would you implement this?
I've been reading a bit about exponentiation here but it just isn't clicking for me:
Wikipedia-Exponentiation by squaring
This Chapter (see section 14.85)
Thanks.
edit: Also found this - is this more what i should be looking at? Wikipedia- Modular Exponentiation
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
通过平方求幂:
让我们举个例子。您想要查找 1723。请注意,23 在二进制中是
10111
。让我们尝试从左到右构建它。平方时,指数加倍(左移 1 位)。乘以 m 时,指数加 1。
如果你想减少模
n
,你可以在每次乘法之后进行(而不是把它留到最后,这会使数字变得非常大)。65537 是二进制的 10000000000000001 ,这使得这一切变得非常简单。基本上,
a、n 和 m 当然是“大整数”。 a 需要至少为 2048 位,因为它可以大到 (n-1)2。
Exponentiation by squaring:
Let's take an example. You want to find 1723. Note that 23 is
10111
in binary. Let's try to build it up from left to right.When you square, you double the exponent (shift left by 1 bit). When you multiply by m, you add 1 to the exponent.
If you want to reduce modulo
n
, you can do it after each multiplication (rather than leaving it to the end, which would make the numbers get very large).65537 is
10000000000000001
in binary which makes all of this pretty easy. It's basicallywhere of course a, n and m are "big integers". a needs to be at least 2048 bits as it can get as large as (n-1)2.
为了获得高效的算法,您需要在每一步之后通过重复应用
mod
来组合求幂。对于奇数e,这成立:
对于偶数 e:
与 m1 = m 作为基本情况,它定义了一种递归方法来进行有效的模幂运算。
但即使使用这样的算法,由于 m 和 n 将非常大,您仍然需要使用可以处理此类大小的整数的类型/库。
For an efficient algorithm you need to combine the exponentiation by squaring with repeated application of
mod
after each step.For odd e this holds:
For even e:
With m1 = m as a base case this defines a recursive way to do efficient modular exponentiation.
But even with an algorithm like this, because m and n will be very large, you will still need to use a type/library that can handle integers of such sizes.
这会检查指数中从最低有效位开始的位。每次我们向上移动一点,它对应于 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。
This checks bits in the exponent starting with the least significant bit. Each time we move up a bit it corresponds to doubling the power of m - hence we shift e and square m. The result only gets the power of m multiplied in if the exponent has a 1 bit in that position. All multiplications need to be reduced mod n.
As an example, consider m^13. 11 = 1101 in binary. so this is the same as m^8 * m^4 * m. Notice the powers 8,4,(not 2),1 which is the same as the bits 1101. And then recall that m^8 = (m^4)^2 and m^4 = (m^2)^2.
如果对于您的 bignum 库来说,对于 N 不能被 2 整除,
g(x) = x mod 2^k
的计算速度比f(x) = x mod N
更快,那么考虑使用蒙哥马利乘法。当与模幂一起使用时,它避免了在每一步计算模N,你只需要在开始和结束时进行“蒙哥马利化”/“非蒙哥马利化”。If
g(x) = x mod 2^k
is faster to calculate for your bignum library thanf(x) = x mod N
for N not divisible by 2, then consider using Montgomery multiplication. When used with modular exponentiation, it avoids having to calculate modulo N at each step, you just need to do the "Montgomeryization" / "un-Montgomeryization" at the beginning and end.