From ed632e4d98ae490dbbf5946c448adb0f5a642044 Mon Sep 17 00:00:00 2001 From: Suyash Bagad Date: Thu, 23 Mar 2023 11:09:12 +0000 Subject: [PATCH] no assertion is need since we anyway check the overflow in loop. --- .../stdlib/primitives/field/array.hpp | 8 ++-- .../stdlib/primitives/field/field.test.cpp | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/cpp/src/barretenberg/stdlib/primitives/field/array.hpp b/cpp/src/barretenberg/stdlib/primitives/field/array.hpp index 331756de30..5ed9ff32f7 100644 --- a/cpp/src/barretenberg/stdlib/primitives/field/array.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/field/array.hpp @@ -1,5 +1,6 @@ #pragma once #include "field.hpp" +#include "../safe_uint/safe_uint.hpp" #include "../bool/bool.hpp" namespace plonk { @@ -110,14 +111,11 @@ void push_array_to_array(std::array, size_1> const& source, // TODO: inefficient to get length this way within this function. Probably best to inline the checks that we need // into the below loops directly. field_t target_length = array_length(target); - field_t source_length = array_length(source); field_t target_capacity = field_t(target.size()); const field_t overflow_capacity = target_capacity + 1; - // TODO: using safe_uint for an underflow check, do: - // remaining_target_capacity = target_capacity.subtract(target_length + source_length); - - // ASSERT(target_capacity.get_value() + 1 > target_length.get_value() + source_length.get_value()); + // ASSERT(uint256_t(target_capacity.get_value()) + 1 > + // uint256_t(target_length.get_value()) + uint256_t(source_length.get_value())); field_t j_ct = 0; // circuit-type index for the inner loop field_t next_target_index = target_length; diff --git a/cpp/src/barretenberg/stdlib/primitives/field/field.test.cpp b/cpp/src/barretenberg/stdlib/primitives/field/field.test.cpp index 33dc6cceae..461f49b4ca 100644 --- a/cpp/src/barretenberg/stdlib/primitives/field/field.test.cpp +++ b/cpp/src/barretenberg/stdlib/primitives/field/field.test.cpp @@ -1196,6 +1196,44 @@ template class stdlib_field : public testing::Test { ASSERT(target[5].get_value() == 2); ASSERT(target[6].get_value() == 0); ASSERT(target[7].get_value() == 0); + + 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_push_array_to_array_full() + { + Composer composer = Composer(); + + std::array source = { 1, 2 }; + std::array target = { 3, 4, 6, 8, 7, 9, 5, 0 }; + std::array source_ct; + std::array target_ct; + for (size_t i = 0; i < source.size(); i++) { + source_ct[i] = witness_ct(&composer, source[i]); + } + for (size_t i = 0; i < target.size(); i++) { + target_ct[i] = witness_ct(&composer, target[i]); + } + + push_array_to_array(source_ct, target_ct); + + // Check that the target array is unchanged as the push operation failed + ASSERT(target_ct[0].get_value() == 3); + ASSERT(target_ct[1].get_value() == 4); + ASSERT(target_ct[2].get_value() == 6); + ASSERT(target_ct[3].get_value() == 8); + ASSERT(target_ct[4].get_value() == 7); + ASSERT(target_ct[5].get_value() == 9); + ASSERT(target_ct[6].get_value() == 5); + ASSERT(target_ct[7].get_value() == 0); + + EXPECT_EQ(composer.failed(), true); + EXPECT_EQ(composer.err(), "push_array_to_array target array capacity exceeded"); } }; @@ -1348,4 +1386,8 @@ TYPED_TEST(stdlib_field, test_array_push_array_to_array) { TestFixture::test_push_array_to_array(); } +TYPED_TEST(stdlib_field, test_array_push_array_to_array_full) +{ + TestFixture::test_push_array_to_array_full(); +} } // namespace test_stdlib_field