50 const auto input_lo_index = circuit_builder.
add_variable(input_lo);
65 std::vector<uint8_t> input_buf;
66 write(input_buf, base_point);
67 const auto offset_generators =
74 for (
size_t i = 0; i < num_tables; ++i) {
80 EXPECT_EQ(
uint256_t(round_scalar), expected_scalar);
82 auto next_scalar =
static_cast<uint256_t>(
83 (i == num_tables - 1) ?
fr(0)
87 EXPECT_EQ(
slice, (
uint256_t(input_lo) >> (i * table_bits)) & mask);
90 offset_generators[i]);
92 EXPECT_EQ(round_x, expected_point.
x);
93 EXPECT_EQ(round_y, expected_point.
y);
94 for (
size_t j = 0; j < table_bits; ++j) {
95 accumulator = accumulator.
dbl();
97 expected_scalar >>= table_bits;
102 EXPECT_EQ(result,
true);
235 auto a_idx =
builder.add_variable(
a);
236 auto b_idx =
builder.add_variable(
a);
237 builder.assert_equal(a_idx, b_idx);
238 auto c_idx =
builder.add_variable(c);
239 auto d_idx =
builder.add_variable(c);
240 builder.assert_equal(c_idx, d_idx);
241 auto e_idx =
builder.add_variable(
a);
242 auto f_idx =
builder.add_variable(
a);
243 builder.assert_equal(e_idx, f_idx);
244 auto g_idx =
builder.add_variable(c);
245 auto h_idx =
builder.add_variable(c);
246 builder.assert_equal(g_idx, h_idx);
261 EXPECT_EQ(result,
true);
264 builder.real_variable_tags[
builder.real_variable_index[a_idx]] = 2;
273 auto a_idx =
builder.add_variable(
a);
274 auto b_idx =
builder.add_variable(
b);
275 auto c_idx =
builder.add_variable(
b);
276 auto d_idx =
builder.add_variable(
a + 1);
278 builder.create_add_gate({ a_idx, b_idx,
builder.zero_idx, 1, 1, 0, 0 });
279 builder.create_add_gate({ c_idx, d_idx,
builder.zero_idx, 1, 1, 0, -1 });
282 EXPECT_EQ(result,
true);
293 EXPECT_EQ(result,
false);
336 auto b_idx =
builder.add_variable(
b);
337 auto c_idx =
builder.add_variable(c);
338 auto d_idx =
builder.add_variable(d);
339 auto e_idx =
builder.add_variable(e);
340 auto f_idx =
builder.add_variable(f);
341 auto g_idx =
builder.add_variable(g);
342 auto h_idx =
builder.add_variable(h);
343 builder.create_sort_constraint_with_edges({ a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
a, h);
345 EXPECT_EQ(result,
true);
351 auto b_idx =
builder.add_variable(
b);
352 auto c_idx =
builder.add_variable(c);
353 auto d_idx =
builder.add_variable(d);
354 auto e_idx =
builder.add_variable(e);
355 auto f_idx =
builder.add_variable(f);
356 auto g_idx =
builder.add_variable(g);
357 auto h_idx =
builder.add_variable(h);
358 builder.create_sort_constraint_with_edges({ a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
a, g);
361 EXPECT_EQ(result,
false);
366 auto b_idx =
builder.add_variable(
b);
367 auto c_idx =
builder.add_variable(c);
368 auto d_idx =
builder.add_variable(d);
369 auto e_idx =
builder.add_variable(e);
370 auto f_idx =
builder.add_variable(f);
371 auto g_idx =
builder.add_variable(g);
372 auto h_idx =
builder.add_variable(h);
373 builder.create_sort_constraint_with_edges({ a_idx, b_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
b, h);
376 EXPECT_EQ(result,
false);
381 auto c_idx =
builder.add_variable(c);
382 auto d_idx =
builder.add_variable(d);
383 auto e_idx =
builder.add_variable(e);
384 auto f_idx =
builder.add_variable(f);
385 auto g_idx =
builder.add_variable(g);
386 auto h_idx =
builder.add_variable(h);
387 auto b2_idx =
builder.add_variable(
fr(15));
388 builder.create_sort_constraint_with_edges({ a_idx, b2_idx, c_idx, d_idx, e_idx, f_idx, g_idx, h_idx },
b, h);
390 EXPECT_EQ(result,
false);
394 auto idx =
add_variables(
builder, { 1, 2, 5, 6, 7, 10, 11, 13, 16, 17, 20, 22, 22, 25,
395 26, 29, 29, 32, 32, 33, 35, 38, 39, 39, 42, 42, 43, 45 });
396 builder.create_sort_constraint_with_edges(idx, 1, 45);
398 EXPECT_EQ(result,
true);
402 auto idx =
add_variables(
builder, { 1, 2, 5, 6, 7, 10, 11, 13, 16, 17, 20, 22, 22, 25,
403 26, 29, 29, 32, 32, 33, 35, 38, 39, 39, 42, 42, 43, 45 });
405 builder.create_sort_constraint_with_edges(idx, 1, 29);
407 EXPECT_EQ(result,
false);
416 for (
size_t i = 0; i < indices.size(); i++) {
417 builder.create_new_range_constraint(indices[i], 8);
420 builder.create_sort_constraint(indices);
422 EXPECT_EQ(result,
true);
427 for (
size_t i = 0; i < indices.size(); i++) {
428 builder.create_new_range_constraint(indices[i], 3);
431 builder.create_dummy_constraints(indices);
433 EXPECT_EQ(result,
true);
438 for (
size_t i = 0; i < indices.size(); i++) {
439 builder.create_new_range_constraint(indices[i], 8);
441 builder.create_sort_constraint(indices);
443 EXPECT_EQ(result,
false);
448 add_variables(
builder, { 1, 2, 3, 4, 5, 6, 10, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 19, 51 });
449 for (
size_t i = 0; i < indices.size(); i++) {
450 builder.create_new_range_constraint(indices[i], 128);
452 builder.create_dummy_constraints(indices);
454 EXPECT_EQ(result,
true);
459 add_variables(
builder, { 1, 2, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
460 for (
size_t i = 0; i < indices.size(); i++) {
461 builder.create_new_range_constraint(indices[i], 79);
463 builder.create_dummy_constraints(indices);
465 EXPECT_EQ(result,
false);
470 add_variables(
builder, { 1, 0, 3, 80, 5, 6, 29, 8, 15, 11, 32, 21, 42, 79, 16, 10, 3, 26, 13, 14 });
471 for (
size_t i = 0; i < indices.size(); i++) {
472 builder.create_new_range_constraint(indices[i], 79);
474 builder.create_dummy_constraints(indices);
476 EXPECT_EQ(result,
false);
484 for (
size_t i = 0; i < idx.size(); i++) {
485 builder.create_new_range_constraint(idx[i], 8);
493 EXPECT_EQ(result,
true);
500 for (
size_t i = 0; i < idx.size(); i++) {
501 builder.create_new_range_constraint(idx[i], 12);
509 EXPECT_EQ(result,
true);
517 std::vector<fr>
a = { 1, 3, 4, 7, 7, 8, 11, 14, 15, 15, 18, 19, 21, 21, 24, 25, 26, 27, 30, 32 };
518 std::vector<uint32_t> ind;
519 for (
size_t i = 0; i <
a.size(); i++)
520 ind.emplace_back(
builder.add_variable(
a[i]));
521 builder.create_sort_constraint(ind);
524 EXPECT_EQ(result,
true);
529 std::vector<fr>
a = { 1, 3, 4, 7, 7, 8, 16, 14, 15, 15, 18, 19, 21, 21, 24, 25, 26, 27, 30, 32 };
530 std::vector<uint32_t> ind;
531 for (
size_t i = 0; i <
a.size(); i++)
532 ind.emplace_back(
builder.add_variable(
a[i]));
533 builder.create_sort_constraint(ind);
536 EXPECT_EQ(result,
false);
598 const auto split_into_limbs = [&](
const uint512_t& input) {
599 constexpr size_t NUM_BITS = 68;
601 limbs[0] = input.slice(0, NUM_BITS).lo;
602 limbs[1] = input.slice(NUM_BITS * 1, NUM_BITS * 2).lo;
603 limbs[2] = input.slice(NUM_BITS * 2, NUM_BITS * 3).lo;
604 limbs[3] = input.slice(NUM_BITS * 3, NUM_BITS * 4).lo;
609 std::array<uint32_t, 4> limb_indices;
610 limb_indices[0] =
builder.add_variable(limbs[0]);
611 limb_indices[1] =
builder.add_variable(limbs[1]);
612 limb_indices[2] =
builder.add_variable(limbs[2]);
613 limb_indices[3] =
builder.add_variable(limbs[3]);
617 auto modulus_limbs = split_into_limbs(BINARY_BASIS_MODULUS -
uint512_t(modulus));
619 const auto a_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(
a)));
620 const auto b_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(
b)));
621 const auto q_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(q)));
622 const auto r_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(r)));
625 a_indices, b_indices, q_indices, r_indices, modulus_limbs,
627 const auto [lo_1_idx, hi_1_idx] =
builder.evaluate_non_native_field_multiplication(inputs);
628 builder.range_constrain_two_limbs(lo_1_idx, hi_1_idx, 70, 70);
631 EXPECT_EQ(result,
true);
656 const auto split_into_limbs = [&](
const uint512_t& input) {
657 constexpr size_t NUM_BITS = 68;
659 limbs[0] = input.slice(0, NUM_BITS).lo;
660 limbs[1] = input.slice(NUM_BITS * 1, NUM_BITS * 2).lo;
661 limbs[2] = input.slice(NUM_BITS * 2, NUM_BITS * 3).lo;
662 limbs[3] = input.slice(NUM_BITS * 3, NUM_BITS * 4).lo;
667 std::array<uint32_t, 4> limb_indices;
668 limb_indices[0] =
builder.add_variable(limbs[0]);
669 limb_indices[1] =
builder.add_variable(limbs[1]);
670 limb_indices[2] =
builder.add_variable(limbs[2]);
671 limb_indices[3] =
builder.add_variable(limbs[3]);
675 auto modulus_limbs = split_into_limbs(BINARY_BASIS_MODULUS -
uint512_t(modulus));
677 const auto a_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(
a)));
678 const auto b_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(
b)));
679 const auto q_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(q)));
680 const auto r_indices = get_limb_witness_indices(split_into_limbs(
uint256_t(r)));
683 a_indices, b_indices, q_indices, r_indices, modulus_limbs,
685 const auto [lo_1_idx, hi_1_idx] =
builder.evaluate_non_native_field_multiplication(inputs);
686 builder.range_constrain_two_limbs(lo_1_idx, hi_1_idx, 70, 70);
689 EXPECT_EQ(result,
true);
693 for (
size_t i = 0; i <
builder.blocks.nnf.size(); ++i) {
694 EXPECT_EQ(
builder.blocks.nnf.q_arith()[i], 0);
695 EXPECT_EQ(
builder.blocks.nnf.q_delta_range()[i], 0);
696 EXPECT_EQ(
builder.blocks.nnf.q_elliptic()[i], 0);
697 EXPECT_EQ(
builder.blocks.nnf.q_lookup_type()[i], 0);
698 EXPECT_EQ(
builder.blocks.nnf.q_poseidon2_external()[i], 0);
699 EXPECT_EQ(
builder.blocks.nnf.q_poseidon2_internal()[i], 0);
plookup::ReadData< uint32_t > create_gates_from_plookup_accumulators(const plookup::MultiTableId &id, const plookup::ReadData< FF > &read_values, const uint32_t key_a_index, std::optional< uint32_t > key_b_index=std::nullopt)
Perform a series of lookups, one for each 'row' in read_values.
static std::vector< affine_element > derive_generators(const std::vector< uint8_t > &domain_separator_bytes, const size_t num_generators, const size_t starting_index=0)
Derives generator points via hash-to-curve.
ReadData< bb::fr > get_lookup_accumulators(const MultiTableId id, const fr &key_a, const fr &key_b, const bool is_2_to_1_lookup)
Given a table ID and the key(s) for a key-value lookup, return the lookup accumulators.