Home | History | Annotate | Download | only in math
      1 /*
      2  *  Licensed to the Apache Software Foundation (ASF) under one or more
      3  *  contributor license agreements.  See the NOTICE file distributed with
      4  *  this work for additional information regarding copyright ownership.
      5  *  The ASF licenses this file to You under the Apache License, Version 2.0
      6  *  (the "License"); you may not use this file except in compliance with
      7  *  the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  *  Unless required by applicable law or agreed to in writing, software
     12  *  distributed under the License is distributed on an "AS IS" BASIS,
     13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  *  See the License for the specific language governing permissions and
     15  *  limitations under the License.
     16  */
     17 /**
     18  * @author Elena Semukhina
     19  */
     20 
     21 package org.apache.harmony.tests.java.math;
     22 
     23 import junit.framework.TestCase;
     24 import java.math.BigInteger;
     25 
     26 /**
     27  * Class:   java.math.BigInteger
     28  * Methods: modPow, modInverse, and gcd
     29  */
     30 public class BigIntegerModPowTest extends TestCase {
     31 	/**
     32 	 * modPow: non-positive modulus
     33 	 */
     34 	public void testModPowException() {
     35 		byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
     36 		byte eBytes[] = {1, 2, 3, 4, 5};
     37 		byte mBytes[] = {1, 2, 3};
     38 		int aSign = 1;
     39 		int eSign = 1;
     40 		int mSign = -1;
     41 		BigInteger aNumber = new BigInteger(aSign, aBytes);
     42 		BigInteger exp = new BigInteger(eSign, eBytes);
     43 		BigInteger modulus = new BigInteger(mSign, mBytes);
     44 		try {
     45 			aNumber.modPow(exp, modulus);
     46 			fail("ArithmeticException has not been caught");
     47 		} catch (ArithmeticException e) {
     48 		}
     49 
     50         try {
     51             BigInteger.ZERO.modPow(new BigInteger("-1"), new BigInteger("10"));
     52             fail("ArithmeticException has not been caught");
     53         } catch (ArithmeticException e) {
     54             // expected
     55         }
     56 	}
     57 
     58 	/**
     59 	 * modPow: positive exponent
     60 	 */
     61 	public void testModPowPosExp() {
     62 		byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75, 48, -7};
     63 		byte eBytes[] = {27, -15, 65, 39};
     64 		byte mBytes[] = {-128, 2, 3, 4, 5};
     65 		int aSign = 1;
     66 		int eSign = 1;
     67 		int mSign = 1;
     68 		byte rBytes[] = {113, 100, -84, -28, -85};
     69 		BigInteger aNumber = new BigInteger(aSign, aBytes);
     70 		BigInteger exp = 	 new BigInteger(eSign, eBytes);
     71 		BigInteger modulus = new BigInteger(mSign, mBytes);
     72 		BigInteger result = aNumber.modPow(exp, modulus);
     73 		byte resBytes[] = new byte[rBytes.length];
     74 		resBytes = result.toByteArray();
     75 		for(int i = 0; i < resBytes.length; i++) {
     76 			assertTrue(resBytes[i] == rBytes[i]);
     77 		}
     78 		assertEquals("incorrect sign", 1, result.signum());
     79 	}
     80 
     81 	/**
     82 	 * modPow: negative exponent
     83 	 */
     84 	public void testModPowNegExp() {
     85 		byte aBytes[] = {-127, 100, 56, 7, 98, -1, 39, -128, 127, 75, 48, -7};
     86 		byte eBytes[] = {27, -15, 65, 39};
     87 		byte mBytes[] = {-128, 2, 3, 4, 5};
     88 		int aSign = 1;
     89 		int eSign = -1;
     90 		int mSign = 1;
     91 		byte rBytes[] = {12, 118, 46, 86, 92};
     92 		BigInteger aNumber = new BigInteger(aSign, aBytes);
     93 		BigInteger exp = 	 new BigInteger(eSign, eBytes);
     94 		BigInteger modulus = new BigInteger(mSign, mBytes);
     95 		BigInteger result = aNumber.modPow(exp, modulus);
     96 		byte resBytes[] = new byte[rBytes.length];
     97 		resBytes = result.toByteArray();
     98 		for(int i = 0; i < resBytes.length; i++) {
     99 			assertTrue(resBytes[i] == rBytes[i]);
    100 		}
    101 		assertEquals("incorrect sign", 1, result.signum());
    102 	}
    103 
    104     public void testModPowZeroExp() {
    105         BigInteger exp = new BigInteger("0");
    106         BigInteger[] base = new BigInteger[] {new BigInteger("-1"), new BigInteger("0"), new BigInteger("1")};
    107         BigInteger[] mod = new BigInteger[] {new BigInteger("2"), new BigInteger("10"), new BigInteger("2147483648")};
    108 
    109         for (int i = 0; i < base.length; ++i) {
    110             for (int j = 0; j < mod.length; ++j) {
    111                 assertEquals(base[i] + " modePow(" + exp + ", " + mod[j]
    112                         + ") should be " + BigInteger.ONE, BigInteger.ONE,
    113                         base[i].modPow(exp, mod[j]));
    114             }
    115         }
    116 
    117         mod = new BigInteger[] {new BigInteger("1")};
    118         for (int i = 0; i < base.length; ++i) {
    119             for (int j = 0; j < mod.length; ++j) {
    120                 assertEquals(base[i] + " modePow(" + exp + ", " + mod[j]
    121                         + ") should be " + BigInteger.ZERO, BigInteger.ZERO,
    122                         base[i].modPow(exp, mod[j]));
    123             }
    124         }
    125     }
    126 
    127 	/**
    128 	 * modInverse: non-positive modulus
    129 	 */
    130 	public void testmodInverseException() {
    131 		byte aBytes[] = {1, 2, 3, 4, 5, 6, 7};
    132 		byte mBytes[] = {1, 2, 3};
    133 		int aSign = 1;
    134 		int mSign = -1;
    135 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    136 		BigInteger modulus = new BigInteger(mSign, mBytes);
    137 		try {
    138 			aNumber.modInverse(modulus);
    139 			fail("ArithmeticException has not been caught");
    140 		} catch (ArithmeticException e) {
    141 		}
    142 	}
    143 
    144 	/**
    145 	 * modInverse: non-invertible number
    146 	 */
    147 	public void testmodInverseNonInvertible() {
    148 		byte aBytes[] = {-15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
    149 		byte mBytes[] = {-12, 1, 0, 0, 0, 23, 44, 55, 66};
    150 		int aSign = 1;
    151 		int mSign = 1;
    152 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    153 		BigInteger modulus = new BigInteger(mSign, mBytes);
    154 		try {
    155 			aNumber.modInverse(modulus);
    156 			fail("ArithmeticException has not been caught");
    157 		} catch (ArithmeticException e) {
    158 		}
    159 	}
    160 
    161 	/**
    162 	 * modInverse: positive number
    163 	 */
    164 	public void testmodInversePos1() {
    165 		byte aBytes[] = {24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
    166 		byte mBytes[] = {122, 45, 36, 100, 122, 45};
    167 		int aSign = 1;
    168 		int mSign = 1;
    169 		byte rBytes[] = {47, 3, 96, 62, 87, 19};
    170 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    171 		BigInteger modulus = new BigInteger(mSign, mBytes);
    172 		BigInteger result = aNumber.modInverse(modulus);
    173 		byte resBytes[] = new byte[rBytes.length];
    174 		resBytes = result.toByteArray();
    175 		for(int i = 0; i < resBytes.length; i++) {
    176 			assertTrue(resBytes[i] == rBytes[i]);
    177 		}
    178 		assertEquals("incorrect sign", 1, result.signum());
    179 	}
    180 
    181 	/**
    182 	 * modInverse: positive number (another case: a < 0)
    183 	 */
    184 	public void testmodInversePos2() {
    185 		byte aBytes[] = {15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
    186 		byte mBytes[] = {2, 122, 45, 36, 100};
    187 		int aSign = 1;
    188 		int mSign = 1;
    189 		byte rBytes[] = {1, -93, 40, 127, 73};
    190 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    191 		BigInteger modulus = new BigInteger(mSign, mBytes);
    192 		BigInteger result = aNumber.modInverse(modulus);
    193 		byte resBytes[] = new byte[rBytes.length];
    194 		resBytes = result.toByteArray();
    195 		for(int i = 0; i < resBytes.length; i++) {
    196 			assertTrue(resBytes[i] == rBytes[i]);
    197 		}
    198 		assertEquals("incorrect sign", 1, result.signum());
    199 	}
    200 
    201 	/**
    202 	 * modInverse: negative number
    203 	 */
    204 	public void testmodInverseNeg1() {
    205 		byte aBytes[] = {15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
    206 		byte mBytes[] = {2, 122, 45, 36, 100};
    207 		int aSign = -1;
    208 		int mSign = 1;
    209 		byte rBytes[] = {0, -41, 4, -91, 27};
    210 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    211 		BigInteger modulus = new BigInteger(mSign, mBytes);
    212 		BigInteger result = aNumber.modInverse(modulus);
    213 		byte resBytes[] = new byte[rBytes.length];
    214 		resBytes = result.toByteArray();
    215 		for(int i = 0; i < resBytes.length; i++) {
    216 			assertTrue(resBytes[i] == rBytes[i]);
    217 		}
    218 		assertEquals("incorrect sign", 1, result.signum());
    219 	}
    220 
    221 	/**
    222 	 * modInverse: negative number (another case: x < 0)
    223 	 */
    224 	public void testmodInverseNeg2() {
    225 		byte aBytes[] = {-15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
    226 		byte mBytes[] = {122, 2, 4, 122, 2, 4};
    227 		byte rBytes[] = {85, 47, 127, 4, -128, 45};
    228 		BigInteger aNumber = new BigInteger(aBytes);
    229 		BigInteger modulus = new BigInteger(mBytes);
    230 		BigInteger result = aNumber.modInverse(modulus);
    231 		byte resBytes[] = new byte[rBytes.length];
    232 		resBytes = result.toByteArray();
    233 		for(int i = 0; i < resBytes.length; i++) {
    234 			assertTrue(resBytes[i] == rBytes[i]);
    235 		}
    236 		assertEquals("incorrect sign", 1, result.signum());
    237 	}
    238 
    239 	/**
    240 	 * gcd: the second number is zero
    241 	 */
    242 	public void testGcdSecondZero() {
    243 		byte aBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
    244 		byte bBytes[] = {0};
    245 		int aSign = 1;
    246 		int bSign = 1;
    247 		byte rBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
    248 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    249 		BigInteger bNumber = new BigInteger(bSign, bBytes);
    250 		BigInteger result = aNumber.gcd(bNumber);
    251 		byte resBytes[] = new byte[rBytes.length];
    252 		resBytes = result.toByteArray();
    253 		for(int i = 0; i < resBytes.length; i++) {
    254 			assertTrue(resBytes[i] == rBytes[i]);
    255 		}
    256 		assertEquals("incorrect sign", 1, result.signum());
    257 	}
    258 
    259 	/**
    260 	 * gcd: the first number is zero
    261 	 */
    262 	public void testGcdFirstZero() {
    263 		byte aBytes[] = {0};
    264 		byte bBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
    265 		int aSign = 1;
    266 		int bSign = 1;
    267 		byte rBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
    268 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    269 		BigInteger bNumber = new BigInteger(bSign, bBytes);
    270 		BigInteger result = aNumber.gcd(bNumber);
    271 		byte resBytes[] = new byte[rBytes.length];
    272 		resBytes = result.toByteArray();
    273 		for(int i = 0; i < resBytes.length; i++) {
    274 			assertTrue(resBytes[i] == rBytes[i]);
    275 		}
    276 		assertEquals("incorrect sign", 1, result.signum());
    277 	}
    278 
    279 	/**
    280 	 * gcd: the first number is ZERO
    281 	 */
    282 	public void testGcdFirstZERO() {
    283 		byte bBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
    284 		int bSign = 1;
    285 		byte rBytes[] = {15, 24, 123, 57, -15, 24, 123, 57, -15, 24, 123, 57};
    286 		BigInteger aNumber = BigInteger.ZERO;
    287 		BigInteger bNumber = new BigInteger(bSign, bBytes);
    288 		BigInteger result = aNumber.gcd(bNumber);
    289 		byte resBytes[] = new byte[rBytes.length];
    290 		resBytes = result.toByteArray();
    291 		for(int i = 0; i < resBytes.length; i++) {
    292 			assertTrue(resBytes[i] == rBytes[i]);
    293 		}
    294 		assertEquals("incorrect sign", 1, result.signum());
    295 	}
    296 
    297 	/**
    298 	 * gcd: both numbers are zeros
    299 	 */
    300 	public void testGcdBothZeros() {
    301 		byte rBytes[] = {0};
    302 		BigInteger aNumber = new BigInteger("0");
    303 		BigInteger bNumber = BigInteger.valueOf(0L);
    304 		BigInteger result = aNumber.gcd(bNumber);
    305 		byte resBytes[] = result.toByteArray();
    306 		for(int i = 0; i < resBytes.length; i++) {
    307 			assertTrue(resBytes[i] == rBytes[i]);
    308 		}
    309 		assertEquals("incorrect sign", 0, result.signum());
    310 	}
    311 
    312 	/**
    313 	 * gcd: the first number is longer
    314 	 */
    315 	public void testGcdFirstLonger() {
    316 		byte aBytes[] = {-15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
    317 		byte bBytes[] = {-12, 1, 0, 0, 0, 23, 44, 55, 66};
    318 		int aSign = 1;
    319 		int bSign = 1;
    320 		byte rBytes[] = {7};
    321 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    322 		BigInteger bNumber = new BigInteger(bSign, bBytes);
    323 		BigInteger result = aNumber.gcd(bNumber);
    324 		byte resBytes[] = new byte[rBytes.length];
    325 		resBytes = result.toByteArray();
    326 		for(int i = 0; i < resBytes.length; i++) {
    327 			assertTrue(resBytes[i] == rBytes[i]);
    328 		}
    329 		assertEquals("incorrect sign", 1, result.signum());
    330 	}
    331 
    332 	/**
    333 	 * gcd: the second number is longer
    334 	 */
    335 	public void testGcdSecondLonger() {
    336 		byte aBytes[] = {-12, 1, 0, 0, 0, 23, 44, 55, 66};
    337 		byte bBytes[] = {-15, 24, 123, 56, -11, -112, -34, -98, 8, 10, 12, 14, 25, 125, -15, 28, -127};
    338 		int aSign = 1;
    339 		int bSign = 1;
    340 		byte rBytes[] = {7};
    341 		BigInteger aNumber = new BigInteger(aSign, aBytes);
    342 		BigInteger bNumber = new BigInteger(bSign, bBytes);
    343 		BigInteger result = aNumber.gcd(bNumber);
    344 		byte resBytes[] = new byte[rBytes.length];
    345 		resBytes = result.toByteArray();
    346 		for(int i = 0; i < resBytes.length; i++) {
    347 			assertTrue(resBytes[i] == rBytes[i]);
    348 		}
    349 		assertEquals("incorrect sign", 1, result.signum());
    350 	}
    351 }
    352