SHA1ImplTest.java revision e98fbf8686c5289bf03fe5c3de7ff82d3a77104d
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 19package org.apache.harmony.security.tests.provider.crypto; 20 21 22import java.io.UnsupportedEncodingException; 23 24import junit.framework.Test; 25import junit.framework.TestCase; 26import junit.framework.TestSuite; 27 28import org.apache.harmony.security.provider.crypto.SHA1Impl; 29 30import java.security.MessageDigest; 31 32 33/** 34 * Tests against methods in SHA1Impl class. 35 * The input data and results of computing are defined in Secure Hash Standard, 36 * see http://www.itl.nist.gov/fipspubs/fip180-1.htm 37 */ 38 39 40public class SHA1ImplTest extends TestCase { 41 42 43 // SHA1Data constant used in below methods 44 private static final int INDEX = SHA1Impl.BYTES_OFFSET; 45 46 private static MessageDigest md; 47 48 49 /* 50 * @see TestCase#setUp() 51 */ 52 protected void setUp() throws Exception { 53 super.setUp(); 54 md = MessageDigest.getInstance("SHA-1", "Crypto"); 55 } 56 57 58 /* 59 * The test checks out that for given three byte input 60 * a value returned by SHA1Impl is equal to both : 61 * - one defined in the Standard and 62 * - one calculated with alternative computation algorithm defined in the Standard. 63 */ 64 public final void testOneBlockMessage() { 65 66 int[] words = new int[INDEX +6]; // working array to compute hash 67 68 // values defined in examples in Secure Hash Standard 69 int[] hash1 = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; 70 int[] hash = {0xA9993E36, 0x4706816A, 0xBA3E2571, 0x7850C26C, 0x9CD0D89D }; 71 72 for (int i = 0; i < words.length; i++ ) { 73 words[i] = 0; 74 } 75 words[0] = 0x61626380; // constants from Secure Hash Standard 76 words[15] = 0x00000018; 77 78 alternateHash(words, hash1); 79 80 81 md.update(new byte[]{0x61,0x62,0x63}); 82 byte[] dgst = md.digest(); 83 84 for ( int k = 0; k < 5; k++ ) { 85 int i = k*4; 86 87 int j = ((dgst[i ]&0xff)<<24) | ((dgst[i+1]&0xff)<<16) | 88 ((dgst[i+2]&0xff)<<8 ) | (dgst[i+3]&0xff) ; 89 90 assertTrue("false1: k=" + k + " hash1[k]=" + Integer.toHexString(hash1[k]), 91 hash[k] == hash1[k] ); 92 93 assertTrue("false2: k=" + k + " j=" + Integer.toHexString(j), hash[k] == j ); 94 } 95 } 96 97 98 99 100 /* 101 * The test checks out that SHA1Impl computes correct value 102 * if data supplied takes exactly fourteen words of sixteen word buffer. 103 */ 104 public final void testMultiBlockMessage() throws UnsupportedEncodingException { 105 106 // values defined in examples in Secure Hash Standard 107 int[] hash = {0x84983e44, 0x1c3bd26e, 0xbaae4aa1, 0xf95129e5, 0xe54670f1 }; 108 109 // string defined in examples in Secure Hash Standard 110 md.update("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".getBytes("UTF-8")); 111 byte[] dgst = md.digest(); 112 113 for ( int k = 0; k < 5; k++ ) { 114 int i = k*4; 115 116 int j = ((dgst[i ]&0xff)<<24) | ((dgst[i+1]&0xff)<<16) | 117 ((dgst[i+2]&0xff)<<8 ) | (dgst[i+3]&0xff) ; 118 119 assertTrue("false: k=" + k + " j=" + Integer.toHexString(j), hash[k] == j ); 120 } 121 } 122 123 124 /* 125 * The test checks out that SHA1Impl returns correct values 126 * for four different cases of infilling internal buffer and computing intermediate hash. 127 */ 128 public final void testLongMessage() { 129 130 // values defined in examples in Secure Hash Standard 131 int[] hash = {0x34aa973c, 0xd4c4daa4, 0xf61eeb2b, 0xdbad2731, 0x6534016f }; 132 133 byte msgs[][] = new byte[][] { {0x61}, 134 {0x61, 0x61}, 135 {0x61, 0x61, 0x61}, 136 {0x61, 0x61, 0x61, 0x61} }; 137 138 int lngs[] = new int[]{1000000, 500000, 333333, 250000}; 139 140 for ( int n = 0; n < 4; n++ ) { 141 142 for ( int i = 0; i < lngs[n]; i++) { 143 md.update(msgs[n]); 144 } 145 if ( n == 2 ) { 146 md.update(msgs[0]); 147 } 148 149 byte[] dgst = md.digest(); 150 for ( int k = 0; k < 5; k++ ) { 151 int i = k*4; 152 153 int j = ((dgst[i ]&0xff)<<24) | ((dgst[i+1]&0xff)<<16) | 154 ((dgst[i+2]&0xff)<<8 ) | (dgst[i+3]&0xff) ; 155 156 assertTrue("false: n =" + n + " k=" + k + " j" + Integer.toHexString(j), 157 hash[k] == j ); 158 } 159 } 160 } 161 162 163 /** 164 * implements alternative algorithm described in the SECURE HASH STANDARD 165 */ 166 private void alternateHash(int[] bufW, int[] hash) { 167 168 // constants defined in Secure Hash Standard 169 final int[] K = { 170 171 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 172 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 173 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 174 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 175 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 176 177 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 178 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 179 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 180 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 181 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 182 183 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 184 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 185 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 186 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 187 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 188 189 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 190 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 191 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 192 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 193 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6 194 }; 195 196 int a = hash[0]; //0x67452301 ; 197 int b = hash[1]; //0xEFCDAB89 ; 198 int c = hash[2]; //0x98BADCFE ; 199 int d = hash[3]; //0x10325476 ; 200 int e = hash[4]; //0xC3D2E1F0 ; 201 202 // implementation constant and variables 203 204 final int MASK = 0x0000000F; 205 int temp; 206 int s; 207 int tmp; 208 209 // computation defined in Secure Hash Standard 210 for ( int t = 0 ; t < 80 ; t++ ) { 211 212 s = t & MASK; 213 214 if ( t >= 16) { 215 216 tmp = bufW[ (s+13)&MASK ] ^ bufW[(s+8)&MASK ] ^ bufW[ (s+2)&MASK ] ^ bufW[s]; 217 bufW[s] = ( tmp<<1 ) | ( tmp>>>31 ); 218 } 219 220 temp = ( a << 5 ) | ( a >>> 27 ); 221 222 if ( t < 20 ) { 223 temp += ( b & c ) | ( (~b) & d ) ; 224 } else if ( t < 40 ) { 225 temp += b ^ c ^ d ; 226 } else if ( t < 60 ) { 227 temp += ( b & c ) | ( b & d ) | ( c & d ) ; 228 } else { 229 temp += b ^ c ^ d ; 230 } 231 232 temp += e + bufW[s] + K[t] ; 233 e = d; 234 d = c; 235 c = ( b<<30 ) | ( b>>>2 ) ; 236 b = a; 237 a = temp; 238 } 239 hash[0] += a; 240 hash[1] += b; 241 hash[2] += c; 242 hash[3] += d; 243 hash[4] += e; 244 } 245 246 247 public static Test suite() { 248 return new TestSuite(SHA1ImplTest.class); 249 } 250 251 } 252