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

Math 如何实现c=m^e mod n的巨大数字?,math,encryption,cryptography,biginteger,bignum,Math,Encryption,Cryptography,Biginteger,Bignum,我正试图找出如何从头开始实现RSA crypto(只是为了进行智力练习),但我仍停留在这一点上: 对于加密,c=me mod n 现在,e通常是65537。m和n是1024位整数(例如128字节数组)。对于标准方法来说,这显然太大了。您将如何实现这一点 我在这里读了一些关于指数运算的书,但它对我来说并不合适: (见第14.85节) 谢谢 编辑:也发现了这个-这是我应该看的更多吗 对于一个有效的算法,您需要在每一步之后将平方求幂与重复应用mod相结合 对于奇数e,这适用于: me mod n=m

我正试图找出如何从头开始实现RSA crypto(只是为了进行智力练习),但我仍停留在这一点上:

对于加密,c=me mod n

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

我在这里读了一些关于指数运算的书,但它对我来说并不合适:

(见第14.85节)

谢谢


编辑:也发现了这个-这是我应该看的更多吗

对于一个有效的算法,您需要在每一步之后将平方求幂与重复应用
mod
相结合

对于奇数e,这适用于:

me mod n=m⋅ me-1模块n

对于e:

me模块n=(me/2模块n)2模块n

以m1=m为基本情况,这定义了一种进行有效模幂运算的递归方法


但即使使用这样的算法,因为m和n将非常大,您仍然需要使用能够处理此类大小整数的类型/库。

平方求幂:

让我们举个例子。你想找到1723。注意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是二进制的
100000000000001
,这使得所有这些都非常简单。基本上是

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 当e>0时: 如果(e&1)!=0: 结果=结果*m 结果=结果模块n m=m*m m=m模n e=e>>1 返回结果 这将检查指数中以最低有效位开始的位。每次我们向上移动一点,它就相当于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。

< p>如果<代码> g(x)=x mod 2 ^ k < /代码>对于你的bigm文库来说,比<代码> f(x)=x mod n < /> > n不能被2分割,更快地计算,然后考虑使用。当与模幂运算结合使用时,它避免了在每一步计算模N,您只需在开始和结束时进行“蒙哥马利化”/“非蒙哥马利化”。

Hmm。。。我想我想问的是,我只是想知道在实现它的时候从哪里开始。是的,你们应该看看模幂运算。主要的一点是在每一步重复模块化缩减,而不是在最后一步。记住,过早优化是万恶之源。实施一个简单的算法,如果需要一分钟以上的时间,找到最慢的部分并进行优化。在我的回答中,通过平方使用简单的求幂运算,可以将bigint运算的数量从130000减少到35,所以可能不需要再找到更快的运算了。这个答案太棒了。我要花点时间把它泡进去,这要花点时间!而且,为了实现的缘故,我需要做的就是为上面的乘法和模运算步骤实现一个bignum?你几乎肯定会错误地实现bignum。大数相乘和大数相加的问题几乎和指数法一样棘手。你不能使用一个自动处理的语言库吗?添加大的数字并不难。虽然Karatsuba算法并不难实现,但将它们相乘则更为棘手。我建议从一个库开始,然后用自己的实现替换它,如果你真的想的话。啊,好的:)。缓慢的乘法将通过平方法消除指数,因此在解决主要问题之前,您需要先获得正确的结果。当我上大学的时候,我的算法课上就出现了这组问题,大约80%的学生用乘法撞到了砖墙上。谢谢你发现了这一点。修正了。我们不是必须从最重要的位开始吗?见这里的VII.A:我的错误,你使用的是从右到左的二进制方法,这是一个与我所想的不同的算法:我本来打算写它,从左到右扫描,但当时看起来很麻烦。这样,您不需要查找MSB,但必须在每个循环中移动整个指数。这是一个小交易。N不能是偶数,例如26不能用于蒙哥马利乘法,但26不是2的幂。 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