Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
keccak_chi.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
9#include "../types.hpp"
12
14
64class Chi {
65 public:
66 // 1 + 2a - b + c => a xor (~b & c)
67 static constexpr uint64_t CHI_NORMALIZATION_TABLE[5]{
68 0, 0, 1, 1, 0,
69 };
70
71 static constexpr uint64_t BASE = 11;
72
73 // effective base = maximum value each input 'quasi-bit' can reach at this stage of the Keccak algo
74 // (we use base11 as it's a bit more efficient to use a consistent base across the entire Keccak hash algorithm.
75 // The THETA round requires base-11 in order to most efficiently convert XOR operations into algebraic operations)
76 static constexpr uint64_t EFFECTIVE_BASE = 5;
77
78 // TABLE_BITS defines table size. More bits = fewer lookups but larger tables!
79 static constexpr uint64_t TABLE_BITS = 6;
80
90 {
91 uint64_t accumulator = 0;
92 uint64_t input = key[0];
93 uint64_t base_shift = 1;
94 constexpr uint64_t divisor_exponent = (64 % TABLE_BITS == 0) ? (TABLE_BITS - 1) : (64 % TABLE_BITS) - 1;
95 constexpr uint64_t divisor = numeric::pow64(BASE, divisor_exponent);
96 while (input > 0) {
97 uint64_t slice = input % BASE;
98 uint64_t bit = CHI_NORMALIZATION_TABLE[static_cast<size_t>(slice)];
99 accumulator += (bit * base_shift);
100 input /= BASE;
101 base_shift *= BASE;
102 }
103
104 return { bb::fr(accumulator), bb::fr(accumulator / divisor) };
105 }
106
114 {
116 uint64_t acc = 1;
117 for (size_t i = 0; i < TABLE_BITS; ++i) {
118 result[i] = acc;
119 acc *= BASE;
120 }
121 return result;
122 }
123
138 {
139 static constexpr auto scaled_bases = get_scaled_bases();
140
141 // want the most significant bit of the 64-bit integer, when this table is used on the most significant slice
142 constexpr uint64_t divisor_exponent = (64 % TABLE_BITS == 0) ? (TABLE_BITS - 1) : (64 % TABLE_BITS) - 1;
143 constexpr uint64_t divisor = numeric::pow64(static_cast<uint64_t>(BASE), divisor_exponent);
144
145 for (size_t i = 0; i < TABLE_BITS; ++i) {
146 if (counts[i] == EFFECTIVE_BASE - 1) {
147 counts[i] = 0;
148 } else {
149 counts[i] += 1;
150 break;
151 }
152 }
153
154 uint64_t value = 0;
155 uint64_t normalized_value = 0;
156 for (size_t i = 0; i < TABLE_BITS; ++i) {
157 value += counts[i] * scaled_bases[i];
158 normalized_value += (CHI_NORMALIZATION_TABLE[counts[i]]) * scaled_bases[i];
159 }
160 return { value, normalized_value, normalized_value / divisor };
161 }
162
172 static BasicTable generate_chi_renormalization_table(BasicTableId id, const size_t table_index)
173 {
174 BasicTable table;
175 table.id = id;
176 table.table_index = table_index;
177 table.use_twin_keys = false;
178 auto table_size = numeric::pow64(static_cast<uint64_t>(EFFECTIVE_BASE), TABLE_BITS);
179
181 std::array<uint64_t, 3> column_values{ 0, 0, 0 };
182 for (size_t i = 0; i < table_size; ++i) {
183 table.column_1.emplace_back(column_values[0]);
184 table.column_2.emplace_back(column_values[1]);
185 table.column_3.emplace_back(column_values[2]);
186 column_values = get_column_values_for_next_row(counts);
187 }
188
190
191 constexpr uint64_t step_size = numeric::pow64(static_cast<uint64_t>(BASE), TABLE_BITS);
192 table.column_1_step_size = bb::fr(step_size);
193 table.column_2_step_size = bb::fr(step_size);
194 table.column_3_step_size = bb::fr(0);
195 return table;
196 }
197
240 {
241 constexpr size_t num_tables_per_multitable =
242 (64 / TABLE_BITS) + (64 % TABLE_BITS == 0 ? 0 : 1); // 64 bits, 8 bits per entry
243
244 // column_multiplier is used to define the gap between rows when deriving colunn values via relative differences
245 uint64_t column_multiplier = numeric::pow64(BASE, TABLE_BITS);
246 MultiTable table(column_multiplier, column_multiplier, 0, num_tables_per_multitable);
247
248 table.id = id;
249 for (size_t i = 0; i < num_tables_per_multitable; ++i) {
250 table.slice_sizes.emplace_back(numeric::pow64(BASE, TABLE_BITS));
251 table.basic_table_ids.emplace_back(KECCAK_CHI);
253 }
254 return table;
255 }
256};
257} // namespace bb::plookup::keccak_tables
Generates plookup tables required for CHI round of Keccak hash function.
static constexpr uint64_t TABLE_BITS
static std::array< uint64_t, 3 > get_column_values_for_next_row(std::array< size_t, TABLE_BITS > &counts)
Get column values for next row of plookup table. Used to generate plookup table row values.
static BasicTable generate_chi_renormalization_table(BasicTableId id, const size_t table_index)
Generate the CHI plookup table.
static constexpr uint64_t EFFECTIVE_BASE
static constexpr uint64_t CHI_NORMALIZATION_TABLE[5]
static MultiTable get_chi_output_table(const MultiTableId id=KECCAK_CHI_OUTPUT)
Create the CHI MultiTable used by plookup to generate a sequence of lookups.
static std::array< bb::fr, 2 > get_chi_renormalization_values(const std::array< uint64_t, 2 > key)
Given a table input value, return the table output value.
static constexpr std::array< uint64_t, TABLE_BITS > get_scaled_bases()
Precompute an array of base multipliers (11^i for i = [0, ..., TABLE_BITS - 1]) Code is slightly fast...
static constexpr uint64_t BASE
constexpr uint64_t pow64(const uint64_t input, const uint64_t exponent)
Definition pow.hpp:13
@ KECCAK_CHI_OUTPUT
Definition types.hpp:134
field< Bn254FrParams > fr
Definition fr.hpp:174
C slice(C const &container, size_t start)
Definition container.hpp:9
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
A basic table from which we can perform lookups (for example, an xor table)
Definition types.hpp:348
std::vector< bb::fr > column_3
Definition types.hpp:383
std::vector< bb::fr > column_2
Definition types.hpp:382
std::array< bb::fr, 2 >(* get_values_from_key)(const std::array< uint64_t, 2 >)
Definition types.hpp:391
std::vector< bb::fr > column_1
Definition types.hpp:381
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