40 constexpr size_t left_bits = ROTATIONS[lane_index];
43 constexpr size_t right_bits = 64 - ROTATIONS[lane_index];
49 constexpr size_t num_left_tables = left_bits / max_bits_per_table + (left_bits % max_bits_per_table > 0 ? 1 : 0);
50 constexpr size_t num_right_tables = right_bits / max_bits_per_table + (right_bits % max_bits_per_table > 0 ? 1 : 0);
55 constexpr uint256_t slice_divisor = BASE.
pow(right_bits);
56 const auto [left, right] = input.
divmod(slice_divisor);
60 uint256_t left_normalized = normalize_sparse(left);
61 uint256_t right_normalized = normalize_sparse(right);
106 auto compute_lookup_witnesses_for_limb = [&]<
size_t limb_bits,
size_t num_lookups>(
uint256_t& normalized) {
108 bb::constexpr_for<0, num_lookups, 1>([&]<
size_t i> {
109 constexpr size_t num_bits_processed = i * max_bits_per_table;
115 constexpr size_t bit_slice = (num_bits_processed + max_bits_per_table > limb_bits)
116 ? limb_bits % max_bits_per_table
117 : max_bits_per_table;
120 lookup[ColumnIdx::C1].push_back(input);
121 lookup[ColumnIdx::C2].push_back(normalized);
123 constexpr uint64_t divisor =
numeric::pow64(
static_cast<uint64_t
>(BASE), bit_slice);
124 constexpr uint64_t msb_divisor = divisor /
static_cast<uint64_t
>(BASE);
127 const auto [normalized_quotient, normalized_slice] = normalized.divmod(divisor);
130 const uint64_t normalized_msb = (
static_cast<uint64_t
>(normalized_slice) / msb_divisor);
131 lookup[ColumnIdx::C3].push_back(normalized_msb);
135 const auto [input_quotient, input_slice] = input.divmod(divisor);
137 { {
static_cast<uint64_t
>(input_slice), 0 }, { normalized_slice, normalized_msb } });
140 input = input_quotient;
141 normalized = normalized_quotient;
149 compute_lookup_witnesses_for_limb.template operator()<right_bits, num_right_tables>(right_normalized);
150 compute_lookup_witnesses_for_limb.template operator()<left_bits, num_left_tables>(left_normalized);
156 const auto accumulator_witnesses = limb.
context->create_gates_from_plookup_accumulators(
161 accumulator_witnesses[ColumnIdx::C3][num_left_tables + num_right_tables - 1]);
167 if (num_left_tables == 0) {
173 limb.
get_context(), accumulator_witnesses[ColumnIdx::C2][num_right_tables]);
176 constexpr uint256_t shift = BASE.
pow(ROTATIONS[lane_index]);
177 return (left_output + right_output * shift);
256 auto& state = internal.
state;
258 for (
size_t i = 0; i < 5; ++i) {
269 twisted_state[5 + i],
270 twisted_state[10 + i],
271 twisted_state[15 + i],
272 twisted_state[20 + i] });
279 for (
size_t i = 0; i < 5; ++i) {
280 const auto non_shifted_equivalent = (
C[(i + 4) % 5]);
281 const auto shifted_equivalent =
C[(i + 1) % 5] * BASE;
282 D[i] = (non_shifted_equivalent + shifted_equivalent);
303 for (
size_t i = 0; i < 5; ++i) {
305 const auto [D_quotient, lo_native] = D_native.
divmod(BASE);
306 const uint256_t hi_native = D_quotient / divisor;
307 const uint256_t mid_native = D_quotient - hi_native * divisor;
314 D[i].assert_equal((hi * multiplicand).add_two(mid * 11, lo));
335 D[i] = accumulators[ColumnIdx::C2][0];
339 const field_ct most_significant_slice = accumulators[ColumnIdx::C1][accumulators[ColumnIdx::C1].size() - 1];
344 const field_ct target = -most_significant_slice + maximum;
347 "input to KECCAK_THETA_OUTPUT too large!");
352 for (
size_t i = 0; i < 5; ++i) {
353 for (
size_t j = 0; j < 5; ++j) {
354 state[j * 5 + i] = state[j * 5 + i] + D[i];
506 for (
size_t i = 0; i < state.size(); ++i) {
508 internal.
state[i] = accumulators[ColumnIdx::C2][0];
509 internal.
state_msb[i] = accumulators[ColumnIdx::C3][accumulators[ColumnIdx::C3].size() - 1];
511 compute_twisted_state(internal);
512 keccakf1600(internal);
514 return extended_2_normal(internal);