10#include <botan/internal/blake2s.h>
12#include <botan/exceptn.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/loadstor.h>
15#include <botan/internal/rotate.h>
23const uint32_t blake2s_iv[8] = {
24 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19};
28inline void B2S_G(uint8_t a, uint8_t
b, uint8_t c, uint8_t d, uint32_t x, uint32_t y, uint32_t* v) {
29 v[a] = v[a] + v[
b] + x;
33 v[a] = v[a] + v[
b] + y;
42 return fmt(
"BLAKE2s({})", m_outlen << 3);
48void BLAKE2s::state_init(
size_t outlen,
const uint8_t* key,
size_t keylen) {
49 for(
size_t i = 0; i < 8; i++) {
50 m_h[i] = blake2s_iv[i];
52 m_h[0] ^= 0x01010000 ^ (keylen << 8) ^ outlen;
59 for(
size_t i = keylen; i < 64; i++) {
63 add_data(std::span<const uint8_t>(key, keylen));
70void BLAKE2s::compress(
bool last) {
71 const uint8_t
sigma[10][16] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
72 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
73 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
74 {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
75 {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
76 {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
77 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
78 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
79 {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
80 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}};
81 uint32_t v[16], m[16];
83 for(
size_t i = 0; i < 8; i++) {
85 v[i + 8] = blake2s_iv[i];
95 for(
size_t i = 0; i < 10; i++) {
96 B2S_G(0, 4, 8, 12, m[
sigma[i][0]], m[
sigma[i][1]], v);
97 B2S_G(1, 5, 9, 13, m[
sigma[i][2]], m[
sigma[i][3]], v);
98 B2S_G(2, 6, 10, 14, m[
sigma[i][4]], m[
sigma[i][5]], v);
99 B2S_G(3, 7, 11, 15, m[
sigma[i][6]], m[
sigma[i][7]], v);
100 B2S_G(0, 5, 10, 15, m[
sigma[i][8]], m[
sigma[i][9]], v);
101 B2S_G(1, 6, 11, 12, m[
sigma[i][10]], m[
sigma[i][11]], v);
102 B2S_G(2, 7, 8, 13, m[
sigma[i][12]], m[
sigma[i][13]], v);
103 B2S_G(3, 4, 9, 14, m[
sigma[i][14]], m[
sigma[i][15]], v);
106 for(
size_t i = 0; i < 8; ++i) {
107 m_h[i] ^= v[i] ^ v[i + 8];
115 state_init(m_outlen,
nullptr, 0);
118void BLAKE2s::add_data(std::span<const uint8_t> in) {
119 for(
size_t i = 0; i < in.size(); i++) {
132void BLAKE2s::final_result(std::span<uint8_t> out) {
150 std::unique_ptr<BLAKE2s> h = std::make_unique<BLAKE2s>(m_outlen << 3);
151 memcpy(h->m_b, m_b,
sizeof(m_b));
152 memcpy(h->m_h, m_h,
sizeof(m_h));
153 memcpy(h->m_t, m_t,
sizeof(m_t));
162 if(output_bits == 0 || output_bits > 256 || output_bits % 8 != 0) {
165 state_init(output_bits >> 3,
nullptr, 0);
std::unique_ptr< HashFunction > copy_state() const override
BLAKE2s(size_t output_bits=256)
std::string name() const override
size_t output_length() const override
std::string fmt(std::string_view format, const T &... args)
constexpr T rotr(T input)
void secure_scrub_memory(void *ptr, size_t n)
void copy_out_le(std::span< uint8_t > out, InR &&in)
constexpr auto load_le(ParamTs &&... params)