Botan  1.11.15
src/lib/hash/md4/md4.cpp
Go to the documentation of this file.
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 }