Botan
1.11.15
|
00001 /* 00002 * Keccak 00003 * (C) 2010 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/keccak.h> 00010 #include <botan/parsing.h> 00011 #include <botan/exceptn.h> 00012 #include <botan/internal/xor_buf.h> 00013 00014 namespace Botan { 00015 00016 BOTAN_REGISTER_HASH_NAMED_1LEN(Keccak_1600, "Keccak-1600", 512); 00017 00018 namespace { 00019 00020 void keccak_f_1600(u64bit A[25]) 00021 { 00022 static const u64bit RC[24] = { 00023 0x0000000000000001, 0x0000000000008082, 0x800000000000808A, 00024 0x8000000080008000, 0x000000000000808B, 0x0000000080000001, 00025 0x8000000080008081, 0x8000000000008009, 0x000000000000008A, 00026 0x0000000000000088, 0x0000000080008009, 0x000000008000000A, 00027 0x000000008000808B, 0x800000000000008B, 0x8000000000008089, 00028 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, 00029 0x000000000000800A, 0x800000008000000A, 0x8000000080008081, 00030 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 00031 }; 00032 00033 for(size_t i = 0; i != 24; ++i) 00034 { 00035 const u64bit C0 = A[0] ^ A[5] ^ A[10] ^ A[15] ^ A[20]; 00036 const u64bit C1 = A[1] ^ A[6] ^ A[11] ^ A[16] ^ A[21]; 00037 const u64bit C2 = A[2] ^ A[7] ^ A[12] ^ A[17] ^ A[22]; 00038 const u64bit C3 = A[3] ^ A[8] ^ A[13] ^ A[18] ^ A[23]; 00039 const u64bit C4 = A[4] ^ A[9] ^ A[14] ^ A[19] ^ A[24]; 00040 00041 const u64bit D0 = rotate_left(C0, 1) ^ C3; 00042 const u64bit D1 = rotate_left(C1, 1) ^ C4; 00043 const u64bit D2 = rotate_left(C2, 1) ^ C0; 00044 const u64bit D3 = rotate_left(C3, 1) ^ C1; 00045 const u64bit D4 = rotate_left(C4, 1) ^ C2; 00046 00047 const u64bit B00 = A[ 0] ^ D1; 00048 const u64bit B01 = rotate_left(A[ 6] ^ D2, 44); 00049 const u64bit B02 = rotate_left(A[12] ^ D3, 43); 00050 const u64bit B03 = rotate_left(A[18] ^ D4, 21); 00051 const u64bit B04 = rotate_left(A[24] ^ D0, 14); 00052 const u64bit B05 = rotate_left(A[ 3] ^ D4, 28); 00053 const u64bit B06 = rotate_left(A[ 9] ^ D0, 20); 00054 const u64bit B07 = rotate_left(A[10] ^ D1, 3); 00055 const u64bit B08 = rotate_left(A[16] ^ D2, 45); 00056 const u64bit B09 = rotate_left(A[22] ^ D3, 61); 00057 const u64bit B10 = rotate_left(A[ 1] ^ D2, 1); 00058 const u64bit B11 = rotate_left(A[ 7] ^ D3, 6); 00059 const u64bit B12 = rotate_left(A[13] ^ D4, 25); 00060 const u64bit B13 = rotate_left(A[19] ^ D0, 8); 00061 const u64bit B14 = rotate_left(A[20] ^ D1, 18); 00062 const u64bit B15 = rotate_left(A[ 4] ^ D0, 27); 00063 const u64bit B16 = rotate_left(A[ 5] ^ D1, 36); 00064 const u64bit B17 = rotate_left(A[11] ^ D2, 10); 00065 const u64bit B18 = rotate_left(A[17] ^ D3, 15); 00066 const u64bit B19 = rotate_left(A[23] ^ D4, 56); 00067 const u64bit B20 = rotate_left(A[ 2] ^ D3, 62); 00068 const u64bit B21 = rotate_left(A[ 8] ^ D4, 55); 00069 const u64bit B22 = rotate_left(A[14] ^ D0, 39); 00070 const u64bit B23 = rotate_left(A[15] ^ D1, 41); 00071 const u64bit B24 = rotate_left(A[21] ^ D2, 2); 00072 00073 A[ 0] = B00 ^ (~B01 & B02); 00074 A[ 1] = B01 ^ (~B02 & B03); 00075 A[ 2] = B02 ^ (~B03 & B04); 00076 A[ 3] = B03 ^ (~B04 & B00); 00077 A[ 4] = B04 ^ (~B00 & B01); 00078 A[ 5] = B05 ^ (~B06 & B07); 00079 A[ 6] = B06 ^ (~B07 & B08); 00080 A[ 7] = B07 ^ (~B08 & B09); 00081 A[ 8] = B08 ^ (~B09 & B05); 00082 A[ 9] = B09 ^ (~B05 & B06); 00083 A[10] = B10 ^ (~B11 & B12); 00084 A[11] = B11 ^ (~B12 & B13); 00085 A[12] = B12 ^ (~B13 & B14); 00086 A[13] = B13 ^ (~B14 & B10); 00087 A[14] = B14 ^ (~B10 & B11); 00088 A[15] = B15 ^ (~B16 & B17); 00089 A[16] = B16 ^ (~B17 & B18); 00090 A[17] = B17 ^ (~B18 & B19); 00091 A[18] = B18 ^ (~B19 & B15); 00092 A[19] = B19 ^ (~B15 & B16); 00093 A[20] = B20 ^ (~B21 & B22); 00094 A[21] = B21 ^ (~B22 & B23); 00095 A[22] = B22 ^ (~B23 & B24); 00096 A[23] = B23 ^ (~B24 & B20); 00097 A[24] = B24 ^ (~B20 & B21); 00098 00099 A[0] ^= RC[i]; 00100 } 00101 } 00102 00103 } 00104 00105 Keccak_1600::Keccak_1600(size_t output_bits) : 00106 output_bits(output_bits), 00107 bitrate(1600 - 2*output_bits), 00108 S(25), 00109 S_pos(0) 00110 { 00111 // We only support the parameters for the SHA-3 proposal 00112 00113 if(output_bits != 224 && output_bits != 256 && 00114 output_bits != 384 && output_bits != 512) 00115 throw Invalid_Argument("Keccak_1600: Invalid output length " + 00116 std::to_string(output_bits)); 00117 } 00118 00119 std::string Keccak_1600::name() const 00120 { 00121 return "Keccak-1600(" + std::to_string(output_bits) + ")"; 00122 } 00123 00124 HashFunction* Keccak_1600::clone() const 00125 { 00126 return new Keccak_1600(output_bits); 00127 } 00128 00129 void Keccak_1600::clear() 00130 { 00131 zeroise(S); 00132 S_pos = 0; 00133 } 00134 00135 void Keccak_1600::add_data(const byte input[], size_t length) 00136 { 00137 if(length == 0) 00138 return; 00139 00140 while(length) 00141 { 00142 size_t to_take = std::min(length, bitrate / 8 - S_pos); 00143 00144 length -= to_take; 00145 00146 while(to_take && S_pos % 8) 00147 { 00148 S[S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (S_pos % 8)); 00149 00150 ++S_pos; 00151 ++input; 00152 --to_take; 00153 } 00154 00155 while(to_take && to_take % 8 == 0) 00156 { 00157 S[S_pos / 8] ^= load_le<u64bit>(input, 0); 00158 S_pos += 8; 00159 input += 8; 00160 to_take -= 8; 00161 } 00162 00163 while(to_take) 00164 { 00165 S[S_pos / 8] ^= static_cast<u64bit>(input[0]) << (8 * (S_pos % 8)); 00166 00167 ++S_pos; 00168 ++input; 00169 --to_take; 00170 } 00171 00172 if(S_pos == bitrate / 8) 00173 { 00174 keccak_f_1600(&S[0]); 00175 S_pos = 0; 00176 } 00177 } 00178 } 00179 00180 void Keccak_1600::final_result(byte output[]) 00181 { 00182 std::vector<byte> padding(bitrate / 8 - S_pos); 00183 00184 padding[0] = 0x01; 00185 padding[padding.size()-1] |= 0x80; 00186 00187 add_data(&padding[0], padding.size()); 00188 00189 /* 00190 * We never have to run the permutation again because we only support 00191 * limited output lengths 00192 */ 00193 for(size_t i = 0; i != output_bits/8; ++i) 00194 output[i] = get_byte(7 - (i % 8), S[i/8]); 00195 00196 clear(); 00197 } 00198 00199 }