Botan  1.11.15
src/lib/hash/rmd128/rmd128.cpp
Go to the documentation of this file.
00001 /*
00002 * RIPEMD-128
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/rmd128.h>
00010 
00011 namespace Botan {
00012 
00013 BOTAN_REGISTER_HASH_NAMED_NOARGS(RIPEMD_128, "RIPEMD-128");
00014 
00015 namespace RIPEMD_128_F {
00016 
00017 /*
00018 * RIPEMD-128 F1 Function
00019 */
00020 inline void F1(u32bit& A, u32bit B, u32bit C, u32bit D,
00021                u32bit msg, u32bit shift)
00022    {
00023    A += (B ^ C ^ D) + msg;
00024    A  = rotate_left(A, shift);
00025    }
00026 
00027 /*
00028 * RIPEMD-128 F2 Function
00029 */
00030 inline void F2(u32bit& A, u32bit B, u32bit C, u32bit D,
00031                u32bit msg, u32bit shift, u32bit magic)
00032    {
00033    A += (D ^ (B & (C ^ D))) + msg + magic;
00034    A  = rotate_left(A, shift);
00035    }
00036 
00037 /*
00038 * RIPEMD-128 F3 Function
00039 */
00040 inline void F3(u32bit& A, u32bit B, u32bit C, u32bit D,
00041                u32bit msg, u32bit shift, u32bit magic)
00042    {
00043    A += (D ^ (B | ~C)) + msg + magic;
00044    A  = rotate_left(A, shift);
00045    }
00046 
00047 /*
00048 * RIPEMD-128 F4 Function
00049 */
00050 inline void F4(u32bit& A, u32bit B, u32bit C, u32bit D,
00051                u32bit msg, u32bit shift, u32bit magic)
00052    {
00053    A += (C ^ (D & (B ^ C))) + msg + magic;
00054    A  = rotate_left(A, shift);
00055    }
00056 
00057 }
00058 
00059 /*
00060 * RIPEMD-128 Compression Function
00061 */
00062 void RIPEMD_128::compress_n(const byte input[], size_t blocks)
00063    {
00064    using namespace RIPEMD_128_F;
00065 
00066    const u32bit MAGIC2 = 0x5A827999, MAGIC3 = 0x6ED9EBA1,
00067                 MAGIC4 = 0x8F1BBCDC, MAGIC5 = 0x50A28BE6,
00068                 MAGIC6 = 0x5C4DD124, MAGIC7 = 0x6D703EF3;
00069 
00070    for(size_t i = 0; i != blocks; ++i)
00071       {
00072       load_le(&M[0], input, M.size());
00073 
00074       u32bit A1 = digest[0], A2 = A1, B1 = digest[1], B2 = B1,
00075              C1 = digest[2], C2 = C1, D1 = digest[3], D2 = D1;
00076 
00077       F1(A1,B1,C1,D1,M[ 0],11       );   F4(A2,B2,C2,D2,M[ 5], 8,MAGIC5);
00078       F1(D1,A1,B1,C1,M[ 1],14       );   F4(D2,A2,B2,C2,M[14], 9,MAGIC5);
00079       F1(C1,D1,A1,B1,M[ 2],15       );   F4(C2,D2,A2,B2,M[ 7], 9,MAGIC5);
00080       F1(B1,C1,D1,A1,M[ 3],12       );   F4(B2,C2,D2,A2,M[ 0],11,MAGIC5);
00081       F1(A1,B1,C1,D1,M[ 4], 5       );   F4(A2,B2,C2,D2,M[ 9],13,MAGIC5);
00082       F1(D1,A1,B1,C1,M[ 5], 8       );   F4(D2,A2,B2,C2,M[ 2],15,MAGIC5);
00083       F1(C1,D1,A1,B1,M[ 6], 7       );   F4(C2,D2,A2,B2,M[11],15,MAGIC5);
00084       F1(B1,C1,D1,A1,M[ 7], 9       );   F4(B2,C2,D2,A2,M[ 4], 5,MAGIC5);
00085       F1(A1,B1,C1,D1,M[ 8],11       );   F4(A2,B2,C2,D2,M[13], 7,MAGIC5);
00086       F1(D1,A1,B1,C1,M[ 9],13       );   F4(D2,A2,B2,C2,M[ 6], 7,MAGIC5);
00087       F1(C1,D1,A1,B1,M[10],14       );   F4(C2,D2,A2,B2,M[15], 8,MAGIC5);
00088       F1(B1,C1,D1,A1,M[11],15       );   F4(B2,C2,D2,A2,M[ 8],11,MAGIC5);
00089       F1(A1,B1,C1,D1,M[12], 6       );   F4(A2,B2,C2,D2,M[ 1],14,MAGIC5);
00090       F1(D1,A1,B1,C1,M[13], 7       );   F4(D2,A2,B2,C2,M[10],14,MAGIC5);
00091       F1(C1,D1,A1,B1,M[14], 9       );   F4(C2,D2,A2,B2,M[ 3],12,MAGIC5);
00092       F1(B1,C1,D1,A1,M[15], 8       );   F4(B2,C2,D2,A2,M[12], 6,MAGIC5);
00093 
00094       F2(A1,B1,C1,D1,M[ 7], 7,MAGIC2);   F3(A2,B2,C2,D2,M[ 6], 9,MAGIC6);
00095       F2(D1,A1,B1,C1,M[ 4], 6,MAGIC2);   F3(D2,A2,B2,C2,M[11],13,MAGIC6);
00096       F2(C1,D1,A1,B1,M[13], 8,MAGIC2);   F3(C2,D2,A2,B2,M[ 3],15,MAGIC6);
00097       F2(B1,C1,D1,A1,M[ 1],13,MAGIC2);   F3(B2,C2,D2,A2,M[ 7], 7,MAGIC6);
00098       F2(A1,B1,C1,D1,M[10],11,MAGIC2);   F3(A2,B2,C2,D2,M[ 0],12,MAGIC6);
00099       F2(D1,A1,B1,C1,M[ 6], 9,MAGIC2);   F3(D2,A2,B2,C2,M[13], 8,MAGIC6);
00100       F2(C1,D1,A1,B1,M[15], 7,MAGIC2);   F3(C2,D2,A2,B2,M[ 5], 9,MAGIC6);
00101       F2(B1,C1,D1,A1,M[ 3],15,MAGIC2);   F3(B2,C2,D2,A2,M[10],11,MAGIC6);
00102       F2(A1,B1,C1,D1,M[12], 7,MAGIC2);   F3(A2,B2,C2,D2,M[14], 7,MAGIC6);
00103       F2(D1,A1,B1,C1,M[ 0],12,MAGIC2);   F3(D2,A2,B2,C2,M[15], 7,MAGIC6);
00104       F2(C1,D1,A1,B1,M[ 9],15,MAGIC2);   F3(C2,D2,A2,B2,M[ 8],12,MAGIC6);
00105       F2(B1,C1,D1,A1,M[ 5], 9,MAGIC2);   F3(B2,C2,D2,A2,M[12], 7,MAGIC6);
00106       F2(A1,B1,C1,D1,M[ 2],11,MAGIC2);   F3(A2,B2,C2,D2,M[ 4], 6,MAGIC6);
00107       F2(D1,A1,B1,C1,M[14], 7,MAGIC2);   F3(D2,A2,B2,C2,M[ 9],15,MAGIC6);
00108       F2(C1,D1,A1,B1,M[11],13,MAGIC2);   F3(C2,D2,A2,B2,M[ 1],13,MAGIC6);
00109       F2(B1,C1,D1,A1,M[ 8],12,MAGIC2);   F3(B2,C2,D2,A2,M[ 2],11,MAGIC6);
00110 
00111       F3(A1,B1,C1,D1,M[ 3],11,MAGIC3);   F2(A2,B2,C2,D2,M[15], 9,MAGIC7);
00112       F3(D1,A1,B1,C1,M[10],13,MAGIC3);   F2(D2,A2,B2,C2,M[ 5], 7,MAGIC7);
00113       F3(C1,D1,A1,B1,M[14], 6,MAGIC3);   F2(C2,D2,A2,B2,M[ 1],15,MAGIC7);
00114       F3(B1,C1,D1,A1,M[ 4], 7,MAGIC3);   F2(B2,C2,D2,A2,M[ 3],11,MAGIC7);
00115       F3(A1,B1,C1,D1,M[ 9],14,MAGIC3);   F2(A2,B2,C2,D2,M[ 7], 8,MAGIC7);
00116       F3(D1,A1,B1,C1,M[15], 9,MAGIC3);   F2(D2,A2,B2,C2,M[14], 6,MAGIC7);
00117       F3(C1,D1,A1,B1,M[ 8],13,MAGIC3);   F2(C2,D2,A2,B2,M[ 6], 6,MAGIC7);
00118       F3(B1,C1,D1,A1,M[ 1],15,MAGIC3);   F2(B2,C2,D2,A2,M[ 9],14,MAGIC7);
00119       F3(A1,B1,C1,D1,M[ 2],14,MAGIC3);   F2(A2,B2,C2,D2,M[11],12,MAGIC7);
00120       F3(D1,A1,B1,C1,M[ 7], 8,MAGIC3);   F2(D2,A2,B2,C2,M[ 8],13,MAGIC7);
00121       F3(C1,D1,A1,B1,M[ 0],13,MAGIC3);   F2(C2,D2,A2,B2,M[12], 5,MAGIC7);
00122       F3(B1,C1,D1,A1,M[ 6], 6,MAGIC3);   F2(B2,C2,D2,A2,M[ 2],14,MAGIC7);
00123       F3(A1,B1,C1,D1,M[13], 5,MAGIC3);   F2(A2,B2,C2,D2,M[10],13,MAGIC7);
00124       F3(D1,A1,B1,C1,M[11],12,MAGIC3);   F2(D2,A2,B2,C2,M[ 0],13,MAGIC7);
00125       F3(C1,D1,A1,B1,M[ 5], 7,MAGIC3);   F2(C2,D2,A2,B2,M[ 4], 7,MAGIC7);
00126       F3(B1,C1,D1,A1,M[12], 5,MAGIC3);   F2(B2,C2,D2,A2,M[13], 5,MAGIC7);
00127 
00128       F4(A1,B1,C1,D1,M[ 1],11,MAGIC4);   F1(A2,B2,C2,D2,M[ 8],15       );
00129       F4(D1,A1,B1,C1,M[ 9],12,MAGIC4);   F1(D2,A2,B2,C2,M[ 6], 5       );
00130       F4(C1,D1,A1,B1,M[11],14,MAGIC4);   F1(C2,D2,A2,B2,M[ 4], 8       );
00131       F4(B1,C1,D1,A1,M[10],15,MAGIC4);   F1(B2,C2,D2,A2,M[ 1],11       );
00132       F4(A1,B1,C1,D1,M[ 0],14,MAGIC4);   F1(A2,B2,C2,D2,M[ 3],14       );
00133       F4(D1,A1,B1,C1,M[ 8],15,MAGIC4);   F1(D2,A2,B2,C2,M[11],14       );
00134       F4(C1,D1,A1,B1,M[12], 9,MAGIC4);   F1(C2,D2,A2,B2,M[15], 6       );
00135       F4(B1,C1,D1,A1,M[ 4], 8,MAGIC4);   F1(B2,C2,D2,A2,M[ 0],14       );
00136       F4(A1,B1,C1,D1,M[13], 9,MAGIC4);   F1(A2,B2,C2,D2,M[ 5], 6       );
00137       F4(D1,A1,B1,C1,M[ 3],14,MAGIC4);   F1(D2,A2,B2,C2,M[12], 9       );
00138       F4(C1,D1,A1,B1,M[ 7], 5,MAGIC4);   F1(C2,D2,A2,B2,M[ 2],12       );
00139       F4(B1,C1,D1,A1,M[15], 6,MAGIC4);   F1(B2,C2,D2,A2,M[13], 9       );
00140       F4(A1,B1,C1,D1,M[14], 8,MAGIC4);   F1(A2,B2,C2,D2,M[ 9],12       );
00141       F4(D1,A1,B1,C1,M[ 5], 6,MAGIC4);   F1(D2,A2,B2,C2,M[ 7], 5       );
00142       F4(C1,D1,A1,B1,M[ 6], 5,MAGIC4);   F1(C2,D2,A2,B2,M[10],15       );
00143       F4(B1,C1,D1,A1,M[ 2],12,MAGIC4);   F1(B2,C2,D2,A2,M[14], 8       );
00144 
00145       D2        = digest[1] + C1 + D2;
00146       digest[1] = digest[2] + D1 + A2;
00147       digest[2] = digest[3] + A1 + B2;
00148       digest[3] = digest[0] + B1 + C2;
00149       digest[0] = D2;
00150 
00151       input += hash_block_size();
00152       }
00153    }
00154 
00155 /*
00156 * Copy out the digest
00157 */
00158 void RIPEMD_128::copy_out(byte output[])
00159    {
00160    copy_out_vec_le(output, output_length(), digest);
00161    }
00162 
00163 /*
00164 * Clear memory of sensitive data
00165 */
00166 void RIPEMD_128::clear()
00167    {
00168    MDx_HashFunction::clear();
00169    zeroise(M);
00170    digest[0] = 0x67452301;
00171    digest[1] = 0xEFCDAB89;
00172    digest[2] = 0x98BADCFE;
00173    digest[3] = 0x10325476;
00174    }
00175 
00176 }