Montgomery Multiplication如何在加速计算c = m ^ e%n的加密过程中使用RSA加密? 我知道蒙哥马利乘法可以有效地乘以a * b%n但是当试图找到m ^ e%n时,是否有一种更有效的方法来乘以m * me次数而不仅仅是循环并且每次计算蒙哥马利乘法?
mpz_class mod(mpz_class &m, mpz_class &exp, mpz_class &n) {
//End goal is to return m^exp%n
// cout << "Begin mod";
mpz_class orig_m = m; //the original message
mpz_class loc_m = m; //local value of m (to be changed as you cycle through)
cout << "m: " << m << " exp: " << exp << " n: " << n << endl;
//Conversion to the montgomery world
mpz_class mm_xp = (loc_m*r)%n;
mpz_class mm_yp = (orig_m*r)%n;
for(int i=0; i < exp-1; i++) //Repeat multiplaction "exp" number of times
{
mm(mm_xp, mm_yp, n); //montgomery multiplication algorithm returns m*orig_m%n but in the montgomery world form
}
mm_xp = (mm_xp*r_p)%n; //convert from montgomery world to normal numbers
return mm_xp;
}
我正在使用gmp库,所以我可以在这里使用更大的数字。 r和r_p在一个单独的函数中预先计算并且是全局的。在这个例子中,我正在以10的幂工作(虽然我意识到使用2的幂更有效率)
我在乘法之前转换为蒙哥马利形式,并在for循环中重复乘以m * m,在m ^ e步骤结束时转换回正常世界。我很想知道是否有另一种方法以不同的方式计算操作m ^ e%n,而不是仅仅在for循环中循环?截至目前,我认为这是计算的瓶颈,但我很可能是错的。
实际的蒙哥马利乘法步骤发生在下面的函数中。
void mm(mpz_class &ret, const mpz_class &y, const mpz_class &n)
{
mpz_class a = ret*y;
while(a%r != 0)
{
a += n;
}
ret = a/r; //ret*y%n in montgomery form
// cout << ret << endl;
}
这就是RSA加密如何与蒙哥马利乘法优化一起工作的?
答案 0 :(得分:1)
不,您不希望自己e
乘以m
来计算RSA。
您通常希望通过重复平方来做m e mod n(还有其他可能性,但这是一个很简单的适用于许多典型目的)。
在previous post on RSA中,我添加了一个使用pow_mod
函数的实现。反过来,它使用mul_mod
函数。蒙哥马利乘法(基本上)是mul_mod
函数的一种实现,它更适合处理大数。然而,为了使其有用,您至少需要对pow_mod
函数的一般顺序进行操作,而不仅仅是对e
进行mul_mod
调用的循环。
考虑到实际使用RSA所涉及的数量的大小,尝试使用重复乘法计算m e modn可能需要数年(很可能是相当多年)来完成甚至单个加密。换句话说,一个不同的算法不仅仅是一个很好的优化 - 它绝对有必要用于实用。
用算法来表示,使用普通乘法提高A B 基本上是O(B)。使用那里显示的重复平方算法,它基本上是O(log B)。如果B非常大,那么两者之间的区别是巨大的。