Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
blake_util.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
10
12
13using namespace bb::plookup;
14
15// constants
17
18constexpr uint8_t MSG_SCHEDULE_BLAKE3[7][16] = {
19 { 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 },
20 { 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 },
21 { 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 },
22 { 11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13 },
23};
24
25constexpr uint8_t MSG_SCHEDULE_BLAKE2[10][16] = {
26 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
27 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
28 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
29 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
30 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
31};
32
39template <typename Builder> field_t<Builder> add_normalize(const field_t<Builder>& a, const field_t<Builder>& b)
40{
43
44 Builder* ctx = a.get_context() ? a.get_context() : b.get_context();
45
46 uint256_t sum = a.get_value() + b.get_value();
47
48 uint256_t normalized_sum = static_cast<uint32_t>(sum.data[0]);
49
50 if (a.witness_index == IS_CONSTANT && b.witness_index == IS_CONSTANT) {
51 return field_pt(ctx, normalized_sum);
52 }
53
54 field_pt overflow = witness_pt(ctx, fr((sum - normalized_sum) >> 32));
55
56 // The overflow here could be of 2 bits because we allow that much overflow in the Blake rounds.
57 overflow.create_range_constraint(3);
58
59 // a + b - (overflow * 2^{32})
60 field_pt result = a.add_two(b, overflow * field_pt(ctx, -fr((uint64_t)(1ULL << 32ULL))));
61
62 return result;
63}
64
112template <typename Builder>
114 size_t a,
115 size_t b,
116 size_t c,
117 size_t d,
120 const bool last_update = false)
121{
123
124 // For simplicity, state[a] is written as `a' in comments.
125 // a = a + b + x
126 state[a] = state[a].add_two(state[b], x);
127
128 // d = (d ^ a).ror(16)
129 const auto lookup_1 = plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR_ROTATE_16, state[d], state[a], true);
130 field_pt scaling_factor_1 = (1 << (32 - 16));
131 state[d] = lookup_1[ColumnIdx::C3][0] * scaling_factor_1;
132
133 // c = c + d
134 state[c] = state[c] + state[d];
135
136 // b = (b ^ c).ror(12)
137 const auto lookup_2 = plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR, state[b], state[c], true);
138 field_pt lookup_output = lookup_2[ColumnIdx::C3][2];
139 field_pt t2_term = field_pt(1 << 12) * lookup_2[ColumnIdx::C3][2];
140 lookup_output += (lookup_2[ColumnIdx::C3][0] - t2_term) * field_pt(1 << 20);
141 state[b] = lookup_output;
142
143 // a = a + b + y
144 if (!last_update) {
145 state[a] = state[a].add_two(state[b], y);
146 } else {
147 state[a] = add_normalize(state[a], state[b] + y);
148 }
149
150 // d = (d ^ a).ror(8)
151 const auto lookup_3 = plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR_ROTATE_8, state[d], state[a], true);
152 field_pt scaling_factor_3 = (1 << (32 - 8));
153 state[d] = lookup_3[ColumnIdx::C3][0] * scaling_factor_3;
154
155 // c = c + d
156 if (!last_update) {
157 state[c] = state[c] + state[d];
158 } else {
159 state[c] = add_normalize(state[c], state[d]);
160 }
161
162 // b = (b ^ c).ror(7)
163 const auto lookup_4 = plookup_read<Builder>::get_lookup_accumulators(BLAKE_XOR_ROTATE_7, state[b], state[c], true);
164 field_pt scaling_factor_4 = (1 << (32 - 7));
165 state[b] = lookup_4[ColumnIdx::C3][0] * scaling_factor_4;
166}
167
168/*
169 * This is the round function used in Blake2s and Blake3s for Ultra.
170 * Inputs: - 16-word state
171 * - 16-word msg
172 * - round numbe
173 * - which_blake to choose Blake2 or Blake3 (false -> Blake2)
174 */
175template <typename Builder>
178 size_t round,
179 const bool which_blake = false)
180{
181 // Select the message schedule based on the round.
182 const uint8_t* schedule = which_blake ? MSG_SCHEDULE_BLAKE3[round] : MSG_SCHEDULE_BLAKE2[round];
183
184 // Mix the columns.
185 g<Builder>(state, 0, 4, 8, 12, msg[schedule[0]], msg[schedule[1]]);
186 g<Builder>(state, 1, 5, 9, 13, msg[schedule[2]], msg[schedule[3]]);
187 g<Builder>(state, 2, 6, 10, 14, msg[schedule[4]], msg[schedule[5]]);
188 g<Builder>(state, 3, 7, 11, 15, msg[schedule[6]], msg[schedule[7]]);
189
190 // Mix the rows.
191 g<Builder>(state, 0, 5, 10, 15, msg[schedule[8]], msg[schedule[9]], true);
192 g<Builder>(state, 1, 6, 11, 12, msg[schedule[10]], msg[schedule[11]], true);
193 g<Builder>(state, 2, 7, 8, 13, msg[schedule[12]], msg[schedule[13]], true);
194 g<Builder>(state, 3, 4, 9, 14, msg[schedule[14]], msg[schedule[15]], true);
195}
196
197} // namespace bb::stdlib::blake_util
void create_range_constraint(size_t num_bits, std::string const &msg="field_t::range_constraint") const
Let x = *this.normalize(), constrain x.v < 2^{num_bits}.
Definition field.cpp:908
field_t add_two(const field_t &add_b, const field_t &add_c) const
Efficiently compute (this + a + b) using big_mul gate.
Definition field.cpp:572
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
FF a
FF b
stdlib::witness_t< bb::UltraCircuitBuilder > witness_pt
stdlib::field_t< UltraCircuitBuilder > field_pt
@ BLAKE_XOR_ROTATE_16
Definition types.hpp:129
@ BLAKE_XOR_ROTATE_7
Definition types.hpp:131
@ BLAKE_XOR_ROTATE_8
Definition types.hpp:130
constexpr uint8_t MSG_SCHEDULE_BLAKE2[10][16]
field_t< Builder > add_normalize(const field_t< Builder > &a, const field_t< Builder > &b)
constexpr uint8_t MSG_SCHEDULE_BLAKE3[7][16]
void g(field_t< Builder > state[BLAKE_STATE_SIZE], size_t a, size_t b, size_t c, size_t d, field_t< Builder > x, field_t< Builder > y, const bool last_update=false)
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)
field< Bn254FrParams > fr
Definition fr.hpp:174
Inner sum(Cont< Inner, Args... > const &in)
Definition container.hpp:70