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