4#include "barretenberg/common/constexpr_utils.hpp"
5#include "barretenberg/numeric/bitop/pow.hpp"
8namespace keccak_tables {
55template <
size_t TABLE_BITS = 0,
size_t LANE_INDEX = 0>
class Rho {
58 static constexpr uint64_t BASE = 11;
63 static constexpr uint64_t EFFECTIVE_BASE = 3;
67 static constexpr size_t MAXIMUM_MULTITABLE_BITS = 8;
70 static constexpr std::array<size_t, 25> ROTATIONS = {
71 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43, 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14,
74 static constexpr uint64_t RHO_NORMALIZATION_TABLE[3]{
90 uint64_t accumulator = 0;
91 uint64_t input = key[0];
92 uint64_t base_shift = 1;
93 constexpr uint64_t divisor_exponent = TABLE_BITS - 1;
94 constexpr uint64_t divisor = numeric::pow64(BASE, divisor_exponent);
96 uint64_t slice = input % BASE;
97 uint64_t bit = RHO_NORMALIZATION_TABLE[
static_cast<size_t>(slice)];
98 accumulator += (bit * base_shift);
114 std::array<uint64_t, TABLE_BITS> result;
116 for (
size_t i = 0; i < TABLE_BITS; ++i) {
141 constexpr uint64_t divisor = numeric::pow64(
static_cast<uint64_t
>(BASE), TABLE_BITS - 1);
143 for (
size_t i = 0; i < TABLE_BITS; ++i) {
144 if (counts[i] == EFFECTIVE_BASE - 1) {
153 uint64_t normalized_value = 0;
154 for (
size_t i = 0; i < TABLE_BITS; ++i) {
155 value += counts[i] * scaled_bases[i];
156 normalized_value += (RHO_NORMALIZATION_TABLE[counts[i]]) * scaled_bases[i];
158 return { value, normalized_value, normalized_value / divisor };
172 table.table_index = table_index;
173 table.use_twin_keys =
false;
174 table.size = numeric::pow64(
static_cast<uint64_t
>(EFFECTIVE_BASE), TABLE_BITS);
176 std::array<size_t, TABLE_BITS> counts{};
177 std::array<uint64_t, 3> column_values{ 0, 0, 0 };
179 for (
size_t i = 0; i < table.size; ++i) {
180 table.column_1.emplace_back(column_values[0]);
181 table.column_2.emplace_back(column_values[1]);
182 table.column_3.emplace_back(column_values[2]);
188 uint64_t step_size = numeric::pow64(
static_cast<uint64_t
>(BASE), TABLE_BITS);
234 constexpr size_t left_bits = ROTATIONS[LANE_INDEX];
235 constexpr size_t right_bits = 64 - ROTATIONS[LANE_INDEX];
236 constexpr size_t num_left_tables =
237 left_bits / MAXIMUM_MULTITABLE_BITS + (left_bits % MAXIMUM_MULTITABLE_BITS > 0 ? 1 : 0);
238 constexpr size_t num_right_tables =
239 right_bits / MAXIMUM_MULTITABLE_BITS + (right_bits % MAXIMUM_MULTITABLE_BITS > 0 ? 1 : 0);
244 table.column_1_step_sizes.push_back(1);
245 table.column_2_step_sizes.push_back(1);
246 table.column_3_step_sizes.push_back(1);
249 barretenberg::constexpr_for<0, num_right_tables, 1>([&]<
size_t i> {
250 constexpr size_t num_bits_processed = (i * MAXIMUM_MULTITABLE_BITS);
251 constexpr size_t bit_slice = (num_bits_processed + MAXIMUM_MULTITABLE_BITS > right_bits)
252 ? right_bits % MAXIMUM_MULTITABLE_BITS
253 : MAXIMUM_MULTITABLE_BITS;
255 constexpr uint64_t scaled_base = numeric::pow64(BASE, bit_slice);
256 if (i == num_right_tables - 1) {
257 table.column_1_step_sizes.push_back(scaled_base);
258 table.column_2_step_sizes.push_back(0);
259 table.column_3_step_sizes.push_back(0);
261 table.column_1_step_sizes.push_back(scaled_base);
262 table.column_2_step_sizes.push_back(scaled_base);
263 table.column_3_step_sizes.push_back(0);
266 table.slice_sizes.push_back(scaled_base);
268 table.lookup_ids.push_back((BasicTableId)((
size_t)KECCAK_RHO_1 + (bit_slice - 1)));
272 barretenberg::constexpr_for<0, num_left_tables, 1>([&]<
size_t i> {
273 constexpr size_t num_bits_processed = (i * MAXIMUM_MULTITABLE_BITS);
275 constexpr size_t bit_slice = (num_bits_processed + MAXIMUM_MULTITABLE_BITS > left_bits)
276 ? left_bits % MAXIMUM_MULTITABLE_BITS
277 : MAXIMUM_MULTITABLE_BITS;
278 constexpr uint64_t scaled_base = numeric::pow64(BASE, bit_slice);
280 if (i != num_left_tables - 1) {
281 table.column_1_step_sizes.push_back(scaled_base);
282 table.column_2_step_sizes.push_back(scaled_base);
283 table.column_3_step_sizes.push_back(0);
286 table.slice_sizes.push_back(scaled_base);
288 table.lookup_ids.push_back((BasicTableId)((
size_t)KECCAK_RHO_1 + (bit_slice - 1)));
Generate the plookup tables used for the RHO round of the Keccak hash algorithm.
Definition: keccak_rho.hpp:55
static BasicTable generate_rho_renormalization_table(BasicTableId id, const size_t table_index)
Generate plookup table that normalizes a TABLE_BITS-slice of a base-11 integer and extracts the msb.
Definition: keccak_rho.hpp:168
static std::array< barretenberg::fr, 2 > get_rho_renormalization_values(const std::array< uint64_t, 2 > key)
Given a table input value, return the table output value.
Definition: keccak_rho.hpp:88
static MultiTable get_rho_output_table(const MultiTableId id=KECCAK_NORMALIZE_AND_ROTATE)
Create the Rho MultiTable used by plookup to generate a sequence of lookups.
Definition: keccak_rho.hpp:232
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...
Definition: keccak_rho.hpp:112
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.
Definition: keccak_rho.hpp:136
The structure contains the most basic table serving one function (for, example an xor table)
Definition: types.hpp:263
Definition: types.hpp:124