diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp index 97180856c6c6..06b1f20e5351 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.hpp @@ -83,6 +83,21 @@ class ClientIVC { return buffer; } + /** + * @brief Very quirky method to convert a msgpack buffer to a "heap" buffer + * @details This method results in a buffer that is double-size-prefixed with the buffer size. This is to mimmic + * the original bb.js behavior which did a *out_proof = to_heap_buffer(to_buffer(proof)); + * + * @return uint8_t* Double size-prefixed msgpack buffer + */ + uint8_t* to_msgpack_heap_buffer() const + { + msgpack::sbuffer buffer = to_msgpack_buffer(); + + std::vector buf(buffer.data(), buffer.data() + buffer.size()); + return to_heap_buffer(buf); + } + class DeserializationError : public std::runtime_error { public: DeserializationError(const std::string& msg) @@ -90,6 +105,16 @@ class ClientIVC { {} }; + static Proof from_msgpack_buffer(uint8_t const*& buffer) + { + auto uint8_buffer = from_buffer>(buffer); + + msgpack::sbuffer sbuf; + sbuf.write(reinterpret_cast(uint8_buffer.data()), uint8_buffer.size()); + + return from_msgpack_buffer(sbuf); + } + static Proof from_msgpack_buffer(const msgpack::sbuffer& buffer) { msgpack::object_handle oh = msgpack::unpack(buffer.data(), buffer.size()); diff --git a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp index 109f9893ba31..0e5d0dbac8da 100644 --- a/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp +++ b/barretenberg/cpp/src/barretenberg/client_ivc/client_ivc.test.cpp @@ -516,6 +516,34 @@ TEST_F(ClientIVCTests, MsgpackProofFromFile) EXPECT_TRUE(ivc.verify(proof_deserialized)); }; +/** + * @brief Test methods for serializing and deserializing a proof to/from a "heap" buffer in msgpack format + * + */ +TEST_F(ClientIVCTests, MsgpackProofFromBuffer) +{ + ClientIVC ivc; + + ClientIVCMockCircuitProducer circuit_producer; + + // Initialize the IVC with an arbitrary circuit + Builder circuit_0 = circuit_producer.create_next_circuit(ivc); + ivc.accumulate(circuit_0); + + // Create another circuit and accumulate + Builder circuit_1 = circuit_producer.create_next_circuit(ivc); + ivc.accumulate(circuit_1); + + const auto proof = ivc.prove(); + + // Serialize/deserialize proof to/from a heap buffer, check that it verifies + uint8_t const* buffer = proof.to_msgpack_heap_buffer(); + auto uint8_buffer = from_buffer>(buffer); + uint8_t const* uint8_ptr = uint8_buffer.data(); + auto proof_deserialized = ClientIVC::Proof::from_msgpack_buffer(uint8_ptr); + EXPECT_TRUE(ivc.verify(proof_deserialized)); +}; + /** * @brief Check that a CIVC proof can be serialized and deserialized via msgpack and that attempting to deserialize a * random buffer of bytes fails gracefully with a type error diff --git a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp index 6affe278fe71..e2ac38475cc6 100644 --- a/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp +++ b/barretenberg/cpp/src/barretenberg/dsl/acir_proofs/c_bind.cpp @@ -276,7 +276,7 @@ WASM_EXPORT void acir_prove_aztec_client(uint8_t const* acir_stack, vinfo("time to construct, accumulate, prove all circuits: ", diff.count()); start = std::chrono::steady_clock::now(); - *out_proof = to_heap_buffer(to_buffer(proof)); + *out_proof = proof.to_msgpack_heap_buffer(); end = std::chrono::steady_clock::now(); diff = std::chrono::duration_cast(end - start); vinfo("time to serialize proof: ", diff.count()); @@ -290,7 +290,7 @@ WASM_EXPORT void acir_prove_aztec_client(uint8_t const* acir_stack, WASM_EXPORT void acir_verify_aztec_client(uint8_t const* proof_buf, uint8_t const* vk_buf, bool* result) { - const auto proof = from_buffer(from_buffer>(proof_buf)); + const auto proof = ClientIVC::Proof::from_msgpack_buffer(proof_buf); const auto vk = from_buffer(from_buffer>(vk_buf)); // TODO(https://github.com/AztecProtocol/barretenberg/issues/1335): Should be able to remove this.