60template <
size_t TABLE_BITS = 0,
size_t LANE_INDEX = 0>
class Rho {
63 static constexpr uint64_t
BASE = 11;
75 static constexpr std::array<size_t, 25>
ROTATIONS = {
76 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,
95 uint64_t accumulator = 0;
96 uint64_t input =
key[0];
97 uint64_t base_shift = 1;
98 constexpr uint64_t divisor_exponent = TABLE_BITS - 1;
103 accumulator += (bit * base_shift);
108 return {
bb::fr(accumulator),
bb::fr(accumulator / divisor) };
121 for (
size_t i = 0; i < TABLE_BITS; ++i) {
146 constexpr uint64_t divisor =
numeric::pow64(
static_cast<uint64_t
>(
BASE), TABLE_BITS - 1);
148 for (
size_t i = 0; i < TABLE_BITS; ++i) {
158 uint64_t normalized_value = 0;
159 for (
size_t i = 0; i < TABLE_BITS; ++i) {
160 value += counts[i] * scaled_bases[i];
163 return {
value, normalized_value, normalized_value / divisor };
184 for (
size_t i = 0; i < table_size; ++i) {
185 table.
column_1.emplace_back(column_values[0]);
186 table.
column_2.emplace_back(column_values[1]);
187 table.
column_3.emplace_back(column_values[2]);
239 constexpr size_t left_bits =
ROTATIONS[LANE_INDEX];
240 constexpr size_t right_bits = 64 -
ROTATIONS[LANE_INDEX];
241 constexpr size_t num_left_tables =
243 constexpr size_t num_right_tables =
249 table.column_1_step_sizes.push_back(1);
250 table.column_2_step_sizes.push_back(1);
251 table.column_3_step_sizes.push_back(1);
254 bb::constexpr_for<0, num_right_tables, 1>([&]<
size_t i> {
261 if (i == num_right_tables - 1) {
262 table.column_1_step_sizes.push_back(scaled_base);
263 table.column_2_step_sizes.push_back(0);
264 table.column_3_step_sizes.push_back(0);
266 table.column_1_step_sizes.push_back(scaled_base);
267 table.column_2_step_sizes.push_back(scaled_base);
268 table.column_3_step_sizes.push_back(0);
271 table.slice_sizes.push_back(scaled_base);
277 bb::constexpr_for<0, num_left_tables, 1>([&]<
size_t i> {
285 if (i != num_left_tables - 1) {
286 table.column_1_step_sizes.push_back(scaled_base);
287 table.column_2_step_sizes.push_back(scaled_base);
288 table.column_3_step_sizes.push_back(0);
291 table.slice_sizes.push_back(scaled_base);
Generate the plookup tables used for the RHO round of the Keccak hash algorithm.
static constexpr size_t MAXIMUM_MULTITABLE_BITS
static constexpr uint64_t EFFECTIVE_BASE
static constexpr uint64_t BASE
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 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 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.
static std::array< bb::fr, 2 > get_rho_renormalization_values(const std::array< uint64_t, 2 > key)
Given a table input value, return the table output value.
static constexpr std::array< size_t, 25 > ROTATIONS
static constexpr uint64_t RHO_NORMALIZATION_TABLE[3]
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.
constexpr uint64_t pow64(const uint64_t input, const uint64_t exponent)
@ KECCAK_NORMALIZE_AND_ROTATE
field< Bn254FrParams > fr
C slice(C const &container, size_t start)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
A basic table from which we can perform lookups (for example, an xor table)
bb::fr column_2_step_size
bb::fr column_1_step_size
std::vector< bb::fr > column_3
std::vector< bb::fr > column_2
std::array< bb::fr, 2 >(* get_values_from_key)(const std::array< uint64_t, 2 >)
std::vector< bb::fr > column_1
bb::fr column_3_step_size
Container for managing multiple BasicTables plus the data needed to combine basic table outputs (e....