diff options
author | Kenny Root <kroot@google.com> | 2013-08-16 08:46:24 -0700 |
---|---|---|
committer | Kenny Root <kroot@google.com> | 2013-09-05 10:35:45 -0700 |
commit | c82a204d28ce840fcbb671ec4309ac8e490f194e (patch) | |
tree | 74cc35f5e39aa1d2dc359e3a3ad2746c1c848fee | |
parent | 341cfb18f9ef761eddbc87859583e19f09fbbfdd (diff) | |
download | libcore-c82a204d28ce840fcbb671ec4309ac8e490f194e.zip libcore-c82a204d28ce840fcbb671ec4309ac8e490f194e.tar.gz libcore-c82a204d28ce840fcbb671ec4309ac8e490f194e.tar.bz2 |
Move SHA1PRNG_SecureRandomImpl tests to libcore
Moved from the external/apache-harmony tree to here.
(cherry picked from commit 3c9191d16348246eca060fe5627a7068d0842f07)
Bug: 6642616
Change-Id: Id75e1b00b97732210257d7d01c834110fadaef75
-rw-r--r-- | luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java b/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java new file mode 100644 index 0000000..ffdbe92 --- /dev/null +++ b/luni/src/test/java/org/apache/harmony/security/tests/provider/crypto/SHA1PRNG_SecureRandomTest.java @@ -0,0 +1,403 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.security.tests.provider.crypto; + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.SecureRandom; + +import junit.framework.TestCase; + +/** + * Tests against methods in SecureRandom class object using + * SHA1PRNG_SecureRandomImpl. + */ +public class SHA1PRNG_SecureRandomTest extends TestCase { + + private static final int LENGTH = 20; // constant defining loop limit + + private static final int INCR = 2; // constant defining loop increment + + private static final String algorithm = "SHA1PRNG"; // algorithm's name + + private static final String provider = "Crypto"; // provider's name + + private static SecureRandom sr; // fields used by tests + + private static SecureRandom sr2; // + + /* + * @see TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + sr = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + } + + /** + * test against the "void generateSeed(int)" method; it checks out that the + * method throws NegativeArraySizeException if argument <0 + */ + public final void testGenerateSeedint01() { + try { + sr.generateSeed(-1); + fail("generateSeed(-1) :: No NegativeArraySizeException"); + } catch (NegativeArraySizeException e) { + } + } + + /** + * test against the "void generateSeed(int)" method; it checks out that + * number of bits returned is equal to one requested; the check includes + * case for argument's value == 0; + */ + public final void testGenerateSeedint02() { + for (int i = 0; i < LENGTH; i++) { + byte[] myBytes = sr.generateSeed(i); + assertFalse("unexpected: myBytes.length != i :: i==" + i + " myBytes.length=" + + myBytes.length, myBytes.length != i); + } + } + + /** + * test against the "void generateSeed(int)" method; it checks out the + * quality of entropy (# of different bytes in sequential calls is more or + * equal to 50%) + */ + public final void testGenerateSeedint03() { + byte[] myBytes1; + byte[] myBytes2; + + for (int i = 0; i < LENGTH; i += INCR) { + int n = 0; + myBytes1 = sr.generateSeed(i); + myBytes2 = sr.generateSeed(i); + + for (int j = 0; j < i; j++) { + if (myBytes1[j] == myBytes2[j]) { + n++; + } + } + assertFalse("unexpected: n*2 > i :: i=" + i + " n=" + n, n * 2 > i); + } + } + + /** + * test against the "void nextBytes(byte[])" method; it checks out that the + * method throws NPE if argument supplied is null + */ + public final void testNextBytesbyteArray01() { + try { + sr.nextBytes(null); + fail("unexpected: nextBytes(null) :: No NullPointerException"); + } catch (NullPointerException e) { + } + } + + /** + * test against the "void nextBytes(byte[])" method; it checks out that + * different SecureRandom objects being supplied with the same seed return + * the same sequencies of bytes as results of their "nextBytes(byte[])" + * methods + */ + public final void testNextBytesbyteArray02() { + byte[] myBytes; + byte[] myBytes1; + byte[] myBytes2; + + // case1: sequencies are of the same length + for (int i = 1; i < LENGTH; i += INCR) { + myBytes = new byte[i]; + + for (int j = 1; j < i; j++) { + myBytes[j] = (byte) (j & 0xFF); + } + sr.setSeed(myBytes); + sr2.setSeed(myBytes); + + for (int k = 1; k < LENGTH; k += INCR) { + myBytes1 = new byte[k]; + myBytes2 = new byte[k]; + sr.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + + for (int l = 0; l < k; l++) { + assertFalse("unexpected: myBytes1[l] != myBytes2[l] :: l==" + l + " k=" + k + + " i=" + i + " myBytes1[l]=" + myBytes1[l] + " myBytes2[l]=" + + myBytes2[l], myBytes1[l] != myBytes2[l]); + } + } + } + + // case2: sequencies are of different lengths + for (int n = 1; n < LENGTH; n += INCR) { + int n1 = 10; + int n2 = 20; + int n3 = 100; + byte[][] bytes1 = new byte[10][n1]; + byte[][] bytes2 = new byte[5][n2]; + + for (int k = 0; k < bytes1.length; k++) { + sr.nextBytes(bytes1[k]); + } + for (int k = 0; k < bytes2.length; k++) { + sr2.nextBytes(bytes2[k]); + } + + for (int k = 0; k < n3; k++) { + int i1 = k / n1; + int i2 = k % n1; + int i3 = k / n2; + int i4 = k % n2; + assertTrue("non-equality: i1=" + i1 + " i2=" + i2 + " i3=" + i3 + " i4=" + i4, + bytes1[i1][i2] == bytes2[i3][i4]); + } + } + } + + /** + * test against the "void nextBytes(byte[])" method; it checks out that + * different SecureRandom objects being supplied with seed by themselves + * return different sequencies of bytes as results of their + * "nextBytes(byte[])" methods + */ + public final void testNextBytesbyteArray03() throws NoSuchAlgorithmException, + NoSuchProviderException { + /* these are needed to test new SecureRandom objects in loop */ + SecureRandom sr1; + SecureRandom sr2; + + byte[] myBytes1; + byte[] myBytes2; + + for (int i = 1; i < LENGTH / 2; i += INCR) { + sr1 = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + + boolean flag = true; + + myBytes1 = new byte[i]; + myBytes2 = new byte[i]; + + sr1.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + for (int j = 0; j < i; j++) { + flag &= myBytes1[j] == myBytes2[j]; + } + + // check again to avoid intermittent failures + sr1.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + for (int j = 0; j < i; j++) { + flag &= myBytes1[j] == myBytes2[j]; + } + + if (flag) { + // probability of false failure is 1.5*10^-5 per run for i=1 or + // less for i > 1 + fail("TESTING RANDOM NUMBER GENERATOR QUALITY: IGNORE THIS FAILURE IF INTERMITTENT :: i=" + + i); + } + } + } + + /** + * test against the "void nextBytes(byte[])" method; it checks out behavior + * of SecureRandom object in cases of passing byte array of zero length to + * "nextBytes(byte[])" method. The test contains two testcases: - first + * testcase checks out that if for two newly created SecureRandom objects + * invocation of "nextBytes(new byte[0])" method are first ones then further + * calls to nextBytes(..) methods return different byte arrays, that is, + * first "nextBytes(new byte[0])" aslo randomizes internal state; - second + * testcase checks out that if for two newly created SecureRandom objects + * invocation of "setSeed(..)" methods are first ones then further calls to + * "nextBytes(new byte[0])" methods has no effect + */ + public final void testNextBytesbyteArray04() throws NoSuchAlgorithmException, + NoSuchProviderException { + /* + * these are needed to test new SecureRandom objects in loop + */ + SecureRandom sr1; + SecureRandom sr2; + + byte[] myBytes; + byte[] myBytes1; + byte[] myBytes2; + + // case 1: + for (int i = 1; i < LENGTH / 2; i += INCR) { + sr1 = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + + sr1.nextBytes(new byte[0]); + sr2.nextBytes(new byte[0]); + + boolean flag = true; + + myBytes1 = new byte[i]; + myBytes2 = new byte[i]; + + sr1.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + for (int j = 0; j < i; j++) { + flag &= myBytes1[j] == myBytes2[j]; + } + + // check again to avoid intermittent failures + sr1.nextBytes(myBytes1); + sr2.nextBytes(myBytes2); + for (int j = 0; j < i; j++) { + flag &= myBytes1[j] == myBytes2[j]; + } + + if (flag) { + // probability of false failure is 1.5*10^-5 per run for i=1 or + // less for i > 1 + fail("TESTING RANDOM NUMBER GENERATOR QUALITY: IGNORE THIS FAILURE IF INTERMITTENT :: i=" + + i); + } + } + + myBytes = new byte[] { + (byte) 0 + }; + + // case2: + for (int n = 1; n < LENGTH; n += INCR) { + byte[][] bytes1 = new byte[2][n]; + byte[][] bytes2 = new byte[2][n]; + + sr1 = SecureRandom.getInstance(algorithm, provider); + sr2 = SecureRandom.getInstance(algorithm, provider); + + sr1.setSeed(myBytes); + sr2.setSeed(myBytes); + + sr1.nextBytes(bytes1[0]); + sr1.nextBytes(bytes1[1]); + + sr2.nextBytes(bytes2[0]); + sr2.nextBytes(new byte[0]); + sr2.nextBytes(bytes2[1]); + + for (int k = 0; k < 2; k++) { + for (int j = 0; j < n; j++) { + assertTrue("non-equality: k=" + k + " j=" + j + " bytes1[k][j]=" + bytes1[k][j] + + " bytes2[k][j]=" + bytes2[k][j], bytes1[k][j] == bytes2[k][j]); + } + } + } + } + + /** + * test against the "void setSeed(byte[])" method; it checks out that the + * method throws NPE if argument supplied is null + */ + public final void testSetSeedbyteArray01() { + try { + sr.setSeed(null); + fail("setSeed(null) :: No NullPointerException"); + } catch (NullPointerException e) { + } + } + + /** + * test against the "void setSeed(byte[])" method; it checks out that + * "setSeed(byte[])" method supplements its argument to current seed rather + * than replaces current seed + */ + public final void testSetSeedbyteArray02() throws NoSuchFieldException, SecurityException, + IllegalAccessException { + byte[] seed = new byte[LENGTH]; + byte[] bytes1 = new byte[LENGTH]; + byte[] bytes2 = new byte[LENGTH]; + boolean b; + + for (int i = 0; i < seed.length; i++) { + seed[i] = (byte) i; + } + + sr.setSeed(seed); + sr.setSeed(seed); + sr2.setSeed(seed); + + sr.nextBytes(bytes1); + sr2.nextBytes(bytes2); + + b = true; + for (int j = 0; j < bytes1.length; j++) { + b &= bytes1[j] == bytes2[j]; + } + assertFalse("unexpected: sequences are equal", b); + } + + /** + * test against the "void setSeed(byte[])" method; it checks out that the + * "byte[0]" argument has no effect; there are two testcases: - if one of + * two SecureRandom objects supplied with the same seed is additionally + * supplied with such array, "nextBytes(..)" of both objects return the same + * bytes; - two byte arrays returned by "nextBytes(..)" in following + * sequence nextBytes(..); setSeed(new byte[0]); nextBytes(..); don't + * contain the same byte sequencies. + */ + public final void testSetSeedbyteArray03() throws NoSuchFieldException, SecurityException, + IllegalAccessException { + byte[] seed = new byte[LENGTH]; + byte[] bytes1; + byte[] bytes2; + + for (int i = 0; i < seed.length; i++) { + seed[i] = (byte) i; + } + + // testcase begins with "bytes1" and "bytes2" of zero length + for (int i = 0; i < LENGTH; i++) { + bytes1 = new byte[i]; + bytes2 = new byte[i]; + + sr.setSeed(seed); + sr.setSeed(new byte[0]); + sr.nextBytes(bytes1); + + sr2.setSeed(seed); + sr2.nextBytes(bytes2); + + for (int j = 0; j < bytes1.length; j++) { + assertEquals("bytes1[j] != bytes2[j] :: j=" + j, bytes1[j], bytes2[j]); + } + } + + for (int i = 1; i < LENGTH; i++) { + bytes1 = new byte[i]; + bytes2 = new byte[i]; + + sr.setSeed(seed); + sr.nextBytes(bytes1); + sr.setSeed(new byte[0]); + sr.nextBytes(bytes2); + + boolean b = true; + for (int j = 0; j < bytes1.length; j++) { + b &= bytes1[j] == bytes2[j]; + } + assertFalse("sequences are equal i=" + i, b); + } + } +} |