141 const fr input_lo =
static_cast<uint256_t>(input_value).
slice(0, plookup::fixed_base::table::BITS_PER_LO_SCALAR);
142 const auto input_lo_index = circuit_builder.add_variable(input_lo);
146 const auto lookup_witnesses = circuit_builder.create_gates_from_plookup_accumulators(
147 plookup::MultiTableId::FIXED_BASE_LEFT_LO, sequence_data_lo, input_lo_index);
149 const size_t num_lookups = plookup::fixed_base::table::NUM_TABLES_PER_LO_MULTITABLE;
151 EXPECT_EQ(num_lookups, lookup_witnesses[plookup::ColumnIdx::C1].size());
154 const auto mask = plookup::fixed_base::table::MAX_TABLE_SIZE - 1;
157 std::vector<uint8_t> input_buf;
158 write(input_buf, base_point);
159 const auto offset_generators =
164 const auto table_bits = plookup::fixed_base::table::BITS_PER_TABLE;
165 const auto num_tables = plookup::fixed_base::table::NUM_TABLES_PER_LO_MULTITABLE;
166 for (
size_t i = 0; i < num_tables; ++i) {
168 auto round_scalar = circuit_builder.get_variable(lookup_witnesses[plookup::ColumnIdx::C1][i]);
169 auto round_x = circuit_builder.get_variable(lookup_witnesses[plookup::ColumnIdx::C2][i]);
170 auto round_y = circuit_builder.get_variable(lookup_witnesses[plookup::ColumnIdx::C3][i]);
172 EXPECT_EQ(
uint256_t(round_scalar), expected_scalar);
174 auto next_scalar =
static_cast<uint256_t>(
175 (i == num_tables - 1) ?
fr(0)
176 : circuit_builder.get_variable(lookup_witnesses[plookup::ColumnIdx::C1][i + 1]));
179 EXPECT_EQ(
slice, (
uint256_t(input_lo) >> (i * table_bits)) & mask);
182 offset_generators[i]);
184 EXPECT_EQ(round_x, expected_point.
x);
185 EXPECT_EQ(round_y, expected_point.
y);
186 for (
size_t j = 0; j < table_bits; ++j) {
187 accumulator = accumulator.
dbl();
189 expected_scalar >>= table_bits;
192 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
194 TestFixture::prove_and_verify(circuit_builder,
true);
205 auto construct_circuit_with_lookups = [
this]() {
210 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(
builder);
217 auto builder = construct_circuit_with_lookups();
219 TestFixture::prove_and_verify(
builder,
true);
224 auto builder = construct_circuit_with_lookups();
227 auto& polynomials = prover_instance->polynomials;
235 polynomials.lookup_inverses = polynomials.lookup_inverses.full();
236 polynomials.lookup_read_counts = polynomials.lookup_read_counts.full();
237 polynomials.lookup_read_counts.at(25) = 1;
238 polynomials.lookup_read_tags = polynomials.lookup_read_tags.full();
239 polynomials.lookup_read_tags.at(25) = 1;
241 TestFixture::prove_and_verify(prover_instance,
false);
246 auto builder = construct_circuit_with_lookups();
249 auto& polynomials = prover_instance->polynomials;
251 bool altered =
false;
253 for (
auto [i, q_lookup] : polynomials.q_lookup.indexed_values()) {
254 if (!q_lookup.is_zero() && polynomials.q_lookup.is_valid_set_index(i)) {
255 polynomials.w_o.at(i) += 1;
260 EXPECT_TRUE(altered);
261 TestFixture::prove_and_verify(prover_instance,
false);
266 auto builder = construct_circuit_with_lookups();
269 auto& polynomials = prover_instance->polynomials;
272 polynomials.lookup_inverses = polynomials.lookup_inverses.full();
273 polynomials.q_lookup = polynomials.q_lookup.full();
274 EXPECT_TRUE(polynomials.q_lookup[25] != 1);
275 polynomials.q_lookup.at(25) = 1;
277 TestFixture::prove_and_verify(prover_instance,
false);
315 uint32_t x1 = circuit_builder.add_variable(p1.
x);
316 uint32_t y1 = circuit_builder.add_variable(p1.
y);
317 uint32_t x2 = circuit_builder.add_variable(p2.
x);
318 uint32_t y2 = circuit_builder.add_variable(p2.
y);
319 uint32_t x3 = circuit_builder.add_variable(p3.
x);
320 uint32_t y3 = circuit_builder.add_variable(p3.
y);
322 circuit_builder.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, 1 });
325 x3 = circuit_builder.add_variable(p3.
x);
326 y3 = circuit_builder.add_variable(p3.
y);
327 circuit_builder.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, 1 });
330 x3 = circuit_builder.add_variable(p3.
x);
331 y3 = circuit_builder.add_variable(p3.
y);
332 circuit_builder.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, -1 });
334 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
336 TestFixture::prove_and_verify(circuit_builder,
true);
371 auto a_idx = circuit_builder.add_variable(
a);
372 auto b_idx = circuit_builder.add_variable(
b);
373 auto c_idx = circuit_builder.add_variable(c);
374 auto d_idx = circuit_builder.add_variable(d);
375 auto e_idx = circuit_builder.add_variable(e);
376 auto f_idx = circuit_builder.add_variable(f);
377 auto g_idx = circuit_builder.add_variable(g);
378 auto h_idx = circuit_builder.add_variable(h);
379 circuit_builder.create_sort_constraint_with_edges(
380 { a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
a, h);
382 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
384 TestFixture::prove_and_verify(circuit_builder,
true);
389 auto a_idx = circuit_builder.add_variable(
a);
390 auto b_idx = circuit_builder.add_variable(
b);
391 auto c_idx = circuit_builder.add_variable(c);
392 auto d_idx = circuit_builder.add_variable(d);
393 auto e_idx = circuit_builder.add_variable(e);
394 auto f_idx = circuit_builder.add_variable(f);
395 auto g_idx = circuit_builder.add_variable(g);
396 auto h_idx = circuit_builder.add_variable(h);
397 circuit_builder.create_sort_constraint_with_edges(
398 { a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
a, g);
400 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
402 TestFixture::prove_and_verify(circuit_builder,
false);
406 auto a_idx = circuit_builder.add_variable(
a);
407 auto b_idx = circuit_builder.add_variable(
b);
408 auto c_idx = circuit_builder.add_variable(c);
409 auto d_idx = circuit_builder.add_variable(d);
410 auto e_idx = circuit_builder.add_variable(e);
411 auto f_idx = circuit_builder.add_variable(f);
412 auto g_idx = circuit_builder.add_variable(g);
413 auto h_idx = circuit_builder.add_variable(h);
414 circuit_builder.create_sort_constraint_with_edges(
415 { a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
b, h);
417 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
419 TestFixture::prove_and_verify(circuit_builder,
false);
423 auto a_idx = circuit_builder.add_variable(
a);
424 auto c_idx = circuit_builder.add_variable(c);
425 auto d_idx = circuit_builder.add_variable(d);
426 auto e_idx = circuit_builder.add_variable(e);
427 auto f_idx = circuit_builder.add_variable(f);
428 auto g_idx = circuit_builder.add_variable(g);
429 auto h_idx = circuit_builder.add_variable(h);
430 auto b2_idx = circuit_builder.add_variable(
fr(15));
431 circuit_builder.create_sort_constraint_with_edges(
432 { a_idx, b2_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
b, h);
434 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
436 TestFixture::prove_and_verify(circuit_builder,
false);
441 TestFixture::add_variables(circuit_builder, { 1, 2, 5, 6, 7, 10, 11, 13, 16, 17, 20, 22, 22, 25,
442 26, 29, 29, 32, 32, 33, 35, 38, 39, 39, 42, 42, 43, 45 });
443 circuit_builder.create_sort_constraint_with_edges(idx, 1, 45);
445 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
447 TestFixture::prove_and_verify(circuit_builder,
true);
452 TestFixture::add_variables(circuit_builder, { 1, 2, 5, 6, 7, 10, 11, 13, 16, 17, 20, 22, 22, 25,
453 26, 29, 29, 32, 32, 33, 35, 38, 39, 39, 42, 42, 43, 45 });
454 circuit_builder.create_sort_constraint_with_edges(idx, 1, 29);
456 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
458 TestFixture::prove_and_verify(circuit_builder,
false);
466 auto indices = TestFixture::add_variables(circuit_builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
467 for (
size_t i = 0; i < indices.size(); i++) {
468 circuit_builder.create_new_range_constraint(indices[i], 8);
471 circuit_builder.create_sort_constraint(indices);
473 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
475 TestFixture::prove_and_verify(circuit_builder,
true);
479 auto indices = TestFixture::add_variables(circuit_builder, { 3 });
480 for (
size_t i = 0; i < indices.size(); i++) {
481 circuit_builder.create_new_range_constraint(indices[i], 3);
484 circuit_builder.create_unconstrained_gates(indices);
486 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
488 TestFixture::prove_and_verify(circuit_builder,
true);
492 auto indices = TestFixture::add_variables(circuit_builder, { 1, 2, 3, 4, 5, 6, 8, 25 });
493 for (
size_t i = 0; i < indices.size(); i++) {
494 circuit_builder.create_new_range_constraint(indices[i], 8);
496 circuit_builder.create_sort_constraint(indices);
498 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
500 TestFixture::prove_and_verify(circuit_builder,
false);
504 auto indices = TestFixture::add_variables(
505 circuit_builder, { 1, 2, 3, 4, 5, 6, 10, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 19, 51 });
506 for (
size_t i = 0; i < indices.size(); i++) {
507 circuit_builder.create_new_range_constraint(indices[i], 128);
509 circuit_builder.create_unconstrained_gates(indices);
511 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
513 TestFixture::prove_and_verify(circuit_builder,
true);
517 auto indices = TestFixture::add_variables(
518 circuit_builder, { 1, 2, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
519 for (
size_t i = 0; i < indices.size(); i++) {
520 circuit_builder.create_new_range_constraint(indices[i], 79);
522 circuit_builder.create_unconstrained_gates(indices);
524 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
526 TestFixture::prove_and_verify(circuit_builder,
false);
530 auto indices = TestFixture::add_variables(
531 circuit_builder, { 1, 0, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
532 for (
size_t i = 0; i < indices.size(); i++) {
533 circuit_builder.create_new_range_constraint(indices[i], 79);
535 circuit_builder.create_unconstrained_gates(indices);
537 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
539 TestFixture::prove_and_verify(circuit_builder,
false);
546 auto idx = TestFixture::add_variables(circuit_builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
547 for (
size_t i = 0; i < idx.size(); i++) {
548 circuit_builder.create_new_range_constraint(idx[i], 8);
551 circuit_builder.create_add_gate(
553 circuit_builder.create_add_gate(
555 circuit_builder.create_add_gate(
557 circuit_builder.create_add_gate(
560 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
562 TestFixture::prove_and_verify(circuit_builder,
true);
568 auto idx = TestFixture::add_variables(circuit_builder, { 1, 2, 3, 4, 5, 6, 7, 8 });
569 for (
size_t i = 0; i < idx.size(); i++) {
570 circuit_builder.create_new_range_constraint(idx[i], 12);
573 circuit_builder.create_add_gate(
575 circuit_builder.create_add_gate(
577 circuit_builder.create_add_gate(
579 circuit_builder.create_add_gate(
582 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
584 TestFixture::prove_and_verify(circuit_builder,
true);
592 std::vector<fr>
a = { 1, 3, 4, 7, 7, 8, 11, 14, 15, 15, 18, 19, 21, 21, 24, 25, 26, 27, 30, 32 };
593 std::vector<uint32_t> ind;
594 for (
const fr& val :
a)
595 ind.emplace_back(circuit_builder.add_variable(val));
596 circuit_builder.create_sort_constraint(ind);
598 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
600 TestFixture::prove_and_verify(circuit_builder,
true);
605 std::vector<fr>
a = { 1, 3, 4, 7, 7, 8, 16, 14, 15, 15, 18, 19, 21, 21, 24, 25, 26, 27, 30, 32 };
606 std::vector<uint32_t> ind;
607 for (
const fr& val :
a)
608 ind.emplace_back(circuit_builder.add_variable(val));
609 circuit_builder.create_sort_constraint(ind);
611 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
613 TestFixture::prove_and_verify(circuit_builder,
false);
670 const auto split_into_limbs = [&](
const uint512_t& input) {
671 constexpr size_t NUM_BITS = 68;
673 limbs[0] = input.slice(0, NUM_BITS).lo;
674 limbs[1] = input.slice(NUM_BITS * 1, NUM_BITS * 2).lo;
675 limbs[2] = input.slice(NUM_BITS * 2, NUM_BITS * 3).lo;
676 limbs[3] = input.slice(NUM_BITS * 3, NUM_BITS * 4).lo;
681 std::array<uint32_t, 4> limb_indices;
682 limb_indices[0] = circuit_builder.add_variable(limbs[0]);
683 limb_indices[1] = circuit_builder.add_variable(limbs[1]);
684 limb_indices[2] = circuit_builder.add_variable(limbs[2]);
685 limb_indices[3] = circuit_builder.add_variable(limbs[3]);
689 auto modulus_limbs = split_into_limbs(BINARY_BASIS_MODULUS -
uint512_t(modulus));
691 const auto a_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(
a)));
692 const auto b_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(
b)));
693 const auto q_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(q)));
694 const auto r_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(r)));
697 a_indices, b_indices, q_indices, r_indices, modulus_limbs,
699 const auto [lo_1_idx, hi_1_idx] = circuit_builder.evaluate_non_native_field_multiplication(
inputs);
702 const bool is_low_70_bits =
uint256_t(circuit_builder.get_variable(lo_1_idx)).
get_msb() < 70;
703 const bool is_high_70_bits =
uint256_t(circuit_builder.get_variable(hi_1_idx)).
get_msb() < 70;
704 if (is_low_70_bits && is_high_70_bits) {
706 circuit_builder.range_constrain_two_limbs(lo_1_idx, hi_1_idx, 70, 70);
709 circuit_builder.decompose_into_default_range(lo_1_idx, 72);
710 circuit_builder.decompose_into_default_range(hi_1_idx, 72);
713 TestFixture::set_default_pairing_points_and_ipa_claim_and_proof(circuit_builder);
715 TestFixture::prove_and_verify(circuit_builder,
true);