diff --git a/barretenberg/cpp/src/barretenberg/crypto/blake3s/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/crypto/blake3s/CMakeLists.txt index 31df0b6297e..8fad42d253f 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/blake3s/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/crypto/blake3s/CMakeLists.txt @@ -1 +1 @@ -barretenberg_module(crypto_blake3s crypto_blake2s) \ No newline at end of file +barretenberg_module(crypto_blake3s) \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3-impl.hpp b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3-impl.hpp index 3b875b2b8bc..5d6c3f9708d 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3-impl.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3-impl.hpp @@ -1,3 +1,4 @@ +#pragma once /* BLAKE3 reference source code package - C implementations @@ -20,61 +21,60 @@ #ifndef BLAKE3_IMPL_H #define BLAKE3_IMPL_H -#include -#include -#include -#include -#include +#include +#include +#include #include "blake3s.hpp" namespace blake3 { // Right rotates 32 bit inputs -uint32_t rotr32(uint32_t w, uint32_t c) +constexpr uint32_t rotr32(uint32_t w, uint32_t c) { return (w >> c) | (w << (32 - c)); } -uint32_t load32(const void* src) +constexpr uint32_t load32(const uint8_t* src) { - const uint8_t* p = (const uint8_t*)src; - return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) | ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24); + return (static_cast(src[0]) << 0) | (static_cast(src[1]) << 8) | + (static_cast(src[2]) << 16) | (static_cast(src[3]) << 24); } -void load_key_words(const uint8_t key[BLAKE3_KEY_LEN], uint32_t key_words[8]) +constexpr void load_key_words(const std::array& key, key_array& key_words) { - key_words[0] = load32(&key[0 * 4]); - key_words[1] = load32(&key[1 * 4]); - key_words[2] = load32(&key[2 * 4]); - key_words[3] = load32(&key[3 * 4]); - key_words[4] = load32(&key[4 * 4]); - key_words[5] = load32(&key[5 * 4]); - key_words[6] = load32(&key[6 * 4]); - key_words[7] = load32(&key[7 * 4]); + key_words[0] = load32(&key[0]); + key_words[1] = load32(&key[4]); + key_words[2] = load32(&key[8]); + key_words[3] = load32(&key[12]); + key_words[4] = load32(&key[16]); + key_words[5] = load32(&key[20]); + key_words[6] = load32(&key[24]); + key_words[7] = load32(&key[28]); } -void store32(void* dst, uint32_t w) +constexpr void store32(uint8_t* dst, uint32_t w) { - uint8_t* p = (uint8_t*)dst; - p[0] = (uint8_t)(w >> 0); - p[1] = (uint8_t)(w >> 8); - p[2] = (uint8_t)(w >> 16); - p[3] = (uint8_t)(w >> 24); + dst[0] = static_cast(w >> 0); + dst[1] = static_cast(w >> 8); + dst[2] = static_cast(w >> 16); + dst[3] = static_cast(w >> 24); } -void store_cv_words(uint8_t bytes_out[32], uint32_t cv_words[8]) +constexpr void store_cv_words(out_array& bytes_out, key_array& cv_words) { - store32(&bytes_out[0 * 4], cv_words[0]); - store32(&bytes_out[1 * 4], cv_words[1]); - store32(&bytes_out[2 * 4], cv_words[2]); - store32(&bytes_out[3 * 4], cv_words[3]); - store32(&bytes_out[4 * 4], cv_words[4]); - store32(&bytes_out[5 * 4], cv_words[5]); - store32(&bytes_out[6 * 4], cv_words[6]); - store32(&bytes_out[7 * 4], cv_words[7]); + store32(&bytes_out[0], cv_words[0]); + store32(&bytes_out[4], cv_words[1]); + store32(&bytes_out[8], cv_words[2]); + store32(&bytes_out[12], cv_words[3]); + store32(&bytes_out[16], cv_words[4]); + store32(&bytes_out[20], cv_words[5]); + store32(&bytes_out[24], cv_words[6]); + store32(&bytes_out[28], cv_words[7]); } } // namespace blake3 -#endif /* BLAKE3_IMPL_H */ +#include "blake3s.tcc" + +#endif \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.hpp b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.hpp index bb147d06be8..a9bb85d6743 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.hpp +++ b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.hpp @@ -28,14 +28,14 @@ version relevant to Barretenberg. */ #pragma once -#include -#include +#include +#include +#include +#include #include namespace blake3 { -#define BLAKE3_VERSION_STRING "0.3.7" - // internal flags enum blake3_flags { CHUNK_START = 1 << 0, @@ -56,41 +56,58 @@ enum blake3s_constant { BLAKE3_MAX_DEPTH = 54 }; -static const uint32_t IV[8] = { 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, - 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }; - -static const uint8_t MSG_SCHEDULE[7][16] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8 }, - { 3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1 }, { 10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6 }, - { 12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4 }, { 9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7 }, - { 11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13 }, +using key_array = std::array; +using block_array = std::array; +using state_array = std::array; +using out_array = std::array; + +static constexpr key_array IV = { 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL, + 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }; + +static constexpr std::array MSG_SCHEDULE_0 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; +static constexpr std::array MSG_SCHEDULE_1 = { 2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8 }; +static constexpr std::array MSG_SCHEDULE_2 = { 3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1 }; +static constexpr std::array MSG_SCHEDULE_3 = { 10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6 }; +static constexpr std::array MSG_SCHEDULE_4 = { 12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4 }; +static constexpr std::array MSG_SCHEDULE_5 = { 9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7 }; +static constexpr std::array MSG_SCHEDULE_6 = { 11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13 }; +static constexpr std::array, 7> MSG_SCHEDULE = { + MSG_SCHEDULE_0, MSG_SCHEDULE_1, MSG_SCHEDULE_2, MSG_SCHEDULE_3, MSG_SCHEDULE_4, MSG_SCHEDULE_5, MSG_SCHEDULE_6, }; struct blake3_hasher { - uint32_t key[8]; - uint32_t cv[8]; - uint8_t buf[BLAKE3_BLOCK_LEN]; + key_array key; + key_array cv; + block_array buf; uint8_t buf_len = 0; uint8_t blocks_compressed = 0; uint8_t flags = 0; }; -const char* blake3_version(void); +inline const char* blake3_version() +{ + static const std::string version = "0.3.7"; + return version.c_str(); +} -void blake3_hasher_init(blake3_hasher* self); -void blake3_hasher_update(blake3_hasher* self, const uint8_t* input, size_t input_len); -void blake3_hasher_finalize(const blake3_hasher* self, uint8_t* out); +constexpr void blake3_hasher_init(blake3_hasher* self); +constexpr void blake3_hasher_update(blake3_hasher* self, const uint8_t* input, size_t input_len); +constexpr void blake3_hasher_finalize(const blake3_hasher* self, uint8_t* out); -void g(uint32_t* state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y); -void round_fn(uint32_t state[16], const uint32_t* msg, size_t round); +constexpr void g(state_array& state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y); +constexpr void round_fn(state_array& state, const uint32_t* msg, size_t round); -void compress_pre( - uint32_t state[16], const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint8_t flags); +constexpr void compress_pre( + state_array& state, const key_array& cv, const uint8_t* block, uint8_t block_len, uint8_t flags); -void blake3_compress_in_place(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint8_t flags); +constexpr void blake3_compress_in_place(key_array& cv, const uint8_t* block, uint8_t block_len, uint8_t flags); -void blake3_compress_xof( - const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint8_t flags, uint8_t out[64]); +constexpr void blake3_compress_xof( + const key_array& cv, const uint8_t* block, uint8_t block_len, uint8_t flags, uint8_t* out); + +constexpr std::array blake3s_constexpr(const uint8_t* input, size_t input_size); +inline std::vector blake3s(std::vector const& input); -std::vector blake3s(std::vector const& input); } // namespace blake3 + +#include "blake3-impl.hpp" diff --git a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.cpp b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.tcc similarity index 59% rename from barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.cpp rename to barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.tcc index 6d578257d26..9e2a5ef6126 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.tcc @@ -1,3 +1,4 @@ +#pragma once /* BLAKE3 reference source code package - C implementations @@ -28,13 +29,10 @@ version relevant to Barretenberg. */ -#include #include -#include -#include #include -#include "blake3-impl.hpp" +#include "blake3s.hpp" namespace blake3 { @@ -43,7 +41,7 @@ namespace blake3 { * constant parameters and fewer rounds. * */ -void g(uint32_t* state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y) +constexpr void g(state_array& state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint32_t y) { state[a] = state[a] + state[b] + x; state[d] = rotr32(state[d] ^ state[a], 16); @@ -55,10 +53,10 @@ void g(uint32_t* state, size_t a, size_t b, size_t c, size_t d, uint32_t x, uint state[b] = rotr32(state[b] ^ state[c], 7); } -void round_fn(uint32_t state[16], const uint32_t* msg, size_t round) +constexpr void round_fn(state_array& state, const uint32_t* msg, size_t round) { // Select the message schedule based on the round. - const uint8_t* schedule = MSG_SCHEDULE[round]; + const auto schedule = MSG_SCHEDULE[round]; // Mix the columns. g(state, 0, 4, 8, 12, msg[schedule[0]], msg[schedule[1]]); @@ -73,26 +71,26 @@ void round_fn(uint32_t state[16], const uint32_t* msg, size_t round) g(state, 3, 4, 9, 14, msg[schedule[14]], msg[schedule[15]]); } -void compress_pre( - uint32_t state[16], const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint8_t flags) +constexpr void compress_pre( + state_array& state, const key_array& cv, const uint8_t* block, uint8_t block_len, uint8_t flags) { - uint32_t block_words[16]; - block_words[0] = load32(block + 4 * 0); - block_words[1] = load32(block + 4 * 1); - block_words[2] = load32(block + 4 * 2); - block_words[3] = load32(block + 4 * 3); - block_words[4] = load32(block + 4 * 4); - block_words[5] = load32(block + 4 * 5); - block_words[6] = load32(block + 4 * 6); - block_words[7] = load32(block + 4 * 7); - block_words[8] = load32(block + 4 * 8); - block_words[9] = load32(block + 4 * 9); - block_words[10] = load32(block + 4 * 10); - block_words[11] = load32(block + 4 * 11); - block_words[12] = load32(block + 4 * 12); - block_words[13] = load32(block + 4 * 13); - block_words[14] = load32(block + 4 * 14); - block_words[15] = load32(block + 4 * 15); + std::array block_words; + block_words[0] = load32(&block[0]); + block_words[1] = load32(&block[4]); + block_words[2] = load32(&block[8]); + block_words[3] = load32(&block[12]); + block_words[4] = load32(&block[16]); + block_words[5] = load32(&block[20]); + block_words[6] = load32(&block[24]); + block_words[7] = load32(&block[28]); + block_words[8] = load32(&block[32]); + block_words[9] = load32(&block[36]); + block_words[10] = load32(&block[40]); + block_words[11] = load32(&block[44]); + block_words[12] = load32(&block[48]); + block_words[13] = load32(&block[52]); + block_words[14] = load32(&block[56]); + block_words[15] = load32(&block[60]); state[0] = cv[0]; state[1] = cv[1]; @@ -108,8 +106,8 @@ void compress_pre( state[11] = IV[3]; state[12] = 0; state[13] = 0; - state[14] = (uint32_t)block_len; - state[15] = (uint32_t)flags; + state[14] = static_cast(block_len); + state[15] = static_cast(flags); round_fn(state, &block_words[0], 0); round_fn(state, &block_words[0], 1); @@ -120,9 +118,9 @@ void compress_pre( round_fn(state, &block_words[0], 6); } -void blake3_compress_in_place(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint8_t flags) +constexpr void blake3_compress_in_place(key_array& cv, const uint8_t* block, uint8_t block_len, uint8_t flags) { - uint32_t state[16]; + state_array state; compress_pre(state, cv, block, block_len, flags); cv[0] = state[0] ^ state[8]; cv[1] = state[1] ^ state[9]; @@ -134,55 +132,46 @@ void blake3_compress_in_place(uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_L cv[7] = state[7] ^ state[15]; } -void blake3_compress_xof( - const uint32_t cv[8], const uint8_t block[BLAKE3_BLOCK_LEN], uint8_t block_len, uint8_t flags, uint8_t out[64]) +constexpr void blake3_compress_xof( + const key_array& cv, const uint8_t* block, uint8_t block_len, uint8_t flags, uint8_t* out) { - uint32_t state[16]; + state_array state; compress_pre(state, cv, block, block_len, flags); - store32(&out[0 * 4], state[0] ^ state[8]); - store32(&out[1 * 4], state[1] ^ state[9]); - store32(&out[2 * 4], state[2] ^ state[10]); - store32(&out[3 * 4], state[3] ^ state[11]); - store32(&out[4 * 4], state[4] ^ state[12]); - store32(&out[5 * 4], state[5] ^ state[13]); - store32(&out[6 * 4], state[6] ^ state[14]); - store32(&out[7 * 4], state[7] ^ state[15]); - store32(&out[8 * 4], state[8] ^ cv[0]); - store32(&out[9 * 4], state[9] ^ cv[1]); - store32(&out[10 * 4], state[10] ^ cv[2]); - store32(&out[11 * 4], state[11] ^ cv[3]); - store32(&out[12 * 4], state[12] ^ cv[4]); - store32(&out[13 * 4], state[13] ^ cv[5]); - store32(&out[14 * 4], state[14] ^ cv[6]); - store32(&out[15 * 4], state[15] ^ cv[7]); + store32(&out[0], state[0] ^ state[8]); + store32(&out[4], state[1] ^ state[9]); + store32(&out[8], state[2] ^ state[10]); + store32(&out[12], state[3] ^ state[11]); + store32(&out[16], state[4] ^ state[12]); + store32(&out[20], state[5] ^ state[13]); + store32(&out[24], state[6] ^ state[14]); + store32(&out[28], state[7] ^ state[15]); + store32(&out[32], state[8] ^ cv[0]); + store32(&out[36], state[9] ^ cv[1]); + store32(&out[40], state[10] ^ cv[2]); + store32(&out[44], state[11] ^ cv[3]); + store32(&out[48], state[12] ^ cv[4]); + store32(&out[52], state[13] ^ cv[5]); + store32(&out[56], state[14] ^ cv[6]); + store32(&out[60], state[15] ^ cv[7]); } -const char* blake3_version(void) -{ - return BLAKE3_VERSION_STRING; -} - -uint8_t maybe_start_flag(const blake3_hasher* self) +constexpr uint8_t maybe_start_flag(const blake3_hasher* self) { if (self->blocks_compressed == 0) { return CHUNK_START; - } else { - return 0; } + return 0; } -typedef struct output_t__ { - uint32_t input_cv[8]; - uint8_t block[BLAKE3_BLOCK_LEN]; - uint8_t block_len; - uint8_t flags; -} output_t; - -output_t make_output(const uint32_t input_cv[8], - const uint8_t block[BLAKE3_BLOCK_LEN], - uint8_t block_len, - uint8_t flags) +struct output_t { + key_array input_cv = {}; + block_array block = {}; + uint8_t block_len = 0; + uint8_t flags = 0; +}; + +constexpr output_t make_output(const key_array& input_cv, const uint8_t* block, uint8_t block_len, uint8_t flags) { output_t ret; for (size_t i = 0; i < (BLAKE3_OUT_LEN >> 2); ++i) { @@ -196,7 +185,7 @@ output_t make_output(const uint32_t input_cv[8], return ret; } -void blake3_hasher_init(blake3_hasher* self) +constexpr void blake3_hasher_init(blake3_hasher* self) { for (size_t i = 0; i < (BLAKE3_KEY_LEN >> 2); ++i) { self->key[i] = IV[i]; @@ -210,7 +199,7 @@ void blake3_hasher_init(blake3_hasher* self) self->flags = 0; } -void blake3_hasher_update(blake3_hasher* self, const uint8_t* input, size_t input_len) +constexpr void blake3_hasher_update(blake3_hasher* self, const uint8_t* input, size_t input_len) { if (input_len == 0) { return; @@ -224,11 +213,11 @@ void blake3_hasher_update(blake3_hasher* self, const uint8_t* input, size_t inpu input_len -= BLAKE3_BLOCK_LEN; } - size_t take = BLAKE3_BLOCK_LEN - ((size_t)self->buf_len); + size_t take = BLAKE3_BLOCK_LEN - (static_cast(self->buf_len)); if (take > input_len) { take = input_len; } - uint8_t* dest = self->buf + ((size_t)self->buf_len); + uint8_t* dest = &self->buf[0] + (static_cast(self->buf_len)); for (size_t i = 0; i < take; i++) { dest[i] = input[i]; } @@ -237,28 +226,38 @@ void blake3_hasher_update(blake3_hasher* self, const uint8_t* input, size_t inpu input_len -= take; } -void blake3_hasher_finalize(const blake3_hasher* self, uint8_t* out) +constexpr void blake3_hasher_finalize(const blake3_hasher* self, uint8_t* out) { uint8_t block_flags = self->flags | maybe_start_flag(self) | CHUNK_END; - output_t output = make_output(self->cv, self->buf, self->buf_len, block_flags); + output_t output = make_output(self->cv, &self->buf[0], self->buf_len, block_flags); - uint8_t wide_buf[64]; - blake3_compress_xof(output.input_cv, output.block, output.block_len, output.flags | ROOT, wide_buf); + block_array wide_buf; + blake3_compress_xof(output.input_cv, &output.block[0], output.block_len, output.flags | ROOT, &wide_buf[0]); for (size_t i = 0; i < BLAKE3_OUT_LEN; i++) { out[i] = wide_buf[i]; } - return; } std::vector blake3s(std::vector const& input) { blake3_hasher hasher; blake3_hasher_init(&hasher); - blake3_hasher_update(&hasher, (const uint8_t*)input.data(), input.size()); + blake3_hasher_update(&hasher, static_cast(input.data()), input.size()); std::vector output(BLAKE3_OUT_LEN); blake3_hasher_finalize(&hasher, &output[0]); return output; } +constexpr std::array blake3s_constexpr(const uint8_t* input, const size_t input_size) +{ + blake3_hasher hasher; + blake3_hasher_init(&hasher); + blake3_hasher_update(&hasher, input, input_size); + + std::array output; + blake3_hasher_finalize(&hasher, &output[0]); + return output; +} + } // namespace blake3 diff --git a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.test.cpp b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.test.cpp index 73b46dc864c..59ff387ba0b 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.test.cpp +++ b/barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.test.cpp @@ -1,398 +1,414 @@ #include "blake3s.hpp" -#include "../blake2s/blake2s.hpp" #include +#include "barretenberg/common/constexpr_utils.hpp" +#include #include #include #include struct test_vector { - std::string input; - std::vector output; + std::string_view input; + std::array output; }; -test_vector test_vectors[] = { - { "", - { +template constexpr std::array convert(const std::string_view& in) +{ + std::array output; + for (size_t i = 0; i < S; ++i) { + output[i] = static_cast(in[i]); + } + return output; +} + +static constexpr std::array test_vectors{ + test_vector{ .input = "", + .output = { 0xAF, 0x13, 0x49, 0xB9, 0xF5, 0xF9, 0xA1, 0xA6, 0xA0, 0x40, 0x4D, 0xEA, 0x36, 0xDC, 0xC9, 0x49, 0x9B, 0xCB, 0x25, 0xC9, 0xAD, 0xC1, 0x12, 0xB7, 0xCC, 0x9A, 0x93, 0xCA, 0xE4, 0x1F, 0x32, 0x62, } }, - { "a", - { + test_vector{ .input = "a", + .output = { 0x17, 0x76, 0x2F, 0xDD, 0xD9, 0x69, 0xA4, 0x53, 0x92, 0x5D, 0x65, 0x71, 0x7A, 0xC3, 0xEE, 0xA2, 0x13, 0x20, 0xB6, 0x6B, 0x54, 0x34, 0x2F, 0xDE, 0x15, 0x12, 0x8D, 0x6C, 0xAF, 0x21, 0x21, 0x5F, } }, - { "ab", - { + test_vector{ .input = "ab", + .output = { 0x2D, 0xC9, 0x99, 0x99, 0xA6, 0xAA, 0xEF, 0x3F, 0x20, 0x34, 0x9D, 0x2E, 0xD4, 0x05, 0x7A, 0x2B, 0x54, 0x41, 0x95, 0x45, 0xDA, 0xBB, 0x80, 0x9E, 0x63, 0x81, 0xDE, 0x1B, 0xAD, 0x83, 0x37, 0xE2, } }, - { "abc", - { + test_vector{ .input = "abc", + .output = { 0x64, 0x37, 0xB3, 0xAC, 0x38, 0x46, 0x51, 0x33, 0xFF, 0xB6, 0x3B, 0x75, 0x27, 0x3A, 0x8D, 0xB5, 0x48, 0xC5, 0x58, 0x46, 0x5D, 0x79, 0xDB, 0x03, 0xFD, 0x35, 0x9C, 0x6C, 0xD5, 0xBD, 0x9D, 0x85, } }, - { "abcd", - { + test_vector{ .input = "abcd", + .output = { 0x8C, 0x9C, 0x98, 0x81, 0x80, 0x5D, 0x1A, 0x84, 0x71, 0x02, 0xD7, 0xA4, 0x2E, 0x58, 0xB9, 0x90, 0xD0, 0x88, 0xDD, 0x88, 0xA8, 0x4F, 0x73, 0x14, 0xD7, 0x1C, 0x83, 0x81, 0x07, 0x57, 0x1F, 0x2B, } }, - { "abcde", - { + test_vector{ .input = "abcde", + .output = { 0x06, 0x48, 0xC0, 0x3B, 0x5A, 0xD9, 0xBB, 0x6D, 0xDF, 0x83, 0x06, 0xEE, 0xF6, 0xA3, 0x3E, 0xBA, 0xE8, 0xF8, 0x9C, 0xB4, 0x74, 0x11, 0x50, 0xC1, 0xAE, 0x9C, 0xD6, 0x62, 0xFD, 0xCC, 0x1E, 0xE2, } }, - { "abcdef", - { + test_vector{ .input = "abcdef", + .output = { 0xB3, 0x4B, 0x56, 0x07, 0x67, 0x12, 0xFD, 0x7F, 0xB9, 0xC0, 0x67, 0x24, 0x5A, 0x6C, 0x85, 0xE1, 0x61, 0x74, 0xB3, 0xEF, 0x2E, 0x35, 0xDF, 0x7B, 0x56, 0xB7, 0xF1, 0x64, 0xE5, 0xC3, 0x64, 0x46, } }, - { "abcdefg", - { + test_vector{ .input = "abcdefg", + .output = { 0xE2, 0xD1, 0x8D, 0x70, 0xDB, 0x12, 0x70, 0x5E, 0x18, 0x45, 0xFA, 0xF5, 0x00, 0xDE, 0x11, 0x98, 0xA5, 0xBA, 0x14, 0x83, 0x72, 0x9D, 0x97, 0x93, 0x6F, 0x1D, 0x2B, 0x76, 0x09, 0x68, 0x31, 0x2E, } }, - { "abcdefgh", - { + test_vector{ .input = "abcdefgh", + .output = { 0xDD, 0xAA, 0x2A, 0xC3, 0x0A, 0x98, 0x65, 0x59, 0x62, 0x97, 0x90, 0x19, 0xE4, 0x35, 0x38, 0x32, 0x6A, 0xD7, 0xBE, 0xF0, 0xDA, 0x0E, 0x6A, 0xC2, 0xF3, 0xE5, 0x1F, 0xB3, 0x51, 0x3A, 0x5C, 0xDA, } }, - { "abcdefghi", - { + test_vector{ .input = "abcdefghi", + .output = { 0x89, 0x9E, 0xAD, 0x67, 0x56, 0x1E, 0x6E, 0x71, 0x76, 0xDD, 0xCA, 0xD0, 0xB4, 0x47, 0xCA, 0xEC, 0x42, 0xA6, 0x58, 0xB7, 0x0B, 0xB1, 0x81, 0x75, 0x7F, 0x14, 0x4C, 0xE9, 0xEB, 0xB1, 0x59, 0xC4, } }, - { "abcdefghij", - { + test_vector{ .input = "abcdefghij", + .output = { 0xD1, 0x0C, 0x2A, 0xCB, 0x51, 0x8F, 0xD7, 0x4A, 0xE1, 0x30, 0xF6, 0x3E, 0x3A, 0x45, 0x2A, 0x9A, 0x05, 0x54, 0x71, 0x16, 0x41, 0x81, 0xA6, 0x3A, 0x7D, 0x94, 0xC1, 0x82, 0xF5, 0x70, 0x34, 0x9B, } }, - { "abcdefghijk", - { + test_vector{ .input = "abcdefghijk", + .output = { 0x33, 0x69, 0x93, 0xBC, 0xB0, 0xAA, 0xCB, 0x8B, 0x33, 0xCB, 0xBF, 0x67, 0x70, 0x25, 0x59, 0x29, 0x62, 0x60, 0x6A, 0x69, 0x0C, 0xEC, 0xBE, 0xD3, 0x85, 0x7C, 0x81, 0xF9, 0x49, 0x36, 0x4E, 0xA5, } }, - { "abcdefghijkl", - { + test_vector{ .input = "abcdefghijkl", + .output = { 0xA7, 0x4A, 0x54, 0x2E, 0xA1, 0xF9, 0x95, 0x7F, 0x55, 0xBA, 0xE1, 0x99, 0xF8, 0x9A, 0xB4, 0x6B, 0x90, 0xC8, 0xB4, 0x1E, 0x94, 0x04, 0x89, 0x07, 0x5E, 0xC9, 0x24, 0x49, 0x0F, 0xB6, 0xA9, 0x26, } }, - { "abcdefghijklm", - { + test_vector{ .input = "abcdefghijklm", + .output = { 0xA1, 0xF7, 0xDF, 0x9D, 0x3A, 0x01, 0x44, 0x25, 0x22, 0x0D, 0x2B, 0x96, 0xDF, 0xB3, 0xCE, 0xBA, 0x8A, 0xD1, 0x26, 0x4E, 0xD1, 0x65, 0x56, 0x50, 0x02, 0xA6, 0xEC, 0xC3, 0x02, 0xAF, 0x7A, 0xD0, } }, - { "abcdefghijklmn", - { + test_vector{ .input = "abcdefghijklmn", + .output = { 0x7A, 0x97, 0x9F, 0xCC, 0xF3, 0x89, 0x89, 0xFC, 0xDD, 0x63, 0x09, 0xDB, 0x94, 0x7D, 0x28, 0x6D, 0xF2, 0xF4, 0xF7, 0xEC, 0x80, 0xDD, 0x11, 0x88, 0xEC, 0x07, 0x94, 0xE9, 0x1B, 0x8F, 0xBE, 0x2E, } }, - { "abcdefghijklmno", - { + test_vector{ .input = "abcdefghijklmno", + .output = { 0xF3, 0x50, 0x1B, 0x61, 0x52, 0x06, 0xCE, 0x9E, 0x7D, 0xC2, 0xC6, 0xAD, 0x16, 0xA0, 0xF2, 0xC6, 0x44, 0x34, 0xDD, 0xF1, 0xA5, 0x33, 0xBB, 0xDC, 0x0A, 0x25, 0xA6, 0x0D, 0x20, 0xE4, 0x4E, 0x5E, } }, - { "abcdefghijklmnop", - { + test_vector{ .input = "abcdefghijklmnop", + .output = { 0x00, 0x9E, 0x43, 0x83, 0x6D, 0x52, 0xF4, 0x8B, 0x87, 0x6D, 0x62, 0x74, 0xFF, 0x17, 0xFA, 0xF3, 0xB5, 0xA3, 0x4A, 0xF7, 0x7E, 0x68, 0xD7, 0xFA, 0x73, 0x0E, 0x5E, 0xF9, 0xFE, 0xA2, 0xD3, 0x58, } }, - { "abcdefghijklmnopq", - { + test_vector{ .input = "abcdefghijklmnopq", + .output = { 0x26, 0xDC, 0x2E, 0x71, 0x55, 0x16, 0xD4, 0x06, 0xC3, 0x70, 0x02, 0x05, 0x68, 0x90, 0xFE, 0xD1, 0x94, 0x64, 0x83, 0x38, 0x7E, 0xFB, 0xB8, 0x0E, 0x87, 0x33, 0x74, 0x32, 0x67, 0x37, 0x21, 0x61, } }, - { "abcdefghijklmnopqr", - { + test_vector{ .input = "abcdefghijklmnopqr", + .output = { 0xD1, 0x32, 0x17, 0xD1, 0x80, 0xF3, 0x75, 0xED, 0xDD, 0x8A, 0x18, 0x9E, 0x03, 0x18, 0x31, 0x69, 0x1F, 0xBD, 0x73, 0xB0, 0x28, 0xEE, 0x49, 0x7A, 0x5C, 0xAF, 0xC0, 0x8B, 0xD2, 0x9C, 0xEA, 0x6C, } }, - { "abcdefghijklmnopqrs", - { + test_vector{ .input = "abcdefghijklmnopqrs", + .output = { 0x24, 0x5F, 0xE8, 0x6C, 0xDE, 0x9B, 0x1E, 0x6F, 0xAD, 0xDB, 0xFA, 0xEE, 0xAF, 0x7F, 0x9C, 0x7C, 0xD9, 0xC0, 0x9A, 0xD6, 0x2B, 0x38, 0x45, 0x2D, 0x10, 0x3F, 0x62, 0x09, 0x83, 0x4C, 0xBF, 0x23, } }, - { "abcdefghijklmnopqrst", - { + test_vector{ .input = "abcdefghijklmnopqrst", + .output = { 0x18, 0xC5, 0x4F, 0xED, 0x84, 0xD3, 0x23, 0xE2, 0xEE, 0x91, 0x94, 0x81, 0x19, 0x22, 0x4F, 0x31, 0x59, 0xBF, 0xD4, 0xCD, 0xD3, 0xF5, 0x85, 0xF8, 0x2B, 0x56, 0xE0, 0xA6, 0x30, 0x92, 0xAD, 0xDE, } }, - { "abcdefghijklmnopqrstu", - { + test_vector{ .input = "abcdefghijklmnopqrstu", + .output = { 0x61, 0x4A, 0x68, 0x5B, 0xE9, 0x1B, 0xC4, 0x46, 0x05, 0xEA, 0xE3, 0x31, 0x17, 0x5F, 0x45, 0xB8, 0xDA, 0xC2, 0x6F, 0xE3, 0xD1, 0xC5, 0xFB, 0xCD, 0x5D, 0x76, 0x1E, 0x0F, 0x74, 0x12, 0xB8, 0x2F, } }, - { "abcdefghijklmnopqrstuv", - { + test_vector{ .input = "abcdefghijklmnopqrstuv", + .output = { 0x22, 0x37, 0x6F, 0x74, 0xFE, 0x12, 0x93, 0xC4, 0xB7, 0x3B, 0xA3, 0x53, 0x7F, 0x00, 0xA3, 0x52, 0xE6, 0xA1, 0x2D, 0x67, 0xBF, 0xF9, 0x74, 0xC3, 0xBB, 0xA4, 0x4A, 0x5F, 0xC0, 0x3F, 0xED, 0xE7, } }, - { "abcdefghijklmnopqrstuvw", - { + test_vector{ .input = "abcdefghijklmnopqrstuvw", + .output = { 0xC9, 0x65, 0xC1, 0xCC, 0xCE, 0x9C, 0xBC, 0xCB, 0xB8, 0x68, 0x31, 0x64, 0x91, 0xAA, 0x01, 0x86, 0xAB, 0x83, 0x9C, 0xFE, 0x86, 0xEF, 0xA4, 0xFE, 0xDF, 0xF0, 0x79, 0x2C, 0x79, 0xCF, 0x4E, 0xF9, } }, - { "abcdefghijklmnopqrstuvwx", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwx", + .output = { 0x3A, 0x00, 0x36, 0x42, 0xAB, 0x93, 0xEA, 0xD3, 0xDC, 0xEB, 0xDE, 0x1C, 0xD7, 0x4D, 0x48, 0x2A, 0xEA, 0xB7, 0x6C, 0x51, 0x52, 0xA7, 0xF2, 0xE4, 0x02, 0x39, 0x63, 0xBF, 0x36, 0x57, 0x03, 0xD8, } }, - { "abcdefghijklmnopqrstuvwxy", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxy", + .output = { 0xF7, 0xD9, 0x71, 0xE0, 0x5B, 0xAF, 0xD5, 0x8A, 0x22, 0x0F, 0x3A, 0x95, 0x34, 0x54, 0x2F, 0xE5, 0x45, 0x60, 0x4A, 0x7F, 0x99, 0x16, 0x56, 0x49, 0xB6, 0x59, 0x09, 0x3A, 0xEB, 0xA5, 0xFA, 0x6A, } }, - { "abcdefghijklmnopqrstuvwxyz", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz", + .output = { 0x24, 0x68, 0xEE, 0xC8, 0x89, 0x4A, 0xCF, 0xB4, 0xE4, 0xDF, 0x3A, 0x51, 0xEA, 0x91, 0x6B, 0xA1, 0x15, 0xD4, 0x82, 0x68, 0x28, 0x77, 0x54, 0x29, 0x0A, 0xAE, 0x8E, 0x9E, 0x62, 0x28, 0xE8, 0x5F, } }, - { "abcdefghijklmnopqrstuvwxyz0", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0", + .output = { 0xD6, 0xC9, 0xDE, 0x2C, 0x54, 0xD2, 0x7B, 0xDB, 0x4F, 0x68, 0xCD, 0x3C, 0x73, 0x42, 0x1D, 0x81, 0xF5, 0x2C, 0xC8, 0x06, 0xD2, 0x55, 0xDA, 0x08, 0xE2, 0x25, 0x4A, 0x0D, 0x57, 0x03, 0x1F, 0xF0, } }, - { "abcdefghijklmnopqrstuvwxyz01", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz01", + .output = { 0x4D, 0x0C, 0x6F, 0x2F, 0xB0, 0xC1, 0xEB, 0xC4, 0x1B, 0xF2, 0x3C, 0xBA, 0xED, 0x30, 0x88, 0x39, 0xD7, 0x80, 0xAB, 0x47, 0xC8, 0xA3, 0x81, 0x23, 0xAF, 0x46, 0xB6, 0xE3, 0xAD, 0x82, 0x5F, 0xA4, } }, - { "abcdefghijklmnopqrstuvwxyz012", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz012", + .output = { 0x4C, 0xEB, 0x7C, 0x49, 0x7A, 0xF4, 0xB6, 0x73, 0xC8, 0x58, 0xD8, 0x74, 0x6F, 0xDD, 0xBA, 0x3B, 0xFA, 0x80, 0xFA, 0x1A, 0xCB, 0x84, 0xE2, 0xAE, 0x91, 0x76, 0x9D, 0x4B, 0xD8, 0x74, 0xEA, 0x70, } }, - { "abcdefghijklmnopqrstuvwxyz0123", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123", + .output = { 0xED, 0x4C, 0x4A, 0xC9, 0x6A, 0x2E, 0xB3, 0xC0, 0xCC, 0x80, 0x88, 0xB4, 0x30, 0x3F, 0xD6, 0x78, 0x9B, 0x65, 0x16, 0x2F, 0x35, 0xD2, 0x77, 0xB2, 0xE6, 0xA8, 0x0F, 0xAF, 0x48, 0xCA, 0x67, 0x5E, } }, - { "abcdefghijklmnopqrstuvwxyz01234", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz01234", + .output = { 0x6A, 0x96, 0x16, 0x1F, 0x64, 0xDB, 0x0D, 0x56, 0xF0, 0x73, 0xFF, 0xE3, 0xC2, 0xC6, 0x66, 0xEB, 0x70, 0x2F, 0xFF, 0xCA, 0xA1, 0xF0, 0x96, 0xEB, 0xB1, 0x97, 0x0F, 0x78, 0xFD, 0xB5, 0x2B, 0xC9, } }, - { "abcdefghijklmnopqrstuvwxyz012345", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz012345", + .output = { 0x35, 0x5E, 0x5F, 0xD6, 0x25, 0xA9, 0xCD, 0x5C, 0x27, 0xB3, 0x12, 0xB3, 0xC4, 0x20, 0x8D, 0x02, 0x36, 0xED, 0x6D, 0x32, 0x56, 0x6B, 0xD5, 0xA0, 0x64, 0x25, 0x99, 0xC1, 0xC8, 0x99, 0x64, 0x06, } }, - { "abcdefghijklmnopqrstuvwxyz0123456", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456", + .output = { 0x86, 0xDE, 0x08, 0xB3, 0x23, 0x46, 0xA1, 0x21, 0xDB, 0xC1, 0xBB, 0xB9, 0x0C, 0xFF, 0xCA, 0x94, 0x29, 0xA5, 0x06, 0x8D, 0x79, 0x52, 0xFE, 0xF8, 0x97, 0x41, 0x6E, 0xBC, 0xE2, 0x47, 0xC6, 0xAE, } }, - { "abcdefghijklmnopqrstuvwxyz01234567", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz01234567", + .output = { 0xFA, 0x75, 0xCD, 0x23, 0x99, 0x2C, 0x82, 0xCF, 0x11, 0x0B, 0x4C, 0xA1, 0xEE, 0x6A, 0x11, 0x86, 0x15, 0x48, 0xE9, 0xBD, 0x9C, 0xCB, 0x63, 0x2C, 0x7B, 0x60, 0x1F, 0xC3, 0xCB, 0x10, 0x65, 0x9F, } }, - { "abcdefghijklmnopqrstuvwxyz012345678", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz012345678", + .output = { 0x2F, 0x96, 0xFC, 0xD5, 0x47, 0x6D, 0x14, 0x65, 0xB0, 0xA9, 0x9B, 0x37, 0x31, 0xCA, 0xF2, 0x41, 0x4B, 0xD2, 0xF0, 0x90, 0x10, 0xEE, 0x09, 0x44, 0x48, 0xBD, 0xB5, 0x59, 0x8A, 0xEC, 0xFF, 0xD2, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789", + .output = { 0xB0, 0xB9, 0x2F, 0x78, 0x81, 0x54, 0x3E, 0xFB, 0x77, 0xF3, 0x18, 0x6D, 0x81, 0x86, 0x09, 0x44, 0x20, 0xA9, 0x00, 0x63, 0xBB, 0x5A, 0x38, 0xC7, 0x55, 0x1D, 0xFB, 0x3D, 0xAC, 0x2F, 0xEB, 0xB1, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789a", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789a", + .output = { 0x0B, 0xE1, 0x2A, 0x0C, 0xFC, 0xE8, 0xCF, 0xAF, 0xB4, 0x66, 0x2D, 0xBC, 0xFD, 0xD4, 0x21, 0xAF, 0x55, 0x98, 0xE2, 0x01, 0x5D, 0xC8, 0xA3, 0x80, 0x5A, 0x68, 0xA7, 0x6D, 0x9D, 0xB0, 0xFE, 0xC3, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789ab", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789ab", + .output = { 0x82, 0x0F, 0x15, 0xAE, 0x80, 0x73, 0x5E, 0x1B, 0x0A, 0x67, 0x6C, 0xA6, 0x9D, 0x36, 0xA1, 0x8D, 0x86, 0x93, 0x21, 0x39, 0x84, 0xD5, 0x5B, 0x5E, 0x3A, 0x7C, 0xC9, 0x60, 0x45, 0x08, 0x49, 0x79, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abc", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abc", + .output = { 0xD8, 0x42, 0xF4, 0x26, 0xC3, 0x02, 0xDD, 0x36, 0xE7, 0x26, 0xD8, 0x59, 0xF0, 0xD3, 0x54, 0x3B, 0xA9, 0xF3, 0x31, 0xE2, 0xA4, 0xFC, 0x93, 0xF9, 0x22, 0xC0, 0xDD, 0xFA, 0x60, 0x2E, 0x36, 0x32, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcd", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcd", + .output = { 0x50, 0xA4, 0xDE, 0x4F, 0x65, 0x9A, 0x28, 0x2C, 0xD0, 0x99, 0x68, 0x60, 0x12, 0xDB, 0xD9, 0xAF, 0x2C, 0x1F, 0xD9, 0x7B, 0x50, 0x8E, 0xE8, 0x7B, 0xF6, 0x5F, 0x6F, 0x3E, 0x7F, 0x67, 0xB5, 0xF9, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcde", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcde", + .output = { 0x05, 0xC5, 0x21, 0xE1, 0x77, 0x93, 0xF5, 0x5D, 0xAF, 0x1D, 0x3A, 0xDD, 0xD1, 0x3A, 0xC8, 0xF7, 0x84, 0x51, 0xAF, 0xE4, 0x1C, 0x3D, 0xAC, 0x3D, 0xE5, 0x5D, 0x9F, 0x11, 0xE8, 0x31, 0xED, 0x2B, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdef", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdef", + .output = { 0x1D, 0x7D, 0x82, 0xB2, 0xD2, 0x17, 0xD9, 0xDF, 0xCB, 0xC6, 0xD9, 0x72, 0x47, 0x22, 0x0C, 0xC5, 0x2D, 0xF1, 0x0F, 0xAF, 0xD4, 0x51, 0x61, 0xD2, 0x6A, 0x36, 0x36, 0x5D, 0x0E, 0xB8, 0xDD, 0x65, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefg", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefg", + .output = { 0xC7, 0x82, 0x41, 0x6B, 0xF3, 0xE7, 0x40, 0x6B, 0x1A, 0xFD, 0xC8, 0x2A, 0xFB, 0x6D, 0xE6, 0xB9, 0x15, 0xFF, 0x83, 0x48, 0x2D, 0x61, 0x11, 0x8E, 0xE1, 0xC0, 0x35, 0xE6, 0x48, 0x39, 0x9E, 0xE6, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefgh", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefgh", + .output = { 0x0C, 0xB5, 0x2C, 0xD0, 0x1B, 0x97, 0x54, 0x0F, 0x87, 0x3E, 0xD6, 0x71, 0x9D, 0x5F, 0xF6, 0xFE, 0xB1, 0xE1, 0x46, 0x91, 0x35, 0x50, 0x0E, 0x6E, 0xD5, 0x9D, 0x21, 0x41, 0x43, 0xD9, 0x50, 0xC2, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghi", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghi", + .output = { 0x6F, 0xE1, 0xD4, 0x04, 0x47, 0x58, 0x8C, 0x8D, 0xD9, 0x7B, 0x63, 0x72, 0xE4, 0x85, 0xD9, 0x33, 0x63, 0x36, 0x2A, 0x5B, 0xF6, 0x4E, 0x4C, 0x1B, 0x34, 0x1B, 0xD7, 0xF7, 0xFF, 0x86, 0x81, 0xFC, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghij", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghij", + .output = { 0xB4, 0x75, 0xF1, 0x63, 0xEF, 0x54, 0x19, 0x19, 0x01, 0x9D, 0x5B, 0xF2, 0x87, 0xC5, 0x6E, 0xD6, 0x47, 0x24, 0xFD, 0x54, 0x86, 0x5A, 0x6A, 0xC1, 0xF0, 0x1D, 0x20, 0x06, 0x23, 0x29, 0x85, 0x01, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijk", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijk", + .output = { 0x57, 0xA5, 0xD1, 0x5A, 0xAB, 0x13, 0x3A, 0x41, 0x25, 0xBA, 0x8E, 0xFC, 0x97, 0x90, 0x48, 0x16, 0x6A, 0x21, 0x58, 0x5F, 0x47, 0xDA, 0xC9, 0x64, 0xA6, 0x4C, 0xCA, 0xD0, 0x49, 0xF9, 0x5B, 0xC1, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijkl", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijkl", + .output = { 0x40, 0x9F, 0x20, 0x6E, 0xBE, 0x1D, 0x31, 0x1C, 0x2E, 0x97, 0x16, 0xC6, 0x8F, 0x81, 0xBF, 0x7D, 0xA2, 0x2A, 0xC3, 0x27, 0x10, 0x07, 0xF6, 0x15, 0x54, 0x0D, 0xF8, 0xA3, 0x22, 0x54, 0x08, 0xA0, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklm", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklm", + .output = { 0xC1, 0x1A, 0x7C, 0x91, 0xAC, 0xC9, 0x02, 0xA6, 0xC5, 0x41, 0xFC, 0x0C, 0x79, 0x49, 0xDC, 0x86, 0xF5, 0xBE, 0xCD, 0x3E, 0xFD, 0x21, 0x89, 0x64, 0xD2, 0x36, 0x1A, 0x9D, 0xEB, 0xC9, 0xD6, 0x24, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmn", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmn", + .output = { 0xC4, 0xBB, 0x86, 0x95, 0x20, 0x61, 0xEC, 0xB5, 0x97, 0x16, 0x3E, 0xB3, 0xAD, 0xD6, 0xAB, 0x55, 0xEB, 0x76, 0x25, 0xCD, 0xA7, 0x43, 0x89, 0x39, 0xF0, 0x58, 0xFD, 0x37, 0x43, 0xF7, 0x50, 0xE6, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmno", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmno", + .output = { 0x52, 0x37, 0x53, 0x3B, 0x57, 0x4F, 0x97, 0xAE, 0x1F, 0x93, 0xEE, 0x00, 0x56, 0x59, 0xCD, 0xCB, 0x2D, 0x93, 0xF5, 0x28, 0x2D, 0x88, 0x12, 0xCD, 0xCD, 0xF1, 0xB2, 0x3C, 0xE6, 0xC0, 0x5D, 0xE1, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnop", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnop", + .output = { 0x12, 0x31, 0x05, 0x55, 0x14, 0x80, 0x59, 0xFD, 0x7D, 0x68, 0x56, 0xD8, 0x66, 0x5D, 0xBB, 0xCF, 0xC8, 0x27, 0x88, 0x7F, 0x4F, 0xE3, 0x3E, 0x60, 0x5B, 0x3F, 0xF8, 0x3D, 0x5F, 0x42, 0xCB, 0x4B, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopq", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopq", + .output = { 0xF1, 0xEF, 0x42, 0xBD, 0x61, 0x26, 0x88, 0x75, 0x92, 0x98, 0x37, 0x2B, 0x04, 0x3C, 0xBB, 0x22, 0x71, 0xA6, 0x51, 0x12, 0x0D, 0x99, 0xA4, 0x02, 0x52, 0xC0, 0x75, 0xC8, 0x32, 0x57, 0x61, 0xA1, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqr", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqr", + .output = { 0x39, 0xC9, 0x89, 0x0B, 0x86, 0xAC, 0xDF, 0xD8, 0xB8, 0x76, 0x4C, 0x78, 0x34, 0x62, 0x25, 0xF9, 0xD0, 0x69, 0xCC, 0x53, 0xB8, 0xD8, 0xC3, 0xB9, 0xD5, 0xD9, 0x99, 0x22, 0xBA, 0x4E, 0x2C, 0x43, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrs", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrs", + .output = { 0x94, 0x84, 0xD7, 0x8C, 0x2C, 0x64, 0x9C, 0x38, 0x41, 0xE5, 0x95, 0xCD, 0x20, 0xA4, 0xD0, 0x87, 0xBF, 0x52, 0xCE, 0x14, 0x69, 0xE2, 0x57, 0x08, 0xA4, 0x18, 0x32, 0x58, 0xC6, 0x1E, 0xD2, 0xEF, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrst", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrst", + .output = { 0x38, 0x5C, 0xC1, 0x1A, 0x36, 0x61, 0x12, 0xBE, 0x5B, 0xF3, 0x36, 0x32, 0xB3, 0x63, 0xD4, 0x95, 0x5D, 0x29, 0x5F, 0x1F, 0x2B, 0x4C, 0xF0, 0x08, 0xBB, 0x0E, 0x67, 0x90, 0xB1, 0x17, 0xD3, 0xE6, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstu", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstu", + .output = { 0x52, 0x35, 0x52, 0x89, 0x00, 0xF4, 0xBC, 0x82, 0xF5, 0x47, 0x46, 0x33, 0x05, 0x87, 0xD1, 0x1B, 0x8F, 0x20, 0x3E, 0x66, 0x35, 0xD8, 0x3A, 0xB7, 0x08, 0xC6, 0x9A, 0x95, 0xBC, 0x6E, 0xC7, 0xAD, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuv", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuv", + .output = { 0xD1, 0x40, 0x7E, 0x7D, 0x6B, 0x47, 0x49, 0xF9, 0x9F, 0xEB, 0x9C, 0xAE, 0x77, 0xFF, 0x4B, 0x3B, 0x32, 0xA6, 0xD0, 0xD3, 0x6E, 0xB1, 0xA2, 0x79, 0x28, 0xBD, 0xAB, 0x1A, 0x98, 0x21, 0xF0, 0xD7, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvw", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvw", + .output = { 0x4F, 0xE7, 0xCC, 0x9F, 0x96, 0x3F, 0x77, 0x03, 0xB4, 0x48, 0x26, 0xEC, 0x47, 0x6E, 0x63, 0x3F, 0x22, 0xCA, 0x25, 0x97, 0xAE, 0x1A, 0x5B, 0x75, 0xF8, 0x4A, 0xFE, 0x6C, 0x8A, 0x04, 0xAD, 0x56, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwx", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwx", + .output = { 0xD0, 0x50, 0x10, 0x40, 0xA4, 0xCE, 0x8E, 0xB2, 0x73, 0x55, 0x19, 0xC3, 0xFB, 0xED, 0x76, 0x5E, 0x9D, 0x80, 0x42, 0xDD, 0x3B, 0xD4, 0x3F, 0xF9, 0x07, 0xCC, 0xD9, 0x5D, 0xCC, 0x17, 0xC6, 0xCC, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxy", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxy", + .output = { 0xE8, 0x8C, 0xAF, 0x20, 0x5D, 0x3C, 0x9F, 0x8F, 0x82, 0x2F, 0x65, 0x3A, 0xD5, 0x80, 0x9F, 0x43, 0xD1, 0xF9, 0xD4, 0x6A, 0x3E, 0x45, 0xA9, 0xEB, 0xCF, 0xF2, 0xE6, 0xC0, 0x64, 0x38, 0xF8, 0x7D, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz", + .output = { 0x23, 0xCE, 0xAA, 0xFD, 0xAC, 0x74, 0xFB, 0xB0, 0x87, 0x33, 0xC0, 0x03, 0x25, 0xA6, 0x96, 0x40, 0xEE, 0x85, 0xC9, 0xB3, 0x32, 0x68, 0x2C, 0x5A, 0xE2, 0x68, 0xB4, 0x53, 0x90, 0x48, 0x7C, 0x6A, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0", + .output = { 0xD4, 0x91, 0x25, 0x0A, 0x64, 0xC0, 0xA6, 0xB6, 0xDB, 0x2D, 0xDE, 0x1A, 0xEA, 0x38, 0x92, 0xEE, 0x56, 0x47, 0x8D, 0x2B, 0x26, 0xC4, 0x26, 0xE2, 0xA2, 0x52, 0xE5, 0x39, 0x37, 0x5F, 0xFB, 0x59, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01", + .output = { 0xF7, 0xF8, 0x54, 0x5A, 0x00, 0x36, 0x5D, 0xE0, 0x08, 0x90, 0xAF, 0x80, 0x89, 0x96, 0xED, 0x71, 0x87, 0x8A, 0xDA, 0x34, 0x9A, 0x98, 0xD2, 0xCB, 0x5B, 0x91, 0x06, 0xC1, 0x95, 0x60, 0x71, 0x37, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz012", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz012", + .output = { 0xF5, 0x2B, 0x8E, 0x5E, 0x75, 0xC5, 0x6B, 0x8E, 0xAD, 0x21, 0xE5, 0xEF, 0x19, 0x19, 0xBD, 0xA7, 0x30, 0x70, 0x8B, 0xA3, 0x3F, 0x9F, 0x24, 0x6A, 0x73, 0xC4, 0x03, 0xE1, 0x41, 0xCE, 0xED, 0x0F, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123", + .output = { 0x8D, 0x07, 0x4A, 0xB3, 0xB4, 0x1A, 0xF8, 0xCF, 0x10, 0xCB, 0x52, 0x60, 0x6A, 0xED, 0xEC, 0x0B, 0xFB, 0x8D, 0xD9, 0xF0, 0xD5, 0x22, 0xA8, 0xAA, 0xD4, 0x5C, 0x4C, 0x50, 0x01, 0x60, 0xF3, 0x07, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01234", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01234", + .output = { 0x35, 0xFF, 0xDE, 0x6F, 0x4A, 0xF5, 0xE6, 0x5F, 0x5E, 0xCF, 0x17, 0x46, 0x4A, 0xE6, 0xDE, 0x27, 0x56, 0x06, 0x5F, 0xAF, 0x72, 0xF6, 0x3A, 0xD9, 0x02, 0xBD, 0x0E, 0x56, 0x2B, 0xB7, 0x18, 0x94, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz012345", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz012345", + .output = { 0xFE, 0x4F, 0x12, 0xD6, 0x2E, 0xC1, 0x73, 0x6E, 0x99, 0x4A, 0x78, 0xD8, 0xEF, 0x66, 0x7E, 0x5B, 0x35, 0xB3, 0x03, 0x74, 0x85, 0x76, 0x0E, 0x8F, 0xFA, 0xDD, 0xE2, 0x41, 0xA6, 0x19, 0x34, 0x66, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456", + .output = { 0xA3, 0x27, 0xA8, 0xF0, 0xCE, 0xF2, 0x24, 0x4E, 0x39, 0x3F, 0xE9, 0x8B, 0xA7, 0xE5, 0x59, 0x5C, 0x5E, 0x40, 0xE4, 0x35, 0x93, 0xE5, 0x87, 0xCE, 0x55, 0x43, 0x02, 0x1C, 0xD5, 0xF9, 0x4C, 0xAD, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01234567", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz01234567", + .output = { 0xD2, 0x17, 0xD0, 0xA3, 0xEC, 0x35, 0x28, 0x99, 0xDD, 0xB1, 0xD0, 0x38, 0xE5, 0x33, 0x6A, 0xE7, 0x15, 0x56, 0xC0, 0xEA, 0x61, 0x2A, 0xF9, 0x70, 0xCB, 0x75, 0xD4, 0x9B, 0x1E, 0x25, 0x36, 0x6E, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz012345678", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz012345678", + .output = { 0x05, 0x5E, 0x47, 0x72, 0x8E, 0x3C, 0xE5, 0xD4, 0x83, 0xBD, 0xB4, 0x8F, 0x47, 0x14, 0x5C, 0xF6, 0xF7, 0x31, 0xF5, 0x0F, 0xC9, 0x34, 0xA1, 0xF6, 0x4B, 0x58, 0xBD, 0xE6, 0x41, 0x38, 0x38, 0x07, } }, - { "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789", - { + test_vector{ .input = "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789", + .output = { 0xAA, 0x60, 0x21, 0x6D, 0xE8, 0x21, 0x17, 0x5F, 0x97, 0x3E, 0x38, 0x26, 0xED, 0x7A, 0x0B, 0x74, 0x31, 0xEC, 0x87, 0xE8, 0xE2, 0x19, 0x2E, 0x80, 0x24, 0x12, 0x53, 0xB2, 0xA9, 0x4D, 0xB0, 0x11, - } }, + }} }; -std::vector test_input(size_t input_len) -{ - std::vector input; - for (size_t i = 0; i < input_len; ++i) { - input.push_back(uint8_t(i % 251)); - } - return input; -} - -TEST(misc_blake3s, test_vectors) +TEST(MiscBlake3s, TestVectors) { - for (auto v : test_vectors) { + barretenberg::constexpr_for<0, 1, 73>([&]() { + constexpr auto v = test_vectors[index]; std::vector input(v.input.begin(), v.input.end()); - EXPECT_EQ(blake3::blake3s(input), v.output); - } + auto result_vector = blake3::blake3s(input); + std::array result; + std::copy(result_vector.begin(), result_vector.end(), result.begin()); + + EXPECT_EQ(result, v.output); + + // There's no such thing as a compile-time pointer to &input_array[0] if array is empty. + // We use `dummy_array` as a workaround for this edge-case + constexpr std::array dummy_array{ 0 }; + constexpr size_t S = index > 0 ? v.input.size() : 1; + constexpr std::array input_array = index > 0 ? convert(v.input) : dummy_array; + constexpr std::array result_constexpr = + blake3::blake3s_constexpr(&input_array[0], index > 0 ? S : 0); + EXPECT_EQ(result_constexpr, v.output); + static_assert(result_constexpr == v.output); + }); }