我需要一种计算方法:
(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实现 - 验证部分要求解决这个问题。
答案 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