1 module dcrypt.crypto.digests.generaldigest; 2 3 public import dcrypt.crypto.digest; 4 5 /** 6 * base implementation of MD4 family style digest as outlined in 7 * "Handbook of Applied Cryptography", pages 344 - 347. 8 */ 9 @safe 10 package class GeneralDigest : Digest 11 { 12 alias put update; 13 14 public: 15 16 override void put(in ubyte[] input...) nothrow @nogc 17 { 18 uint inOff = 0; 19 size_t len = input.length; 20 // 21 // fill the current word 22 // 23 while ((xBufOff != 0) && (len > 0)) 24 { 25 putSingleByte(input[inOff]); 26 27 inOff++; 28 len--; 29 } 30 31 // 32 // process whole words. 33 // 34 while (len > xBuf.length) 35 { 36 processWord(input[inOff .. $]); 37 38 inOff += xBuf.length; 39 len -= xBuf.length; 40 byteCount += xBuf.length; 41 } 42 43 // 44 // load in the remainder. 45 // 46 while (len > 0) 47 { 48 putSingleByte(input[inOff]); 49 50 inOff++; 51 len--; 52 } 53 } 54 55 protected void finish() nothrow @nogc 56 { 57 ulong bitLength = (byteCount << 3); 58 59 // 60 // add the pad bytes. 61 // 62 put(128); 63 64 while (xBufOff != 0) 65 { 66 put(0); 67 } 68 69 processLength(bitLength); 70 71 processBlock(); 72 } 73 74 override void start() nothrow @nogc 75 { 76 byteCount = 0; 77 78 xBufOff = 0; 79 xBuf[] = 0; 80 } 81 82 override uint blockSize() pure nothrow @nogc { 83 return 64; 84 } 85 86 // abstract string getAlgorithmName() pure nothrow; 87 // abstract uint getDigestSize() pure nothrow; 88 // abstract uint doFinal(ubyte[] output); 89 90 override uint getByteLength() pure nothrow @nogc 91 { 92 return BYTE_LENGTH; 93 } 94 95 @property 96 public override GeneralDigest dup() nothrow { 97 GeneralDigest clone = dupImpl(); 98 clone.xBuf = xBuf; 99 clone.xBufOff = xBufOff; 100 clone.byteCount = byteCount; 101 return clone; 102 } 103 104 /// create an independant clone. used by dup() 105 protected abstract GeneralDigest dupImpl() nothrow; 106 107 protected abstract nothrow @nogc { 108 void processWord(in ubyte[] input); 109 void processLength(ulong bitLength); 110 void processBlock(); 111 } 112 113 protected void putSingleByte(ubyte input) nothrow @nogc 114 { 115 xBuf[xBufOff++] = input; 116 117 if (xBufOff == xBuf.length) 118 { 119 processWord(xBuf); 120 xBufOff = 0; 121 } 122 123 byteCount++; 124 } 125 126 private { 127 enum BYTE_LENGTH = 64; 128 ubyte[4] xBuf; 129 uint xBufOff = 0; 130 131 size_t byteCount; 132 } 133 134 }