Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: barretenberg/crypto/blake3s supports compile-time hashing #2556

Merged
merged 10 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1 +1 @@
barretenberg_module(crypto_blake3s crypto_blake2s)
barretenberg_module(crypto_blake3s)
68 changes: 34 additions & 34 deletions barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3-impl.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#pragma once
/*
BLAKE3 reference source code package - C implementations

Expand All @@ -20,61 +21,60 @@
#ifndef BLAKE3_IMPL_H
#define BLAKE3_IMPL_H

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <cstddef>
#include <cstdint>
#include <cstring>

#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<uint32_t>(src[0]) << 0) | (static_cast<uint32_t>(src[1]) << 8) |
(static_cast<uint32_t>(src[2]) << 16) | (static_cast<uint32_t>(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<uint8_t, BLAKE3_KEY_LEN>& 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<uint8_t>(w >> 0);
dst[1] = static_cast<uint8_t>(w >> 8);
dst[2] = static_cast<uint8_t>(w >> 16);
dst[3] = static_cast<uint8_t>(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
71 changes: 44 additions & 27 deletions barretenberg/cpp/src/barretenberg/crypto/blake3s/blake3s.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@
version relevant to Barretenberg.
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
#include <array>
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

namespace blake3 {

#define BLAKE3_VERSION_STRING "0.3.7"

// internal flags
enum blake3_flags {
CHUNK_START = 1 << 0,
Expand All @@ -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<uint32_t, BLAKE3_KEY_LEN>;
using block_array = std::array<uint8_t, BLAKE3_BLOCK_LEN>;
using state_array = std::array<uint32_t, 16>;
using out_array = std::array<uint8_t, BLAKE3_OUT_LEN>;

static constexpr key_array IV = { 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL };

static constexpr std::array<uint8_t, 16> MSG_SCHEDULE_0 = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
static constexpr std::array<uint8_t, 16> MSG_SCHEDULE_1 = { 2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8 };
static constexpr std::array<uint8_t, 16> MSG_SCHEDULE_2 = { 3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1 };
static constexpr std::array<uint8_t, 16> MSG_SCHEDULE_3 = { 10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6 };
static constexpr std::array<uint8_t, 16> MSG_SCHEDULE_4 = { 12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4 };
static constexpr std::array<uint8_t, 16> MSG_SCHEDULE_5 = { 9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7 };
static constexpr std::array<uint8_t, 16> MSG_SCHEDULE_6 = { 11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13 };
static constexpr std::array<std::array<uint8_t, 16>, 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<uint8_t, BLAKE3_OUT_LEN> blake3s_constexpr(const uint8_t* input, size_t input_size);
inline std::vector<uint8_t> blake3s(std::vector<uint8_t> const& input);

std::vector<uint8_t> blake3s(std::vector<uint8_t> const& input);
} // namespace blake3

#include "blake3-impl.hpp"
Loading