diff --git a/cpp/barretenberg b/cpp/barretenberg index 303eaf6e169..d09037f5b75 160000 --- a/cpp/barretenberg +++ b/cpp/barretenberg @@ -1 +1 @@ -Subproject commit 303eaf6e169acede64046a465146aab67036ab43 +Subproject commit d09037f5b75811f148a5884de92bfeb482db4803 diff --git a/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 2d11b2d2038..ecc4642ddf3 100644 --- a/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -637,167 +637,7 @@ TEST(private_kernel_tests, test_basic_contract_deployment) info("n: ", private_kernel_composer.num_gates); } -TEST(private_kernel_tests, test_create_proof_cbind_circuit) -{ - //*************************************************************************** - // Some private CIRCUIT proof (`constructor`, in this case) - // and the cbind to generate it - //*************************************************************************** - - const NT::address new_contract_address = 12345; - // const NT::fr new_contract_leaf_index = 1; - const NT::fr new_portal_contract_address = 23456; - - const NT::fr msg_sender_private_key = 123456789; - const NT::address msg_sender = - NT::fr(uint256_t(0x01071e9a23e0f7edULL, 0x5d77b35d1830fa3eULL, 0xc6ba3660bb1f0c0bULL, 0x2ef9f7f09867fd6eULL)); - const NT::address tx_origin = msg_sender; - - Composer constructor_composer = Composer("../barretenberg/cpp/srs_db/ignition"); - DB db; - - FunctionData function_data{ - .function_selector = 1, // TODO: deduce this from the contract, somehow. - .is_private = true, - .is_constructor = true, - }; - - CallContext call_context{ - .msg_sender = msg_sender, - .storage_contract_address = new_contract_address, - .tx_origin = msg_sender, - .is_delegate_call = false, - .is_static_call = false, - .is_contract_deployment = true, - }; - - NativeOracle constructor_oracle = - NativeOracle(db, new_contract_address, function_data, call_context, msg_sender_private_key); - OracleWrapper constructor_oracle_wrapper = OracleWrapper(constructor_composer, constructor_oracle); - - FunctionExecutionContext constructor_ctx(constructor_composer, constructor_oracle_wrapper); - - auto arg0 = NT::fr(5); - auto arg1 = NT::fr(1); - auto arg2 = NT::fr(999); - - OptionalPrivateCircuitPublicInputs opt_constructor_public_inputs = - constructor(constructor_ctx, arg0, arg1, arg2); - - ContractDeploymentData contract_deployment_data{ - .constructor_vk_hash = 0, // TODO actually get this? - .function_tree_root = 0, // TODO actually get this? - .contract_address_salt = 42, - .portal_contract_address = new_portal_contract_address, - }; - opt_constructor_public_inputs.contract_deployment_data = contract_deployment_data; - - PrivateCircuitPublicInputs constructor_public_inputs = opt_constructor_public_inputs.remove_optionality(); - - Prover constructor_prover = constructor_composer.create_prover(); - NT::Proof constructor_proof = constructor_prover.construct_proof(); - // info("\nconstructor_proof: ", constructor_proof.proof_data); - - std::shared_ptr constructor_vk = constructor_composer.compute_verification_key(); - - //*************************************************************************** - // We can create a TxRequest from some of the above data. Users must sign a TxRequest in order to give permission - // for a tx to take place - creating a SignedTxRequest. - //*************************************************************************** - - TxRequest constructor_tx_request = TxRequest{ - .from = tx_origin, - .to = new_contract_address, - .function_data = function_data, - .args = constructor_public_inputs.args, - .nonce = 0, - .tx_context = - TxContext{ - .is_fee_payment_tx = false, - .is_rebate_payment_tx = false, - .is_contract_deployment_tx = false, - .contract_deployment_data = contract_deployment_data, - }, - .chain_id = 1, - }; - - SignedTxRequest signed_constructor_tx_request = SignedTxRequest{ - .tx_request = constructor_tx_request, - - // .signature = TODO: need a method for signing a TxRequest. - }; - - //*************************************************************************** - // We mock a kernel circuit proof for the base case of kernel recursion (because even the first iteration of the - // kernel circuit expects to verify some previous kernel circuit). - //*************************************************************************** - - Composer mock_kernel_composer = Composer("../barretenberg/cpp/srs_db/ignition"); - - // TODO: we have a choice to make: - // Either the `end` state of the mock kernel's public inputs can be set equal to the public call we _want_ to - // verify in the first round of recursion, OR, we have some fiddly conditional logic in the circuit to ignore - // certain checks if we're handling the 'base case' of the recursion. - // I've chosen the former, for now. - const CallStackItem constructor_call_stack_item{ - .contract_address = constructor_tx_request.to, - - .function_data = constructor_tx_request.function_data, - - .public_inputs = constructor_public_inputs, - }; - - std::array initial_kernel_private_call_stack{}; - initial_kernel_private_call_stack[0] = constructor_call_stack_item.hash(); - - uint8_t const* pk_buf; - size_t pk_size = private_kernel__init_proving_key(&pk_buf); - info("Proving key size: ", pk_size); - - uint8_t const* vk_buf; - size_t vk_size = private_kernel__init_verification_key(pk_buf, &vk_buf); - info("Verification key size: ", vk_size); - - std::vector signed_constructor_tx_request_vec; - write(signed_constructor_tx_request_vec, signed_constructor_tx_request); - - PrivateCallData private_constructor_call = PrivateCallData{ - .call_stack_item = constructor_call_stack_item, - .private_call_stack_preimages = constructor_ctx.get_private_call_stack_items(), - - .proof = constructor_proof, - .vk = constructor_vk, - - // .function_leaf_membership_witness TODO - // .contract_leaf_membership_witness TODO - - .portal_contract_address = new_portal_contract_address, - }; - std::vector private_constructor_call_vec; - write(private_constructor_call_vec, private_constructor_call); - - uint8_t const* proof_data; - size_t proof_data_size; - uint8_t const* public_inputs; - info("creating proof"); - size_t public_inputs_size = private_kernel__create_proof(signed_constructor_tx_request_vec.data(), - pk_buf, - private_constructor_call_vec.data(), - pk_buf, - false, // proverless - &proof_data, - &proof_data_size, - &public_inputs); - info("Proof size: ", proof_data_size); - info("PublicInputs size: ", public_inputs_size); - - free((void*)pk_buf); - free((void*)vk_buf); - free((void*)proof_data); - free((void*)public_inputs); -} - -TEST(private_kernel_tests, test_create_proof_cbind_native) +TEST(private_kernel_tests, test_create_proof_cbinds) { //*************************************************************************** // Some private NATIVE mocked proof (`constructor`, in this case) @@ -937,17 +777,21 @@ TEST(private_kernel_tests, test_create_proof_cbind_native) write(private_constructor_call_vec, private_constructor_call); uint8_t const* proof_data; - size_t proof_data_size; uint8_t const* public_inputs; - info("creating proof"); - size_t public_inputs_size = private_kernel__create_proof(signed_constructor_tx_request_vec.data(), - pk_buf, - private_constructor_call_vec.data(), - pk_buf, - true, // proverless - &proof_data, - &proof_data_size, - &public_inputs); + info("Simulating to generate public inputs..."); + size_t public_inputs_size = private_kernel__sim(signed_constructor_tx_request_vec.data(), + nullptr, // no previous kernel on first iteration + private_constructor_call_vec.data(), + true, // first iteration + &public_inputs); + + info("Proving"); + size_t proof_data_size = private_kernel__prove(signed_constructor_tx_request_vec.data(), + nullptr, + private_constructor_call_vec.data(), + pk_buf, + true, // first iteration + &proof_data); info("Proof size: ", proof_data_size); info("PublicInputs size: ", public_inputs_size); @@ -957,6 +801,4 @@ TEST(private_kernel_tests, test_create_proof_cbind_native) free((void*)public_inputs); } - - } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index 69322ddf00e..9ad0bbe4fa5 100644 --- a/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -1,7 +1,9 @@ #include "index.hpp" #include "init.hpp" +#include "utils.hpp" #include "c_bind.h" +// TODO remove these? present in init/index? #include #include #include "aztec3/circuits/abis/signed_tx_request.hpp" @@ -18,16 +20,22 @@ namespace { using NT = aztec3::utils::types::NativeTypes; using aztec3::circuits::abis::SignedTxRequest; +using aztec3::circuits::abis::TxContext; +using aztec3::circuits::abis::private_kernel::AccumulatedData; +using aztec3::circuits::abis::private_kernel::ConstantData; +using aztec3::circuits::abis::private_kernel::OldTreeRoots; using aztec3::circuits::abis::private_kernel::PreviousKernelData; using aztec3::circuits::abis::private_kernel::PrivateCallData; using aztec3::circuits::abis::private_kernel::PrivateInputs; using aztec3::circuits::abis::private_kernel::PublicInputs; using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::private_kernel_circuit; +using aztec3::circuits::kernel::private_kernel::utils::default_previous_kernel; using aztec3::circuits::mock::mock_kernel_circuit; using plonk::TurboComposer; using namespace plonk::stdlib::types; + } // namespace #define WASM_EXPORT __attribute__((visibility("default"))) @@ -63,16 +71,59 @@ WASM_EXPORT size_t private_kernel__init_verification_key(uint8_t const* pk_buf, // TODO comment about how public_inputs is a confusing name // returns size of public inputs -WASM_EXPORT size_t private_kernel__create_proof(uint8_t const* signed_tx_request_buf, - uint8_t const* previous_kernel_buf, - uint8_t const* private_call_buf, - uint8_t const* pk_buf, - bool proverless, - uint8_t const** proof_data_buf, - size_t* proof_data_size, - uint8_t const** private_kernel_public_inputs_buf) +WASM_EXPORT size_t private_kernel__sim(uint8_t const* signed_tx_request_buf, + uint8_t const* previous_kernel_buf, + uint8_t const* private_call_buf, + bool first_iteration, + uint8_t const** private_kernel_public_inputs_buf) +{ + SignedTxRequest signed_tx_request; + read(signed_tx_request_buf, signed_tx_request); + + PrivateCallData private_call_data; + read(private_call_buf, private_call_data); + + PreviousKernelData previous_kernel; + if (first_iteration) { + previous_kernel = default_previous_kernel(); + + previous_kernel.public_inputs.end.private_call_stack[0] = private_call_data.call_stack_item.hash(); + previous_kernel.public_inputs.constants.old_tree_roots.private_data_tree_root = + private_call_data.call_stack_item.public_inputs.historic_private_data_tree_root; + previous_kernel.public_inputs.constants.tx_context = signed_tx_request.tx_request.tx_context; + previous_kernel.public_inputs.is_private = true; + } else { + read(previous_kernel_buf, previous_kernel); + } + + PrivateInputs private_inputs = PrivateInputs{ + .signed_tx_request = signed_tx_request, + .previous_kernel = previous_kernel, + .private_call = private_call_data, + + }; + + PublicInputs public_inputs = native_private_kernel_circuit(private_inputs); + + // serialize public inputs to bytes vec + std::vector public_inputs_vec; + write(public_inputs_vec, public_inputs); + // copy public inputs to output buffer + auto raw_public_inputs_buf = (uint8_t*)malloc(public_inputs_vec.size()); + memcpy(raw_public_inputs_buf, (void*)public_inputs_vec.data(), public_inputs_vec.size()); + *private_kernel_public_inputs_buf = raw_public_inputs_buf; + + return public_inputs_vec.size(); +} + +// returns size of proof data +WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, + uint8_t const* previous_kernel_buf, + uint8_t const* private_call_buf, + uint8_t const* pk_buf, + bool first_iteration, + uint8_t const** proof_data_buf) { - info(previous_kernel_buf); // TODO accept proving key and use that to initialize composers // this info is just to prevent error for unused pk_buf // TODO do we want to accept it or just get it from our factory? @@ -85,75 +136,45 @@ WASM_EXPORT size_t private_kernel__create_proof(uint8_t const* signed_tx_request PrivateCallData private_call_data; read(private_call_buf, private_call_data); - std::array initial_kernel_private_call_stack{}; - initial_kernel_private_call_stack[0] = private_call_data.call_stack_item.hash(); + PreviousKernelData previous_kernel; + if (first_iteration) { + previous_kernel = default_previous_kernel(); - auto mock_kernel_public_inputs = PublicInputs(); - mock_kernel_public_inputs.end.private_call_stack = initial_kernel_private_call_stack, - // TODO who should inject this? C++ or cbind? - mock_kernel_public_inputs.constants.old_tree_roots.private_data_tree_root = + previous_kernel.public_inputs.end.private_call_stack[0] = private_call_data.call_stack_item.hash(); + previous_kernel.public_inputs.constants.old_tree_roots.private_data_tree_root = private_call_data.call_stack_item.public_inputs.historic_private_data_tree_root; - mock_kernel_public_inputs.constants.tx_context = signed_tx_request.tx_request.tx_context; - mock_kernel_public_inputs.is_private = true; - - // FIXME composer doesn't work in wasm - Composer mock_kernel_composer = Composer(crs_factory); - mock_kernel_circuit(mock_kernel_composer, mock_kernel_public_inputs); - - plonk::stdlib::types::Prover mock_kernel_prover = mock_kernel_composer.create_prover(); - NT::Proof mock_kernel_proof = mock_kernel_prover.construct_proof(); - - std::shared_ptr mock_kernel_vk = mock_kernel_composer.compute_verification_key(); - + previous_kernel.public_inputs.constants.tx_context = signed_tx_request.tx_request.tx_context; + previous_kernel.public_inputs.is_private = true; + } else { + read(previous_kernel_buf, previous_kernel); + } PrivateInputs private_inputs = PrivateInputs{ .signed_tx_request = signed_tx_request, - .previous_kernel = - PreviousKernelData{ - .public_inputs = mock_kernel_public_inputs, - .proof = mock_kernel_proof, - .vk = mock_kernel_vk, - }, + .previous_kernel = previous_kernel, .private_call = private_call_data, - }; - NT::Proof private_kernel_proof; + Composer private_kernel_composer = Composer(crs_factory); + plonk::stdlib::types::Prover private_kernel_prover = private_kernel_composer.create_prover(); + PublicInputs public_inputs; - if (proverless) { - public_inputs = native_private_kernel_circuit(private_inputs); - // mocked proof - zeros - private_kernel_proof = NT::Proof{ std::vector(42, 0) }; - } else { - Composer private_kernel_composer = Composer(crs_factory); - plonk::stdlib::types::Prover private_kernel_prover = private_kernel_composer.create_prover(); - public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); - private_kernel_proof = private_kernel_prover.construct_proof(); - } + public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); + NT::Proof private_kernel_proof; + private_kernel_proof = private_kernel_prover.construct_proof(); // copy proof data to output buffer auto raw_proof_buf = (uint8_t*)malloc(private_kernel_proof.proof_data.size()); memcpy(raw_proof_buf, (void*)private_kernel_proof.proof_data.data(), private_kernel_proof.proof_data.size()); *proof_data_buf = raw_proof_buf; - // copy proof data size to output - *proof_data_size = private_kernel_proof.proof_data.size(); - - // serialize public inputs to bytes vec - std::vector public_inputs_vec; - write(public_inputs_vec, public_inputs); - // copy public inputs to output buffer - auto raw_public_inputs_buf = (uint8_t*)malloc(public_inputs_vec.size()); - memcpy(raw_public_inputs_buf, (void*)public_inputs_vec.data(), public_inputs_vec.size()); - *private_kernel_public_inputs_buf = raw_public_inputs_buf; - return private_kernel_proof.proof_data.size(); } WASM_EXPORT size_t private_kernel__verify_proof(uint8_t const* vk_buf, uint8_t const* proof, uint32_t length) { - info(vk_buf); - info(proof); - info(length); + (void)vk_buf; // unused + (void)proof; // unused + (void)length; // unused return true; } diff --git a/cpp/src/aztec3/circuits/kernel/private/c_bind.h b/cpp/src/aztec3/circuits/kernel/private/c_bind.h index 08fbf39876a..96c63d26648 100644 --- a/cpp/src/aztec3/circuits/kernel/private/c_bind.h +++ b/cpp/src/aztec3/circuits/kernel/private/c_bind.h @@ -7,15 +7,17 @@ extern "C" { WASM_EXPORT size_t private_kernel__init_proving_key(uint8_t const** pk_buf); WASM_EXPORT size_t private_kernel__init_verification_key(uint8_t const* pk_buf, uint8_t const** vk_buf); -//WASM_EXPORT size_t private_kernel__get_default_previous_kernel(uint8_t const** previous_kernel_data); -WASM_EXPORT size_t private_kernel__create_proof(uint8_t const* signed_tx_request_buf, - uint8_t const* previous_kernel_buf, - uint8_t const* private_call_buf, - uint8_t const* pk_buf, - bool proverless, - uint8_t const** proof_data_buf, - size_t* proof_data_size, - uint8_t const** private_kernel_public_inputs_buf); +WASM_EXPORT size_t private_kernel__sim(uint8_t const* signed_tx_request_buf, + uint8_t const* previous_kernel_buf, + uint8_t const* private_call_buf, + bool first_iteration, + uint8_t const** private_kernel_public_inputs_buf); +WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, + uint8_t const* previous_kernel_buf, + uint8_t const* private_call_buf, + uint8_t const* pk_buf, + bool first, + uint8_t const** proof_data_buf); WASM_EXPORT size_t private_kernel__verify_proof(uint8_t const* vk_buf, uint8_t const* proof, uint32_t length); diff --git a/cpp/src/aztec3/circuits/kernel/private/utils.cpp b/cpp/src/aztec3/circuits/kernel/private/utils.cpp new file mode 100644 index 00000000000..6825beee541 --- /dev/null +++ b/cpp/src/aztec3/circuits/kernel/private/utils.cpp @@ -0,0 +1,43 @@ +#include "index.hpp" +#include "init.hpp" + +#include + +namespace { +using NT = aztec3::utils::types::NativeTypes; +using aztec3::circuits::abis::private_kernel::PreviousKernelData; +using aztec3::circuits::abis::private_kernel::PublicInputs; +using aztec3::circuits::mock::mock_kernel_circuit; + +using plonk::TurboComposer; +using namespace plonk::stdlib::types; + +} // namespace + +namespace aztec3::circuits::kernel::private_kernel::utils { + +// TODO rename dummy +PreviousKernelData default_previous_kernel() +{ + // TODO confirm this is the right way to initialize struct of 0s + auto mock_kernel_public_inputs = PublicInputs(); + mock_kernel_public_inputs.is_private = true; + + auto crs_factory = std::make_shared(); + Composer mock_kernel_composer = Composer(crs_factory); + mock_kernel_circuit(mock_kernel_composer, mock_kernel_public_inputs); + + plonk::stdlib::types::Prover mock_kernel_prover = mock_kernel_composer.create_prover(); + NT::Proof mock_kernel_proof = mock_kernel_prover.construct_proof(); + + std::shared_ptr mock_kernel_vk = mock_kernel_composer.compute_verification_key(); + + PreviousKernelData previous_kernel = { + .public_inputs = mock_kernel_public_inputs, + .proof = mock_kernel_proof, + .vk = mock_kernel_vk, + }; + return previous_kernel; +} + +} // namespace aztec3::circuits::kernel::private_kernel::utils \ No newline at end of file diff --git a/cpp/src/aztec3/circuits/kernel/private/utils.hpp b/cpp/src/aztec3/circuits/kernel/private/utils.hpp new file mode 100644 index 00000000000..79c06b1ad00 --- /dev/null +++ b/cpp/src/aztec3/circuits/kernel/private/utils.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "index.hpp" +#include "init.hpp" + +namespace { +using NT = aztec3::utils::types::NativeTypes; +using aztec3::circuits::abis::private_kernel::PreviousKernelData; +using namespace plonk::stdlib::types; +} // namespace + +namespace aztec3::circuits::kernel::private_kernel::utils { + +// TODO rename dummy +PreviousKernelData default_previous_kernel(); + +} // namespace aztec3::circuits::kernel::private_kernel::utils \ No newline at end of file diff --git a/cpp/src/aztec3/circuits/recursion/aggregator.hpp b/cpp/src/aztec3/circuits/recursion/aggregator.hpp index 62f0c91af97..801bb9d733a 100644 --- a/cpp/src/aztec3/circuits/recursion/aggregator.hpp +++ b/cpp/src/aztec3/circuits/recursion/aggregator.hpp @@ -1,3 +1,4 @@ +#pragma once #include #include #include diff --git a/cpp/src/aztec3/circuits/rollup/CMakeLists.txt b/cpp/src/aztec3/circuits/rollup/CMakeLists.txt index fb099fb3e10..4464c55aa9e 100644 --- a/cpp/src/aztec3/circuits/rollup/CMakeLists.txt +++ b/cpp/src/aztec3/circuits/rollup/CMakeLists.txt @@ -1,4 +1,5 @@ barretenberg_module( aztec3_circuits_rollup + aztec3_circuits_kernel barretenberg ) \ No newline at end of file diff --git a/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/cpp/src/aztec3/circuits/rollup/base/.test.cpp index 8755e7703ea..7c6825920de 100644 --- a/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -6,6 +6,7 @@ #include "aztec3/circuits/abis/append_only_tree_snapshot.hpp" #include "aztec3/circuits/abis/private_kernel/new_contract_data.hpp" #include "aztec3/circuits/abis/private_kernel/previous_kernel_data.hpp" +#include "aztec3/circuits/kernel/private/utils.hpp" #include "aztec3/circuits/abis/rollup/nullifier_leaf_preimage.hpp" #include "aztec3/constants.hpp" #include "barretenberg/crypto/sha256/sha256.hpp" @@ -13,6 +14,7 @@ #include "barretenberg/stdlib/merkle_tree/memory_tree.hpp" #include "index.hpp" #include "init.hpp" +#include "c_bind.h" #include #include @@ -76,6 +78,7 @@ using aztec3::circuits::apps::test_apps::basic_contract_deployment::constructor; using aztec3::circuits::apps::test_apps::escrow::deposit; // using aztec3::circuits::mock::mock_circuit; +using aztec3::circuits::kernel::private_kernel::utils::default_previous_kernel; using aztec3::circuits::mock::mock_kernel_circuit; // using aztec3::circuits::mock::mock_kernel_inputs; @@ -92,6 +95,70 @@ using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::OptionallyRevealedData; using aztec3::circuits::abis::private_kernel::NewContractData; +void run_cbind(BaseRollupInputs& base_rollup_inputs, + BaseRollupPublicInputs& expected_public_inputs, + bool compare_pubins = true) +{ + uint8_t const* pk_buf; + size_t pk_size = base_rollup__init_proving_key(&pk_buf); + info("Proving key size: ", pk_size); + + uint8_t const* vk_buf; + size_t vk_size = base_rollup__init_verification_key(pk_buf, &vk_buf); + info("Verification key size: ", vk_size); + + std::vector base_rollup_inputs_vec; + write(base_rollup_inputs_vec, base_rollup_inputs); + + // uint8_t const* proof_data; + // size_t proof_data_size; + uint8_t const* public_inputs_buf; + info("creating proof"); + size_t public_inputs_size = base_rollup__sim(base_rollup_inputs_vec.data(), + false, // second_present + &public_inputs_buf); + // info("Proof size: ", proof_data_size); + info("PublicInputs size: ", public_inputs_size); + + if (compare_pubins) { + BaseRollupPublicInputs public_inputs; + info("about to read..."); + read(public_inputs_buf, public_inputs); + info("about to assert..."); + ASSERT_EQ(public_inputs.calldata_hash.size(), expected_public_inputs.calldata_hash.size()); + for (size_t i = 0; i < public_inputs.calldata_hash.size(); i++) { + ASSERT_EQ(public_inputs.calldata_hash[i], expected_public_inputs.calldata_hash[i]); + } + info("after assert..."); + + // TODO why do the post-write buffers not match? + // something in aggregation object [de]serialization? + // info("about to write expected..."); + // std::vector expected_public_inputs_vec; + // write(expected_public_inputs_vec, expected_public_inputs); + // info("about to assert buffers eq..."); + // ASSERT_EQ(public_inputs_size, expected_public_inputs_vec.size()); + //// Just compare the first 10 bytes of the serialized public outputs + // if (public_inputs_size > 10) { + // // for (size_t 0; i < public_inputs_size; i++) { + // for (size_t i = 0; i < 10; i++) { + // info("testing byte ", i); + // ASSERT_EQ(public_inputs_buf[i], expected_public_inputs_vec[i]); + // } + //} + } + (void)base_rollup_inputs; // unused + (void)expected_public_inputs; // unused + (void)compare_pubins; // unused + + free((void*)pk_buf); + free((void*)vk_buf); + // free((void*)proof_data); + // SCARY WARNING TODO FIXME why does this free cause issues + // free((void*)public_inputs_buf); + info("finished retesting via cbinds..."); +} + } // namespace namespace aztec3::circuits::rollup::base::native_base_rollup_circuit { @@ -193,7 +260,13 @@ class base_rollup_tests : public ::testing::Test { std::array, 2> kernel_data; kernel_data[0] = getEmptyPreviousKernelData(); kernel_data[1] = getEmptyPreviousKernelData(); - // @note If using VK when empty, it will fail with segfault. + // grab a mocked previous kernel and use its proof and vk + PreviousKernelData mocked_kernel0 = default_previous_kernel(); + PreviousKernelData mocked_kernel1 = default_previous_kernel(); + kernel_data[0].proof = mocked_kernel0.proof; + kernel_data[0].vk = mocked_kernel0.vk; + kernel_data[1].proof = mocked_kernel1.proof; + kernel_data[1].vk = mocked_kernel1.vk; BaseRollupInputs baseRollupInputs = { .kernel_data = kernel_data, .start_private_data_tree_snapshot = AppendOnlyTreeSnapshot::empty(), @@ -221,6 +294,8 @@ TEST_F(base_rollup_tests, no_new_contract_leafs) // @todo Check the snaphots are updated accordingly. // ASSERT_EQ(expectedOut, outputs.end_contract_tree_snapshot); + + run_cbind(emptyInputs, outputs); } TEST_F(base_rollup_tests, contract_leaf_inserted) @@ -247,6 +322,8 @@ TEST_F(base_rollup_tests, contract_leaf_inserted) // @todo Check the snaphots are updated accordingly. // ASSERT_EQ(contract_tree.root(), outputs.new_contract_leaves_subtree_root); + + run_cbind(inputs, outputs); } TEST_F(base_rollup_tests, new_nullifier_tree) {} @@ -272,6 +349,8 @@ TEST_F(base_rollup_tests, empty_block_calldata_hash) } ASSERT_EQ(hash, calldata_hash); + + run_cbind(inputs, outputs); } TEST_F(base_rollup_tests, calldata_hash) @@ -325,10 +404,18 @@ TEST_F(base_rollup_tests, calldata_hash) } ASSERT_EQ(hash, calldata_hash); + run_cbind(inputs, outputs); } TEST_F(base_rollup_tests, test_compute_membership_historic) {} TEST_F(base_rollup_tests, test_compute_and_insert_subtree) {} -} // namespace aztec3::circuits::rollup::base::native_base_rollup_circuit \ No newline at end of file +TEST_F(base_rollup_tests, test_cbind_0) +{ + BaseRollupInputs inputs = getEmptyBaseRollupInputs(); + BaseRollupPublicInputs ignored_public_inputs; + run_cbind(inputs, ignored_public_inputs, false); +} + +} // namespace aztec3::circuits::rollup::base::native_base_rollup_circuit diff --git a/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp b/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp new file mode 100644 index 00000000000..f423751c1ce --- /dev/null +++ b/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp @@ -0,0 +1,164 @@ +#include "index.hpp" +#include "init.hpp" +#include "c_bind.h" + +#include +#include +#include "aztec3/circuits/abis/signed_tx_request.hpp" +#include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" +#include +#include +#include + +#include "barretenberg/srs/reference_string/env_reference_string.hpp" + +#include "barretenberg/common/serialize.hpp" +#include "barretenberg/plonk/composer/turbo_composer.hpp" + +namespace { +using NT = aztec3::utils::types::NativeTypes; +using aztec3::circuits::rollup::native_base_rollup::base_rollup_circuit; +using aztec3::circuits::rollup::native_base_rollup::BaseRollupInputs; +using aztec3::circuits::rollup::native_base_rollup::BaseRollupPublicInputs; + +// using aztec3::circuits::abis::SignedTxRequest; +// using aztec3::circuits::abis::private_kernel::PreviousKernelData; +// using aztec3::circuits::abis::private_kernel::PrivateCallData; +// using aztec3::circuits::abis::private_kernel::PrivateInputs; +// using aztec3::circuits::abis::private_kernel::PublicInputs; +// using aztec3::circuits::kernel::private_kernel::private_kernel_circuit; +// using aztec3::circuits::kernel::private_kernel::private_kernel_native; +// using aztec3::circuits::mock::mock_kernel_circuit; + +using plonk::TurboComposer; +using namespace plonk::stdlib::types; +} // namespace + +#define WASM_EXPORT __attribute__((visibility("default"))) +// WASM Cbinds +extern "C" { + +WASM_EXPORT size_t base_rollup__init_proving_key(uint8_t const** pk_buf) +{ + std::vector pk_vec(42, 0); + + auto raw_buf = (uint8_t*)malloc(pk_vec.size()); + memcpy(raw_buf, (void*)pk_vec.data(), pk_vec.size()); + *pk_buf = raw_buf; + + return pk_vec.size(); +} + +WASM_EXPORT size_t base_rollup__init_verification_key(uint8_t const* pk_buf, uint8_t const** vk_buf) +{ + std::vector vk_vec(42, 0); + // TODO remove when proving key is used + (void)pk_buf; // unused + + auto raw_buf = (uint8_t*)malloc(vk_vec.size()); + memcpy(raw_buf, (void*)vk_vec.data(), vk_vec.size()); + *vk_buf = raw_buf; + + return vk_vec.size(); +} + +//// TODO comment about how public_inputs is a confusing name +//// returns size of public inputs +// WASM_EXPORT size_t base_rollup__create_proof(uint8_t const* base_rollup_inputs_buf, +// uint8_t const* base_rollup_public_inputs_buf, +// uint8_t const* pk_buf, +// uint8_t const** proof_data_buf) +//{ +// // TODO accept proving key and use that to initialize composers +// // this info is just to prevent error for unused pk_buf +// // TODO do we want to accept it or just get it from our factory? +// (void)pk_buf; // unused +// auto crs_factory = std::make_shared(); +//} + +WASM_EXPORT size_t base_rollup__sim(uint8_t const* base_rollup_inputs_buf, + bool second_present, + uint8_t const** base_rollup_public_inputs_buf) +{ + (void)second_present; // unused + // TODO accept proving key and use that to initialize composers + // this info is just to prevent error for unused pk_buf + // TODO do we want to accept it or just get it from our factory? + // auto crs_factory = std::make_shared(); + + BaseRollupInputs base_rollup_inputs; + read(base_rollup_inputs_buf, base_rollup_inputs); + + BaseRollupPublicInputs public_inputs = base_rollup_circuit(base_rollup_inputs); + + // TODO for circuit proof version of this function + // NT::Proof base_rollup_proof; + // Composer composer = Composer(crs_factory); + // plonk::stdlib::types::Prover prover = composer.create_prover(); + // public_inputs = base_rollup_circuit(composer, base_rollup_inputs); + // base_rollup_proof = prover.construct_proof(); + + // serialize public inputs to bytes vec + std::vector public_inputs_vec; + write(public_inputs_vec, public_inputs); + // copy public inputs to output buffer + auto raw_public_inputs_buf = (uint8_t*)malloc(public_inputs_vec.size()); + memcpy(raw_public_inputs_buf, (void*)public_inputs_vec.data(), public_inputs_vec.size()); + *base_rollup_public_inputs_buf = raw_public_inputs_buf; + + return public_inputs_vec.size(); +} + +// WASM_EXPORT size_t base_rollup__sim(uint8_t const* base_rollup_inputs_buf, +// bool second_present, +// uint8_t const** base_rollup_public_inputs_buf) +//{ +// // TODO accept proving key and use that to initialize composers +// // this info is just to prevent error for unused pk_buf +// // TODO do we want to accept it or just get it from our factory? +// auto crs_factory = std::make_shared(); +// +// BaseRollupInputs base_rollup_inputs; +// read(base_rollup_inputs_buf, base_rollup_inputs); +// +// NT::Proof base_rollup_proof; +// BaseRollupPublicInputs public_inputs; +// if (proverless) { +// public_inputs = base_rollup_circuit(base_rollup_inputs); +// // mocked proof - zeros +// base_rollup_proof = NT::Proof{ std::vector(42, 0) }; +// }// else { +// // Composer composer = Composer(crs_factory); +// // plonk::stdlib::types::Prover prover = composer.create_prover(); +// // public_inputs = base_rollup_circuit(composer, base_rollup_inputs); +// // base_rollup_proof = prover.construct_proof(); +// //} +// +// // copy proof data to output buffer +// auto raw_proof_buf = (uint8_t*)malloc(base_rollup_proof.proof_data.size()); +// memcpy(raw_proof_buf, (void*)base_rollup_proof.proof_data.data(), base_rollup_proof.proof_data.size()); +// *proof_data_buf = raw_proof_buf; +// +// // copy proof data size to output +// *proof_data_size = base_rollup_proof.proof_data.size(); +// +// // serialize public inputs to bytes vec +// std::vector public_inputs_vec; +// write(public_inputs_vec, public_inputs); +// // copy public inputs to output buffer +// auto raw_public_inputs_buf = (uint8_t*)malloc(public_inputs_vec.size()); +// memcpy(raw_public_inputs_buf, (void*)public_inputs_vec.data(), public_inputs_vec.size()); +// *base_rollup_public_inputs_buf = raw_public_inputs_buf; +// +// return base_rollup_proof.proof_data.size(); +//} + +WASM_EXPORT size_t private_kernel__verify_proof(uint8_t const* vk_buf, uint8_t const* proof, uint32_t length) +{ + (void)vk_buf; // unused + (void)proof; // unused + (void)length; // unused + return true; +} + +} // extern "C" \ No newline at end of file diff --git a/cpp/src/aztec3/circuits/rollup/base/c_bind.h b/cpp/src/aztec3/circuits/rollup/base/c_bind.h new file mode 100644 index 00000000000..7fe33507281 --- /dev/null +++ b/cpp/src/aztec3/circuits/rollup/base/c_bind.h @@ -0,0 +1,18 @@ +#include +#include + +#define WASM_EXPORT __attribute__((visibility("default"))) + +extern "C" { + +WASM_EXPORT size_t base_rollup__init_proving_key(uint8_t const** pk_buf); +WASM_EXPORT size_t base_rollup__init_verification_key(uint8_t const* pk_buf, uint8_t const** vk_buf); +//WASM_EXPORT size_t base_rollup__get_default_previous_rollup(uint8_t const** previous_rollup_data); +WASM_EXPORT size_t base_rollup__sim(uint8_t const* base_rollup_inputs_buf, + bool second_present, + uint8_t const** base_rollup_public_inputs_buf); +WASM_EXPORT size_t base_rollup__verify_proof(uint8_t const* vk_buf, + uint8_t const* proof, + uint32_t length); + +} \ No newline at end of file