Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
blake2s.cpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Nishat], commit: 66052c96cc754339ac3f2761f341f150130555b3}
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#include "blake_util.hpp"
8
11
19namespace bb::stdlib {
20
40template <typename Builder> void Blake2s<Builder>::increment_counter(blake2s_state& S, const uint32_t inc)
41{
42 // Note that the initial blake2s_state values are circuit constants.
43 BB_ASSERT(S.t[0].is_constant());
44 BB_ASSERT(S.t[1].is_constant());
45
46 field_ct inc_scalar(static_cast<uint256_t>(inc));
47
48 S.t[0] = S.t[0] + inc_scalar;
49 // Enforced constant state (t[0], t[1]) allows computing the carry out-of-circuit (with correct 32-bit wrap) without
50 // adding constraints.
51 const bool to_inc = uint32_t(uint256_t(S.t[0].get_value())) < inc;
52 S.t[1] = S.t[1] + (to_inc ? field_ct(1) : field_ct(0));
53}
54
55template <typename Builder> void Blake2s<Builder>::compress(blake2s_state& S, byte_array_ct const& in)
56{
58 using namespace blake_util;
59 field_ct m[BLAKE2S_STATE_SIZE];
60 field_ct v[BLAKE2S_STATE_SIZE];
61
62 for (size_t i = 0; i < BLAKE2S_STATE_SIZE; ++i) {
63 m[i] = static_cast<field_ct>(in.slice(i * 4, 4).reverse());
64 }
65
66 for (size_t i = 0; i < 8; ++i) {
67 v[i] = S.h[i];
68 }
69
70 v[8] = field_ct(uint256_t(blake2s_IV[0]));
71 v[9] = field_ct(uint256_t(blake2s_IV[1]));
72 v[10] = field_ct(uint256_t(blake2s_IV[2]));
73 v[11] = field_ct(uint256_t(blake2s_IV[3]));
74
75 // Use the lookup tables to perform XORs
76 const auto lookup_1 =
78 v[12] = lookup_1[ColumnIdx::C3][0];
79 const auto lookup_2 =
81 v[13] = lookup_2[ColumnIdx::C3][0];
82 const auto lookup_3 =
84 v[14] = lookup_3[ColumnIdx::C3][0];
85 const auto lookup_4 =
87 v[15] = lookup_4[ColumnIdx::C3][0];
88
89 for (size_t idx = 0; idx < 10; idx++) {
90 blake_util::round_fn(v, m, idx);
91 }
92
93 // At this point in the algorithm, the elements (v0, v1, v2, v3) and (v8, v9, v10, v11) in the state matrix 'v' can
94 // be 'overflowed' i.e. contain values > 2^{32}. However we do NOT need to normalize them to be < 2^{32}, the
95 // following `read_sequence_from_table` calls correctly constrain the output to be 32-bits
96 for (size_t i = 0; i < 8; ++i) {
97 const auto lookup_a = plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR, S.h[i], v[i], true);
98 const auto lookup_b =
99 plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR, lookup_a[ColumnIdx::C3][0], v[i + 8], true);
100 S.h[i] = lookup_b[ColumnIdx::C3][0];
101 }
102}
103
104template <typename Builder> void Blake2s<Builder>::blake2s(blake2s_state& S, byte_array_ct const& in)
105{
106 using plookup::ColumnIdx;
107 using namespace blake_util;
108
109 size_t offset = 0;
110 size_t size = in.size();
111
112 while (size > BLAKE2S_BLOCKBYTES) {
113 increment_counter(S, BLAKE2S_BLOCKBYTES);
114 compress(S, in.slice(offset, BLAKE2S_BLOCKBYTES));
115 offset += BLAKE2S_BLOCKBYTES;
116 size -= BLAKE2S_BLOCKBYTES;
117 }
118
119 // Set last block.
120 S.f[0] = field_t<Builder>(uint256_t((uint32_t)-1));
121
122 // Build final block: remaining input + constant padding
123 Builder* ctx = in.get_context();
124 auto remaining = in.slice(offset);
125
126 // Combine remaining bytes and constant padding (no constraints needed for constants)
127 byte_array_ct final = remaining; // Copy constrained remaining bytes
128 byte_array_ct padding = byte_array_ct::constant_padding(ctx, BLAKE2S_BLOCKBYTES - size);
129 final.write(padding);
130
131 increment_counter(S, static_cast<uint32_t>(size));
132 compress(S, final);
133}
134
135template <typename Builder> byte_array<Builder> Blake2s<Builder>::hash(const byte_array_ct& input)
136{
138
139 for (size_t i = 0; i < 8; i++) {
140 S.h[i] = field_ct(uint256_t(initial_H[i]));
141 }
142
143 blake2s(S, input);
144
145 // Build result from state values
147 for (const auto& h : S.h) {
148 // byte_array_ct(field, num_bytes) constructor adds range constraints for each byte
149 byte_array_ct v(h, 4);
150 auto reversed = v.reverse();
151 result.write(reversed);
152 }
153 return result;
154}
155
156template class Blake2s<UltraCircuitBuilder>;
157template class Blake2s<MegaCircuitBuilder>;
158
159} // namespace bb::stdlib
#define BB_ASSERT(expression,...)
Definition assert.hpp:70
static void compress(blake2s_state &S, byte_array_ct const &in)
Definition blake2s.cpp:55
static void blake2s(blake2s_state &S, byte_array_ct const &in)
Definition blake2s.cpp:104
static byte_array_ct hash(const byte_array_ct &input)
Definition blake2s.cpp:135
static void increment_counter(blake2s_state &S, const uint32_t inc)
Definition blake2s.cpp:40
Represents a dynamic array of bytes in-circuit.
byte_array slice(size_t offset) const
Slice bytes from the byte array starting at offset. Does not add any constraints.
byte_array reverse() const
Reverse the bytes in the byte array.
byte_array & write(byte_array const &other)
Appends the contents of another byte_array (other) to the end of this one.
size_t size() const
Builder * get_context() const
static byte_array constant_padding(Builder *parent_context, size_t num_bytes, uint8_t value=0)
bb::fr get_value() const
Given a := *this, compute its value given by a.v * a.mul + a.add.
Definition field.cpp:838
bool is_constant() const
Definition field.hpp:442
static plookup::ReadData< field_pt > get_lookup_accumulators(const plookup::MultiTableId id, const field_pt &key_a, const field_pt &key_b=0, const bool is_2_to_1_lookup=false)
Definition plookup.cpp:19
ssize_t offset
Definition engine.cpp:62
stdlib::field_t< Builder > field_ct
void round_fn(field_t< Builder > state[BLAKE_STATE_SIZE], field_t< Builder > msg[BLAKE_STATE_SIZE], size_t round, const bool which_blake=false)
std::vector< uint8_t > compress(const std::vector< uint8_t > &input)
Save modified ivc-inputs.msgpack when VKs are rewritten.
field_t< Builder > f[2]
Definition blake2s.hpp:35
field_t< Builder > t[2]
Definition blake2s.hpp:34
field_t< Builder > h[8]
Definition blake2s.hpp:33