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