-4

Anyone have an idea on how to implement such a problem in java ?

"Implement a subroutine that takes three positive integer arguments (a; b; n) and returns the value of ( (a to the power of b) mod n), where the arguments are represented by about 100 decimal digits. Using four different methods."

Thanks in advance

UPD : Methods were be as following

M1)

public BigInteger Result1(BigInteger a , BigInteger b , BigInteger n){
    BigInteger Res = new BigInteger("1");
    for (BigInteger i = new BigInteger("0"); !i.equals(b); i = i.add(new BigInteger("1"))) {
        Res = Res.multiply(a).mod(n);
    }
    return Res;
}

M2)

public BigInteger Result2(BigInteger a , BigInteger b , BigInteger n){
    BigInteger Res = new BigInteger("1");
    for (BigInteger i = new BigInteger("0"); !i.equals(b); i = i.add(new BigInteger("1"))) {
        Res = Res.multiply(a);
    }
    return Res.mod(n);
}

M3)

ublic BigInteger Result3(BigInteger a , BigInteger b , BigInteger n){
    if(b.equals(new BigInteger("0"))){
        return new BigInteger("1");
    }
    else if(b.mod(new BigInteger("2")).equals(new BigInteger("0"))){
        BigInteger Res = Result3(a,b.divide(new BigInteger("2")),n);
        return (Res.multiply(Res)).mod(n);
    }
    else{
        return ( (a.mod(n)).multiply(Result3(a, b.subtract(new BigInteger("1")), n)) ).mod(n);
    }
}

M4)

public BigInteger Result4(BigInteger a , BigInteger b , BigInteger n){
    BigInteger Res = new BigInteger("1");
    while(!b.equals(new BigInteger("0"))) {
        if(!(b.mod(new BigInteger("2"))).equals(new BigInteger("0"))) {
            Res = Res.multiply(a).mod(n);
        }
        a = a.multiply(a).mod(n);
        b = b.divide(new BigInteger("2"));
    }
    return Res;
}

3 Answers3

1

To answer your question directly, I think BigInteger.modPow might be what you're looking for.

public BigInteger modPow(BigInteger exponent,
                     BigInteger m)

Returns a BigInteger whose value is (this^exponent mod m)

Alternatively (and more efficiently), you could also take (a mod n) to the (b mod n) power, this should make the code run much quicker.

(a^b mod n) = ((a mod n)^(b mod n) mod n)

Alan L
  • 69
  • 2
  • 3
    (a^b mod n) is not the same as ((a mod n)^(b mod n) mod n). If a=2, b=5, n=3, the first is 2 whereas the second is 1. – Paul Boddington Dec 19 '14 at 01:51
  • @pbabcdefp you can in general reduce the exponent modulo the order of the multiplicative group, which is totient(n), if you know it. But for public-key crypto, which is the only common realworld application of large integer modexp, the numbers are chosen so that a is already mod n and b is already mod totient(n). – dave_thompson_085 Dec 19 '14 at 15:38
  • @dave_thompson_085 You can only reduce it if the base modulo n is actually an element of the multiplicative group, which it may not be. For example, if n = 4, the order of the multiplicative group is 2. But if you work out 2 ^ 2 mod 4 you get 0. Reducing the power by 2 you get 2 ^ 0 = 1 mod 4. I know my number theory! – Paul Boddington Dec 19 '14 at 15:45
0

You can use the BigInteger class for this if you aren't desperately needing performance. BigInteger is immutable.

public static BigInteger getValue(int a, int b, int n) {
    return BigInteger.valueOf(a).modPow(BigInteger.valueOf(b), BigInteger.valueOf(n));
}
Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
mkobit
  • 43,979
  • 12
  • 156
  • 150
  • 1
    Horribly inefficient- the right answer is a CS/math trick about what's actually needed to be calculated. – Gabe Sechan Dec 19 '14 at 01:34
  • @GabeSechan I don't see how this a "wrong answer." He didn't say anything about his other requirements. – mkobit Dec 19 '14 at 01:38
  • 1
    @GabeSechan you've obviously not looked at the implementation of `BigInteger.modPow()` – gknicker Dec 19 '14 at 01:45
  • @GabeSechan Considering he tagged the question with **BigInteger** it seemed as though that is what he was asking for. But maybe I read it wrong and should just go "quit this field permanently." – mkobit Dec 19 '14 at 01:47
  • 1
    Well, for one thing your answer is just wrong anyway- he said a b and n can have hundreds of digits and you're passing them in as integers. THe other guy answered with modPow more correctly. – Gabe Sechan Dec 19 '14 at 01:51
  • @gknicker, in Gabe's defense the original answer was something along the lines of `return BigInteger.valueOf(a).pow(b).mod(BigInteger.valueOf(n));` – Arthur Weborg Dec 19 '14 at 01:51
  • @ArtyMcFly Thanks, I thought that's what I originally saw. – Gabe Sechan Dec 19 '14 at 01:52
0

Flustered this was put on hold...

For the sake of theory, if you wanted to write your own custom method please check the following out, based on a math trick to avoid the computation. First the solution, and then the math behind it.

Your subroutine could look something like the following:

public static BigInteger customPowMod(BigInteger a, BigInteger b, BigInteger n){
    BigInteger previous = a.mod(n);
    BigInteger runningTotal = new BigInteger("1");
    for(int i = 0; i < a.bitLength(); i++){
        if(a.testBit(i)){
            runningTotal = runningTotal.multiply(previous);
        }
        previous = previous.multiply(previous).mod(n);
    }
    return runningTotal.mod(n);
}

The following is an example of how you could call the method:

public static void main(String[] args) {
    BigInteger a = new BigInteger("1700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
    BigInteger b = new BigInteger("6300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
    BigInteger n = new BigInteger("50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
    //note the following produce the same values
    System.out.println(customPowMod(a,b,n)); 
    System.out.println(a.modPow(b,n));
}

Now for the explanation

I'm doing smaller numbers for the sake of explaining things... it's the process by hand that get's turned into the code at the end.

  • let a = 17
  • let b = 63
  • let n = 5

First you want to see what base2 powers your power number b is composed of. For example:

63 = 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 = 32 + 16 + 8 + 4 + 2 + 1.

OR in binary 11111

This can be found programatically by iterating from 0 to our BigInteger b's .bitLength() and and checking with .testBit() the given bits. Hence the for-loop in the Java code.

Next we find multiples of your base modulus (n) target (you need to go as far out in value as your highest power of two from the previous segment):

let us call each simplified value a<power_of_2>.

  • a mod n = a1
  • a^2 mod n = a2
  • a^4 mod n = (a2)^2 mod n = a4 mod n
  • a^8 mod n = (a4)^2 mod n = a8 mod n
  • ...

and the by hand values:

  • 17^1 % 5 = 2
  • 17^2 % 5 = 2^2 mod 5 = 4 mod 5 = 4
  • 17^4 % 5 = 4^2 mod 5 = 16 mod 5 = 1
  • 17^8 % 5 = 1^2 mod 5 = 1 mod 5 = 1
  • 17^16 % 5 = 1^2 mod 5 = 1 mod 5 = 1
  • 17^32 % 5 = 1^2 mod 5 = 1 mod 5 = 1

Problematically this can be done in sync with the previous step of finding the base2 powers, each iteration you also find the newest a<power_of_2>. Each additional square needs to be calculated until we've hit the max value, hence the ever increasing previous value in the loop.

Lastly, we take our neccessary a values and multiple them by each other, followed by modulus of our n. this is within the if statement of the foor-loop.

  • Again, we have the powers: 32 + 16 + 8 + 4 + 2 + 1

and from the above step we have take the values and multiple them together (followed by the modulus at the end of the loop):

1 * 1 * 1 * 1 * 4 * 2 % 5 = 8 % 5 = 3

Arthur Weborg
  • 8,280
  • 5
  • 30
  • 67