Botan
1.11.15
|
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 }