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