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 common parts of the SHA-0 and SHA-1 algoritms 12 13 *******************************************************************************/ 14 15 module tango.util.digest.Sha01; 16 17 private import tango.core.ByteSwap; 18 19 private import tango.util.digest.MerkleDamgard; 20 21 /******************************************************************************* 22 23 *******************************************************************************/ 24 25 package abstract class Sha01 : MerkleDamgard 26 { 27 protected uint[5] context; 28 private static enum ubyte padChar = 0x80; 29 package static enum uint mask = 0x0000000F; 30 31 /*********************************************************************** 32 33 The digest size of Sha-0 and Sha-1 is 20 bytes 34 35 ***********************************************************************/ 36 37 override final uint digestSize() { return 20; } 38 39 /*********************************************************************** 40 41 Initialize the cipher 42 43 Remarks: 44 Returns the cipher state to it's initial value 45 46 ***********************************************************************/ 47 48 final protected override void reset() 49 { 50 super.reset(); 51 context[] = initial[]; 52 } 53 54 /*********************************************************************** 55 56 Obtain the digest 57 58 Returns: 59 the digest 60 61 Remarks: 62 Returns a digest of the current cipher state, this may be the 63 final digest, or a digest of the state between calls to update() 64 65 ***********************************************************************/ 66 67 final protected override void createDigest(ubyte[] buf) 68 { 69 version (LittleEndian) 70 ByteSwap.swap32 (context.ptr, context.length * uint.sizeof); 71 72 buf[] = (cast(ubyte[]) context)[]; 73 } 74 75 /*********************************************************************** 76 77 block size 78 79 Returns: 80 the block size 81 82 Remarks: 83 Specifies the size (in bytes) of the block of data to pass to 84 each call to transform(). For SHA0 the blockSize is 64. 85 86 ***********************************************************************/ 87 88 final protected override uint blockSize() { return 64; } 89 90 /*********************************************************************** 91 92 Length padding size 93 94 Returns: 95 the length padding size 96 97 Remarks: 98 Specifies the size (in bytes) of the padding which uses the 99 length of the data which has been ciphered, this padding is 100 carried out by the padLength method. For SHA0 the addSize is 0. 101 102 ***********************************************************************/ 103 104 final protected override uint addSize() {return 8;} 105 106 /*********************************************************************** 107 108 Pads the cipher data 109 110 Params: 111 data = a slice of the cipher buffer to fill with padding 112 113 Remarks: 114 Fills the passed buffer slice with the appropriate padding for 115 the final call to transform(). This padding will fill the cipher 116 buffer up to blockSize()-addSize(). 117 118 ***********************************************************************/ 119 120 final protected override void padMessage(ubyte[] data) 121 { 122 data[0] = padChar; 123 data[1..$] = 0; 124 } 125 126 /*********************************************************************** 127 128 Performs the length padding 129 130 Params: 131 data = the slice of the cipher buffer to fill with padding 132 length = the length of the data which has been ciphered 133 134 Remarks: 135 Fills the passed buffer slice with addSize() bytes of padding 136 based on the length in bytes of the input data which has been 137 ciphered. 138 139 ***********************************************************************/ 140 141 final protected override void padLength(ubyte[] data, ulong length) 142 { 143 length <<= 3; 144 for(int j = cast(int)data.length-1; j >= 0; j--) 145 data[$-j-1] = cast(ubyte) (length >> j*data.length); 146 } 147 148 149 /*********************************************************************** 150 151 ***********************************************************************/ 152 153 protected static uint f(uint t, uint B, uint C, uint D) 154 { 155 if (t < 20) return (B & C) | ((~B) & D); 156 else if (t < 40) return B ^ C ^ D; 157 else if (t < 60) return (B & C) | (B & D) | (C & D); 158 else return B ^ C ^ D; 159 } 160 161 /*********************************************************************** 162 163 ***********************************************************************/ 164 165 protected __gshared immutable uint[] K = 166 [ 167 0x5A827999, 168 0x6ED9EBA1, 169 0x8F1BBCDC, 170 0xCA62C1D6 171 ]; 172 173 /*********************************************************************** 174 175 ***********************************************************************/ 176 177 private __gshared immutable uint[5] initial = 178 [ 179 0x67452301, 180 0xEFCDAB89, 181 0x98BADCFE, 182 0x10325476, 183 0xC3D2E1F0 184 ]; 185 }