diff --git a/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp b/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp index 6dc3e4d2ed..3d32e63cd2 100644 --- a/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/bool/bool.test.cpp @@ -391,7 +391,26 @@ TEST(stdlib_bool, must_imply) EXPECT_EQ(result, true); } -// TODO: must_imply failure case +TEST(stdlib_bool, must_imply_fails) +{ + honk::StandardHonkComposer composer = honk::StandardHonkComposer(); + for (size_t j = 0; j < 3; ++j) { // ignore the case when both lhs and rhs are constants + bool lhs_constant = (bool)(j % 2); + bool rhs_constant = (bool)(j > 1 ? true : false); + + // If a number is divisible by 2 and 3, it is divisible by 6 + // => 8 is not divisible by 3, so it must not be divisible by 6 + const size_t i = 8; + bool a_val = (bool)(i % 2 == 0); + bool b_val = (bool)(i % 6 == 0); + bool_t a = lhs_constant ? bool_t(a_val) : (witness_t(&composer, a_val)); + bool_t b = rhs_constant ? bool_t(b_val) : (witness_t(&composer, b_val)); + a.must_imply(b, "div by 2 does not imply div by 8"); + + EXPECT_EQ(composer.failed(), true); + EXPECT_EQ(composer.err(), "div by 2 does not imply div by 8"); + } +} TEST(stdlib_bool, must_imply_multiple) { diff --git a/cpp/src/barretenberg/stdlib/primitives/field/array.test.cpp b/cpp/src/barretenberg/stdlib/primitives/field/array.test.cpp index cace1e5b56..8ad43f5e55 100644 --- a/cpp/src/barretenberg/stdlib/primitives/field/array.test.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/field/array.test.cpp @@ -29,8 +29,6 @@ template class stdlib_array : public testing::Test { typedef stdlib::public_witness_t public_witness_ct; public: - // TODO: empty array and singleton array edge cases for all array functions. - static void test_array_length() { Composer composer = Composer(); @@ -55,6 +53,23 @@ template class stdlib_array : public testing::Test { EXPECT_EQ(proof_result, true); } + static void test_array_length_null() + { + Composer composer = Composer(); + + std::array values_ct; + auto filled_len = array_length(values_ct); + EXPECT_EQ(filled_len.get_value(), 0); + EXPECT_TRUE(filled_len.is_constant()); + + auto prover = composer.create_prover(); + auto verifier = composer.create_verifier(); + auto proof = prover.construct_proof(); + info("composer gates = ", composer.get_num_gates()); + bool proof_result = verifier.verify_proof(proof); + EXPECT_EQ(proof_result, true); + } + static void test_array_length_fails() { Composer composer = Composer(); @@ -287,7 +302,7 @@ template class stdlib_array : public testing::Test { } bool proof_result = false; - if (composer.err().empty()) { + if (!composer.failed()) { auto prover = composer.create_prover(); auto verifier = composer.create_verifier(); auto proof = prover.construct_proof(); @@ -375,6 +390,36 @@ template class stdlib_array : public testing::Test { EXPECT_TRUE(proof_result); } + static void test_pata_null_source() + { + // null means array size is 0 + Composer composer = Composer(); + + std::array source; + std::array target = { 1, 2, 0, 0 }; + std::array expected_target = { 1, 2, 0, 0 }; + bool proof_result; + std::string error; + std::tie(proof_result, error) = test_push_array_to_array_helper(composer, source, target, expected_target); + + EXPECT_TRUE(proof_result); + } + + static void test_pata_null_target_fails() + { + Composer composer = Composer(); + + std::array source = { 1, 2, 0, 0 }; + std::array target; + std::array expected_target; + bool proof_result; + std::string error; + std::tie(proof_result, error) = test_push_array_to_array_helper(composer, source, target, expected_target); + + EXPECT_FALSE(proof_result); + EXPECT_EQ(error, "push_array_to_array target array capacity exceeded"); + } + static void test_pata_singletons_full_to_not_full() { Composer composer = Composer(); @@ -389,6 +434,35 @@ template class stdlib_array : public testing::Test { EXPECT_TRUE(proof_result); } + static void test_pata_singletons_not_full_to_full() + { + Composer composer = Composer(); + + std::array source = { 0 }; + std::array target = { 1 }; + std::array expected_target = { 1 }; + bool proof_result; + std::string error; + std::tie(proof_result, error) = test_push_array_to_array_helper(composer, source, target, expected_target); + + EXPECT_TRUE(proof_result); + } + + static void test_pata_singletons_full_to_full() + { + Composer composer = Composer(); + + std::array source = { 2 }; + std::array target = { 1 }; + std::array expected_target = { 1 }; + bool proof_result; + std::string error; + std::tie(proof_result, error) = test_push_array_to_array_helper(composer, source, target, expected_target); + + EXPECT_FALSE(proof_result); + EXPECT_EQ(error, "push_array_to_array target array capacity exceeded"); + } + static void test_pata_same_size_full_to_full_fails() { Composer composer = Composer(); @@ -559,6 +633,10 @@ TYPED_TEST(stdlib_array, test_array_length) { TestFixture::test_array_length(); } +TYPED_TEST(stdlib_array, test_array_length_null) +{ + TestFixture::test_array_length_null(); +} TYPED_TEST(stdlib_array, test_array_length_fails) { TestFixture::test_array_length_fails(); @@ -608,10 +686,26 @@ TYPED_TEST(stdlib_array, test_pata_smaller_source_full_to_not_full) { TestFixture::test_pata_smaller_source_full_to_not_full(); } +TYPED_TEST(stdlib_array, test_pata_null_source) +{ + TestFixture::test_pata_null_source(); +} +TYPED_TEST(stdlib_array, test_pata_null_target_fails) +{ + TestFixture::test_pata_null_target_fails(); +} TYPED_TEST(stdlib_array, test_pata_singletons_full_to_not_full) { TestFixture::test_pata_singletons_full_to_not_full(); } +TYPED_TEST(stdlib_array, test_pata_singletons_not_full_to_full) +{ + TestFixture::test_pata_singletons_not_full_to_full(); +} +TYPED_TEST(stdlib_array, test_pata_singletons_full_to_full) +{ + TestFixture::test_pata_singletons_full_to_full(); +} TYPED_TEST(stdlib_array, test_pata_same_size_full_to_full_fails) { TestFixture::test_pata_same_size_full_to_full_fails();