1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
32using testing::ElementsAre;
98 for (
const auto c : out) {
99 ThreeOperandTestParams params =
tuple_cat(TEST_VALUES_IN.at(i), std::make_tuple(c));
100 res.push_back(params);
109 res.reserve(in.size());
110 for (
const auto& c : in) {
116class AluTraceGenerationTest :
public ::testing::Test {
142class AluAddTraceGenerationTest :
public AluTraceGenerationTest,
143 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
147TEST_P(AluAddTraceGenerationTest, TraceGenerationAdd)
149 auto [
a,
b, c] = GetParam();
150 auto tag =
a.get_tag();
153 { .operation = AluOperation::ADD, .a =
a, .b =
b, .c = c },
177TEST_F(AluTraceGenerationTest, TraceGenerationAddTagError)
181 { .operation = AluOperation::ADD,
182 .a = MemoryValue::from<uint128_t>(1),
183 .b = MemoryValue::from<uint64_t>(2),
184 .c = MemoryValue::from<uint128_t>(3),
185 .error = AluError::TAG_ERROR },
186 { .operation = AluOperation::ADD,
187 .a = MemoryValue::from<uint128_t>(1),
188 .b = MemoryValue::from<uint128_t>(2),
189 .c = MemoryValue::from<uint64_t>(3) },
213 alu_ab_tags_diff_inv,
253class AluSubTraceGenerationTest :
public AluTraceGenerationTest,
254 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
258TEST_P(AluSubTraceGenerationTest, TraceGenerationSub)
260 auto [
a,
b, c] = GetParam();
261 auto tag =
a.get_tag();
264 { .operation = AluOperation::SUB, .a =
a, .b =
b, .c = c },
305class AluMulTraceGenerationTest :
public AluTraceGenerationTest,
306 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
310TEST_P(AluMulTraceGenerationTest, TraceGenerationMul)
312 auto [
a,
b, c] = GetParam();
313 auto tag =
a.get_tag();
325 cf = hi_operand != 0;
326 c_hi = (c_hi - hi_operand) % (
uint256_t(1) << 64);
330 { .operation = AluOperation::MUL, .a =
a, .b =
b, .c = c },
353 alu_tag_u128_diff_inv,
354 is_u128 ? 0 : (
FF(static_cast<uint8_t>(
tag)) -
FF(static_cast<uint8_t>(
MemoryTag::
U128))).invert()),
361TEST_F(AluTraceGenerationTest, TraceGenerationMulU128)
366 { .operation = AluOperation::MUL,
367 .a = MemoryValue::from<uint128_t>(2),
368 .b = MemoryValue::from<uint128_t>(3),
369 .c = MemoryValue::from<uint128_t>(6) },
370 { .operation = AluOperation::MUL,
371 .a = MemoryValue::from<uint128_t>(u128_max),
372 .b = MemoryValue::from<uint128_t>(u128_max - 2),
373 .c = MemoryValue::from<uint128_t>(3) },
452class AluDivTraceGenerationTest :
public AluTraceGenerationTest,
453 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
457TEST_P(AluDivTraceGenerationTest, TraceGenerationDiv)
459 auto [
a,
b, c] = GetParam();
460 auto tag =
a.get_tag();
461 bool div_0_error =
b.as_ff() ==
FF(0);
465 { .operation = AluOperation::DIV,
491 alu_tag_u128_diff_inv,
492 is_u128 ? 0 : (
FF(static_cast<uint8_t>(
tag)) -
FF(static_cast<uint8_t>(
MemoryTag::
U128))).invert()),
497 ROW_FIELD_EQ(alu_sel_div_no_0_err, div_0_error ? 0 : 1),
504TEST_F(AluTraceGenerationTest, TraceGenerationDivU128)
509 { .operation = AluOperation::DIV,
510 .a = MemoryValue::from<uint128_t>(6),
511 .b = MemoryValue::from<uint128_t>(3),
512 .c = MemoryValue::from<uint128_t>(2) },
513 { .operation = AluOperation::DIV,
514 .a = MemoryValue::from<uint128_t>(u128_max),
515 .b = MemoryValue::from<uint128_t>(u128_max - 2),
516 .c = MemoryValue::from<uint128_t>(1) },
574TEST_F(AluTraceGenerationTest, TraceGenerationDivTagError)
581 { .operation = AluOperation::DIV,
582 .a = MemoryValue::from<FF>(6),
583 .b = MemoryValue::from<FF>(3),
584 .c = MemoryValue::from<FF>(2),
585 .error = AluError::TAG_ERROR },
586 { .operation = AluOperation::DIV,
587 .a = MemoryValue::from<FF>(6),
588 .b = MemoryValue::from<uint128_t>(3),
589 .c = MemoryValue::from<FF>(2),
590 .error = AluError::TAG_ERROR },
612 alu_tag_u128_diff_inv,
637 alu_tag_u128_diff_inv,
646 alu_ab_tags_diff_inv,
650TEST_F(AluTraceGenerationTest, TraceGenerationDivByZeroError)
654 { .operation = AluOperation::DIV,
655 .a = MemoryValue::from<uint64_t>(6),
656 .b = MemoryValue::from<uint64_t>(0),
657 .error = AluError::DIV_0_ERROR },
679 alu_tag_u128_diff_inv,
714class AluFDivTraceGenerationTest :
public AluTraceGenerationTest,
715 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
719TEST_P(AluFDivTraceGenerationTest, TraceGenerationFDiv)
721 auto [
a,
b, c] = GetParam();
725 auto tag =
a.get_tag();
727 bool div_0_error =
b.as_ff() ==
FF(0);
731 { .operation = AluOperation::FDIV,
760TEST_F(AluTraceGenerationTest, TraceGenerationFDivTagError)
767 { .operation = AluOperation::FDIV,
768 .a = MemoryValue::from<uint128_t>(6),
769 .b = MemoryValue::from<uint128_t>(3),
770 .c = MemoryValue::from<uint128_t>(2),
771 .error = AluError::TAG_ERROR },
772 { .operation = AluOperation::FDIV,
773 .a = MemoryValue::from<uint64_t>(6),
774 .b = MemoryValue::from<FF>(3),
775 .c = MemoryValue::from<uint64_t>(2),
776 .error = AluError::TAG_ERROR },
826TEST_F(AluTraceGenerationTest, TraceGenerationFDivByZeroError)
830 { .operation = AluOperation::FDIV,
831 .a = MemoryValue::from<FF>(6),
832 .b = MemoryValue::from<FF>(0),
833 .error = AluError::DIV_0_ERROR },
872class AluEQTraceGenerationTest :
public AluTraceGenerationTest,
873 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
877TEST_P(AluEQTraceGenerationTest, TraceGenerationEQ)
879 auto [
a, _b, _c] = GetParam();
880 auto tag =
a.get_tag();
885 .operation = AluOperation::EQ,
908TEST_P(AluEQTraceGenerationTest, TraceGenerationInEQ)
910 auto [
a,
b, c] = GetParam();
911 auto tag =
a.get_tag();
916 .operation = AluOperation::EQ,
931 ROW_FIELD_EQ(alu_ab_diff_inv, c.as_ff() == 1 ? 0 : (
a.as_ff() -
b.as_ff()).invert()),
953class AluLTTraceGenerationTest :
public AluTraceGenerationTest,
954 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
958TEST_P(AluLTTraceGenerationTest, TraceGenerationLT)
960 auto [
a,
b, c] = GetParam();
961 auto tag =
a.get_tag();
965 { .operation = AluOperation::LT, .a =
a, .b =
b, .c = c },
992 is_ff ? 0 : (
FF(static_cast<uint8_t>(
tag)) -
FF(static_cast<uint8_t>(
MemoryTag::
FF))).invert()),
1011class AluLTETraceGenerationTest :
public AluTraceGenerationTest,
1012 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
1016TEST_P(AluLTETraceGenerationTest, TraceGenerationLTE)
1018 auto [
a,
b, c] = GetParam();
1019 auto tag =
a.get_tag();
1023 { .operation = AluOperation::LTE, .a =
a, .b =
b, .c = c },
1042 ROW_FIELD_EQ(alu_lt_ops_result_c, c.as_ff() == 1 ? 0 : 1),
1049 alu_tag_ff_diff_inv,
1050 is_ff ? 0 : (
FF(static_cast<uint8_t>(
tag)) -
FF(static_cast<uint8_t>(
MemoryTag::
FF))).invert()),
1059class AluNOTTraceGenerationTest :
public AluTraceGenerationTest,
public ::testing::WithParamInterface<MemoryValue> {};
1063TEST_P(AluNOTTraceGenerationTest, TraceGenerationNOT)
1065 auto a = GetParam();
1066 auto tag =
a.get_tag();
1072 { .operation = AluOperation::NOT,
1093 alu_tag_ff_diff_inv,
1094 is_ff ? 0 : (
FF(static_cast<uint8_t>(
tag)) -
FF(static_cast<uint8_t>(
MemoryTag::
FF))).invert()),
1118class AluShlTraceGenerationTest :
public AluTraceGenerationTest,
1119 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
1123TEST_P(AluShlTraceGenerationTest, TraceGenerationShl)
1125 auto [
a,
b, c] = GetParam();
1126 auto tag =
a.get_tag();
1128 auto b_num =
static_cast<uint128_t>(
b.as_ff());
1130 auto overflow = b_num > tag_bits;
1131 uint128_t shift_lo_bits = overflow ? tag_bits : tag_bits - b_num;
1132 uint128_t shift_hi_bits = overflow ? tag_bits : b_num;
1133 auto two_pow_shift_lo_bits =
static_cast<uint128_t>(1) << shift_lo_bits;
1134 auto a_lo = overflow ? b_num - tag_bits :
static_cast<uint128_t>(
a.as_ff()) % two_pow_shift_lo_bits;
1135 auto a_hi =
static_cast<uint128_t>(
a.as_ff()) >> shift_lo_bits;
1138 .operation = AluOperation::SHL,
1166 (
FF(
static_cast<uint8_t
>(tag)) -
FF(
static_cast<uint8_t
>(
MemoryTag::FF))).invert()),
1168 ROW_FIELD_EQ(alu_sel_shift_ops_no_overflow, overflow ? 0 : 1),
1170 ROW_FIELD_EQ(alu_two_pow_shift_lo_bits, two_pow_shift_lo_bits),
1176TEST_F(AluShlTraceGenerationTest, TraceGenerationShlTagError)
1183 { .operation = AluOperation::SHL,
1184 .a = MemoryValue::from<FF>(6),
1185 .b = MemoryValue::from<FF>(3),
1186 .c = MemoryValue::from<FF>(48),
1187 .error = AluError::TAG_ERROR },
1188 { .operation = AluOperation::SHL,
1189 .a = MemoryValue::from<FF>(6),
1190 .b = MemoryValue::from<uint128_t>(3),
1191 .c = MemoryValue::from<FF>(48),
1192 .error = AluError::TAG_ERROR },
1257class AluShrTraceGenerationTest :
public AluTraceGenerationTest,
1258 public ::testing::WithParamInterface<ThreeOperandTestParams> {};
1262TEST_P(AluShrTraceGenerationTest, TraceGenerationShr)
1264 auto [
a,
b, c] = GetParam();
1265 auto tag =
a.get_tag();
1267 auto b_num =
static_cast<uint128_t>(
b.as_ff());
1269 auto overflow = b_num > tag_bits;
1270 uint128_t shift_lo_bits = overflow ? tag_bits : b_num;
1271 uint128_t shift_hi_bits = overflow ? tag_bits : tag_bits - b_num;
1272 auto two_pow_shift_lo_bits =
static_cast<uint128_t>(1) << shift_lo_bits;
1273 auto a_lo = overflow ? b_num - tag_bits :
static_cast<uint128_t>(
a.as_ff()) % two_pow_shift_lo_bits;
1274 auto a_hi =
static_cast<uint128_t>(
a.as_ff()) >> shift_lo_bits;
1277 .operation = AluOperation::SHR,
1304 (
FF(
static_cast<uint8_t
>(tag)) -
FF(
static_cast<uint8_t
>(
MemoryTag::FF))).invert()),
1306 ROW_FIELD_EQ(alu_sel_shift_ops_no_overflow, overflow ? 0 : 1),
1308 ROW_FIELD_EQ(alu_two_pow_shift_lo_bits, two_pow_shift_lo_bits),
1314TEST_F(AluShrTraceGenerationTest, TraceGenerationShrTagError)
1321 { .operation = AluOperation::SHR,
1322 .a = MemoryValue::from<FF>(6),
1323 .b = MemoryValue::from<FF>(3),
1324 .c = MemoryValue::from<FF>(0),
1325 .error = AluError::TAG_ERROR },
1326 { .operation = AluOperation::SHR,
1327 .a = MemoryValue::from<FF>(6),
1328 .b = MemoryValue::from<uint128_t>(3),
1329 .c = MemoryValue::from<FF>(0),
1330 .error = AluError::TAG_ERROR },
1376struct TruncateTrivialTestParams {
1386 .expected_result = 1,
1391 .expected_result = 7,
1396 .expected_result = 123456789,
1401 .expected_result = 1234567890123456789ULL,
1406 .expected_result = (
uint256_t(1) << 127) + 982739482,
1415class AluTruncateTrivialTraceGenerationTest :
public AluTraceGenerationTest,
1416 public ::testing::WithParamInterface<TruncateTrivialTestParams> {};
1419 AluTruncateTrivialTraceGenerationTest,
1420 ::testing::ValuesIn(TRUNCATE_TRIVIAL_TEST_PARAMS));
1422TEST_P(AluTruncateTrivialTraceGenerationTest, TraceGenerationTruncateTrivial)
1430 { .operation = AluOperation::TRUNCATE, .a =
a, .b =
b, .c = c },
1435 ElementsAre(AllOf(
ROW_FIELD_EQ(alu_sel_op_truncate, 1),
1454struct TruncateNonTrivialTestParams {
1467 .expected_result = 123456789987654321ULL,
1468 .expected_lo_128 = (
uint256_t(98263) << 64) + 123456789987654321ULL,
1475 .expected_result = 1234567,
1476 .expected_lo_128 = (98263ULL << 32) + 1234567ULL,
1483 .expected_result = 1234,
1484 .expected_lo_128 = (98263ULL << 32) + 1234ULL,
1491 .expected_result = 7,
1492 .expected_lo_128 = 263,
1493 .expected_hi_128 = 0,
1499 .expected_result = 1,
1500 .expected_lo_128 = 999,
1501 .expected_hi_128 = 0,
1502 .expected_mid = 499,
1506class AluTruncateNonTrivialLT128TraceGenerationTest
1507 :
public AluTraceGenerationTest,
1508 public ::testing::WithParamInterface<TruncateNonTrivialTestParams> {};
1511 AluTruncateNonTrivialLT128TraceGenerationTest,
1512 ::testing::ValuesIn(TRUNCATE_LESS_THAN_128_TEST_PARAMS));
1514TEST_P(AluTruncateNonTrivialLT128TraceGenerationTest, TraceGenerationTruncateNonTrivialLT128)
1522 { .operation = AluOperation::TRUNCATE, .a =
a, .b =
b, .c = c },
1527 ElementsAre(AllOf(
ROW_FIELD_EQ(alu_sel_op_truncate, 1),
1548 .a = MemoryValue::from<FF>((
uint256_t(98263) << 128) + (
uint256_t(1111) << 64) + 123456789987654321ULL),
1550 .expected_result = 123456789987654321ULL,
1551 .expected_lo_128 = (
uint256_t(1111) << 64) + 123456789987654321ULL,
1556 .a = MemoryValue::from<FF>((
uint256_t(98263) << 128) + (
uint256_t(1111) << 64) + 123456789),
1558 .expected_result = 123456789,
1559 .expected_lo_128 = (
uint256_t(1111) << 64) + 123456789,
1564 .a = MemoryValue::from<FF>((
uint256_t(98263) << 128) + (
uint256_t(1111) << 64) + 1234),
1566 .expected_result = 1234,
1567 .expected_lo_128 = (
uint256_t(1111) << 64) + 1234,
1572 .a = MemoryValue::from<FF>((
uint256_t(98263) << 150) + (
uint256_t(123456789987654321ULL) << 8) + 234),
1574 .expected_result = 234,
1575 .expected_lo_128 = (
uint256_t(123456789987654321ULL) << 8) + 234,
1581class AluTruncateNonTrivialGT128TraceGenerationTest
1582 :
public AluTraceGenerationTest,
1583 public ::testing::WithParamInterface<TruncateNonTrivialTestParams> {};
1586 AluTruncateNonTrivialGT128TraceGenerationTest,
1587 ::testing::ValuesIn(TRUNCATE_GREATER_THAN_128_TEST_PARAMS));
1589TEST_P(AluTruncateNonTrivialGT128TraceGenerationTest, TraceGenerationTruncateNonTrivialGT128)
1597 { .operation = AluOperation::TRUNCATE, .a =
a, .b =
b, .c = c },
1602 ElementsAre(AllOf(
ROW_FIELD_EQ(alu_sel_op_truncate, 1),
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)
#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_EQ
#define AVM_EXEC_OP_ID_ALU_SUB
#define AVM_EXEC_OP_ID_ALU_NOT
#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)
void process(const simulation::EventEmitterInterface< simulation::AluEvent >::Container &events, TraceContainer &trace)
std::vector< AvmFullRowConstRef > as_rows() const
#define ROW_FIELD_EQ(field_name, expression)
U256Decomposition decompose(const uint256_t &x)
uint8_t get_tag_bits(ValueTag tag)
uint256_t get_tag_max_value(ValueTag tag)
TEST_F(IPATest, ChallengesAreZero)
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
static constexpr uint256_t modulus