Home | History | Annotate | Download | only in digests
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.org.bouncycastle.crypto.digests;
     18 
     19 import junit.framework.TestCase;
     20 import com.android.org.bouncycastle.crypto.Digest;
     21 import com.android.org.bouncycastle.crypto.ExtendedDigest;
     22 
     23 /**
     24  * Implements unit tests for our JNI wrapper around OpenSSL. We use the
     25  * existing Bouncy Castle implementation as our test oracle.
     26  */
     27 public class DigestTest extends TestCase {
     28 
     29     /**
     30      * Processes the two given message digests for the same data and checks
     31      * the results. Requirement is that the results must be equal, the digest
     32      * implementations must have the same properties, and the new implementation
     33      * must be faster than the old one.
     34      *
     35      * @param oldDigest The old digest implementation, provided by Bouncy Castle
     36      * @param newDigest The new digest implementation, provided by OpenSSL
     37      */
     38     public void doTestMessageDigest(Digest oldDigest, Digest newDigest) {
     39         final int ITERATIONS = 100;
     40 
     41         byte[] data = new byte[1024];
     42 
     43         byte[] oldHash = new byte[oldDigest.getDigestSize()];
     44         byte[] newHash = new byte[newDigest.getDigestSize()];
     45 
     46         assertEquals("Hash names must be equal",
     47                      oldDigest.getAlgorithmName(), newDigest.getAlgorithmName());
     48         assertEquals("Hash sizes must be equal",
     49                      oldHash.length, newHash.length);
     50         assertEquals("Hash block sizes must be equal",
     51                      ((ExtendedDigest)oldDigest).getByteLength(),
     52                      ((ExtendedDigest)newDigest).getByteLength());
     53         for (int i = 0; i < data.length; i++) {
     54             data[i] = (byte)i;
     55         }
     56 
     57         long oldTime = 0;
     58         long newTime = 0;
     59 
     60         for (int j = 0; j < ITERATIONS; j++) {
     61             long t0 = System.currentTimeMillis();
     62             for (int i = 0; i < 4; i++) {
     63                 oldDigest.update(data, 0, data.length);
     64             }
     65             int oldLength = oldDigest.doFinal(oldHash, 0);
     66             long t1 = System.currentTimeMillis();
     67 
     68             oldTime = oldTime + (t1 - t0);
     69 
     70             long t2 = System.currentTimeMillis();
     71             for (int i = 0; i < 4; i++) {
     72                 newDigest.update(data, 0, data.length);
     73             }
     74             int newLength = newDigest.doFinal(newHash, 0);
     75             long t3 = System.currentTimeMillis();
     76 
     77             newTime = newTime + (t3 - t2);
     78 
     79             assertEquals("Hash sizes must be equal", oldLength, newLength);
     80 
     81             for (int i = 0; i < oldLength; i++) {
     82                 assertEquals("Hashes[" + i + "] must be equal", oldHash[i], newHash[i]);
     83             }
     84         }
     85 
     86         System.out.println("Time for " + ITERATIONS + " x old hash processing: " + oldTime + " ms");
     87         System.out.println("Time for " + ITERATIONS + " x new hash processing: " + newTime + " ms");
     88 
     89         assertTrue("New hash should be faster", newTime < oldTime);
     90     }
     91 
     92     /**
     93      * Tests the MD5 implementation.
     94      */
     95     public void testMD5() {
     96         Digest oldDigest = new MD5Digest();
     97         Digest newDigest = new OpenSSLDigest.MD5();
     98         doTestMessageDigest(oldDigest, newDigest);
     99     }
    100 
    101     /**
    102      * Tests the SHA-1 implementation.
    103      */
    104     public void testSHA1() {
    105         Digest oldDigest = new SHA1Digest();
    106         Digest newDigest = new OpenSSLDigest.SHA1();
    107         doTestMessageDigest(oldDigest, newDigest);
    108     }
    109 
    110     /**
    111      * Tests the SHA-256 implementation.
    112      */
    113     public void testSHA256() {
    114         Digest oldDigest = new SHA256Digest();
    115         Digest newDigest = new OpenSSLDigest.SHA256();
    116         doTestMessageDigest(oldDigest, newDigest);
    117     }
    118 
    119     /**
    120      * Tests the SHA-384 implementation.
    121      */
    122     public void testSHA384() {
    123         Digest oldDigest = new SHA384Digest();
    124         Digest newDigest = new OpenSSLDigest.SHA384();
    125         doTestMessageDigest(oldDigest, newDigest);
    126     }
    127 
    128     /**
    129      * Tests the SHA-512 implementation.
    130      */
    131     public void testSHA512() {
    132         Digest oldDigest = new SHA512Digest();
    133         Digest newDigest = new OpenSSLDigest.SHA512();
    134         doTestMessageDigest(oldDigest, newDigest);
    135     }
    136 }
    137