Embedded systems coursework 2.
Fork of Crypto_light by
Embed:
(wiki syntax)
Show/hide line numbers
MD4.cpp
00001 #include "MD4.h" 00002 #include <string.h> 00003 00004 static const uint32_t A = 0x67452301; 00005 static const uint32_t B = 0xefcdab89; 00006 static const uint32_t C = 0x98badcfe; 00007 static const uint32_t D = 0x10325476; 00008 00009 #define F(X,Y,Z) ((X & Y) | ((~X) & Z)) 00010 #define G(X,Y,Z) ((X & Y) | (X & Z) | (Y & Z)) 00011 #define H(X,Y,Z) (X ^ Y ^ Z) 00012 00013 00014 #define ROTL(W,N) (((W) << N) | ((W) >> (32-N))) 00015 00016 #define ROUND1(a,b,c,d,x,s) \ 00017 a = ROTL(a + F(b,c,d) + x,s); 00018 00019 #define ROUND2(a,b,c,d,x,s) \ 00020 a = ROTL(a + G(b,c,d) + x + 0x5A827999,s); 00021 00022 #define ROUND3(a,b,c,d,x,s) \ 00023 a = ROTL(a + H(b,c,d) + x + 0x6ED9EBA1,s); 00024 00025 00026 00027 MD4::MD4(): 00028 HashAlgorithm(), 00029 a(A), 00030 b(B), 00031 c(C), 00032 d(D), 00033 totalBufferLength(0), 00034 buffer(), 00035 bufferLength(0) 00036 { 00037 } 00038 00039 uint8_t MD4::outputSize() const 00040 { 00041 return 16; 00042 } 00043 00044 void MD4::update(uint8_t *data, uint32_t length) 00045 { 00046 if((int)length < 64-bufferLength) 00047 { 00048 memcpy(&buffer[bufferLength], data, length); 00049 bufferLength += length; 00050 totalBufferLength += length; 00051 return; 00052 } 00053 int offset = 64-bufferLength; 00054 memcpy(&buffer[bufferLength], data, offset); 00055 computeRounds(&a, &b, &c, &d, buffer); 00056 while(length-offset > 64) 00057 { 00058 memcpy(buffer, &data[offset], 64); 00059 computeRounds(&a, &b, &c, &d, buffer); 00060 offset += 64; 00061 } 00062 if(offset > (int)length) 00063 offset -= 64; 00064 bufferLength = length - offset; 00065 memcpy(buffer, &data[offset], bufferLength); 00066 totalBufferLength += length; 00067 } 00068 00069 void MD4::finalize(uint8_t *hash) 00070 { 00071 uint32_t *hash2 = (uint32_t*)hash; 00072 uint16_t padding; 00073 if(totalBufferLength % 64 < 56) 00074 padding = 56 - (totalBufferLength % 64); 00075 else 00076 padding = 56 + (64 - (totalBufferLength % 64)); 00077 buffer[bufferLength++] = 0x80; 00078 padding--; 00079 if(padding+bufferLength == 56) 00080 memset(&buffer[bufferLength], 0, padding); 00081 else 00082 { 00083 memset(&buffer[bufferLength], 0, 64-bufferLength); 00084 computeRounds(&a, &b, &c, &d, buffer); 00085 memset(buffer, 0, 56); 00086 } 00087 uint64_t lengthBit = totalBufferLength << 3; 00088 uint32_t lengthBitLow = lengthBit; 00089 uint32_t lengthBitHigh = lengthBit >> 32; 00090 memcpy(&buffer[56], &lengthBitLow, 4); 00091 memcpy(&buffer[60], &lengthBitHigh, 4); 00092 computeRounds(&a, &b, &c, &d, buffer); 00093 00094 hash2[0] = a; 00095 hash2[1] = b; 00096 hash2[2] = c; 00097 hash2[3] = d; 00098 // reset state 00099 a = A; 00100 b = B; 00101 c = C; 00102 d = D; 00103 totalBufferLength = 0; 00104 bufferLength = 0; 00105 } 00106 00107 00108 void MD4::computeHash(uint8_t *hash, uint8_t *data, uint32_t length) 00109 { 00110 uint32_t *hash2 = (uint32_t*)hash; 00111 uint64_t lengthBit = length << 3; 00112 uint16_t padding; 00113 if(length % 64 < 56) 00114 padding = 56 - (length % 64); 00115 else 00116 padding = 56 + (64 - (length % 64)); 00117 00118 uint32_t a = A, b = B, c = C, d = D; 00119 while(length >= 64) 00120 { 00121 computeRounds(&a, &b, &c, &d, data); 00122 data += 64; 00123 length -= 64; 00124 } 00125 uint8_t buffer[64]; 00126 memcpy(buffer, data, length); 00127 buffer[length++] = 0x80; 00128 padding--; 00129 if(padding+length == 56) 00130 memset(&buffer[length], 0, padding); 00131 else 00132 { 00133 memset(&buffer[length], 0, 64-length); 00134 computeRounds(&a, &b, &c, &d, data); 00135 memset(buffer, 0, 56); 00136 } 00137 00138 uint32_t lengthBitLow = lengthBit; 00139 uint32_t lengthBitHigh = lengthBit >> 32; 00140 memcpy(&buffer[56], &lengthBitLow, 4); 00141 memcpy(&buffer[60], &lengthBitHigh, 4); 00142 00143 computeRounds(&a, &b, &c, &d, buffer); 00144 00145 hash2[0] = a; 00146 hash2[1] = b; 00147 hash2[2] = c; 00148 hash2[3] = d; 00149 } 00150 00151 void MD4::computeRounds(uint32_t *a2, uint32_t *b2, uint32_t *c2, uint32_t *d2, uint8_t *buffer) 00152 { 00153 uint32_t a = *a2, b = *b2, c = *c2, d = *d2; 00154 uint32_t tmpA = a, tmpB = b, tmpC = c, tmpD = d; 00155 00156 uint32_t *x = (uint32_t*)buffer; 00157 00158 // Round 1 00159 ROUND1(a,b,c,d,x[0],3); ROUND1(d,a,b,c,x[1],7); ROUND1(c,d,a,b,x[2],11); ROUND1(b,c,d,a,x[3],19); 00160 ROUND1(a,b,c,d,x[4],3); ROUND1(d,a,b,c,x[5],7); ROUND1(c,d,a,b,x[6],11); ROUND1(b,c,d,a,x[7],19); 00161 ROUND1(a,b,c,d,x[8],3); ROUND1(d,a,b,c,x[9],7); ROUND1(c,d,a,b,x[10],11); ROUND1(b,c,d,a,x[11],19); 00162 ROUND1(a,b,c,d,x[12],3); ROUND1(d,a,b,c,x[13],7); ROUND1(c,d,a,b,x[14],11); ROUND1(b,c,d,a,x[15],19); 00163 00164 // Round 2 00165 ROUND2(a,b,c,d,x[0],3); ROUND2(d,a,b,c,x[4],5); ROUND2(c,d,a,b,x[8],9); ROUND2(b,c,d,a,x[12],13); 00166 ROUND2(a,b,c,d,x[1],3); ROUND2(d,a,b,c,x[5],5); ROUND2(c,d,a,b,x[9],9); ROUND2(b,c,d,a,x[13],13); 00167 ROUND2(a,b,c,d,x[2],3); ROUND2(d,a,b,c,x[6],5); ROUND2(c,d,a,b,x[10],9); ROUND2(b,c,d,a,x[14],13); 00168 ROUND2(a,b,c,d,x[3],3); ROUND2(d,a,b,c,x[7],5); ROUND2(c,d,a,b,x[11],9); ROUND2(b,c,d,a,x[15],13); 00169 00170 // Round 3 00171 ROUND3(a,b,c,d,x[0],3); ROUND3(d,a,b,c,x[8],9); ROUND3(c,d,a,b,x[4],11); ROUND3(b,c,d,a,x[12],15); 00172 ROUND3(a,b,c,d,x[2],3); ROUND3(d,a,b,c,x[10],9); ROUND3(c,d,a,b,x[6],11); ROUND3(b,c,d,a,x[14],15); 00173 ROUND3(a,b,c,d,x[1],3); ROUND3(d,a,b,c,x[9],9); ROUND3(c,d,a,b,x[5],11); ROUND3(b,c,d,a,x[13],15); 00174 ROUND3(a,b,c,d,x[3],3); ROUND3(d,a,b,c,x[11],9); ROUND3(c,d,a,b,x[7],11); ROUND3(b,c,d,a,x[15],15); 00175 00176 00177 *a2 = a + tmpA; 00178 *b2 = b + tmpB; 00179 *c2 = c + tmpC; 00180 *d2 = d + tmpD; 00181 }
Generated on Wed Jul 20 2022 22:55:43 by 1.7.2