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