Botan  1.11.15
src/lib/hash/sha1/sha160.cpp
Go to the documentation of this file.
00001 /*
00002 * SHA-160
00003 * (C) 1999-2008,2011 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/sha160.h>
00010 
00011 namespace Botan {
00012 
00013 BOTAN_REGISTER_HASH_NAMED_NOARGS(SHA_160, "SHA-160");
00014 
00015 namespace SHA1_F {
00016 
00017 namespace {
00018 
00019 /*
00020 * SHA-160 F1 Function
00021 */
00022 inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
00023    {
00024    E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotate_left(A, 5);
00025    B  = rotate_left(B, 30);
00026    }
00027 
00028 /*
00029 * SHA-160 F2 Function
00030 */
00031 inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
00032    {
00033    E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotate_left(A, 5);
00034    B  = rotate_left(B, 30);
00035    }
00036 
00037 /*
00038 * SHA-160 F3 Function
00039 */
00040 inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
00041    {
00042    E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotate_left(A, 5);
00043    B  = rotate_left(B, 30);
00044    }
00045 
00046 /*
00047 * SHA-160 F4 Function
00048 */
00049 inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg)
00050    {
00051    E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotate_left(A, 5);
00052    B  = rotate_left(B, 30);
00053    }
00054 
00055 }
00056 
00057 }
00058 
00059 /*
00060 * SHA-160 Compression Function
00061 */
00062 void SHA_160::compress_n(const byte input[], size_t blocks)
00063    {
00064    using namespace SHA1_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_be(&W[0], input, 16);
00072 
00073       for(size_t j = 16; j != 80; j += 8)
00074          {
00075          W[j  ] = rotate_left((W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16]), 1);
00076          W[j+1] = rotate_left((W[j-2] ^ W[j-7] ^ W[j-13] ^ W[j-15]), 1);
00077          W[j+2] = rotate_left((W[j-1] ^ W[j-6] ^ W[j-12] ^ W[j-14]), 1);
00078          W[j+3] = rotate_left((W[j  ] ^ W[j-5] ^ W[j-11] ^ W[j-13]), 1);
00079          W[j+4] = rotate_left((W[j+1] ^ W[j-4] ^ W[j-10] ^ W[j-12]), 1);
00080          W[j+5] = rotate_left((W[j+2] ^ W[j-3] ^ W[j- 9] ^ W[j-11]), 1);
00081          W[j+6] = rotate_left((W[j+3] ^ W[j-2] ^ W[j- 8] ^ W[j-10]), 1);
00082          W[j+7] = rotate_left((W[j+4] ^ W[j-1] ^ W[j- 7] ^ W[j- 9]), 1);
00083          }
00084 
00085       F1(A, B, C, D, E, W[ 0]);   F1(E, A, B, C, D, W[ 1]);
00086       F1(D, E, A, B, C, W[ 2]);   F1(C, D, E, A, B, W[ 3]);
00087       F1(B, C, D, E, A, W[ 4]);   F1(A, B, C, D, E, W[ 5]);
00088       F1(E, A, B, C, D, W[ 6]);   F1(D, E, A, B, C, W[ 7]);
00089       F1(C, D, E, A, B, W[ 8]);   F1(B, C, D, E, A, W[ 9]);
00090       F1(A, B, C, D, E, W[10]);   F1(E, A, B, C, D, W[11]);
00091       F1(D, E, A, B, C, W[12]);   F1(C, D, E, A, B, W[13]);
00092       F1(B, C, D, E, A, W[14]);   F1(A, B, C, D, E, W[15]);
00093       F1(E, A, B, C, D, W[16]);   F1(D, E, A, B, C, W[17]);
00094       F1(C, D, E, A, B, W[18]);   F1(B, C, D, E, A, W[19]);
00095 
00096       F2(A, B, C, D, E, W[20]);   F2(E, A, B, C, D, W[21]);
00097       F2(D, E, A, B, C, W[22]);   F2(C, D, E, A, B, W[23]);
00098       F2(B, C, D, E, A, W[24]);   F2(A, B, C, D, E, W[25]);
00099       F2(E, A, B, C, D, W[26]);   F2(D, E, A, B, C, W[27]);
00100       F2(C, D, E, A, B, W[28]);   F2(B, C, D, E, A, W[29]);
00101       F2(A, B, C, D, E, W[30]);   F2(E, A, B, C, D, W[31]);
00102       F2(D, E, A, B, C, W[32]);   F2(C, D, E, A, B, W[33]);
00103       F2(B, C, D, E, A, W[34]);   F2(A, B, C, D, E, W[35]);
00104       F2(E, A, B, C, D, W[36]);   F2(D, E, A, B, C, W[37]);
00105       F2(C, D, E, A, B, W[38]);   F2(B, C, D, E, A, W[39]);
00106 
00107       F3(A, B, C, D, E, W[40]);   F3(E, A, B, C, D, W[41]);
00108       F3(D, E, A, B, C, W[42]);   F3(C, D, E, A, B, W[43]);
00109       F3(B, C, D, E, A, W[44]);   F3(A, B, C, D, E, W[45]);
00110       F3(E, A, B, C, D, W[46]);   F3(D, E, A, B, C, W[47]);
00111       F3(C, D, E, A, B, W[48]);   F3(B, C, D, E, A, W[49]);
00112       F3(A, B, C, D, E, W[50]);   F3(E, A, B, C, D, W[51]);
00113       F3(D, E, A, B, C, W[52]);   F3(C, D, E, A, B, W[53]);
00114       F3(B, C, D, E, A, W[54]);   F3(A, B, C, D, E, W[55]);
00115       F3(E, A, B, C, D, W[56]);   F3(D, E, A, B, C, W[57]);
00116       F3(C, D, E, A, B, W[58]);   F3(B, C, D, E, A, W[59]);
00117 
00118       F4(A, B, C, D, E, W[60]);   F4(E, A, B, C, D, W[61]);
00119       F4(D, E, A, B, C, W[62]);   F4(C, D, E, A, B, W[63]);
00120       F4(B, C, D, E, A, W[64]);   F4(A, B, C, D, E, W[65]);
00121       F4(E, A, B, C, D, W[66]);   F4(D, E, A, B, C, W[67]);
00122       F4(C, D, E, A, B, W[68]);   F4(B, C, D, E, A, W[69]);
00123       F4(A, B, C, D, E, W[70]);   F4(E, A, B, C, D, W[71]);
00124       F4(D, E, A, B, C, W[72]);   F4(C, D, E, A, B, W[73]);
00125       F4(B, C, D, E, A, W[74]);   F4(A, B, C, D, E, W[75]);
00126       F4(E, A, B, C, D, W[76]);   F4(D, E, A, B, C, W[77]);
00127       F4(C, D, E, A, B, W[78]);   F4(B, C, D, E, A, W[79]);
00128 
00129       A = (digest[0] += A);
00130       B = (digest[1] += B);
00131       C = (digest[2] += C);
00132       D = (digest[3] += D);
00133       E = (digest[4] += E);
00134 
00135       input += hash_block_size();
00136       }
00137    }
00138 
00139 /*
00140 * Copy out the digest
00141 */
00142 void SHA_160::copy_out(byte output[])
00143    {
00144    copy_out_vec_be(output, output_length(), digest);
00145    }
00146 
00147 /*
00148 * Clear memory of sensitive data
00149 */
00150 void SHA_160::clear()
00151    {
00152    MDx_HashFunction::clear();
00153    zeroise(W);
00154    digest[0] = 0x67452301;
00155    digest[1] = 0xEFCDAB89;
00156    digest[2] = 0x98BADCFE;
00157    digest[3] = 0x10325476;
00158    digest[4] = 0xC3D2E1F0;
00159    }
00160 
00161 }