1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
37using tracegen::TestTraceContainer;
41using tracegen::AluTraceBuilder;
42using tracegen::ExecutionTraceBuilder;
43using tracegen::FieldGreaterThanTraceBuilder;
44using tracegen::GreaterThanTraceBuilder;
45using tracegen::PrecomputedTraceBuilder;
46using tracegen::RangeCheckTraceBuilder;
48constexpr uint8_t NUM_OF_TAGS =
static_cast<uint8_t
>(
MemoryTag::MAX) + 1;
97 for (
const auto c : out) {
98 ThreeOperandTestParams params =
tuple_cat(TEST_VALUES_IN.at(i), std::make_tuple(c));
99 res.push_back(params);
109 for (
const auto c : out) {
110 TwoOperandTestParams params = std::make_tuple(
std::get<0>(TEST_VALUES_IN.at(i)), c);
111 res.push_back(params);
117class AluConstrainingTest :
public ::testing::Test {
126TEST_F(AluConstrainingTest, EmptyRow)
131TEST_F(AluConstrainingTest, NegativeAluWrongOpId)
157class AluAddConstrainingTest :
public AluConstrainingTest,
158 public ::testing::WithParamInterface<ThreeOperandTestParams> {
160 TestTraceContainer process_basic_add_trace(ThreeOperandTestParams params)
162 auto [
a,
b, c] = params;
163 auto tag =
static_cast<uint8_t
>(
a.get_tag());
177 .execution_mem_tag_reg_0_ =
tag,
178 .execution_mem_tag_reg_1_ =
tag,
179 .execution_mem_tag_reg_2_ =
tag,
180 .execution_register_0_ =
a,
181 .execution_register_1_ =
b,
182 .execution_register_2_ = c,
183 .execution_sel_execute_alu = 1,
193 TestTraceContainer process_basic_add_with_tracegen(ThreeOperandTestParams params,
bool error =
false)
195 TestTraceContainer
trace;
196 auto [
a,
b, c] = params;
213 TestTraceContainer process_carry_add_trace(ThreeOperandTestParams params)
215 auto [
a,
b, c] = params;
216 auto mem_tag =
a.get_tag();
219 auto tag =
static_cast<uint8_t
>(mem_tag);
234 .execution_mem_tag_reg_0_ =
tag,
235 .execution_mem_tag_reg_1_ =
tag,
236 .execution_mem_tag_reg_2_ =
tag,
237 .execution_register_0_ =
a,
238 .execution_register_1_ =
b,
239 .execution_register_2_ = c,
240 .execution_sel_execute_alu = 1,
250 TestTraceContainer process_carry_add_with_tracegen(ThreeOperandTestParams params)
252 TestTraceContainer
trace;
253 auto [
a,
b, c] = params;
254 auto mem_tag =
a.get_tag();
272TEST_P(AluAddConstrainingTest, AluBasicAdd)
274 auto trace = process_basic_add_trace(GetParam());
275 check_all_interactions<AluTraceBuilder>(
trace);
276 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
277 check_relation<alu>(
trace);
280TEST_P(AluAddConstrainingTest, AluBasicAddTraceGen)
282 auto trace = process_basic_add_with_tracegen(GetParam());
283 check_all_interactions<AluTraceBuilder>(
trace);
284 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
285 check_relation<alu>(
trace);
288TEST_P(AluAddConstrainingTest, AluCarryAdd)
290 auto trace = process_carry_add_trace(GetParam());
291 check_all_interactions<AluTraceBuilder>(
trace);
292 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
293 check_relation<alu>(
trace);
296TEST_P(AluAddConstrainingTest, AluCarryAddTraceGen)
298 auto trace = process_carry_add_with_tracegen(GetParam());
299 check_all_interactions<AluTraceBuilder>(
trace);
300 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
301 check_relation<alu>(
trace);
304TEST_P(AluAddConstrainingTest, NegativeBasicAdd)
306 auto trace = process_basic_add_trace(GetParam());
307 check_relation<alu>(
trace);
308 trace.set(Column::alu_ic, 0,
trace.get(Column::alu_ic, 0) + 1);
312TEST_P(AluAddConstrainingTest, NegativeAluCarryAdd)
314 auto params = GetParam();
315 auto trace = process_carry_add_trace(params);
316 auto correct_max_value =
trace.get(Column::alu_max_value, 0);
318 check_all_interactions<AluTraceBuilder>(
trace);
319 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
320 check_relation<alu>(
trace);
323 trace.set(Column::alu_cf, 0, 0);
327 trace.set(Column::alu_cf, 0, 1);
328 trace.set(Column::alu_max_value, 0, 0);
332 trace.set(Column::alu_max_value, 0, correct_max_value);
337 trace.set(Column::alu_ic, 0, correct_max_value + 2);
341TEST_P(AluAddConstrainingTest, NegativeAddWrongTagABMismatch)
343 auto params = GetParam();
345 auto trace = process_basic_add_trace(params);
346 trace.set(Column::alu_ib_tag, 0, tag - 1);
348 trace.set(Column::alu_ab_tags_diff_inv, 0, 1);
349 trace.set(Column::alu_sel_ab_tag_mismatch, 0, 1);
352 trace.set(Column::alu_sel_tag_err, 0, 1);
355 trace.set(Column::alu_sel_err, 0, 1);
357 check_relation<alu>(
trace);
359 trace.set(Column::alu_ab_tags_diff_inv, 0, 0);
361 trace.set(Column::alu_ab_tags_diff_inv, 0, 1);
363 trace.set(Column::alu_sel_ab_tag_mismatch, 0, 0);
364 trace.set(Column::alu_sel_tag_err, 0, 0);
365 trace.set(Column::alu_sel_err, 0, 0);
369TEST_P(AluAddConstrainingTest, NegativeAddTraceGenWrongTagABMismatch)
371 auto [
a,
b, c] = GetParam();
372 auto trace = process_basic_add_with_tracegen(
374 check_all_interactions<AluTraceBuilder>(
trace);
375 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
376 check_relation<alu>(
trace);
379TEST_P(AluAddConstrainingTest, NegativeAddWrongTagCMismatch)
381 auto params = GetParam();
383 auto trace = process_basic_add_trace(params);
384 check_relation<alu>(
trace);
385 trace.set(Column::alu_ic_tag, 0, tag - 1);
403class AluSubConstrainingTest :
public AluConstrainingTest,
404 public ::testing::WithParamInterface<ThreeOperandTestParams> {
406 TestTraceContainer process_sub_trace(ThreeOperandTestParams params)
408 auto [
a,
b, c] = params;
409 auto tag =
static_cast<uint8_t
>(
a.get_tag());
410 auto trace = TestTraceContainer::from_rows({
412 .alu_cf =
a.as_ff() -
b.as_ff() != c.as_ff() ? 1 : 0,
424 .execution_mem_tag_reg_0_ =
tag,
425 .execution_mem_tag_reg_1_ =
tag,
426 .execution_mem_tag_reg_2_ =
tag,
427 .execution_register_0_ =
a,
428 .execution_register_1_ =
b,
429 .execution_register_2_ = c,
430 .execution_sel_execute_alu = 1,
440 TestTraceContainer process_sub_with_tracegen(ThreeOperandTestParams params)
442 TestTraceContainer
trace;
443 auto [
a,
b, c] = params;
447 { .operation = simulation::AluOperation::SUB, .a =
a, .b =
b, .c = c },
459TEST_P(AluSubConstrainingTest, AluSub)
461 auto trace = process_sub_trace(GetParam());
462 check_all_interactions<AluTraceBuilder>(
trace);
463 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
464 check_relation<alu>(
trace);
467TEST_P(AluSubConstrainingTest, AluSubTraceGen)
469 auto trace = process_sub_with_tracegen(GetParam());
470 check_all_interactions<AluTraceBuilder>(
trace);
471 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
472 check_relation<alu>(
trace);
475TEST_P(AluSubConstrainingTest, AluSubNegative)
477 auto params = GetParam();
478 auto is_ff =
std::get<0>(params).get_tag() == MemoryTag::FF;
479 auto trace = process_sub_trace(GetParam());
480 check_all_interactions<AluTraceBuilder>(
trace);
481 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
482 check_relation<alu>(
trace);
484 auto c =
trace.get(Column::alu_ic, 0);
486 trace.set(Column::alu_ic, 0, c + 1);
489 trace.set(Column::alu_ic, 0, c);
490 check_relation<alu>(
trace);
494 trace.set(Column::alu_cf, 0,
trace.get(Column::alu_cf, 0) == 1 ? 0 : 1);
502 MemoryValue::from_tag(MemoryTag::U1, 0),
503 MemoryValue::from_tag(MemoryTag::U8, 16),
504 MemoryValue::from_tag(MemoryTag::U16, 64456),
505 MemoryValue::from_tag(MemoryTag::U32, (
uint256_t(1) << 32) - 50),
506 MemoryValue::from_tag(MemoryTag::U64, (
uint256_t(1) << 64) - 50),
507 MemoryValue::from_tag(MemoryTag::U128, (
uint256_t(1) << 128) - 50),
508 MemoryValue::from_tag(MemoryTag::FF, FF::modulus - 8),
513class AluMulConstrainingTest :
public AluConstrainingTest,
514 public ::testing::WithParamInterface<ThreeOperandTestParams> {
516 TestTraceContainer process_mul_trace(ThreeOperandTestParams params)
518 auto [
a,
b, c] = params;
519 auto mem_tag =
a.get_tag();
520 auto tag =
static_cast<uint8_t
>(mem_tag);
522 auto is_u128 = mem_tag == MemoryTag::U128;
525 auto c_hi = mem_tag == MemoryTag::FF ? 0 : c_int >>
get_tag_bits(mem_tag);
527 auto trace = TestTraceContainer::from_rows({
530 .alu_constant_64 = 64,
541 .alu_sel_decompose_a = is_u128 ? 1 : 0,
542 .alu_sel_is_u128 = is_u128 ? 1 : 0,
543 .alu_sel_mul_div_u128 = is_u128 ? 1 : 0,
544 .alu_sel_mul_u128 = is_u128 ? 1 : 0,
546 .alu_tag_u128_diff_inv = is_u128 ? 0 :
FF(tag -
static_cast<uint8_t
>(MemoryTag::U128)).
invert(),
547 .execution_mem_tag_reg_0_ =
tag,
548 .execution_mem_tag_reg_1_ =
tag,
549 .execution_mem_tag_reg_2_ =
tag,
550 .execution_register_0_ =
a,
551 .execution_register_1_ =
b,
552 .execution_register_2_ = c,
553 .execution_sel_execute_alu = 1,
562 auto a_decomp = simulation::decompose(
a.as<
uint128_t>());
563 auto b_decomp = simulation::decompose(
b.as<
uint128_t>());
565 auto hi_operand =
static_cast<uint256_t>(a_decomp.hi) *
static_cast<uint256_t>(b_decomp.hi);
566 c_hi = (c_hi - hi_operand) % (
uint256_t(1) << 64);
568 { { { Column::alu_a_lo, a_decomp.lo },
569 { Column::alu_a_lo_bits, 64 },
570 { Column::alu_a_hi, a_decomp.hi },
571 { Column::alu_a_hi_bits, 64 },
572 { Column::alu_b_lo, b_decomp.lo },
573 { Column::alu_b_hi, b_decomp.hi },
574 { Column::alu_c_hi, c_hi },
575 { Column::alu_cf, hi_operand == 0 ? 0 : 1 } } });
578 { .value = a_decomp.hi, .num_bits = 64 },
579 { .value = b_decomp.lo, .num_bits = 64 },
580 { .value = b_decomp.hi, .num_bits = 64 },
581 { .value =
static_cast<uint128_t>(c_hi), .num_bits = 64 } },
588 TestTraceContainer process_mul_with_tracegen(ThreeOperandTestParams params)
590 TestTraceContainer
trace;
591 auto [
a,
b, c] = params;
592 auto mem_tag =
a.get_tag();
596 { .operation = simulation::AluOperation::MUL, .a =
a, .b =
b, .c = c },
602 auto c_hi = mem_tag == MemoryTag::FF ? 0 : (a_int * b_int) >>
get_tag_bits(mem_tag);
603 if (mem_tag == MemoryTag::U128) {
604 auto a_decomp = simulation::decompose(
a.as<
uint128_t>());
605 auto b_decomp = simulation::decompose(
b.as<
uint128_t>());
607 auto hi_operand =
static_cast<uint256_t>(a_decomp.hi) *
static_cast<uint256_t>(b_decomp.hi);
608 c_hi = (c_hi - hi_operand) % (
uint256_t(1) << 64);
610 { .value = a_decomp.hi, .num_bits = 64 },
611 { .value = b_decomp.lo, .num_bits = 64 },
612 { .value = b_decomp.hi, .num_bits = 64 },
613 { .value =
static_cast<uint128_t>(c_hi), .num_bits = 64 } },
626TEST_P(AluMulConstrainingTest, AluMul)
628 auto trace = process_mul_trace(GetParam());
629 check_all_interactions<AluTraceBuilder>(
trace);
630 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
631 check_relation<alu>(
trace);
634TEST_P(AluMulConstrainingTest, AluMulTraceGen)
636 auto trace = process_mul_with_tracegen(GetParam());
637 check_all_interactions<AluTraceBuilder>(
trace);
638 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
639 check_relation<alu>(
trace);
642TEST_F(AluConstrainingTest, AluMulU128Carry)
645 auto b = MemoryValue::from_tag(MemoryTag::U128,
get_tag_max_value(MemoryTag::U128) - 2);
649 auto tag =
static_cast<uint8_t
>(MemoryTag::U128);
651 auto a_decomp = simulation::decompose(
a.as<
uint128_t>());
652 auto b_decomp = simulation::decompose(
b.as<
uint128_t>());
655 auto hi_operand =
static_cast<uint256_t>(a_decomp.hi) *
static_cast<uint256_t>(b_decomp.hi);
656 auto c_hi = ((overflow_c_int >> 128) - hi_operand) % (
uint256_t(1) << 64);
657 auto trace = TestTraceContainer::from_rows({
659 .alu_a_hi = a_decomp.hi,
661 .alu_a_lo = a_decomp.lo,
663 .alu_b_hi = b_decomp.hi,
664 .alu_b_lo = b_decomp.lo,
667 .alu_constant_64 = 64,
678 .alu_sel_decompose_a = 1,
679 .alu_sel_is_u128 = 1,
680 .alu_sel_mul_div_u128 = 1,
681 .alu_sel_mul_u128 = 1,
683 .alu_tag_u128_diff_inv = 0,
684 .execution_mem_tag_reg_0_ =
tag,
685 .execution_mem_tag_reg_1_ =
tag,
686 .execution_mem_tag_reg_2_ =
tag,
687 .execution_register_0_ =
a,
688 .execution_register_1_ =
b,
689 .execution_register_2_ = c,
690 .execution_sel_execute_alu = 1,
698 { .value = a_decomp.hi, .num_bits = 64 },
699 { .value = b_decomp.lo, .num_bits = 64 },
700 { .value = b_decomp.hi, .num_bits = 64 },
701 { .value =
static_cast<uint128_t>(c_hi), .num_bits = 64 } },
704 check_all_interactions<AluTraceBuilder>(
trace);
705 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
706 check_relation<alu>(
trace);
709 auto should_fail_overflowed = MemoryValue::from_tag_truncating(MemoryTag::U128,
a.as_ff() *
b.as_ff());
710 trace.set(Column::alu_ic, 0, should_fail_overflowed);
714TEST_P(AluMulConstrainingTest, NegativeAluMul)
716 auto trace = process_mul_trace(GetParam());
717 check_all_interactions<AluTraceBuilder>(
trace);
718 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
719 check_relation<alu>(
trace);
720 trace.set(Column::alu_ic, 0,
trace.get(Column::alu_ic, 0) + 1);
727 MemoryValue::from_tag(MemoryTag::U1, 0),
728 MemoryValue::from_tag(MemoryTag::U8, 4),
729 MemoryValue::from_tag(MemoryTag::U16, 0),
730 MemoryValue::from_tag(MemoryTag::U32, 0x33333331),
731 MemoryValue::from_tag(MemoryTag::U64, 0x3333333333333331ULL),
732 MemoryValue::from_tag(MemoryTag::U128, (((
uint256_t(1) << 128) - 11) / 5)),
737class AluDivConstrainingTest :
public AluConstrainingTest,
738 public ::testing::WithParamInterface<ThreeOperandTestParams> {
740 TestTraceContainer process_div_trace(ThreeOperandTestParams params)
742 auto [
a,
b, c] = params;
743 auto mem_tag =
a.get_tag();
744 auto tag =
static_cast<uint8_t
>(mem_tag);
745 auto remainder =
a -
b * c;
747 auto div_0_error =
b.as_ff() ==
FF(0);
748 auto is_u128 = mem_tag == MemoryTag::U128;
750 auto trace = TestTraceContainer::from_rows({
752 .alu_b_inv = div_0_error ? 0 :
b.as_ff().invert(),
753 .alu_constant_64 = 64,
754 .alu_helper1 = div_0_error ? 0 : remainder.as_ff(),
765 .alu_sel_decompose_a = is_u128 ? 1 : 0,
766 .alu_sel_div_0_err = div_0_error ? 1 : 0,
767 .alu_sel_div_no_0_err = div_0_error ? 0 : 1,
768 .alu_sel_err = div_0_error ? 1 : 0,
769 .alu_sel_is_u128 = is_u128 ? 1 : 0,
770 .alu_sel_mul_div_u128 = is_u128 ? 1 : 0,
772 .alu_tag_ff_diff_inv =
FF(
tag - static_cast<uint8_t>(
MemoryTag::
FF)).invert(),
773 .alu_tag_u128_diff_inv = is_u128 ? 0 :
FF(
tag - static_cast<uint8_t>(
MemoryTag::
U128)).invert(),
774 .execution_mem_tag_reg_0_ =
tag,
775 .execution_mem_tag_reg_1_ =
tag,
776 .execution_mem_tag_reg_2_ =
tag,
777 .execution_register_0_ =
a,
778 .execution_register_1_ =
b,
779 .execution_register_2_ = c,
780 .execution_sel_execute_alu = 1,
781 .execution_sel_opcode_error = div_0_error ? 1 : 0,
789 .b =
static_cast<uint128_t>(remainder.as_ff()),
794 auto c_decomp = simulation::decompose(c.as<
uint128_t>());
795 auto b_decomp = simulation::decompose(
b.as<
uint128_t>());
798 { { { Column::alu_a_lo, c_decomp.lo },
799 { Column::alu_a_lo_bits, 64 },
800 { Column::alu_a_hi, c_decomp.hi },
801 { Column::alu_a_hi_bits, 64 },
802 { Column::alu_b_lo, b_decomp.lo },
803 { Column::alu_b_hi, b_decomp.hi } } });
806 { .value = c_decomp.hi, .num_bits = 64 },
807 { .value = b_decomp.lo, .num_bits = 64 },
808 { .value = b_decomp.hi, .num_bits = 64 } },
815 TestTraceContainer process_div_with_tracegen(ThreeOperandTestParams params)
817 TestTraceContainer
trace;
818 auto [
a,
b, c] = params;
819 bool div_0_error =
b.as_ff() ==
FF(0);
820 auto mem_tag =
a.get_tag();
821 auto remainder =
a -
b * c;
825 { .operation = simulation::AluOperation::DIV,
833 if (mem_tag == MemoryTag::U128) {
834 auto c_decomp = simulation::decompose(c.as<
uint128_t>());
835 auto b_decomp = simulation::decompose(
b.as<
uint128_t>());
838 { .value = c_decomp.hi, .num_bits = 64 },
839 { .value = b_decomp.lo, .num_bits = 64 },
840 { .value = b_decomp.hi, .num_bits = 64 } },
846 .b =
static_cast<uint128_t>(remainder.as_ff()),
855TEST_P(AluDivConstrainingTest, AluDiv)
857 auto trace = process_div_trace(GetParam());
858 check_all_interactions<AluTraceBuilder>(
trace);
859 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
860 check_relation<alu>(
trace);
863TEST_P(AluDivConstrainingTest, AluDivTraceGen)
865 auto trace = process_div_with_tracegen(GetParam());
866 check_all_interactions<AluTraceBuilder>(
trace);
867 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
868 check_relation<alu>(
trace);
871TEST_F(AluDivConstrainingTest, NegativeAluDivUnderflow)
874 auto a = MemoryValue::from_tag(MemoryTag::U32, 2);
875 auto b = MemoryValue::from_tag(MemoryTag::U32, 5);
877 auto trace = process_div_trace({
a,
b, c });
878 check_all_interactions<AluTraceBuilder>(
trace);
879 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
880 check_relation<alu>(
trace);
885 c = MemoryValue::from_tag(MemoryTag::U32, 2);
886 auto wrong_remainder =
a.as_ff() -
b.as_ff() * c.as_ff();
888 trace.set(Column::alu_ic, 0, c);
889 trace.set(Column::alu_helper1, 0, wrong_remainder);
892 check_relation<alu>(
trace);
897TEST_F(AluDivConstrainingTest, NegativeAluDivU128Carry)
900 auto a = MemoryValue::from_tag(MemoryTag::U128, 2);
901 auto b = MemoryValue::from_tag(MemoryTag::U128, (
uint256_t(1) << 64) + 2);
904 auto trace = process_div_trace({
a,
b, c });
906 check_all_interactions<AluTraceBuilder>(
trace);
907 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
908 check_relation<alu>(
trace);
912 c = MemoryValue::from_tag(MemoryTag::U128, (
uint256_t(1) << 64) + 3);
913 auto wrong_remainder =
a.as_ff() -
FF(
static_cast<uint256_t>(
b.as_ff()) *
static_cast<uint256_t>(c.as_ff()));
917 trace.set(Column::alu_ic, 0, c);
918 trace.set(Column::alu_helper1, 0, wrong_remainder);
923 auto c_decomp = simulation::decompose(c.as<
uint128_t>());
924 trace.set(Column::alu_a_lo, 0, c_decomp.lo);
925 trace.set(Column::alu_a_hi, 0, c_decomp.hi);
931TEST_F(AluDivConstrainingTest, NegativeAluDivByZero)
933 auto a = MemoryValue::from_tag(MemoryTag::U32, 2);
934 auto b = MemoryValue::from_tag(MemoryTag::U32, 5);
937 for (
const bool with_tracegen : {
false,
true }) {
938 auto trace = with_tracegen ? process_div_with_tracegen({
a,
b, c }) : process_div_trace({
a,
b, c });
939 check_all_interactions<AluTraceBuilder>(
trace);
940 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
941 check_relation<alu>(
trace);
944 trace.set(Column::alu_ib, 0, 0);
945 trace.set(Column::alu_b_inv, 0, 0);
949 trace.set(Column::alu_sel_div_0_err, 0, 1);
950 trace.set(Column::alu_sel_div_no_0_err, 0, 0);
953 trace.set(Column::alu_sel_err, 0, 1);
954 check_relation<alu>(
trace);
957 trace.set(Column::alu_sel_op_div, 0, 0);
958 trace.set(Column::alu_sel_op_mul, 0, 1);
962 trace.set(Column::alu_sel_op_div, 0, 1);
963 trace.set(Column::alu_sel_op_mul, 0, 0);
965 check_relation<alu>(
trace);
968 trace.set(Column::alu_ib, 0,
b);
969 trace.set(Column::alu_b_inv, 0,
b.as_ff().invert());
974TEST_F(AluDivConstrainingTest, NegativeAluDivFF)
976 auto a = MemoryValue::from_tag(MemoryTag::FF, 2);
977 auto b = MemoryValue::from_tag(MemoryTag::FF, 5);
979 auto trace = process_div_with_tracegen({
a,
b, c });
982 trace.set(Column::alu_sel_tag_err, 0, 1);
983 trace.set(Column::alu_sel_err, 0, 1);
984 check_relation<alu>(
trace);
985 check_all_interactions<AluTraceBuilder>(
trace);
986 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
989TEST_F(AluDivConstrainingTest, NegativeAluDivByZeroFF)
992 auto a = MemoryValue::from_tag(MemoryTag::FF, 2);
993 auto b = MemoryValue::from_tag(MemoryTag::FF, 5);
995 auto trace = process_div_with_tracegen({
a,
b, c });
996 trace.set(Column::alu_sel_tag_err, 0, 1);
997 trace.set(Column::alu_sel_err, 0, 1);
998 check_relation<alu>(
trace);
1000 trace.set(Column::alu_ib, 0, 0);
1001 trace.set(Column::alu_b_inv, 0, 0);
1003 trace.set(Column::alu_sel_div_0_err, 0, 1);
1004 trace.set(Column::alu_sel_div_no_0_err, 0, 0);
1005 check_relation<alu>(
trace);
1006 check_all_interactions<AluTraceBuilder>(
trace);
1007 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1010TEST_F(AluDivConstrainingTest, NegativeAluDivByZeroFFTagMismatch)
1013 auto a = MemoryValue::from_tag(MemoryTag::FF, 2);
1014 auto b = MemoryValue::from_tag(MemoryTag::FF, 5);
1016 auto trace = process_div_with_tracegen({
a,
b, c });
1017 trace.set(Column::alu_sel_tag_err, 0, 1);
1018 trace.set(Column::alu_sel_err, 0, 1);
1019 check_relation<alu>(
trace);
1021 trace.set(Column::alu_ib_tag, 0,
static_cast<uint8_t
>(MemoryTag::U8));
1023 trace.set(Column::alu_sel_ab_tag_mismatch, 0, 1);
1024 trace.set(Column::alu_ab_tags_diff_inv,
1026 (
FF(
static_cast<uint8_t
>(MemoryTag::FF)) -
FF(
static_cast<uint8_t
>(MemoryTag::U8))).invert());
1027 check_relation<alu>(
trace);
1029 trace.set(Column::alu_ib, 0, 0);
1030 trace.set(Column::alu_b_inv, 0, 0);
1032 trace.set(Column::alu_sel_div_0_err, 0, 1);
1033 trace.set(Column::alu_sel_div_no_0_err, 0, 0);
1034 check_relation<alu>(
trace);
1035 check_all_interactions<AluTraceBuilder>(
trace);
1036 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1044 MemoryValue::from_tag(MemoryTag::FF, 0),
1045 MemoryValue::from_tag(MemoryTag::FF, 4),
1046 MemoryValue::from_tag(MemoryTag::FF,
FF(
"0x1e980ebbc51694827ee20074ac28b250a037a43eb44b38e6aa367c57a05e6d48")),
1047 MemoryValue::from_tag(MemoryTag::FF,
FF(
"0x135b52945a13d9aa49b9b57c33cd568ba9ae5ce9ca4a2d06e7f3fbd4f9999998")),
1048 MemoryValue::from_tag(MemoryTag::FF,
FF(
"0x135b52945a13d9aa49b9b57c33cd568ba9ae5ce9ca4a2d071b272f07f9999998")),
1049 MemoryValue::from_tag(MemoryTag::FF,
FF(
"0x135b52945a13d9aa49b9b57c33cd568bdce1901cfd7d603a1b272f07f9999998")),
1050 MemoryValue::from_tag(MemoryTag::FF, FF::modulus - 2),
1055class AluFDivConstrainingTest :
public AluConstrainingTest,
1056 public ::testing::WithParamInterface<ThreeOperandTestParams> {
1058 TestTraceContainer process_fdiv_trace(ThreeOperandTestParams params)
1060 auto [
a,
b, c] = params;
1061 a = MemoryValue::from_tag(MemoryTag::FF,
a);
1062 b = MemoryValue::from_tag(MemoryTag::FF,
b);
1063 c = MemoryValue::from_tag(MemoryTag::FF, c);
1064 auto div_0_error =
b.as_ff() ==
FF(0);
1066 auto mem_tag =
a.get_tag();
1067 auto tag =
static_cast<uint8_t
>(mem_tag);
1069 auto trace = TestTraceContainer::from_rows({
1071 .alu_b_inv = div_0_error ? 0 :
b.as_ff().invert(),
1082 .alu_sel_div_0_err = div_0_error ? 1 : 0,
1083 .alu_sel_err = div_0_error ? 1 : 0,
1085 .alu_sel_op_fdiv = 1,
1086 .execution_mem_tag_reg_0_ =
tag,
1087 .execution_mem_tag_reg_1_ =
tag,
1088 .execution_mem_tag_reg_2_ =
tag,
1089 .execution_register_0_ =
a,
1090 .execution_register_1_ =
b,
1091 .execution_register_2_ = c,
1092 .execution_sel_execute_alu = 1,
1093 .execution_sel_opcode_error = div_0_error ? 1 : 0,
1104 TestTraceContainer process_fdiv_with_tracegen(ThreeOperandTestParams params)
1106 TestTraceContainer
trace;
1107 auto [
a,
b, c] = params;
1108 a = MemoryValue::from_tag(MemoryTag::FF,
a);
1109 b = MemoryValue::from_tag(MemoryTag::FF,
b);
1110 c = MemoryValue::from_tag(MemoryTag::FF, c);
1111 bool div_0_error =
b.as_ff() ==
FF(0);
1115 { .operation = simulation::AluOperation::FDIV,
1132TEST_P(AluFDivConstrainingTest, AluFDiv)
1134 auto trace = process_fdiv_trace(GetParam());
1135 check_all_interactions<AluTraceBuilder>(
trace);
1136 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1137 check_relation<alu>(
trace);
1140TEST_P(AluFDivConstrainingTest, AluFDivTraceGen)
1142 auto trace = process_fdiv_with_tracegen(GetParam());
1143 check_all_interactions<AluTraceBuilder>(
trace);
1144 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1145 check_relation<alu>(
trace);
1148TEST_F(AluFDivConstrainingTest, NegativeAluFDivByZero)
1150 auto a = MemoryValue::from_tag(MemoryTag::FF, 2);
1151 auto b = MemoryValue::from_tag(MemoryTag::FF, 5);
1153 auto trace = process_fdiv_trace({
a,
b, c });
1154 check_all_interactions<AluTraceBuilder>(
trace);
1155 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1156 check_relation<alu>(
trace);
1159 trace.set(Column::alu_ib, 0, 0);
1160 trace.set(Column::alu_b_inv, 0, 0);
1164 trace.set(Column::alu_sel_div_0_err, 0, 1);
1167 trace.set(Column::alu_sel_err, 0, 1);
1168 check_relation<alu>(
trace);
1171 trace.set(Column::alu_ib, 0,
b);
1172 trace.set(Column::alu_b_inv, 0,
b.as_ff().invert());
1176TEST_F(AluFDivConstrainingTest, NegativeAluFDivByZeroNonFFTagMismatch)
1178 auto a = MemoryValue::from_tag(MemoryTag::U8, 4);
1179 auto b = MemoryValue::from_tag(MemoryTag::U8, 2);
1182 auto c = MemoryValue::from_tag(MemoryTag::FF, 2);
1183 auto tag =
static_cast<uint8_t
>(MemoryTag::U8);
1185 auto trace = TestTraceContainer::from_rows({
1187 .alu_b_inv =
b.as_ff().invert(),
1193 .alu_ic_tag =
static_cast<uint8_t
>(MemoryTag::FF),
1198 .alu_sel_op_fdiv = 1,
1199 .execution_mem_tag_reg_0_ = tag,
1200 .execution_mem_tag_reg_1_ = tag,
1201 .execution_mem_tag_reg_2_ =
static_cast<uint8_t
>(MemoryTag::FF),
1202 .execution_register_0_ =
a,
1203 .execution_register_1_ =
b,
1204 .execution_register_2_ = c,
1205 .execution_sel_execute_alu = 1,
1214 trace.set(Column::alu_tag_ff_diff_inv, 0,
FF(
FF(tag) -
FF(
static_cast<uint8_t
>(MemoryTag::FF))).invert());
1217 trace.set(Column::alu_sel_tag_err, 0, 1);
1218 trace.set(Column::alu_sel_err, 0, 1);
1219 trace.set(Column::execution_sel_opcode_error, 0, 1);
1220 check_relation<alu>(
trace);
1221 check_all_interactions<AluTraceBuilder>(
trace);
1222 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1225 trace.set(Column::alu_ib, 0, 0);
1226 trace.set(Column::alu_b_inv, 0, 0);
1228 trace.set(Column::alu_sel_div_0_err, 0, 1);
1229 check_relation<alu>(
trace);
1230 check_all_interactions<AluTraceBuilder>(
trace);
1231 trace.set(Column::execution_register_1_, 0, 0);
1232 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1235 trace.set(Column::alu_ib_tag, 0,
static_cast<uint8_t
>(MemoryTag::U16));
1237 trace.set(Column::alu_sel_ab_tag_mismatch, 0, 1);
1238 trace.set(Column::alu_ab_tags_diff_inv, 0, (
FF(tag) -
FF(
static_cast<uint8_t
>(MemoryTag::U16))).invert());
1239 check_relation<alu>(
trace);
1248class AluEQConstrainingTest :
public AluConstrainingTest,
public ::testing::WithParamInterface<ThreeOperandTestParams> {
1250 TestTraceContainer process_eq_with_tracegen(
const ThreeOperandTestParams& params)
1252 TestTraceContainer
trace;
1253 auto [
a,
b, c] = params;
1257 { .operation = simulation::AluOperation::EQ, .a =
a, .b =
b, .c = c },
1269TEST_P(AluEQConstrainingTest, AluEQTraceGen)
1273 process_eq_with_tracegen(ThreeOperandTestParams{ param, param, MemoryValue::from_tag(MemoryTag::U1, 1) });
1274 check_all_interactions<AluTraceBuilder>(
trace);
1275 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1276 check_relation<alu>(
trace);
1279TEST_P(AluEQConstrainingTest, AluInEQTraceGen)
1281 auto trace = process_eq_with_tracegen(GetParam());
1282 check_all_interactions<AluTraceBuilder>(
trace);
1283 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1284 check_relation<alu>(
trace);
1287TEST_P(AluEQConstrainingTest, NegativeAluEqResult)
1289 auto params = GetParam();
1290 for (
const bool is_eq : {
false,
true }) {
1291 auto trace = process_eq_with_tracegen(is_eq ? ThreeOperandTestParams{
std::get<0>(params),
1293 MemoryValue::from_tag(MemoryTag::U1, 1) }
1295 check_relation<alu>(
trace);
1296 check_all_interactions<AluTraceBuilder>(
trace);
1297 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1298 bool c =
trace.get(Column::alu_ic, 0) == 1;
1300 trace.set(Column::alu_ic, 0,
static_cast<uint8_t
>(!c));
1305TEST_P(AluEQConstrainingTest, NegativeAluEqHelper)
1307 auto trace = process_eq_with_tracegen(GetParam());
1308 check_relation<alu>(
trace);
1309 check_all_interactions<AluTraceBuilder>(
trace);
1310 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1311 auto helper =
trace.get(Column::alu_helper1, 0);
1312 trace.set(Column::alu_helper1, 0, helper + 1);
1319 MemoryValue::from_tag(MemoryTag::U1, 0), MemoryValue::from_tag(MemoryTag::U1, 0),
1320 MemoryValue::from_tag(MemoryTag::U1, 0), MemoryValue::from_tag(MemoryTag::U1, 1),
1321 MemoryValue::from_tag(MemoryTag::U1, 0), MemoryValue::from_tag(MemoryTag::U1, 0),
1322 MemoryValue::from_tag(MemoryTag::U1, 0),
1327class AluLTConstrainingTest :
public AluConstrainingTest,
public ::testing::WithParamInterface<ThreeOperandTestParams> {
1329 TestTraceContainer process_lt_trace(ThreeOperandTestParams params)
1331 auto [
a,
b, c] = params;
1332 auto mem_tag =
a.get_tag();
1333 auto tag =
static_cast<uint8_t
>(mem_tag);
1334 auto is_ff = mem_tag == MemoryTag::FF;
1336 auto trace = TestTraceContainer::from_rows({
1343 .alu_ic_tag =
static_cast<uint8_t
>(MemoryTag::U1),
1344 .alu_lt_ops_input_a =
b,
1345 .alu_lt_ops_input_b =
a,
1346 .alu_lt_ops_result_c = c,
1351 .alu_sel_ff_lt_ops =
static_cast<uint8_t
>(is_ff),
1352 .alu_sel_int_lt_ops =
static_cast<uint8_t
>(!is_ff),
1353 .alu_sel_is_ff =
static_cast<uint8_t
>(is_ff),
1354 .alu_sel_lt_ops = 1,
1356 .alu_tag_ff_diff_inv = is_ff ? 0 :
FF(
tag - static_cast<uint8_t>(
MemoryTag::
FF)).invert(),
1357 .execution_mem_tag_reg_0_ =
tag,
1358 .execution_mem_tag_reg_1_ =
tag,
1359 .execution_mem_tag_reg_2_ = static_cast<uint8_t>(
MemoryTag::
U1),
1360 .execution_register_0_ =
a,
1361 .execution_register_1_ =
b,
1362 .execution_register_2_ = c,
1363 .execution_sel_execute_alu = 1,
1373 .result = c.as_ff() == 1 } },
1382 TestTraceContainer process_lt_with_tracegen(ThreeOperandTestParams params)
1384 TestTraceContainer
trace;
1385 auto [
a,
b, c] = params;
1386 auto is_ff =
a.get_tag() == MemoryTag::FF;
1390 { .operation = simulation::AluOperation::LT, .a =
a, .b =
b, .c = c },
1399 .result = c.as_ff() == 1 } },
1410TEST_P(AluLTConstrainingTest, AluLT)
1412 auto trace = process_lt_trace(GetParam());
1413 check_all_interactions<AluTraceBuilder>(
trace);
1414 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1415 check_relation<alu>(
trace);
1418TEST_P(AluLTConstrainingTest, AluLTTraceGen)
1420 auto trace = process_lt_with_tracegen(GetParam());
1421 check_all_interactions<AluTraceBuilder>(
trace);
1422 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1423 check_relation<alu>(
trace);
1426TEST_P(AluLTConstrainingTest, NegativeAluLT)
1428 auto params = GetParam();
1429 auto trace = process_lt_trace(params);
1430 auto is_ff =
std::get<0>(params).get_tag() == MemoryTag::FF;
1431 check_relation<alu>(
trace);
1432 check_all_interactions<AluTraceBuilder>(
trace);
1433 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1434 bool c =
trace.get(Column::alu_ic, 0) == 1;
1436 trace.set(Column::alu_ic, 0,
static_cast<uint8_t
>(!c));
1438 trace.set(Column::alu_lt_ops_result_c, 0,
static_cast<uint8_t
>(!c));
1442 "LOOKUP_ALU_FF_GT");
1445 "LOOKUP_ALU_INT_GT");
1453class AluLTEConstrainingTest :
public AluConstrainingTest,
1454 public ::testing::WithParamInterface<ThreeOperandTestParams> {
1456 TestTraceContainer process_lte_trace(ThreeOperandTestParams params,
bool eq =
false)
1458 auto [
a,
b, c] = params;
1459 auto mem_tag =
a.get_tag();
1460 auto tag =
static_cast<uint8_t
>(mem_tag);
1461 auto is_ff = mem_tag == MemoryTag::FF;
1463 c = eq ? MemoryValue::from_tag(MemoryTag::U1, 1) : c;
1465 auto trace = TestTraceContainer::from_rows({
1472 .alu_ic_tag =
static_cast<uint8_t
>(MemoryTag::U1),
1473 .alu_lt_ops_input_a =
a,
1474 .alu_lt_ops_input_b =
b,
1475 .alu_lt_ops_result_c = c.as_ff() == 0 ? 1 : 0,
1480 .alu_sel_ff_lt_ops =
static_cast<uint8_t
>(is_ff),
1481 .alu_sel_int_lt_ops =
static_cast<uint8_t
>(!is_ff),
1482 .alu_sel_is_ff =
static_cast<uint8_t
>(is_ff),
1483 .alu_sel_lt_ops = 1,
1484 .alu_sel_op_lte = 1,
1485 .alu_tag_ff_diff_inv = is_ff ? 0 :
FF(
tag - static_cast<uint8_t>(
MemoryTag::
FF)).invert(),
1486 .execution_mem_tag_reg_0_ =
tag,
1487 .execution_mem_tag_reg_1_ =
tag,
1488 .execution_mem_tag_reg_2_ = static_cast<uint8_t>(
MemoryTag::
U1),
1489 .execution_register_0_ =
a,
1490 .execution_register_1_ =
b,
1491 .execution_register_2_ = c,
1492 .execution_sel_execute_alu = 1,
1502 .result = c.as_ff() == 0 } },
1510 TestTraceContainer process_lte_with_tracegen(ThreeOperandTestParams params,
bool eq =
false)
1512 TestTraceContainer
trace;
1513 auto [
a,
b, c] = params;
1514 auto is_ff =
a.get_tag() == MemoryTag::FF;
1516 c = eq ? MemoryValue::from_tag(MemoryTag::U1, 1) : c;
1520 { .operation = simulation::AluOperation::LTE, .a =
a, .b =
b, .c = c },
1529 .result = c.as_ff() == 0 } },
1540TEST_P(AluLTEConstrainingTest, AluLTE)
1542 auto trace = process_lte_trace(GetParam());
1543 check_all_interactions<AluTraceBuilder>(
trace);
1544 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1545 check_relation<alu>(
trace);
1548TEST_P(AluLTEConstrainingTest, AluLTEEq)
1550 auto trace = process_lte_trace(GetParam(),
true);
1551 check_all_interactions<AluTraceBuilder>(
trace);
1552 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1553 check_relation<alu>(
trace);
1556TEST_P(AluLTEConstrainingTest, AluLTETraceGen)
1558 auto trace = process_lte_with_tracegen(GetParam());
1559 check_all_interactions<AluTraceBuilder>(
trace);
1560 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1561 check_relation<alu>(
trace);
1564TEST_P(AluLTEConstrainingTest, AluLTEEqTraceGen)
1566 auto trace = process_lte_with_tracegen(GetParam(),
true);
1567 check_all_interactions<AluTraceBuilder>(
trace);
1568 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1569 check_relation<alu>(
trace);
1572TEST_P(AluLTEConstrainingTest, NegativeAluLTEResult)
1574 auto params = GetParam();
1576 for (
const bool is_eq : {
false,
true }) {
1577 auto trace = process_lte_trace(params, is_eq);
1578 auto is_ff =
std::get<0>(params).get_tag() == MemoryTag::FF;
1579 check_relation<alu>(
trace);
1580 check_all_interactions<AluTraceBuilder>(
trace);
1581 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1582 bool c =
trace.get(Column::alu_ic, 0) == 1;
1584 trace.set(Column::alu_ic, 0,
static_cast<uint8_t
>(!c));
1586 trace.set(Column::alu_lt_ops_result_c, 0,
static_cast<uint8_t
>(c));
1590 "LOOKUP_ALU_FF_GT");
1593 "LOOKUP_ALU_INT_GT");
1598TEST_P(AluLTEConstrainingTest, NegativeAluLTEInput)
1600 auto params = GetParam();
1602 for (
const bool is_eq : {
false,
true }) {
1603 auto trace = process_lte_trace(params, is_eq);
1604 auto is_ff =
std::get<0>(params).get_tag() == MemoryTag::FF;
1605 check_relation<alu>(
trace);
1606 check_all_interactions<AluTraceBuilder>(
trace);
1607 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1608 bool c =
trace.get(Column::alu_ic, 0) == 1;
1609 auto a =
trace.get(Column::alu_ia, 0);
1610 auto wrong_b = c ?
a - 1 :
a + 1;
1611 trace.set(Column::alu_ib, 0, wrong_b);
1612 trace.set(Column::alu_lt_ops_input_b, 0, wrong_b);
1614 check_relation<alu>(
trace);
1620 "LOOKUP_ALU_FF_GT");
1623 "LOOKUP_ALU_INT_GT");
1631 MemoryValue::from_tag(MemoryTag::U1, 0),
1632 MemoryValue::from_tag(MemoryTag::U8, 55),
1633 MemoryValue::from_tag(MemoryTag::U16, 65505),
1634 MemoryValue::from_tag(MemoryTag::U32, 9),
1635 MemoryValue::from_tag(MemoryTag::U64, 9),
1636 MemoryValue::from_tag(MemoryTag::U128, 9),
1637 MemoryValue::from_tag(
static_cast<MemoryTag>(0), 0),
1642class AluNotConstrainingTest :
public AluConstrainingTest,
public ::testing::WithParamInterface<TwoOperandTestParams> {
1644 TestTraceContainer process_not_with_tracegen(
const TwoOperandTestParams& params,
bool error =
false)
1646 TestTraceContainer
trace;
1647 auto [
a,
b] = params;
1648 auto is_ff =
a.get_tag() == MemoryTag::FF;
1652 { .operation = simulation::AluOperation::NOT,
1667TEST_P(AluNotConstrainingTest, AluNotTraceGen)
1669 auto trace = process_not_with_tracegen(GetParam());
1670 check_all_interactions<AluTraceBuilder>(
trace);
1671 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1672 check_relation<alu>(
trace);
1675TEST_P(AluNotConstrainingTest, NegativeAluNotTraceGen)
1677 auto params = GetParam();
1678 auto trace = process_not_with_tracegen(params);
1679 check_all_interactions<AluTraceBuilder>(
trace);
1680 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1681 check_relation<alu>(
trace);
1682 trace.set(Column::alu_ib, 0,
trace.get(Column::alu_ib, 0) + 1);
1684 if (
std::get<0>(params).get_tag() != MemoryTag::FF) {
1689TEST_P(AluNotConstrainingTest, AluNotTraceGenTagError)
1691 auto [
a,
b] = GetParam();
1692 auto trace = process_not_with_tracegen(
1693 TwoOperandTestParams{
a, MemoryValue::from_tag(TAG_ERROR_TEST_VALUES.at(
b.get_tag()),
b.as_ff()) },
true);
1694 check_all_interactions<AluTraceBuilder>(
trace);
1695 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1696 check_relation<alu>(
trace);
1702 MemoryValue::from_tag(MemoryTag::U1, 1),
1703 MemoryValue::from_tag(MemoryTag::U8, 0),
1704 MemoryValue::from_tag(MemoryTag::U16, 0),
1705 MemoryValue::from_tag(MemoryTag::U32, 0xfffffec0),
1706 MemoryValue::from_tag(MemoryTag::U64, 0xfffffffffffffec0ULL),
1707 MemoryValue::from_tag(MemoryTag::U128, (
uint256_t(1) << 128) - 320),
1712class AluShlConstrainingTest :
public AluConstrainingTest,
1713 public ::testing::WithParamInterface<ThreeOperandTestParams> {
1715 TestTraceContainer process_shl_trace(ThreeOperandTestParams params)
1717 auto [
a,
b, c] = params;
1719 auto mem_tag =
a.get_tag();
1720 auto tag =
static_cast<uint8_t
>(mem_tag);
1722 auto a_num =
static_cast<uint128_t>(
a.as_ff());
1723 auto b_num =
static_cast<uint128_t>(
b.as_ff());
1725 auto overflow = b_num > tag_bits;
1726 uint128_t shift_lo_bits = overflow ? tag_bits : tag_bits - b_num;
1727 uint128_t shift_hi_bits = overflow ? tag_bits : b_num;
1728 auto two_pow_shift_lo_bits =
static_cast<uint128_t>(1) << shift_lo_bits;
1729 auto a_lo = overflow ? b_num - tag_bits : a_num % two_pow_shift_lo_bits;
1730 auto a_hi = a_num >> shift_lo_bits;
1732 auto trace = TestTraceContainer::from_rows({
1735 .alu_a_hi_bits = shift_hi_bits,
1737 .alu_a_lo_bits = shift_lo_bits,
1738 .alu_helper1 =
static_cast<uint128_t>(1) << b_num,
1745 .alu_max_bits = tag_bits,
1749 .alu_sel_decompose_a = 1,
1750 .alu_sel_op_shl = 1,
1751 .alu_sel_shift_ops = 1,
1752 .alu_sel_shift_ops_no_overflow = overflow ? 0 : 1,
1753 .alu_shift_lo_bits = shift_lo_bits,
1754 .alu_tag_ff_diff_inv =
FF(tag -
static_cast<uint8_t
>(MemoryTag::FF)).
invert(),
1755 .alu_two_pow_shift_lo_bits = two_pow_shift_lo_bits,
1756 .execution_mem_tag_reg_0_ =
tag,
1757 .execution_mem_tag_reg_1_ =
tag,
1758 .execution_mem_tag_reg_2_ =
tag,
1759 .execution_register_0_ =
a,
1760 .execution_register_1_ =
b,
1761 .execution_register_2_ = c,
1762 .execution_sel_execute_alu = 1,
1771 range_check_builder.process({ { .value = a_lo, .num_bits =
static_cast<uint8_t
>(shift_lo_bits) },
1772 { .value = a_hi, .num_bits =
static_cast<uint8_t
>(shift_hi_bits) } },
1778 TestTraceContainer process_shl_with_tracegen(ThreeOperandTestParams params)
1780 TestTraceContainer
trace;
1781 auto [
a,
b, c] = params;
1782 auto b_num =
static_cast<uint128_t>(
b.as_ff());
1784 auto overflow = b_num > tag_bits;
1785 uint128_t shift_lo_bits = overflow ? tag_bits : tag_bits - b_num;
1786 auto a_lo = overflow ? b_num - tag_bits
1791 { .operation = simulation::AluOperation::SHL, .a =
a, .b =
b, .c = c },
1798 range_check_builder.process({ { .value = a_lo, .num_bits =
static_cast<uint8_t
>(shift_lo_bits) },
1799 { .value =
static_cast<uint128_t>(
a.as_ff()) >> shift_lo_bits,
1800 .num_bits =
static_cast<uint8_t
>(overflow ? tag_bits : b_num) } },
1808TEST_P(AluShlConstrainingTest, AluShl)
1810 auto trace = process_shl_trace(GetParam());
1811 check_all_interactions<AluTraceBuilder>(
trace);
1812 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1813 check_relation<alu>(
trace);
1816TEST_P(AluShlConstrainingTest, AluShlTraceGen)
1818 auto trace = process_shl_with_tracegen(GetParam());
1819 check_all_interactions<AluTraceBuilder>(
trace);
1820 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1821 check_relation<alu>(
trace);
1824TEST_F(AluShlConstrainingTest, NegativeAluShlFF)
1826 auto a = MemoryValue::from_tag(MemoryTag::FF, 2);
1827 auto b = MemoryValue::from_tag(MemoryTag::FF, 5);
1828 auto c = MemoryValue::from_tag(MemoryTag::FF, 2 << 5);
1829 auto trace = process_shl_with_tracegen({
a,
b, c });
1832 trace.set(Column::alu_sel_tag_err, 0, 1);
1833 trace.set(Column::alu_sel_err, 0, 1);
1834 check_relation<alu>(
trace);
1835 check_all_interactions<AluTraceBuilder>(
trace);
1836 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1838 trace.set(Column::alu_ib, 0, 0);
1839 check_relation<alu>(
trace);
1840 check_all_interactions<AluTraceBuilder>(
trace);
1841 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1844TEST_F(AluShlConstrainingTest, NegativeAluShlTagMismatchOverflow)
1846 auto a = MemoryValue::from_tag(MemoryTag::U8, 2);
1847 auto b = MemoryValue::from_tag(MemoryTag::U32, 256);
1848 auto c = MemoryValue::from_tag(MemoryTag::U8, 0);
1849 auto trace = process_shl_with_tracegen({
a,
b, c });
1851 trace.set(Column::alu_sel_ab_tag_mismatch, 0, 1);
1852 trace.set(Column::alu_ab_tags_diff_inv,
1854 (
FF(
static_cast<uint8_t
>(MemoryTag::U8)) -
FF(
static_cast<uint8_t
>(MemoryTag::U32))).invert());
1857 trace.set(Column::alu_sel_tag_err, 0, 1);
1858 trace.set(Column::alu_sel_err, 0, 1);
1859 check_relation<alu>(
trace);
1860 check_all_interactions<AluTraceBuilder>(
trace);
1861 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1867 MemoryValue::from_tag(MemoryTag::U1, 1),
1868 MemoryValue::from_tag(MemoryTag::U8, 0),
1869 MemoryValue::from_tag(MemoryTag::U16, 0),
1870 MemoryValue::from_tag(MemoryTag::U32, 0x7ffffff),
1871 MemoryValue::from_tag(MemoryTag::U64, 0x7ffffffffffffffULL),
1872 MemoryValue::from_tag(MemoryTag::U128,
1878class AluShrConstrainingTest :
public AluConstrainingTest,
1879 public ::testing::WithParamInterface<ThreeOperandTestParams> {
1881 TestTraceContainer process_shr_trace(ThreeOperandTestParams params)
1883 auto [
a,
b, c] = params;
1885 auto mem_tag =
a.get_tag();
1886 auto tag =
static_cast<uint8_t
>(mem_tag);
1888 auto a_num =
static_cast<uint128_t>(
a.as_ff());
1889 auto b_num =
static_cast<uint128_t>(
b.as_ff());
1891 auto overflow = b_num > tag_bits;
1892 uint128_t shift_lo_bits = overflow ? tag_bits : b_num;
1893 uint128_t shift_hi_bits = overflow ? tag_bits : tag_bits - b_num;
1894 auto two_pow_shift_lo_bits =
static_cast<uint128_t>(1) << shift_lo_bits;
1895 auto a_lo = overflow ? b_num - tag_bits : a_num % two_pow_shift_lo_bits;
1896 auto a_hi = a_num >> shift_lo_bits;
1898 auto trace = TestTraceContainer::from_rows({
1901 .alu_a_hi_bits = shift_hi_bits,
1903 .alu_a_lo_bits = shift_lo_bits,
1910 .alu_max_bits = tag_bits,
1914 .alu_sel_decompose_a = 1,
1915 .alu_sel_op_shr = 1,
1916 .alu_sel_shift_ops = 1,
1917 .alu_sel_shift_ops_no_overflow = overflow ? 0 : 1,
1918 .alu_shift_lo_bits = shift_lo_bits,
1919 .alu_tag_ff_diff_inv =
FF(tag -
static_cast<uint8_t
>(MemoryTag::FF)).
invert(),
1920 .alu_two_pow_shift_lo_bits = two_pow_shift_lo_bits,
1921 .execution_mem_tag_reg_0_ =
tag,
1922 .execution_mem_tag_reg_1_ =
tag,
1923 .execution_mem_tag_reg_2_ =
tag,
1924 .execution_register_0_ =
a,
1925 .execution_register_1_ =
b,
1926 .execution_register_2_ = c,
1927 .execution_sel_execute_alu = 1,
1936 range_check_builder.process({ { .value = a_lo, .num_bits =
static_cast<uint8_t
>(shift_lo_bits) },
1937 { .value = a_hi, .num_bits =
static_cast<uint8_t
>(shift_hi_bits) } },
1943 TestTraceContainer process_shr_with_tracegen(ThreeOperandTestParams params)
1945 TestTraceContainer
trace;
1946 auto [
a,
b, c] = params;
1947 auto b_num =
static_cast<uint128_t>(
b.as_ff());
1949 auto overflow = b_num > tag_bits;
1950 uint128_t shift_lo_bits = overflow ? tag_bits : b_num;
1951 auto a_lo = overflow ? b_num - tag_bits
1956 { .operation = simulation::AluOperation::SHR, .a =
a, .b =
b, .c = c },
1963 range_check_builder.process({ { .value = a_lo, .num_bits =
static_cast<uint8_t
>(shift_lo_bits) },
1964 { .value =
static_cast<uint128_t>(
a.as_ff()) >> shift_lo_bits,
1965 .num_bits =
static_cast<uint8_t
>(overflow ? tag_bits : tag_bits - b_num) } },
1973TEST_P(AluShrConstrainingTest, AluShr)
1975 auto trace = process_shr_trace(GetParam());
1976 check_all_interactions<AluTraceBuilder>(
trace);
1977 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1978 check_relation<alu>(
trace);
1981TEST_P(AluShrConstrainingTest, AluShrTraceGen)
1983 auto trace = process_shr_with_tracegen(GetParam());
1984 check_all_interactions<AluTraceBuilder>(
trace);
1985 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
1986 check_relation<alu>(
trace);
1989TEST_F(AluShrConstrainingTest, NegativeAluShrFF)
1991 auto a = MemoryValue::from_tag(MemoryTag::FF, 2);
1992 auto b = MemoryValue::from_tag(MemoryTag::FF, 5);
1993 auto c = MemoryValue::from_tag(MemoryTag::FF, 2 << 5);
1994 auto trace = process_shr_with_tracegen({
a,
b, c });
1997 trace.set(Column::alu_sel_tag_err, 0, 1);
1998 trace.set(Column::alu_sel_err, 0, 1);
1999 check_relation<alu>(
trace);
2000 check_all_interactions<AluTraceBuilder>(
trace);
2001 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
2003 trace.set(Column::alu_ib, 0, 0);
2004 check_relation<alu>(
trace);
2005 check_all_interactions<AluTraceBuilder>(
trace);
2006 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
2009TEST_F(AluShrConstrainingTest, NegativeAluShrTagMismatchOverflow)
2011 auto a = MemoryValue::from_tag(MemoryTag::U16, 2);
2012 auto b = MemoryValue::from_tag(MemoryTag::U64, 123456);
2013 auto c = MemoryValue::from_tag(MemoryTag::U16, 0);
2014 auto trace = process_shr_with_tracegen({
a,
b, c });
2016 trace.set(Column::alu_sel_ab_tag_mismatch, 0, 1);
2017 trace.set(Column::alu_ab_tags_diff_inv,
2019 (
FF(
static_cast<uint8_t
>(MemoryTag::U16)) -
FF(
static_cast<uint8_t
>(MemoryTag::U64))).invert());
2022 trace.set(Column::alu_sel_tag_err, 0, 1);
2023 trace.set(Column::alu_sel_err, 0, 1);
2024 check_relation<alu>(
trace);
2025 check_all_interactions<AluTraceBuilder>(
trace);
2026 check_interaction<ExecutionTraceBuilder, lookup_alu_register_tag_value_settings>(
trace);
2034 { MemoryValue::from_tag(MemoryTag::FF, 1),
2035 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U1)),
2036 MemoryValue::from_tag(MemoryTag::U1, 1) },
2037 { MemoryValue::from_tag(MemoryTag::FF, 42),
2038 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U8)),
2039 MemoryValue::from_tag(MemoryTag::U8, 42) },
2040 { MemoryValue::from_tag(MemoryTag::FF, 12345),
2041 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U16)),
2042 MemoryValue::from_tag(MemoryTag::U16, 12345) },
2043 { MemoryValue::from_tag(MemoryTag::FF, 123456789),
2044 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U32)),
2045 MemoryValue::from_tag(MemoryTag::U32, 123456789) },
2046 { MemoryValue::from_tag(MemoryTag::FF, 1234567890123456789ULL),
2047 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U64)),
2048 MemoryValue::from_tag(MemoryTag::U64, 1234567890123456789ULL) },
2049 { MemoryValue::from_tag(MemoryTag::FF, (
uint256_t(1) << 127) + 23423429816234ULL),
2050 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U128)),
2051 MemoryValue::from_tag(MemoryTag::U128, (
uint256_t(1) << 127) + 23423429816234ULL) },
2052 { MemoryValue::from_tag(MemoryTag::FF, FF::modulus - 3),
2053 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::FF)),
2054 MemoryValue::from_tag(MemoryTag::FF, FF::modulus - 3) },
2056 { MemoryValue::from_tag(MemoryTag::FF, 212),
2057 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U1)),
2058 MemoryValue::from_tag(MemoryTag::U1, 0) },
2059 { MemoryValue::from_tag(MemoryTag::FF, 257),
2060 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U8)),
2061 MemoryValue::from_tag(MemoryTag::U8, 1) },
2062 { MemoryValue::from_tag(MemoryTag::FF, 65540),
2063 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U16)),
2064 MemoryValue::from_tag(MemoryTag::U16, 4) },
2065 { MemoryValue::from_tag(MemoryTag::FF, 4294967298ULL),
2066 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U32)),
2067 MemoryValue::from_tag(MemoryTag::U32, 2) },
2068 { MemoryValue::from_tag(MemoryTag::FF, 18446744073709551615ULL + 4),
2069 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U64)),
2070 MemoryValue::from_tag(MemoryTag::U64, 3) },
2072 { MemoryValue::from_tag(MemoryTag::FF, (
uint256_t(134534) << 129) + 986132),
2073 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U1)),
2074 MemoryValue::from_tag(MemoryTag::U1, 0) },
2075 { MemoryValue::from_tag(MemoryTag::FF, FF::modulus - 128735618772ULL),
2076 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U8)),
2077 MemoryValue::from_tag(MemoryTag::U8, 45) },
2078 { MemoryValue::from_tag(MemoryTag::FF, (
uint256_t(999) << 128) - 986132ULL),
2079 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U16)),
2080 MemoryValue::from_tag(MemoryTag::U16, 62444) },
2081 { MemoryValue::from_tag(MemoryTag::FF, (
uint256_t(134534) << 198) + 986132ULL),
2082 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U32)),
2083 MemoryValue::from_tag(MemoryTag::U32, 986132ULL) },
2084 { MemoryValue::from_tag(MemoryTag::FF, (
uint256_t(134534) << 198) - 986132ULL),
2085 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U64)),
2086 MemoryValue::from_tag(MemoryTag::U64,
static_cast<uint64_t
>(-986132ULL)) },
2087 { MemoryValue::from_tag(MemoryTag::FF, FF::modulus - 8723),
2088 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U128)),
2089 MemoryValue::from_tag(MemoryTag::U128,
static_cast<uint128_t>(FF::modulus - 8723)) },
2092class AluTruncateConstrainingTest :
public AluConstrainingTest,
2093 public ::testing::WithParamInterface<ThreeOperandTestParams> {
2095 TestTraceContainer process_truncate_with_tracegen(
const ThreeOperandTestParams& params, TestTraceContainer&
trace)
2097 auto [
a,
b, c] = params;
2101 { .operation = simulation::AluOperation::TRUNCATE, .a =
a, .b =
b, .c = c },
2108 auto is_non_trivial =
trace.get(Column::alu_sel_trunc_non_trivial, 0) == 1;
2110 if (is_non_trivial) {
2111 auto a_decomp = simulation::decompose(
static_cast<uint256_t>(
a.as_ff()));
2115 .num_bits =
static_cast<uint8_t
>(128 - bits) } },
2117 auto is_gte_128 =
trace.get(Column::alu_sel_trunc_gte_128, 0) == 1;
2119 auto p_limbs = simulation::decompose(FF::modulus);
2120 simulation::LimbsComparisonWitness p_sub_a_witness = { .lo = p_limbs.lo - a_decomp.lo,
2121 .hi = p_limbs.hi - a_decomp.hi,
2123 field_gt_builder.process({ { .operation = simulation::FieldGreaterOperation::CANONICAL_DECOMPOSITION,
2125 .a_limbs = a_decomp,
2126 .p_sub_a_witness = p_sub_a_witness } },
2134 TestTraceContainer process_set_with_tracegen(
const ThreeOperandTestParams& params)
2136 TestTraceContainer
trace;
2137 auto [
a,
b, _c] = params;
2139 auto c = MemoryValue::from_tag_truncating(
dst_tag,
a);
2142 { Column::execution_sel_execute_set, 1 },
2143 { Column::execution_rop_2_,
a },
2144 { Column::execution_rop_1_,
static_cast<uint8_t
>(
dst_tag) },
2146 { Column::execution_register_0_, c.as_ff() },
2147 { Column::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
dst_tag) },
2150 process_truncate_with_tracegen(params,
trace);
2155 TestTraceContainer process_cast_with_tracegen(
const ThreeOperandTestParams& params)
2157 TestTraceContainer
trace;
2158 auto [
a,
b, _c] = params;
2160 auto c = MemoryValue::from_tag_truncating(
dst_tag,
a);
2163 { Column::execution_sel_execute_cast, 1 },
2164 { Column::execution_register_0_,
a },
2165 { Column::execution_rop_2_,
static_cast<uint8_t
>(
dst_tag) },
2167 { Column::execution_register_1_, c.as_ff() },
2168 { Column::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
dst_tag) },
2171 process_truncate_with_tracegen(params,
trace);
2177INSTANTIATE_TEST_SUITE_P(AluConstrainingTest, AluTruncateConstrainingTest, ::testing::ValuesIn(TEST_VALUES_TRUNCATE));
2179TEST_P(AluTruncateConstrainingTest, AluSet)
2181 auto trace = process_set_with_tracegen(GetParam());
2182 check_all_interactions<AluTraceBuilder>(
trace);
2183 check_interaction<ExecutionTraceBuilder, lookup_alu_exec_dispatching_set_settings>(
trace);
2184 check_relation<alu>(
trace);
2187TEST_P(AluTruncateConstrainingTest, AluCast)
2189 auto trace = process_cast_with_tracegen(GetParam());
2190 check_all_interactions<AluTraceBuilder>(
trace);
2191 check_interaction<ExecutionTraceBuilder, lookup_alu_exec_dispatching_set_settings>(
trace);
2192 check_relation<alu>(
trace);
2195TEST_P(AluTruncateConstrainingTest, NegativeTruncateWrongTrivialCase)
2197 TestTraceContainer
trace;
2198 process_truncate_with_tracegen(GetParam(),
trace);
2199 check_relation<alu>(
trace);
2200 bool is_trivial =
trace.get(Column::alu_sel_trunc_trivial, 0) == 1;
2201 trace.set(Column::alu_sel_trunc_trivial, 0,
static_cast<uint8_t
>(!is_trivial));
2203 trace.set(Column::alu_sel_trunc_trivial, 0,
static_cast<uint8_t
>(is_trivial));
2204 trace.set(Column::alu_sel_trunc_non_trivial, 0,
static_cast<uint8_t
>(is_trivial));
2208TEST_P(AluTruncateConstrainingTest, NegativeTruncateWrong128BitsCase)
2210 TestTraceContainer
trace;
2211 process_truncate_with_tracegen(GetParam(),
trace);
2212 check_relation<alu>(
trace);
2213 bool is_lt_128 =
trace.get(Column::alu_sel_trunc_lt_128, 0) == 1;
2214 trace.set(Column::alu_sel_trunc_lt_128, 0,
static_cast<uint8_t
>(!is_lt_128));
2216 trace.set(Column::alu_sel_trunc_lt_128, 0,
static_cast<uint8_t
>(is_lt_128));
2217 check_relation<alu>(
trace);
2218 bool is_gte_128 =
trace.get(Column::alu_sel_trunc_gte_128, 0) == 1;
2219 trace.set(Column::alu_sel_trunc_gte_128, 0,
static_cast<uint8_t
>(!is_gte_128));
2223TEST_F(AluTruncateConstrainingTest, NegativeTruncateWrongMid)
2225 TestTraceContainer
trace;
2226 process_truncate_with_tracegen({ MemoryValue::from_tag(MemoryTag::FF, 4294967298ULL),
2227 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U32)),
2228 MemoryValue::from_tag(MemoryTag::U32, 2) },
2230 check_relation<alu>(
trace);
2231 trace.set(Column::alu_mid, 0, 1234ULL);
2235TEST_F(AluTruncateConstrainingTest, NegativeTruncateWrongMidBits)
2237 TestTraceContainer
trace;
2238 process_truncate_with_tracegen({ MemoryValue::from_tag(MemoryTag::FF, FF::modulus - 2),
2239 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U1)),
2240 MemoryValue::from_tag(MemoryTag::U1, 1) },
2242 check_relation<alu>(
trace);
2243 trace.set(Column::alu_mid_bits, 0, 32);
2247TEST_F(AluTruncateConstrainingTest, NegativeTruncateWrongLo128FromCanonDec)
2249 TestTraceContainer
trace;
2250 process_truncate_with_tracegen({ MemoryValue::from_tag(MemoryTag::FF, (
uint256_t(134534) << 198) - 986132ULL),
2251 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U64)),
2252 MemoryValue::from_tag(MemoryTag::U64,
static_cast<uint64_t
>(-986132ULL)) },
2254 check_relation<alu>(
trace);
2255 check_all_interactions<AluTraceBuilder>(
trace);
2256 trace.set(Column::alu_a_lo, 0, 1234ULL);
2258 (check_interaction<AluTraceBuilder, lookup_alu_large_trunc_canonical_dec_settings>(
trace)),
2259 "Failed.*LARGE_TRUNC_CANONICAL_DEC. Could not find tuple in destination.");
2262TEST_F(AluTruncateConstrainingTest, NegativeTruncateWrongMidIntoRangeCheck)
2264 TestTraceContainer
trace;
2265 process_truncate_with_tracegen({ MemoryValue::from_tag(MemoryTag::FF, (
uint256_t(134534) << 198) - 986132ULL),
2266 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U64)),
2267 MemoryValue::from_tag(MemoryTag::U64,
static_cast<uint64_t
>(-986132ULL)) },
2269 check_relation<alu>(
trace);
2270 check_all_interactions<AluTraceBuilder>(
trace);
2271 trace.set(Column::alu_mid, 0, 1234ULL);
2273 "Failed.*RANGE_CHECK_TRUNC_MID. Could not find tuple in destination.");
2276TEST_F(AluTruncateConstrainingTest, NegativeCastWrongDispatching)
2279 process_cast_with_tracegen({ MemoryValue::from_tag(MemoryTag::FF, 4294967298ULL),
2280 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U32)),
2281 MemoryValue::from_tag(MemoryTag::U32, 2) });
2282 check_relation<alu>(
trace);
2283 check_all_interactions<AluTraceBuilder>(
trace);
2284 check_interaction<ExecutionTraceBuilder, lookup_alu_exec_dispatching_cast_settings>(
trace);
2285 trace.set(Column::execution_register_0_, 0,
trace.get(Column::execution_register_0_, 0) + 1);
2287 (check_interaction<ExecutionTraceBuilder, lookup_alu_exec_dispatching_cast_settings>(
trace)),
2288 "Failed.*EXEC_DISPATCHING_CAST. Could not find tuple in destination.");
2291TEST_F(AluTruncateConstrainingTest, NegativeSetWrongDispatching)
2293 auto trace = process_set_with_tracegen({ MemoryValue::from_tag(MemoryTag::FF, 4294967298ULL),
2294 MemoryValue::from_tag(MemoryTag::FF,
static_cast<uint8_t
>(MemoryTag::U32)),
2295 MemoryValue::from_tag(MemoryTag::U32, 2) });
2296 check_relation<alu>(
trace);
2297 check_all_interactions<AluTraceBuilder>(
trace);
2298 check_interaction<ExecutionTraceBuilder, lookup_alu_exec_dispatching_set_settings>(
trace);
2299 trace.set(Column::execution_rop_2_, 0,
trace.get(Column::execution_rop_2_, 0) + 1);
2301 (check_interaction<ExecutionTraceBuilder, lookup_alu_exec_dispatching_set_settings>(
trace)),
2302 "Failed.*EXEC_DISPATCHING_SET. Could not find tuple in destination.");
INSTANTIATE_TEST_SUITE_P(AcirTests, AcirIntegrationSingleTest, testing::Values("a_1327_concrete_in_generic", "a_1_mul", "a_2_div", "a_3_add", "a_4_sub", "a_5_over", "a_6", "a_6_array", "a_7", "a_7_function", "aes128_encrypt", "arithmetic_binary_operations", "array_dynamic", "array_dynamic_blackbox_input", "array_dynamic_main_output", "array_dynamic_nested_blackbox_input", "array_eq", "array_if_cond_simple", "array_len", "array_neq", "array_sort", "array_to_slice", "array_to_slice_constant_length", "assert", "assert_statement", "assign_ex", "bigint", "bit_and", "bit_not", "bit_shifts_comptime", "bit_shifts_runtime", "blake3", "bool_not", "bool_or", "break_and_continue", "brillig_acir_as_brillig", "brillig_array_eq", "brillig_array_to_slice", "brillig_arrays", "brillig_assert", "brillig_bit_shifts_runtime", "brillig_blake2s", "brillig_blake3", "brillig_calls", "brillig_calls_array", "brillig_calls_conditionals", "brillig_conditional", "brillig_cow", "brillig_cow_assign", "brillig_cow_regression", "brillig_ecdsa_secp256k1", "brillig_ecdsa_secp256r1", "brillig_embedded_curve", "brillig_fns_as_values", "brillig_hash_to_field", "brillig_identity_function", "brillig_keccak", "brillig_loop", "brillig_nested_arrays", "brillig_not", "brillig_oracle", "brillig_pedersen", "brillig_recursion", "brillig_references", "brillig_schnorr", "brillig_sha256", "brillig_signed_cmp", "brillig_signed_div", "brillig_slices", "brillig_to_be_bytes", "brillig_to_bits", "brillig_to_bytes_integration", "brillig_to_le_bytes", "brillig_top_level", "brillig_uninitialized_arrays", "brillig_wrapping", "cast_bool", "closures_mut_ref", "conditional_1", "conditional_2", "conditional_regression_421", "conditional_regression_547", "conditional_regression_661", "conditional_regression_short_circuit", "conditional_regression_underflow", "custom_entry", "databus", "debug_logs", "diamond_deps_0", "double_verify_nested_proof", "double_verify_proof", "ecdsa_secp256k1", "ecdsa_secp256r1", "ecdsa_secp256r1_3x", "eddsa", "embedded_curve_ops", "field_attribute", "generics", "global_consts", "hash_to_field", "hashmap", "higher_order_functions", "if_else_chain", "import", "inline_never_basic", "integer_array_indexing", "keccak256", "main_bool_arg", "main_return", "merkle_insert", "missing_closure_env", "modules", "modules_more", "modulus", "nested_array_dynamic", "nested_array_dynamic_simple", "nested_array_in_slice", "nested_arrays_from_brillig", "no_predicates_basic", "no_predicates_brillig", "no_predicates_numeric_generic_poseidon", "operator_overloading", "pedersen_check", "pedersen_commitment", "pedersen_hash", "poseidon_bn254_hash", "poseidonsponge_x5_254", "pred_eq", "prelude", "references", "regression", "regression_2660", "regression_3051", "regression_3394", "regression_3607", "regression_3889", "regression_4088", "regression_4124", "regression_4202", "regression_4449", "regression_4709", "regression_5045", "regression_capacity_tracker", "regression_mem_op_predicate", "regression_method_cannot_be_found", "regression_struct_array_conditional", "schnorr", "sha256", "sha2_byte", "side_effects_constrain_array", "signed_arithmetic", "signed_comparison", "signed_division", "simple_2d_array", "simple_add_and_ret_arr", "simple_array_param", "simple_bitwise", "simple_comparison", "simple_mut", "simple_not", "simple_print", "simple_program_addition", "simple_radix", "simple_shield", "simple_shift_left_right", "slice_coercion", "slice_dynamic_index", "slice_loop", "slices", "strings", "struct", "struct_array_inputs", "struct_fields_ordering", "struct_inputs", "submodules", "to_be_bytes", "to_bytes_consistent", "to_bytes_integration", "to_le_bytes", "trait_as_return_type", "trait_impl_base_type", "traits_in_crates_1", "traits_in_crates_2", "tuple_inputs", "tuples", "type_aliases", "u128", "u16_support", "unconstrained_empty", "unit_value", "unsafe_range_constraint", "witness_compression", "xor"))
TEST_P(AcirIntegrationSingleTest, DISABLED_ProveAndVerifyProgram)
TEST_F(ClientIVCAPITests, DISABLED_ProveAndVerifyFileBasedFlow)
#define AVM_EXEC_OP_ID_ALU_TRUNCATE
#define AVM_EXEC_OP_ID_ALU_LTE
#define AVM_EXEC_OP_ID_ALU_DIV
#define AVM_EXEC_OP_ID_ALU_ADD
#define AVM_EXEC_OP_ID_ALU_SHL
#define AVM_EXEC_OP_ID_ALU_SUB
#define AVM_EXEC_OP_ID_ALU_MUL
#define AVM_EXEC_OP_ID_ALU_FDIV
#define AVM_EXEC_OP_ID_ALU_SHR
#define AVM_EXEC_OP_ID_ALU_LT
static TaggedValue from_tag(ValueTag tag, FF value)
static constexpr size_t SR_OP_ID_CHECK
static TestTraceContainer from_rows(const std::vector< AvmFullRow > &rows)
RangeCheckTraceBuilder range_check_builder
PrecomputedTraceBuilder precomputed_builder
FieldGreaterThanTraceBuilder field_gt_builder
GreaterThanTraceBuilder gt_builder
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
TEST_F(AvmRecursiveTests, GoblinRecursion)
A test of the Goblinized AVM recursive verifier.
TestTraceContainer empty_trace()
uint8_t get_tag_bits(ValueTag tag)
uint256_t get_tag_max_value(ValueTag tag)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::integral_constant< size_t, I > tag
constexpr auto tuple_cat(T &&... ts)
unsigned __int128 uint128_t
constexpr field invert() const noexcept