RSA中的蒙哥马利乘法:c = m ^ e%n

时间:2016-03-03 01:29:52

标签: c++ encryption optimization rsa montgomery-multiplication

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加密如何与蒙哥马利乘法优化一起工作的?

1 个答案:

答案 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非常大,那么两者之间的区别是巨大的