我正在编写一个加密方法的代码,用于使用重复平方来计算x ^ d模数
public static long repeatedSquaring(long x, long d, long n){
x = x%n;
boolean dj = d % 2 == 1;
long c = dj ? x : 1;
d = d / 2;
while (d > 0){
dj = d % 2 == 1;
x = x * x % n; //Here
if (dj)
c = c * x % n; //and here..
d = d / 2;
}
return c;
}
当n
很小时,此代码可以正常工作。但是使用n > sqrt(Long.MAX_VALUE)
会产生意外结果。
由于使用x ≈ n
,我们可以x*x > Long.MAX_VALUE
,然后模数运算符会将不正确的值分配给x
(或c
)。
所以,我的问题是,我们如何只使用数学相关的方法计算(A * B)%N(都是long
类型)。
我不想使用BigInteger(BigA.multiply(BigB).remainder(BigN)
或我们可以直接使用BigX.modPow(BigD, BigN)
来解决这个大问题。)
我认为普通计算会比String计算运行得更快吗?除了我的问题,所有的临时值都是long
类型'足够的'。
我想知道解决方案在最坏的情况下可以正常工作:A, B, N <≈ Long.MAX_VALUE
。
答案 0 :(得分:1)
乘法可以在log(B)时间内与指数相似
if(b为奇数)a +乘(2 * a,(b-1)/ 2)mod N
否则乘以(2 * a,b / 2)mod N
这可以工作到longvalue / 2
答案 1 :(得分:1)
真的,简短的回答是你需要使用BigInteger
,即使你不想这样做。正如您所发现的那样,您目前采用的方法将超出long
的范围;即使您改进算法,使用long
仍然无法在答案中获得超过64位。
你说你用它来加密;但64位公钥加密是如此之弱,以至于比没有它更糟糕(因为它给出了一种错误的安全感)。对于公钥来说,即使1024位也不够,64位可能会或多或少地瞬间破解。
请注意,这与对称加密不同,其中密钥可以小得多。 (但即便如此,64位还不足以阻止业余黑客。)
请参阅this question,其中指出64位RSA可以在几分之一秒内破解......那是四年前的事了!