Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
sha256.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
8
13
14#include "sparse.hpp"
15#include "types.hpp"
16
18
19static constexpr uint64_t choose_normalization_table[28]{
20 /* xor result = 0 */
21 0, // e + 2f + 3g = 0 => e = 0, f = 0, g = 0 => t = 0
22 0, // e + 2f + 3g = 1 => e = 1, f = 0, g = 0 => t = 0
23 0, // e + 2f + 3g = 2 => e = 0, f = 1, g = 0 => t = 0
24 1, // e + 2f + 3g = 3 => e = 0, f = 0, g = 1 OR e = 1, f = 1, g = 0 => t = 1
25 0, // e + 2f + 3g = 4 => e = 1, f = 0, g = 1 => t = 0
26 1, // e + 2f + 3g = 5 => e = 0, f = 1, g = 1 => t = 1
27 1, // e + 2f + 3g = 6 => e = 1, f = 1, g = 1 => t = 1
28 /* xor result = 1 */
29 1, // e + 2f + 3g = 0 => e = 0, f = 0, g = 0 => t = 0
30 1, // e + 2f + 3g = 1 => e = 1, f = 0, g = 0 => t = 0
31 1, // e + 2f + 3g = 2 => e = 0, f = 1, g = 0 => t = 0
32 2, // e + 2f + 3g = 3 => e = 0, f = 0, g = 1 OR e = 1, f = 1, g = 0 => t = 1
33 1, // e + 2f + 3g = 4 => e = 1, f = 0, g = 1 => t = 0
34 2, // e + 2f + 3g = 5 => e = 0, f = 1, g = 1 => t = 1
35 2, // e + 2f + 3g = 6 => e = 1, f = 1, g = 1 => t = 1
36 /* xor result = 2 */
37 0, // e + 2f + 3g = 0 => e = 0, f = 0, g = 0 => t = 0
38 0, // e + 2f + 3g = 1 => e = 1, f = 0, g = 0 => t = 0
39 0, // e + 2f + 3g = 2 => e = 0, f = 1, g = 0 => t = 0
40 1, // e + 2f + 3g = 3 => e = 0, f = 0, g = 1 OR e = 1, f = 1, g = 0 => t = 1
41 0, // e + 2f + 3g = 4 => e = 1, f = 0, g = 1 => t = 0
42 1, // e + 2f + 3g = 5 => e = 0, f = 1, g = 1 => t = 1
43 1, // e + 2f + 3g = 6 => e = 1, f = 1, g = 1 => t = 1
44 1, // e + 2f + 3g = 0 => e = 0, f = 0, g = 0 => t = 0
45 /* xor result = 3 */
46 1, // e + 2f + 3g = 1 => e = 1, f = 0, g = 0 => t = 0
47 1, // e + 2f + 3g = 2 => e = 0, f = 1, g = 0 => t = 0
48 2, // e + 2f + 3g = 3 => e = 0, f = 0, g = 1 OR e = 1, f = 1, g = 0 => t = 1
49 1, // e + 2f + 3g = 4 => e = 1, f = 0, g = 1 => t = 0
50 2, // e + 2f + 3g = 5 => e = 0, f = 1, g = 1 => t = 1
51 2, // e + 2f + 3g = 6 => e = 1, f = 1, g = 1 => t = 1
52};
53
54static constexpr uint64_t majority_normalization_table[16]{
55 /* xor result = 0 */
56 0, // a + b + c = 0 => (a & b) ^ (a & c) ^ (b & c) = 0
57 0, // a + b + c = 1 => (a & b) ^ (a & c) ^ (b & c) = 0
58 1, // a + b + c = 2 => (a & b) ^ (a & c) ^ (b & c) = 1
59 1, // a + b + c = 3 => (a & b) ^ (a & c) ^ (b & c) = 1
60 /* xor result = 1 */
61 1,
62 1,
63 2,
64 2,
65 /* xor result = 2 */
66 0,
67 0,
68 1,
69 1,
70 /* xor result = 3 */
71 1,
72 1,
73 2,
74 2,
75};
76
77static constexpr uint64_t witness_extension_normalization_table[16]{
78 /* xor result = 0 */
79 0,
80 1,
81 0,
82 1,
83 /* xor result = 1 */
84 1,
85 2,
86 1,
87 2,
88 /* xor result = 2 */
89 0,
90 1,
91 0,
92 1,
93 /* xor result = 3 */
94 1,
95 2,
96 1,
97 2,
98};
99
101{
102 return sparse_tables::generate_sparse_normalization_table<16, 3, witness_extension_normalization_table>(
103 id, table_index);
104}
105
107{
108 return sparse_tables::generate_sparse_normalization_table<28, 2, choose_normalization_table>(id, table_index);
109}
110
112{
113 return sparse_tables::generate_sparse_normalization_table<16, 3, majority_normalization_table>(id, table_index);
114}
115
117{
118 const size_t num_entries = 11;
119
120 MultiTable table(numeric::pow64(16, 3), 1 << 3, 0, num_entries);
121
122 table.id = id;
123 for (size_t i = 0; i < num_entries; ++i) {
124 table.slice_sizes.emplace_back(numeric::pow64(16, 3));
125 table.basic_table_ids.emplace_back(SHA256_WITNESS_NORMALIZE);
126 table.get_table_values.emplace_back(
127 &sparse_tables::get_sparse_normalization_values<16, witness_extension_normalization_table>);
128 }
129 return table;
130}
131
133{
134 const size_t num_entries = 16;
135
136 MultiTable table(numeric::pow64(28, 2), 1 << 2, 0, num_entries);
137
138 table.id = id;
139 for (size_t i = 0; i < num_entries; ++i) {
140 table.slice_sizes.emplace_back(numeric::pow64(28, 2));
141 table.basic_table_ids.emplace_back(SHA256_CH_NORMALIZE);
142 table.get_table_values.emplace_back(
143 &sparse_tables::get_sparse_normalization_values<28, choose_normalization_table>);
144 }
145 return table;
146}
147
149{
150 const size_t num_entries = 11;
151
152 MultiTable table(numeric::pow64(16, 3), 1 << 3, 0, num_entries);
153
154 table.id = id;
155 for (size_t i = 0; i < num_entries; ++i) {
156 table.slice_sizes.emplace_back(numeric::pow64(16, 3));
157 table.basic_table_ids.emplace_back(SHA256_MAJ_NORMALIZE);
158 table.get_table_values.emplace_back(
159 &sparse_tables::get_sparse_normalization_values<16, majority_normalization_table>);
160 }
161 return table;
162}
163
165{
166 constexpr uint64_t base_temp = 16;
167 auto base = bb::fr(base_temp);
168 // scaling factors applied to a's sparse limbs, excluding the rotated limb
169 const std::array<bb::fr, 3> rot2_coefficients{ 0, base.pow(11 - 2), base.pow(22 - 2) };
170 const std::array<bb::fr, 3> rot13_coefficients{ base.pow(32 - 13), 0, base.pow(22 - 13) };
171 const std::array<bb::fr, 3> rot22_coefficients{ base.pow(32 - 22), base.pow(32 - 22 + 11), 0 };
172
173 // these are the coefficients that we want
174 const std::array<bb::fr, 3> target_rotation_coefficients{
175 rot2_coefficients[0] + rot13_coefficients[0] + rot22_coefficients[0],
176 rot2_coefficients[1] + rot13_coefficients[1] + rot22_coefficients[1],
177 rot2_coefficients[2] + rot13_coefficients[2] + rot22_coefficients[2],
178 };
179
180 bb::fr column_2_row_1_multiplier = target_rotation_coefficients[0];
181 bb::fr column_2_row_2_multiplier =
182 target_rotation_coefficients[0] * (-bb::fr(base).pow(11)) + target_rotation_coefficients[1];
183
184 std::array<bb::fr, 3> rotation_multipliers = { column_2_row_1_multiplier, column_2_row_2_multiplier, bb::fr(0) };
185 return rotation_multipliers;
186}
187
188// template <uint64_t rot_a, uint64_t rot_b, uint64_t rot_c>
190{
191 const std::array<bb::fr, 3> column_2_row_3_coefficients{
192 bb::fr(1),
193 bb::fr(28).pow(11),
194 bb::fr(28).pow(22),
195 };
196
197 // scaling factors applied to a's sparse limbs, excluding the rotated limb
198 const std::array<bb::fr, 3> rot6_coefficients{ bb::fr(0), bb::fr(28).pow(11 - 6), bb::fr(28).pow(22 - 6) };
199 const std::array<bb::fr, 3> rot11_coefficients{ bb::fr(28).pow(32 - 11), bb::fr(0), bb::fr(28).pow(22 - 11) };
200 const std::array<bb::fr, 3> rot25_coefficients{ bb::fr(28).pow(32 - 25), bb::fr(28).pow(32 - 25 + 11), bb::fr(0) };
201
202 // these are the coefficients that we want
203 const std::array<bb::fr, 3> target_rotation_coefficients{
204 rot6_coefficients[0] + rot11_coefficients[0] + rot25_coefficients[0],
205 rot6_coefficients[1] + rot11_coefficients[1] + rot25_coefficients[1],
206 rot6_coefficients[2] + rot11_coefficients[2] + rot25_coefficients[2],
207 };
208
209 bb::fr column_2_row_1_multiplier = bb::fr(1) * target_rotation_coefficients[0]; // why multiply by one?
210
211 // this gives us the correct scaling factor for a0's 1st limb
212 std::array<bb::fr, 3> current_coefficients{
213 column_2_row_3_coefficients[0] * column_2_row_1_multiplier,
214 column_2_row_3_coefficients[1] * column_2_row_1_multiplier,
215 column_2_row_3_coefficients[2] * column_2_row_1_multiplier,
216 };
217
218 bb::fr column_2_row_3_multiplier = -(current_coefficients[2]) + target_rotation_coefficients[2];
219
220 std::array<bb::fr, 3> rotation_multipliers = { column_2_row_1_multiplier, bb::fr(0), column_2_row_3_multiplier };
221 return rotation_multipliers;
222}
223
225{
226 std::vector<bb::fr> column_1_coefficients{ 1, 1 << 3, 1 << 10, 1 << 18 };
227 std::vector<bb::fr> column_2_coefficients{ 0, 0, 0, 0 };
228 std::vector<bb::fr> column_3_coefficients{ 0, 0, 0, 0 };
229 MultiTable table(column_1_coefficients, column_2_coefficients, column_3_coefficients);
230 table.id = id;
231 table.slice_sizes = { (1 << 3), (1 << 7), (1 << 8), (1 << 18) };
236
237 table.get_table_values = {
238 &sparse_tables::get_sparse_table_with_rotation_values<16, 0>,
239 &sparse_tables::get_sparse_table_with_rotation_values<16, 4>,
240 &sparse_tables::get_sparse_table_with_rotation_values<16, 7>,
241 &sparse_tables::get_sparse_table_with_rotation_values<16, 1>,
242 };
243 return table;
244}
245
247{
300 // scaling factors applied to a's sparse limbs, excluding the rotated limb
301 const std::array<bb::fr, 3> rot6_coefficients{ bb::fr(0), bb::fr(28).pow(11 - 6), bb::fr(28).pow(22 - 6) };
302 const std::array<bb::fr, 3> rot11_coefficients{ bb::fr(28).pow(32 - 11), bb::fr(0), bb::fr(28).pow(22 - 11) };
303 const std::array<bb::fr, 3> rot25_coefficients{ bb::fr(28).pow(32 - 25), bb::fr(28).pow(32 - 25 + 11), bb::fr(0) };
304
305 // these are the coefficients that we want
306 const std::array<bb::fr, 3> target_rotation_coefficients{
307 rot6_coefficients[0] + rot11_coefficients[0] + rot25_coefficients[0],
308 rot6_coefficients[1] + rot11_coefficients[1] + rot25_coefficients[1],
309 rot6_coefficients[2] + rot11_coefficients[2] + rot25_coefficients[2],
310 };
311
312 bb::fr column_2_row_1_multiplier = target_rotation_coefficients[0];
313
314 // this gives us the correct scaling factor for a0's 1st limb
315 std::array<bb::fr, 3> current_coefficients{
316 column_2_row_1_multiplier,
317 bb::fr(28).pow(11) * column_2_row_1_multiplier,
318 bb::fr(28).pow(22) * column_2_row_1_multiplier,
319 };
320
321 // bb::fr column_2_row_3_multiplier = -(current_coefficients[2]) + target_rotation_coefficients[2];
322 bb::fr column_3_row_2_multiplier = -(current_coefficients[1]) + target_rotation_coefficients[1];
323
324 std::vector<bb::fr> column_1_coefficients{ bb::fr(1), bb::fr(1 << 11), bb::fr(1 << 22) };
325 std::vector<bb::fr> column_2_coefficients{ bb::fr(1), bb::fr(28).pow(11), bb::fr(28).pow(22) };
326 std::vector<bb::fr> column_3_coefficients{ bb::fr(1), column_3_row_2_multiplier + bb::fr(1), bb::fr(1) };
327 MultiTable table(column_1_coefficients, column_2_coefficients, column_3_coefficients);
328 table.id = id;
329 table.slice_sizes = { (1 << 11), (1 << 11), (1 << 10) };
331
332 table.get_table_values.push_back(&sparse_tables::get_sparse_table_with_rotation_values<28, 6>);
333 table.get_table_values.push_back(&sparse_tables::get_sparse_table_with_rotation_values<28, 0>);
334 table.get_table_values.push_back(&sparse_tables::get_sparse_table_with_rotation_values<28, 3>);
335 // table.get_table_values = std::vector<MultiTable::table_out (*)(MultiTable::table_in)>{
336
337 // &get_sha256_sparse_map_values<28, 0, 0>,
338 // &get_sha256_sparse_map_values<28, 3, 0>,
339 // };
340 return table;
341}
342
343// This table (at third row and column) returns the sum of roations that "non-trivially wrap"
345{
363 constexpr uint64_t base = 16;
364
365 // scaling factors applied to a's sparse limbs, excluding the rotated limb
366 const std::array<bb::fr, 3> rot2_coefficients{ bb::fr(0), bb::fr(base).pow(11 - 2), bb::fr(base).pow(22 - 2) };
367 const std::array<bb::fr, 3> rot13_coefficients{ bb::fr(base).pow(32 - 13), bb::fr(0), bb::fr(base).pow(22 - 13) };
368 const std::array<bb::fr, 3> rot22_coefficients{ bb::fr(base).pow(32 - 22),
369 bb::fr(base).pow(32 - 22 + 11),
370 bb::fr(0) };
371
372 // these are the coefficients that we want
373 const std::array<bb::fr, 3> target_rotation_coefficients{
374 rot2_coefficients[0] + rot13_coefficients[0] + rot22_coefficients[0],
375 rot2_coefficients[1] + rot13_coefficients[1] + rot22_coefficients[1],
376 rot2_coefficients[2] + rot13_coefficients[2] + rot22_coefficients[2],
377 };
378
379 bb::fr column_2_row_3_multiplier =
380 target_rotation_coefficients[1] * (-bb::fr(base).pow(11)) + target_rotation_coefficients[2];
381
382 std::vector<bb::fr> column_1_coefficients{ bb::fr(1), bb::fr(1 << 11), bb::fr(1 << 22) };
383 std::vector<bb::fr> column_2_coefficients{ bb::fr(1), bb::fr(base).pow(11), bb::fr(base).pow(22) };
384 std::vector<bb::fr> column_3_coefficients{ bb::fr(1), bb::fr(1), bb::fr(1) + column_2_row_3_multiplier };
385
386 MultiTable table(column_1_coefficients, column_2_coefficients, column_3_coefficients);
387 table.id = id;
388 table.slice_sizes = { (1 << 11), (1 << 11), (1 << 10) };
390 table.get_table_values = {
391 &sparse_tables::get_sparse_table_with_rotation_values<16, 2>,
392 &sparse_tables::get_sparse_table_with_rotation_values<16, 2>,
393 &sparse_tables::get_sparse_table_with_rotation_values<16, 0>,
394 };
395 return table;
396}
397
398} // namespace bb::plookup::sha256_tables
constexpr uint64_t pow64(const uint64_t input, const uint64_t exponent)
Definition pow.hpp:13
MultiTable get_witness_extension_input_table(const MultiTableId id=SHA256_WITNESS_INPUT)
Definition sha256.hpp:224
MultiTable get_majority_input_table(const MultiTableId id=SHA256_MAJ_INPUT)
Definition sha256.hpp:344
BasicTable generate_choose_normalization_table(BasicTableId id, const size_t table_index)
Definition sha256.hpp:106
MultiTable get_witness_extension_output_table(const MultiTableId id=SHA256_WITNESS_OUTPUT)
Definition sha256.hpp:116
BasicTable generate_majority_normalization_table(BasicTableId id, const size_t table_index)
Definition sha256.hpp:111
MultiTable get_choose_output_table(const MultiTableId id=SHA256_CH_OUTPUT)
Definition sha256.hpp:132
std::array< bb::fr, 3 > get_choose_rotation_multipliers()
Definition sha256.hpp:189
MultiTable get_choose_input_table(const MultiTableId id=SHA256_CH_INPUT)
Definition sha256.hpp:246
MultiTable get_majority_output_table(const MultiTableId id=SHA256_MAJ_OUTPUT)
Definition sha256.hpp:148
std::array< bb::fr, 3 > get_majority_rotation_multipliers()
Definition sha256.hpp:164
plookup::BasicTable generate_witness_extension_normalization_table(BasicTableId id, const size_t table_index)
Definition sha256.hpp:100
@ SHA256_WITNESS_SLICE_8_ROTATE_7
Definition types.hpp:29
@ SHA256_BASE28
Definition types.hpp:33
@ SHA256_BASE16_ROTATE2
Definition types.hpp:37
@ SHA256_CH_NORMALIZE
Definition types.hpp:31
@ SHA256_WITNESS_SLICE_3
Definition types.hpp:27
@ SHA256_MAJ_NORMALIZE
Definition types.hpp:32
@ SHA256_BASE28_ROTATE6
Definition types.hpp:34
@ SHA256_BASE16
Definition types.hpp:36
@ SHA256_WITNESS_SLICE_7_ROTATE_4
Definition types.hpp:28
@ SHA256_WITNESS_NORMALIZE
Definition types.hpp:26
@ SHA256_WITNESS_SLICE_14_ROTATE_1
Definition types.hpp:30
@ SHA256_BASE28_ROTATE3
Definition types.hpp:35
@ SHA256_WITNESS_INPUT
Definition types.hpp:95
@ SHA256_CH_INPUT
Definition types.hpp:91
@ SHA256_MAJ_OUTPUT
Definition types.hpp:94
@ SHA256_CH_OUTPUT
Definition types.hpp:92
@ SHA256_WITNESS_OUTPUT
Definition types.hpp:96
@ SHA256_MAJ_INPUT
Definition types.hpp:93
field< Bn254FrParams > fr
Definition fr.hpp:174
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept
A basic table from which we can perform lookups (for example, an xor table)
Definition types.hpp:348
Container for managing multiple BasicTables plus the data needed to combine basic table outputs (e....
Definition types.hpp:154
std::vector< BasicTableId > basic_table_ids
Definition types.hpp:160
std::vector< uint64_t > slice_sizes
Definition types.hpp:161
std::vector< table_out(*)(table_in)> get_table_values
Definition types.hpp:168