am 58f1d208: am 5761584c: am a3c562af: Merge "Move SHA1PRNG_SecureRandomImpl tests to libcore" into jb-dev

* commit '58f1d20853f7945995a838d6974ded05062c5d8b':
  Move SHA1PRNG_SecureRandomImpl tests to libcore
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);
+        }
+    }
+}