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