Java中的模块化指数

时间:2010-11-01 06:10:36

标签: java math modulus dsa exponentiation

我需要一种计算方法:

(g^u * y^v) mod p

在Java中。

我发现这个算法用于计算(g ^ u)mod p:

int modulo(int a,int b,int c) {
    long x=1
    long y=a;
    while(b > 0){
        if(b%2 == 1){
            x=(x*y)%c;
        }
        y = (y*y)%c; // squaring the base
        b /= 2;
    }
    return (int) x%c;
}

并且效果很好,但我似乎找不到为

做到这一点的方法
(g^u * y^v) mod p

因为我的数学技能很低落。

要把它放在上下文中,它是用于“减少”DSA的java实现 - 验证部分要求解决这个问题。

3 个答案:

答案 0 :(得分:9)

假设这两个因素不会溢出,我相信你可以用这种方式简化这样的表达式:

(x * y) mod p = ( (x mod p)*(y mod p) ) mod p。我相信你可以从那里弄明白。

答案 1 :(得分:4)

该代码片段实现了众所周知的“快速取幂”算法,也称为Exponentiation by squaring

它还使用(a * b)mod p =((a mod p)*(b mod p))mod p的事实。 (加法和乘法都是采用素数模的保留结构 - 它是同态)。这种方式在算法的每个点都减少到小于p的数字

虽然您可以尝试在循环中以交错的方式计算这些,但这样做并没有什么好处。只需单独计算它们,将它们相乘,最后一次取mod。

请注意,如果p ^ 2大于最大可表示的int,您将会溢出,这将导致您得到错误的答案。对于Java,切换到大整数可能是谨慎的,或者至少对p的大小进行运行时检查并抛出异常。

最后,如果这是出于加密目的,您可能应该使用库来执行此操作,而不是自己实现它。做一些看起来有效的错误很容易,但提供的安全性很小甚至没有。

答案 2 :(得分:1)

尝试

  

(Math.pow(q,u)* Math.pow(y,v))%p