9 #include <botan/blake2b.h> 10 #include <botan/exceptn.h> 11 #include <botan/mem_ops.h> 12 #include <botan/loadstor.h> 13 #include <botan/rotate.h> 21 BLAKE2B_BLOCKBYTES = 128,
22 BLAKE2B_IVU64COUNT = 8
25 const uint64_t blake2b_IV[BLAKE2B_IVU64COUNT] = {
26 0x6a09e667f3bcc908, 0xbb67ae8584caa73b,
27 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
28 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
29 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
35 m_output_bits(output_bits),
36 m_buffer(BLAKE2B_BLOCKBYTES),
38 m_H(BLAKE2B_IVU64COUNT)
40 if(output_bits == 0 || output_bits > 512 || output_bits % 8 != 0)
48 void Blake2b::state_init()
50 copy_mem(m_H.data(), blake2b_IV, BLAKE2B_IVU64COUNT);
58 inline void G(uint64_t& a, uint64_t& b, uint64_t& c, uint64_t& d,
59 uint64_t M0, uint64_t M1)
71 template<
size_t i0,
size_t i1,
size_t i2,
size_t i3,
size_t i4,
size_t i5,
size_t i6,
size_t i7,
72 size_t i8,
size_t i9,
size_t iA,
size_t iB,
size_t iC,
size_t iD,
size_t iE,
size_t iF>
73 inline void ROUND(uint64_t* v,
const uint64_t* M)
75 G(v[ 0], v[ 4], v[ 8], v[12], M[i0], M[i1]);
76 G(v[ 1], v[ 5], v[ 9], v[13], M[i2], M[i3]);
77 G(v[ 2], v[ 6], v[10], v[14], M[i4], M[i5]);
78 G(v[ 3], v[ 7], v[11], v[15], M[i6], M[i7]);
79 G(v[ 0], v[ 5], v[10], v[15], M[i8], M[i9]);
80 G(v[ 1], v[ 6], v[11], v[12], M[iA], M[iB]);
81 G(v[ 2], v[ 7], v[ 8], v[13], M[iC], M[iD]);
82 G(v[ 3], v[ 4], v[ 9], v[14], M[iE], M[iF]);
88 void Blake2b::compress(
const uint8_t* input,
size_t blocks, uint64_t increment)
90 for(
size_t b = 0; b != blocks; ++b)
93 if(m_T[0] < increment)
102 input += BLAKE2B_BLOCKBYTES;
104 for(
size_t i = 0; i < 8; i++)
106 for(
size_t i = 0; i != 8; ++i)
107 v[i + 8] = blake2b_IV[i];
114 ROUND< 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15>(v, M);
115 ROUND<14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3>(v, M);
116 ROUND<11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4>(v, M);
117 ROUND< 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8>(v, M);
118 ROUND< 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13>(v, M);
119 ROUND< 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9>(v, M);
120 ROUND<12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11>(v, M);
121 ROUND<13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10>(v, M);
122 ROUND< 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5>(v, M);
123 ROUND<10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0>(v, M);
124 ROUND< 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15>(v, M);
125 ROUND<14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3>(v, M);
127 for(
size_t i = 0; i < 8; i++)
129 m_H[i] ^= v[i] ^ v[i + 8];
134 void Blake2b::add_data(
const uint8_t input[],
size_t length)
141 if(m_bufpos < BLAKE2B_BLOCKBYTES)
143 const size_t take = std::min(BLAKE2B_BLOCKBYTES - m_bufpos, length);
144 copy_mem(&m_buffer[m_bufpos], input, take);
150 if(m_bufpos == m_buffer.size() && length > 0)
152 compress(m_buffer.data(), 1, BLAKE2B_BLOCKBYTES);
157 if(length > BLAKE2B_BLOCKBYTES)
159 const size_t full_blocks = ((length-1) / BLAKE2B_BLOCKBYTES);
160 compress(input, full_blocks, BLAKE2B_BLOCKBYTES);
162 input += full_blocks * BLAKE2B_BLOCKBYTES;
163 length -= full_blocks * BLAKE2B_BLOCKBYTES;
168 copy_mem(&m_buffer[m_bufpos], input, length);
173 void Blake2b::final_result(uint8_t output[])
175 if(m_bufpos != BLAKE2B_BLOCKBYTES)
176 clear_mem(&m_buffer[m_bufpos], BLAKE2B_BLOCKBYTES - m_bufpos);
177 m_F[0] = 0xFFFFFFFFFFFFFFFF;
178 compress(m_buffer.data(), 1, m_bufpos);
190 return new Blake2b(m_output_bits);
195 return std::unique_ptr<HashFunction>(
new Blake2b(*
this));
HashFunction * clone() const override
Blake2b(size_t output_bits=512)
void clear_mem(T *ptr, size_t n)
std::string to_string(const BER_Object &obj)
std::unique_ptr< HashFunction > copy_state() const override
T load_le(const uint8_t in[], size_t off)
void copy_mem(T *out, const T *in, size_t n)
std::string name() const override
size_t output_length() const override
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)