9#include <botan/loadstor.h>
10#include <botan/rotate.h>
11#include <botan/exceptn.h>
12#include <botan/cpuid.h>
18inline void SHA3_round(uint64_t
T[25],
const uint64_t A[25], uint64_t RC)
20 const uint64_t C0 = A[0] ^ A[5] ^ A[10] ^ A[15] ^ A[20];
21 const uint64_t C1 = A[1] ^ A[6] ^ A[11] ^ A[16] ^ A[21];
22 const uint64_t C2 = A[2] ^ A[7] ^ A[12] ^ A[17] ^ A[22];
23 const uint64_t C3 = A[3] ^ A[8] ^ A[13] ^ A[18] ^ A[23];
24 const uint64_t C4 = A[4] ^ A[9] ^ A[14] ^ A[19] ^ A[24];
26 const uint64_t D0 = rotl<1>(C0) ^ C3;
27 const uint64_t D1 = rotl<1>(C1) ^ C4;
28 const uint64_t D2 = rotl<1>(C2) ^ C0;
29 const uint64_t D3 = rotl<1>(C3) ^ C1;
30 const uint64_t D4 = rotl<1>(C4) ^ C2;
32 const uint64_t B00 = A[ 0] ^ D1;
33 const uint64_t B01 = rotl<44>(A[ 6] ^ D2);
34 const uint64_t B02 = rotl<43>(A[12] ^ D3);
35 const uint64_t B03 = rotl<21>(A[18] ^ D4);
36 const uint64_t B04 = rotl<14>(A[24] ^ D0);
37 T[ 0] = B00 ^ (~B01 & B02) ^ RC;
38 T[ 1] = B01 ^ (~B02 & B03);
39 T[ 2] = B02 ^ (~B03 & B04);
40 T[ 3] = B03 ^ (~B04 & B00);
41 T[ 4] = B04 ^ (~B00 & B01);
43 const uint64_t B05 = rotl<28>(A[ 3] ^ D4);
44 const uint64_t B06 = rotl<20>(A[ 9] ^ D0);
45 const uint64_t B07 = rotl< 3>(A[10] ^ D1);
46 const uint64_t B08 = rotl<45>(A[16] ^ D2);
47 const uint64_t B09 = rotl<61>(A[22] ^ D3);
48 T[ 5] = B05 ^ (~B06 & B07);
49 T[ 6] = B06 ^ (~B07 & B08);
50 T[ 7] = B07 ^ (~B08 & B09);
51 T[ 8] = B08 ^ (~B09 & B05);
52 T[ 9] = B09 ^ (~B05 & B06);
54 const uint64_t B10 = rotl< 1>(A[ 1] ^ D2);
55 const uint64_t B11 = rotl< 6>(A[ 7] ^ D3);
56 const uint64_t B12 = rotl<25>(A[13] ^ D4);
57 const uint64_t B13 = rotl< 8>(A[19] ^ D0);
58 const uint64_t B14 = rotl<18>(A[20] ^ D1);
59 T[10] = B10 ^ (~B11 & B12);
60 T[11] = B11 ^ (~B12 & B13);
61 T[12] = B12 ^ (~B13 & B14);
62 T[13] = B13 ^ (~B14 & B10);
63 T[14] = B14 ^ (~B10 & B11);
65 const uint64_t B15 = rotl<27>(A[ 4] ^ D0);
66 const uint64_t B16 = rotl<36>(A[ 5] ^ D1);
67 const uint64_t B17 = rotl<10>(A[11] ^ D2);
68 const uint64_t B18 = rotl<15>(A[17] ^ D3);
69 const uint64_t B19 = rotl<56>(A[23] ^ D4);
70 T[15] = B15 ^ (~B16 & B17);
71 T[16] = B16 ^ (~B17 & B18);
72 T[17] = B17 ^ (~B18 & B19);
73 T[18] = B18 ^ (~B19 & B15);
74 T[19] = B19 ^ (~B15 & B16);
76 const uint64_t B20 = rotl<62>(A[ 2] ^ D3);
77 const uint64_t B21 = rotl<55>(A[ 8] ^ D4);
78 const uint64_t B22 = rotl<39>(A[14] ^ D0);
79 const uint64_t B23 = rotl<41>(A[15] ^ D1);
80 const uint64_t B24 = rotl< 2>(A[21] ^ D2);
81 T[20] = B20 ^ (~B21 & B22);
82 T[21] = B21 ^ (~B22 & B23);
83 T[22] = B22 ^ (~B23 & B24);
84 T[23] = B23 ^ (~B24 & B20);
85 T[24] = B24 ^ (~B20 & B21);
93#if defined(BOTAN_HAS_SHA3_BMI2)
96 return permute_bmi2(A);
100 static const uint64_t RC[24] = {
101 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,
102 0x8000000080008000, 0x000000000000808B, 0x0000000080000001,
103 0x8000000080008081, 0x8000000000008009, 0x000000000000008A,
104 0x0000000000000088, 0x0000000080008009, 0x000000008000000A,
105 0x000000008000808B, 0x800000000000008B, 0x8000000000008089,
106 0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
107 0x000000000000800A, 0x800000008000000A, 0x8000000080008081,
108 0x8000000000008080, 0x0000000080000001, 0x8000000080008008
113 for(
size_t i = 0; i != 24; i += 2)
115 SHA3_round(
T, A, RC[i+0]);
116 SHA3_round(A,
T, RC[i+1]);
123 const uint8_t input[],
size_t length)
127 size_t to_take = std::min(length, bitrate / 8 - S_pos);
131 while(to_take && S_pos % 8)
133 S[S_pos / 8] ^=
static_cast<uint64_t
>(input[0]) << (8 * (S_pos % 8));
140 while(to_take && to_take % 8 == 0)
150 S[S_pos / 8] ^=
static_cast<uint64_t
>(input[0]) << (8 * (S_pos % 8));
157 if(S_pos == bitrate / 8)
170 uint8_t init_pad, uint8_t fini_pad)
172 BOTAN_ARG_CHECK(bitrate % 64 == 0,
"SHA-3 bitrate must be multiple of 64");
174 S[S_pos / 8] ^=
static_cast<uint64_t
>(init_pad) << (8 * (S_pos % 8));
175 S[(bitrate / 64) - 1] ^=
static_cast<uint64_t
>(fini_pad) << 56;
182 uint8_t output[],
size_t output_length)
184 BOTAN_ARG_CHECK(bitrate % 64 == 0,
"SHA-3 bitrate must be multiple of 64");
186 const size_t byterate = bitrate / 8;
205 m_output_bits(output_bits),
206 m_bitrate(1600 - 2*output_bits),
212 if(output_bits != 224 && output_bits != 256 &&
213 output_bits != 384 && output_bits != 512)
225#if defined(BOTAN_HAS_SHA3_BMI2)
226 if(CPUID::has_bmi2())
237 return std::unique_ptr<HashFunction>(
new SHA_3(*
this));
242 return new SHA_3(m_output_bits);
251void SHA_3::add_data(
const uint8_t input[],
size_t length)
253 m_S_pos =
SHA_3::absorb(m_bitrate, m_S, m_S_pos, input, length);
256void SHA_3::final_result(uint8_t output[])
#define BOTAN_ARG_CHECK(expr, msg)
static void permute(uint64_t A[25])
HashFunction * clone() const override
SHA_3(size_t output_bits)
static void finish(size_t bitrate, secure_vector< uint64_t > &S, size_t S_pos, uint8_t init_pad, uint8_t fini_pad)
std::string provider() const override
static size_t absorb(size_t bitrate, secure_vector< uint64_t > &S, size_t S_pos, const uint8_t input[], size_t length)
static void expand(size_t bitrate, secure_vector< uint64_t > &S, uint8_t output[], size_t output_length)
std::string name() const override
size_t output_length() const override
std::unique_ptr< HashFunction > copy_state() const override
std::string to_string(const BER_Object &obj)
void zeroise(std::vector< T, Alloc > &vec)
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
std::vector< T, secure_allocator< T > > secure_vector
uint64_t load_le< uint64_t >(const uint8_t in[], size_t off)