Botan
1.11.15
|
00001 /* 00002 * MD4 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/hash_utils.h> 00009 #include <botan/md4.h> 00010 00011 namespace Botan { 00012 00013 BOTAN_REGISTER_HASH_NOARGS(MD4); 00014 00015 namespace { 00016 00017 /* 00018 * MD4 FF Function 00019 */ 00020 inline void FF(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S) 00021 { 00022 A += (D ^ (B & (C ^ D))) + M; 00023 A = rotate_left(A, S); 00024 } 00025 00026 /* 00027 * MD4 GG Function 00028 */ 00029 inline void GG(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S) 00030 { 00031 A += ((B & C) | (D & (B | C))) + M + 0x5A827999; 00032 A = rotate_left(A, S); 00033 } 00034 00035 /* 00036 * MD4 HH Function 00037 */ 00038 inline void HH(u32bit& A, u32bit B, u32bit C, u32bit D, u32bit M, byte S) 00039 { 00040 A += (B ^ C ^ D) + M + 0x6ED9EBA1; 00041 A = rotate_left(A, S); 00042 } 00043 00044 } 00045 00046 /* 00047 * MD4 Compression Function 00048 */ 00049 void MD4::compress_n(const byte input[], size_t blocks) 00050 { 00051 u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3]; 00052 00053 for(size_t i = 0; i != blocks; ++i) 00054 { 00055 load_le(&M[0], input, M.size()); 00056 00057 FF(A,B,C,D,M[ 0], 3); FF(D,A,B,C,M[ 1], 7); 00058 FF(C,D,A,B,M[ 2],11); FF(B,C,D,A,M[ 3],19); 00059 FF(A,B,C,D,M[ 4], 3); FF(D,A,B,C,M[ 5], 7); 00060 FF(C,D,A,B,M[ 6],11); FF(B,C,D,A,M[ 7],19); 00061 FF(A,B,C,D,M[ 8], 3); FF(D,A,B,C,M[ 9], 7); 00062 FF(C,D,A,B,M[10],11); FF(B,C,D,A,M[11],19); 00063 FF(A,B,C,D,M[12], 3); FF(D,A,B,C,M[13], 7); 00064 FF(C,D,A,B,M[14],11); FF(B,C,D,A,M[15],19); 00065 00066 GG(A,B,C,D,M[ 0], 3); GG(D,A,B,C,M[ 4], 5); 00067 GG(C,D,A,B,M[ 8], 9); GG(B,C,D,A,M[12],13); 00068 GG(A,B,C,D,M[ 1], 3); GG(D,A,B,C,M[ 5], 5); 00069 GG(C,D,A,B,M[ 9], 9); GG(B,C,D,A,M[13],13); 00070 GG(A,B,C,D,M[ 2], 3); GG(D,A,B,C,M[ 6], 5); 00071 GG(C,D,A,B,M[10], 9); GG(B,C,D,A,M[14],13); 00072 GG(A,B,C,D,M[ 3], 3); GG(D,A,B,C,M[ 7], 5); 00073 GG(C,D,A,B,M[11], 9); GG(B,C,D,A,M[15],13); 00074 00075 HH(A,B,C,D,M[ 0], 3); HH(D,A,B,C,M[ 8], 9); 00076 HH(C,D,A,B,M[ 4],11); HH(B,C,D,A,M[12],15); 00077 HH(A,B,C,D,M[ 2], 3); HH(D,A,B,C,M[10], 9); 00078 HH(C,D,A,B,M[ 6],11); HH(B,C,D,A,M[14],15); 00079 HH(A,B,C,D,M[ 1], 3); HH(D,A,B,C,M[ 9], 9); 00080 HH(C,D,A,B,M[ 5],11); HH(B,C,D,A,M[13],15); 00081 HH(A,B,C,D,M[ 3], 3); HH(D,A,B,C,M[11], 9); 00082 HH(C,D,A,B,M[ 7],11); HH(B,C,D,A,M[15],15); 00083 00084 A = (digest[0] += A); 00085 B = (digest[1] += B); 00086 C = (digest[2] += C); 00087 D = (digest[3] += D); 00088 00089 input += hash_block_size(); 00090 } 00091 } 00092 00093 /* 00094 * Copy out the digest 00095 */ 00096 void MD4::copy_out(byte output[]) 00097 { 00098 copy_out_vec_le(output, output_length(), digest); 00099 } 00100 00101 /* 00102 * Clear memory of sensitive data 00103 */ 00104 void MD4::clear() 00105 { 00106 MDx_HashFunction::clear(); 00107 zeroise(M); 00108 digest[0] = 0x67452301; 00109 digest[1] = 0xEFCDAB89; 00110 digest[2] = 0x98BADCFE; 00111 digest[3] = 0x10325476; 00112 } 00113 00114 }