我试图了解Java的BigInteger类的modPow和modInverse的行为,因为它们没有像我期望的那样工作。也许我错过了一些简单的东西,所以这里有一段非常简单的代码:
BigInteger a = BigInteger.valueOf(2);
BigInteger b = BigInteger.valueOf(5);
BigInteger n1 = new BigInteger(32, 100, new SecureRandom());
System.out.println("n = " + n1);
System.out.println("a^b = " + a.modPow(b, n1) + " ;; (a^b)^(b^-1) = " + a.modPow(b, n1).modPow(b.modInverse(n1), n1));
我得到的输出是:
n = 2664021049 (This is a random prime, can change each run)
a^b = 32 ;; (a^b)^(b^-1) = 4
现在,我希望最后一行中的4
为2
,因为它是(a^b)^(1/b) = a^(b*(1/b)) = a
这是否也适用于模数字段?
我做错了什么?
答案 0 :(得分:0)
我猜混淆来自那个
d
因为(5 * 532804210)mod 2664021049 == 1
之后:
b.modInverse(n1) == 532804210
=> 32 ^ b.modInverse(n1)mod 2664021049
=> 32 ^ 532804210 mod 2664021049 == 4
答案 1 :(得分:0)
简短回答:反转b
mod p-1
,而不是mod p
。 (如果b
不可翻转mod p-1
,则问题无法解决。)
虽然如果是x ≡ y (mod p)
,然后是x^z ≡ y^z (mod p)
,我们无法得出z^x ≡ z^y (mod p)
。例如,通过费马的小定理,
x^p ≡ x (mod p)
即使p ≡ 0 (mod p)
和x^0 = 1
。
然而,费马的小定理给了我们一个解决方案。对于整数x
和y
以及素数p
,如果我们可以找到z
mod y
的乘法逆p-1
,然后
(x^y)^z = x^(yz)
= x^(k(p-1) + 1) for some k
= (x^(p-1))^k * x
如果x ≡ 0 (mod p)
,则为(x^(p-1))^k * x ≡ x (mod p)
,因为双方都与0一致。
如果x !≡ 0 (mod p)
,我们可以从x^(p-1) ≡ 1 (mod p)
派生x^p ≡ x (mod p)
,我们有(x^(p-1))^k * x ≡ 1^k * x ≡ x (mod p)
。
因此,(x^y)^z ≡ x (mod p)
。
另一方面,如果y
不是可逆的mod p-1
,那么事实证明我们无法从x
恢复x^y
,因为有多种可能x
值。例如,对于x = 2, y = 3, p = 7
,我们有x^y ≡ 1 (mod p)
,但x
可能是1
。
答案 2 :(得分:-1)
请参阅此内容以了解BigInteger类的modPow()和modInverse()的行为。
modPow:
BigInteger numOne = new BigInteger("5");
BigInteger numTwo = new BigInteger("20");
BigInteger exponent = new BigInteger("3");
BigInteger MP = numOne.modPow(exponent, numTwo);
System.out.println(numOne + " ^ " + exponent + " mod " + numTwo + " = " + MP);
modInverse:
BigInteger numOne = new BigInteger("7");
BigInteger numTwo = new BigInteger("20");
BigInteger MI = numOne.modInverse(numTwo);
System.out.println(numOne + " ^-1 mod " + numTwo + " = " + MI);