Botan  1.11.15
src/lib/hash/whirlpool/whirlpool.cpp
Go to the documentation of this file.
00001 /*
00002 * Whirlpool
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/whrlpool.h>
00010 
00011 namespace Botan {
00012 
00013 BOTAN_REGISTER_HASH_NOARGS(Whirlpool);
00014 
00015 /*
00016 * Whirlpool Compression Function
00017 */
00018 void Whirlpool::compress_n(const byte in[], size_t blocks)
00019    {
00020    static const u64bit RC[10] = {
00021       0x1823C6E887B8014F, 0x36A6D2F5796F9152,
00022       0x60BC9B8EA30C7B35, 0x1DE0D7C22E4BFE57,
00023       0x157737E59FF04ADA, 0x58C9290AB1A06B85,
00024       0xBD5D10F4CB3E0567, 0xE427418BA77D95D8,
00025       0xFBEE7C66DD17479E, 0xCA2DBF07AD5A8333
00026    };
00027 
00028    for(size_t i = 0; i != blocks; ++i)
00029       {
00030       load_be(&M[0], in, M.size());
00031 
00032       u64bit K0, K1, K2, K3, K4, K5, K6, K7;
00033       K0 = digest[0]; K1 = digest[1]; K2 = digest[2]; K3 = digest[3];
00034       K4 = digest[4]; K5 = digest[5]; K6 = digest[6]; K7 = digest[7];
00035 
00036       u64bit B0, B1, B2, B3, B4, B5, B6, B7;
00037       B0 = K0 ^ M[0]; B1 = K1 ^ M[1]; B2 = K2 ^ M[2]; B3 = K3 ^ M[3];
00038       B4 = K4 ^ M[4]; B5 = K5 ^ M[5]; B6 = K6 ^ M[6]; B7 = K7 ^ M[7];
00039 
00040       for(size_t j = 0; j != 10; ++j)
00041          {
00042          u64bit T0, T1, T2, T3, T4, T5, T6, T7;
00043          T0 = C0[get_byte(0, K0)] ^ C1[get_byte(1, K7)] ^
00044               C2[get_byte(2, K6)] ^ C3[get_byte(3, K5)] ^
00045               C4[get_byte(4, K4)] ^ C5[get_byte(5, K3)] ^
00046               C6[get_byte(6, K2)] ^ C7[get_byte(7, K1)] ^ RC[j];
00047          T1 = C0[get_byte(0, K1)] ^ C1[get_byte(1, K0)] ^
00048               C2[get_byte(2, K7)] ^ C3[get_byte(3, K6)] ^
00049               C4[get_byte(4, K5)] ^ C5[get_byte(5, K4)] ^
00050               C6[get_byte(6, K3)] ^ C7[get_byte(7, K2)];
00051          T2 = C0[get_byte(0, K2)] ^ C1[get_byte(1, K1)] ^
00052               C2[get_byte(2, K0)] ^ C3[get_byte(3, K7)] ^
00053               C4[get_byte(4, K6)] ^ C5[get_byte(5, K5)] ^
00054               C6[get_byte(6, K4)] ^ C7[get_byte(7, K3)];
00055          T3 = C0[get_byte(0, K3)] ^ C1[get_byte(1, K2)] ^
00056               C2[get_byte(2, K1)] ^ C3[get_byte(3, K0)] ^
00057               C4[get_byte(4, K7)] ^ C5[get_byte(5, K6)] ^
00058               C6[get_byte(6, K5)] ^ C7[get_byte(7, K4)];
00059          T4 = C0[get_byte(0, K4)] ^ C1[get_byte(1, K3)] ^
00060               C2[get_byte(2, K2)] ^ C3[get_byte(3, K1)] ^
00061               C4[get_byte(4, K0)] ^ C5[get_byte(5, K7)] ^
00062               C6[get_byte(6, K6)] ^ C7[get_byte(7, K5)];
00063          T5 = C0[get_byte(0, K5)] ^ C1[get_byte(1, K4)] ^
00064               C2[get_byte(2, K3)] ^ C3[get_byte(3, K2)] ^
00065               C4[get_byte(4, K1)] ^ C5[get_byte(5, K0)] ^
00066               C6[get_byte(6, K7)] ^ C7[get_byte(7, K6)];
00067          T6 = C0[get_byte(0, K6)] ^ C1[get_byte(1, K5)] ^
00068               C2[get_byte(2, K4)] ^ C3[get_byte(3, K3)] ^
00069               C4[get_byte(4, K2)] ^ C5[get_byte(5, K1)] ^
00070               C6[get_byte(6, K0)] ^ C7[get_byte(7, K7)];
00071          T7 = C0[get_byte(0, K7)] ^ C1[get_byte(1, K6)] ^
00072               C2[get_byte(2, K5)] ^ C3[get_byte(3, K4)] ^
00073               C4[get_byte(4, K3)] ^ C5[get_byte(5, K2)] ^
00074               C6[get_byte(6, K1)] ^ C7[get_byte(7, K0)];
00075 
00076          K0 = T0; K1 = T1; K2 = T2; K3 = T3;
00077          K4 = T4; K5 = T5; K6 = T6; K7 = T7;
00078 
00079          T0 = C0[get_byte(0, B0)] ^ C1[get_byte(1, B7)] ^
00080               C2[get_byte(2, B6)] ^ C3[get_byte(3, B5)] ^
00081               C4[get_byte(4, B4)] ^ C5[get_byte(5, B3)] ^
00082               C6[get_byte(6, B2)] ^ C7[get_byte(7, B1)] ^ K0;
00083          T1 = C0[get_byte(0, B1)] ^ C1[get_byte(1, B0)] ^
00084               C2[get_byte(2, B7)] ^ C3[get_byte(3, B6)] ^
00085               C4[get_byte(4, B5)] ^ C5[get_byte(5, B4)] ^
00086               C6[get_byte(6, B3)] ^ C7[get_byte(7, B2)] ^ K1;
00087          T2 = C0[get_byte(0, B2)] ^ C1[get_byte(1, B1)] ^
00088               C2[get_byte(2, B0)] ^ C3[get_byte(3, B7)] ^
00089               C4[get_byte(4, B6)] ^ C5[get_byte(5, B5)] ^
00090               C6[get_byte(6, B4)] ^ C7[get_byte(7, B3)] ^ K2;
00091          T3 = C0[get_byte(0, B3)] ^ C1[get_byte(1, B2)] ^
00092               C2[get_byte(2, B1)] ^ C3[get_byte(3, B0)] ^
00093               C4[get_byte(4, B7)] ^ C5[get_byte(5, B6)] ^
00094               C6[get_byte(6, B5)] ^ C7[get_byte(7, B4)] ^ K3;
00095          T4 = C0[get_byte(0, B4)] ^ C1[get_byte(1, B3)] ^
00096               C2[get_byte(2, B2)] ^ C3[get_byte(3, B1)] ^
00097               C4[get_byte(4, B0)] ^ C5[get_byte(5, B7)] ^
00098               C6[get_byte(6, B6)] ^ C7[get_byte(7, B5)] ^ K4;
00099          T5 = C0[get_byte(0, B5)] ^ C1[get_byte(1, B4)] ^
00100               C2[get_byte(2, B3)] ^ C3[get_byte(3, B2)] ^
00101               C4[get_byte(4, B1)] ^ C5[get_byte(5, B0)] ^
00102               C6[get_byte(6, B7)] ^ C7[get_byte(7, B6)] ^ K5;
00103          T6 = C0[get_byte(0, B6)] ^ C1[get_byte(1, B5)] ^
00104               C2[get_byte(2, B4)] ^ C3[get_byte(3, B3)] ^
00105               C4[get_byte(4, B2)] ^ C5[get_byte(5, B1)] ^
00106               C6[get_byte(6, B0)] ^ C7[get_byte(7, B7)] ^ K6;
00107          T7 = C0[get_byte(0, B7)] ^ C1[get_byte(1, B6)] ^
00108               C2[get_byte(2, B5)] ^ C3[get_byte(3, B4)] ^
00109               C4[get_byte(4, B3)] ^ C5[get_byte(5, B2)] ^
00110               C6[get_byte(6, B1)] ^ C7[get_byte(7, B0)] ^ K7;
00111 
00112          B0 = T0; B1 = T1; B2 = T2; B3 = T3;
00113          B4 = T4; B5 = T5; B6 = T6; B7 = T7;
00114          }
00115 
00116       digest[0] ^= B0 ^ M[0];
00117       digest[1] ^= B1 ^ M[1];
00118       digest[2] ^= B2 ^ M[2];
00119       digest[3] ^= B3 ^ M[3];
00120       digest[4] ^= B4 ^ M[4];
00121       digest[5] ^= B5 ^ M[5];
00122       digest[6] ^= B6 ^ M[6];
00123       digest[7] ^= B7 ^ M[7];
00124 
00125       in += hash_block_size();
00126       }
00127    }
00128 
00129 /*
00130 * Copy out the digest
00131 */
00132 void Whirlpool::copy_out(byte output[])
00133    {
00134    copy_out_vec_be(output, output_length(), digest);
00135    }
00136 
00137 /*
00138 * Clear memory of sensitive data
00139 */
00140 void Whirlpool::clear()
00141    {
00142    MDx_HashFunction::clear();
00143    zeroise(M);
00144    zeroise(digest);
00145    }
00146 
00147 }