I am trying to understand the behavior of modPow and modInverse of Java's BigInteger class as they do not work as I would expect. Maybe I am missing something simple, so here is a very simple piece of code:
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));
The output I get is:
n = 2664021049 (This is a random prime, can change each run)
a^b = 32 ;; (a^b)^(b^-1) = 4
Now, I would expect the 4 there in the last line to be 2, as it is (a^b)^(1/b) = a^(b*(1/b)) = a
Should this also work in a modulo field?
What am I doing wrong?
Short answer: Invert b mod p-1, not mod p. (If b isn't invertible mod p-1, the problem is unsolvable.)
While it is the case that if x ≡ y (mod p), then x^z ≡ y^z (mod p), we cannot conclude that z^x ≡ z^y (mod p). For example, by Fermat's Little Theorem,
x^p ≡ x (mod p)
even though p ≡ 0 (mod p), and x^0 = 1.
However, Fermat's Little Theorem gives us a solution. For integers x and y and a prime modulus p, if we can find a multiplicative inverse z for y mod p-1, then
(x^y)^z = x^(yz)
= x^(k(p-1) + 1) for some k
= (x^(p-1))^k * x
If x ≡ 0 (mod p), then (x^(p-1))^k * x ≡ x (mod p) because both sides are congruent to 0.
If x !≡ 0 (mod p), then we can derive x^(p-1) ≡ 1 (mod p) from x^p ≡ x (mod p), and we have (x^(p-1))^k * x ≡ 1^k * x ≡ x (mod p).
Thus, (x^y)^z ≡ x (mod p).
On the other hand, if y is not invertible mod p-1, then it turns out we can't recover x from x^y, because there are multiple possible x values. For example, with x = 2, y = 3, p = 7, we have x^y ≡ 1 (mod p), but x could have been 1.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With