1 /******************************************************************************* 2 3 copyright: Copyright (c) 2006 Tango. All rights reserved 4 5 license: BSD style: see doc/license.txt for details 6 7 version: Initial release: Feb 2006 8 9 author: Regan Heath, Oskar Linde 10 11 This module implements the SHA-1 Algorithm described by Secure Hash 12 Standard, FIPS PUB 180-1, and RFC 3174 US Secure Hash Algorithm 1 13 (SHA1). D. Eastlake 3rd, P. Jones. September 2001. 14 15 *******************************************************************************/ 16 17 module tango.util.digest.Sha1; 18 19 private import tango.util.digest.Sha01; 20 21 public import tango.util.digest.Digest; 22 23 /******************************************************************************* 24 25 *******************************************************************************/ 26 27 final class Sha1 : Sha01 28 { 29 /*********************************************************************** 30 31 Construct a Sha1 hash algorithm context 32 33 ***********************************************************************/ 34 35 this() { } 36 37 /*********************************************************************** 38 39 Performs the cipher on a block of data 40 41 Params: 42 data = the block of data to cipher 43 44 Remarks: 45 The actual cipher algorithm is carried out by this method on 46 the passed block of data. This method is called for every 47 blockSize() bytes of input data and once more with the remaining 48 data padded to blockSize(). 49 50 ***********************************************************************/ 51 52 final protected override void transform(const(ubyte[]) input) 53 { 54 uint A,B,C,D,E,TEMP; 55 uint[16] W; 56 uint s; 57 58 bigEndian32(input,W); 59 A = context[0]; 60 B = context[1]; 61 C = context[2]; 62 D = context[3]; 63 E = context[4]; 64 65 for(uint t = 0; t < 80; t++) { 66 s = t & mask; 67 if (t >= 16) 68 expand(W,s); 69 TEMP = rotateLeft(A,5) + f(t,B,C,D) + E + W[s] + K[t/20]; 70 E = D; D = C; C = rotateLeft(B,30); B = A; A = TEMP; 71 } 72 73 context[0] += A; 74 context[1] += B; 75 context[2] += C; 76 context[3] += D; 77 context[4] += E; 78 } 79 80 /*********************************************************************** 81 82 ***********************************************************************/ 83 84 final static void expand (uint[] W, uint s) 85 { 86 W[s] = rotateLeft(W[(s+13)&mask] ^ W[(s+8)&mask] ^ W[(s+2)&mask] ^ W[s],1); 87 } 88 89 } 90 91 92 /******************************************************************************* 93 94 *******************************************************************************/ 95 96 debug(UnitTest) 97 { 98 unittest 99 { 100 __gshared immutable immutable(char)[][] strings = 101 [ 102 "abc", 103 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 104 "a", 105 "0123456701234567012345670123456701234567012345670123456701234567" 106 ]; 107 108 __gshared immutable immutable(char)[][] results = 109 [ 110 "a9993e364706816aba3e25717850c26c9cd0d89d", 111 "84983e441c3bd26ebaae4aa1f95129e5e54670f1", 112 "34aa973cd4c4daa4f61eeb2bdbad27316534016f", 113 "dea356a2cddd90c7a7ecedc5ebb563934f460452" 114 ]; 115 116 __gshared immutable int[] repeat = 117 [ 118 1, 119 1, 120 1000000, 121 10 122 ]; 123 124 Sha1 h = new Sha1(); 125 126 foreach (int i, immutable(char)[] s; strings) 127 { 128 for(int r = 0; r < repeat[i]; r++) 129 h.update(s); 130 131 char[] d = h.hexDigest(); 132 assert(d == results[i],":("~s~")("~d~")!=("~results[i]~")"); 133 } 134 } 135 }