diff --git a/barretenberg/barretenberg.code-workspace b/barretenberg/barretenberg.code-workspace index 362ddc1783c..ac2b6bb11f5 100644 --- a/barretenberg/barretenberg.code-workspace +++ b/barretenberg/barretenberg.code-workspace @@ -79,6 +79,9 @@ // Some settings can only be configured here. // The following are just provided as example. "settings": { + "files.associations": { + "*.tcc": "cpp", + }, // // Clangd. Note that this setting may be overridden by user settings // to the default value "clangd". diff --git a/barretenberg/cpp/scripts/bb-tests.sh b/barretenberg/cpp/scripts/bb-tests.sh index f9dbe34fabc..b0d91871ce9 100755 --- a/barretenberg/cpp/scripts/bb-tests.sh +++ b/barretenberg/cpp/scripts/bb-tests.sh @@ -33,7 +33,6 @@ TESTS=( crypto_schnorr_tests crypto_sha256_tests ecc_tests - join_split_example_proofs_inner_proof_data_tests join_split_example_proofs_notes_tests numeric_tests plonk_tests diff --git a/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc b/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc index 455101e7548..efd6bc03518 100644 --- a/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc +++ b/barretenberg/cpp/src/barretenberg/crypto/schnorr/schnorr.tcc @@ -88,7 +88,7 @@ schnorr_signature schnorr_construct_signature(const std::string& message, const // method is overloaded to utilise a suitable entropy source // (see https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md) // - // TODO: securely erase `k` + // TODO(https://github.com/AztecProtocol/barretenberg/issues/895): securely erase `k` Fr k = Fr::random_element(); typename G1::affine_element R(G1::one * k); diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/compute_circuit_data.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/compute_circuit_data.hpp deleted file mode 100644 index d3c9d30ab3e..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/compute_circuit_data.hpp +++ /dev/null @@ -1,261 +0,0 @@ -#pragma once -#include -#include - -#include "../constants.hpp" -#include "barretenberg/common/log.hpp" -#include "barretenberg/common/timer.hpp" -#include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" -#include "join_split/join_split.hpp" -#include "mock/mock_circuit.hpp" - -#ifndef __wasm__ -#include -#endif - -namespace bb::join_split_example::proofs { - -struct circuit_data { - circuit_data() - : num_gates(0) - {} - - std::shared_ptr> srs; - std::shared_ptr proving_key; - std::shared_ptr verification_key; - size_t num_gates; - std::vector padding_proof; - bool mock; -}; - -namespace { -inline bool exists(std::string const& path) -{ - struct stat st; - return (stat(path.c_str(), &st) != -1); -} -} // namespace - -template -circuit_data get_circuit_data(std::string const& name, - std::string const& path_name, - std::shared_ptr> const& srs, - std::string const& key_path, - bool compute, - bool save, - bool load, - bool pk, - bool vk, - bool padding, - bool mock, // TODO(#541) - F const& build_circuit, - std::string const name_suffix_for_benchmarks = "") -{ - using Builder = typename Composer::CircuitBuilder; - circuit_data data; - data.srs = srs; - data.mock = mock; - Composer composer; - Builder builder; - Composer mock_proof_composer; - Builder mock_builder; - BenchmarkInfoCollator benchmark_collator; - - auto circuit_key_path = key_path + "/" + path_name; - auto pk_path = circuit_key_path + "/proving_key/proving_key"; - auto vk_path = circuit_key_path + "/verification_key"; - auto padding_path = circuit_key_path + "/padding_proof"; - - // If we're missing required data, and compute is enabled, or if - // compute is enabled and load is disabled, build the circuit. - if (((!exists(pk_path) || !exists(vk_path) || (!exists(padding_path) && padding)) && compute) || - (compute && !load)) { - info(name, ": Building circuit..."); - Timer timer; - build_circuit(builder); - - benchmark_collator.benchmark_info_deferred( - Composer::NAME_STRING, "Core", name + name_suffix_for_benchmarks, "Build time", timer.toString()); - benchmark_collator.benchmark_info_deferred( - Composer::NAME_STRING, "Core", name + name_suffix_for_benchmarks, "Gates", builder.get_num_gates()); - info(name, ": Circuit built in: ", timer.toString(), "s"); - info(name, ": Circuit size: ", builder.get_num_gates()); - if (mock) { - auto public_inputs = builder.get_public_inputs(); - ::bb::join_split_example::proofs::mock::mock_circuit(mock_builder, public_inputs); - info(name, ": Mock circuit size: ", mock_builder.get_num_gates()); - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Mock Gates", - builder.get_num_gates()); - } - } - -#ifndef __wasm__ - // If we're saving data, create the circuit data directory. - if (save) { - std::filesystem::create_directories(key_path.c_str()); - std::filesystem::create_directories(circuit_key_path.c_str()); - } -#endif - - if (pk) { - auto pk_dir = circuit_key_path + "/proving_key"; - if (exists(pk_path) && load) { - info(name, ": Loading proving key: ", pk_path); - auto pk_stream = std::ifstream(pk_path); - plonk::proving_key_data pk_data; - read_from_file(pk_stream, pk_dir, pk_data); - data.proving_key = - std::make_shared(std::move(pk_data), srs->get_prover_crs(pk_data.circuit_size + 1)); - data.num_gates = pk_data.circuit_size; - info(name, ": Circuit size 2^n: ", data.num_gates); - benchmark_collator.benchmark_info_deferred( - Composer::NAME_STRING, "Core", name + name_suffix_for_benchmarks, "Gates 2^n", data.num_gates); - } else if (compute) { - Timer timer; - info(name, ": Computing proving key..."); - - if (!mock) { - data.num_gates = builder.get_num_gates(); - data.proving_key = composer.compute_proving_key(builder); - info(name, ": Circuit size 2^n: ", data.proving_key->circuit_size); - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Gates 2^n", - data.proving_key->circuit_size); - } else { - data.num_gates = mock_builder.get_num_gates(); - data.proving_key = mock_proof_composer.compute_proving_key(mock_builder); - info(name, ": Mock circuit size 2^n: ", data.proving_key->circuit_size); - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Mock Gates 2^n", - data.proving_key->circuit_size); - } - - info(name, ": Proving key computed in ", timer.toString(), "s"); - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Proving key computed in", - timer.toString()); -#ifndef __wasm__ - if (save) { - info(name, ": Saving proving key..."); - std::filesystem::create_directories(pk_dir.c_str()); - Timer write_timer; - std::ofstream os(pk_path); - write_to_file(os, pk_dir, *data.proving_key); - if (!os.good()) { - throw_or_abort(format("Failed to write: ", pk_path)); - } - info(name, ": Saved in ", write_timer.toString(), "s"); - } -#endif - } - } - - if (vk) { - if (exists(vk_path) && load) { - info(name, ": Loading verification key from: ", vk_path); - auto vk_stream = std::ifstream(vk_path); - plonk::verification_key_data vk_data; - serialize::read(vk_stream, vk_data); - data.verification_key = - std::make_shared(std::move(vk_data), data.srs->get_verifier_crs()); - info(name, ": Verification key hash: ", data.verification_key->sha256_hash()); - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Verification key hash", - data.verification_key->sha256_hash()); - } else if (compute) { - info(name, ": Computing verification key..."); - Timer timer; - - if (!mock) { - data.verification_key = composer.compute_verification_key(builder); - } else { - data.verification_key = mock_proof_composer.compute_verification_key(mock_builder); - } - info(name, ": Computed verification key in ", timer.toString(), "s"); - - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Verification key computed in", - timer.toString()); - info(name, ": Verification key hash: ", data.verification_key->sha256_hash()); - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Verification key hash", - data.verification_key->sha256_hash()); - - if (save) { - std::ofstream os(vk_path); - write(os, *data.verification_key); - if (!os.good()) { - throw_or_abort(format("Failed to write: ", vk_path)); - } - } - } - } - - if (padding) { - if (exists(padding_path) && load) { - info(name, ": Loading padding proof from: ", padding_path); - std::ifstream is(padding_path); - std::vector proof((std::istreambuf_iterator(is)), std::istreambuf_iterator()); - data.padding_proof = proof; - } else if (data.proving_key) { - info(name, ": Computing padding proof..."); - - if (builder.failed()) { - info(name, ": Composer logic failed: ", builder.err()); - info(name, ": Warning, padding proof can only be used to aid upstream pk construction!"); - } - - Timer timer; - if (!mock) { - auto prover = composer.create_prover(builder); - auto proof = prover.construct_proof(); - data.padding_proof = proof.proof_data; - data.num_gates = builder.get_num_gates(); - info(name, ": Circuit size: ", data.num_gates); - auto verifier = composer.create_verifier(builder); - info(name, ": Padding verified: ", verifier.verify_proof(proof)); - } else { - auto prover = mock_proof_composer.create_prover(mock_builder); - auto proof = prover.construct_proof(); - data.padding_proof = proof.proof_data; - data.num_gates = mock_builder.get_num_gates(); - info(name, ": Mock circuit size: ", data.num_gates); - auto verifier = mock_proof_composer.create_verifier(mock_builder); - info(name, ": Padding verified: ", verifier.verify_proof(proof)); - } - info(name, ": Padding proof computed in ", timer.toString(), "s"); - benchmark_collator.benchmark_info_deferred(Composer::NAME_STRING, - "Core", - name + name_suffix_for_benchmarks, - "Padding proof computed in", - timer.toString()); - - if (save) { - std::ofstream os(padding_path); - os.write((char*)data.padding_proof.data(), (std::streamsize)data.padding_proof.size()); - if (!os.good()) { - throw_or_abort(format("Failed to write: ", padding_path)); - } - } - } - } - - return data; -} - -} // namespace bb::join_split_example::proofs diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/inner_proof_data/inner_proof_data.test.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/inner_proof_data/inner_proof_data.test.cpp deleted file mode 100644 index 4721089cdc9..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/inner_proof_data/inner_proof_data.test.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "inner_proof_data.hpp" -#include - -using namespace bb; -using namespace bb::join_split_example::proofs; - -namespace { -auto& rand_engine = numeric::get_debug_randomness(); -} - -TEST(client_proofs_inner_proof_data, test_proof_to_data) -{ - uint256_t proof_id = 0; - auto note1 = fr::random_element(&rand_engine); - auto note2 = fr::random_element(&rand_engine); - auto merkle_root = fr::random_element(&rand_engine); - uint256_t nullifier1 = rand_engine.get_random_uint256(); - uint256_t nullifier2 = rand_engine.get_random_uint256(); - uint256_t public_value = rand_engine.get_random_uint256(); - auto public_owner = fr::random_element(&rand_engine); - uint256_t asset_id = 1; - uint256_t tx_fee = rand_engine.get_random_uint256(); - uint256_t tx_fee_asset_id = 2; - uint256_t bridge_call_data = rand_engine.get_random_uint256(); - uint256_t defi_deposit_value = rand_engine.get_random_uint256(); - auto defi_root = fr::random_element(&rand_engine); - auto backward_link = fr::random_element(&rand_engine); - uint256_t allow_chain = 0; - - using serialize::write; - std::vector proof_data; - write(proof_data, proof_id); - write(proof_data, note1); - write(proof_data, note2); - write(proof_data, nullifier1); - write(proof_data, nullifier2); - write(proof_data, public_value); - write(proof_data, public_owner); - write(proof_data, asset_id); - write(proof_data, merkle_root); - write(proof_data, tx_fee); - write(proof_data, tx_fee_asset_id); - write(proof_data, bridge_call_data); - write(proof_data, defi_deposit_value); - write(proof_data, defi_root); - write(proof_data, backward_link); - write(proof_data, allow_chain); - - auto data = inner_proof_data(proof_data); - - EXPECT_EQ(data.proof_id, proof_id); - EXPECT_EQ(data.note_commitment1, note1); - EXPECT_EQ(data.note_commitment2, note2); - EXPECT_EQ(data.nullifier1, nullifier1); - EXPECT_EQ(data.nullifier2, nullifier2); - EXPECT_EQ(data.public_value, public_value); - EXPECT_EQ(data.public_owner, public_owner); - EXPECT_EQ(data.asset_id, asset_id); - EXPECT_EQ(data.merkle_root, merkle_root); - EXPECT_EQ(data.tx_fee, tx_fee); - EXPECT_EQ(data.tx_fee_asset_id, tx_fee_asset_id); - EXPECT_EQ(data.bridge_call_data, bridge_call_data); - EXPECT_EQ(data.defi_deposit_value, defi_deposit_value); - EXPECT_EQ(data.defi_root, defi_root); - EXPECT_EQ(data.backward_link, backward_link); - EXPECT_EQ(data.allow_chain, allow_chain); -} diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.cpp deleted file mode 100644 index 7d8533dd600..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include "compute_circuit_data.hpp" -#include "../notes/native/index.hpp" -#include "barretenberg/crypto/merkle_tree/hash_path.hpp" -#include "barretenberg/join_split_example/types.hpp" -#include "join_split_circuit.hpp" -#include "sign_join_split_tx.hpp" - -namespace bb::join_split_example::proofs::join_split { - -using namespace bb::join_split_example::proofs::join_split; -using namespace bb::stdlib; -using namespace bb::join_split_example::proofs::notes::native; -using namespace bb::crypto::merkle_tree; - -join_split_tx noop_tx() -{ - grumpkin::fr priv_key = grumpkin::fr::random_element(); - grumpkin::g1::affine_element pub_key = grumpkin::g1::one * priv_key; - - value::value_note input_note1 = { 0, 0, 0, pub_key, fr::random_element(), 0, fr::random_element() }; - value::value_note input_note2 = { 0, 0, 0, pub_key, fr::random_element(), 0, fr::random_element() }; - auto input_nullifier1 = compute_nullifier(input_note1.commit(), priv_key, false); - auto input_nullifier2 = compute_nullifier(input_note2.commit(), priv_key, false); - value::value_note output_note1 = { 0, 0, 0, pub_key, fr::random_element(), 0, input_nullifier1 }; - value::value_note output_note2 = { 0, 0, 0, pub_key, fr::random_element(), 0, input_nullifier2 }; - - auto gibberish_path = fr_hash_path(DATA_TREE_DEPTH, std::make_pair(fr::random_element(), fr::random_element())); - - join_split_tx tx; - tx.proof_id = proof_ids::DEPOSIT; - tx.public_value = 1; - tx.public_owner = fr::one(); - tx.asset_id = 0; - tx.num_input_notes = 0; - tx.input_index = { 0, 1 }; - tx.old_data_root = fr::random_element(); - tx.input_path = { gibberish_path, gibberish_path }; - tx.input_note = { input_note1, input_note2 }; - tx.output_note = { output_note1, output_note2 }; - tx.partial_claim_note = { - .deposit_value = 0, - .bridge_call_data = 0, - .note_secret = fr::random_element(), - .input_nullifier = 0, - }; - tx.account_note_index = 0; - tx.account_note_path = gibberish_path; - tx.signing_pub_key = pub_key; - tx.account_private_key = priv_key; - tx.alias_hash = 0; - tx.account_required = false; - tx.backward_link = fr::zero(); - tx.allow_chain = 0; - - tx.signature = sign_join_split_tx(tx, { priv_key, pub_key }); - - return tx; -} - -circuit_data get_circuit_data(std::shared_ptr> const& srs, bool mock) -{ - std::cerr << "Getting join-split circuit data..." << std::endl; - - auto build_circuit = [&](Builder& builder) { - join_split_tx tx(noop_tx()); - join_split_circuit(builder, tx); - }; - - return proofs::get_circuit_data( - "join split", "", srs, "", true, false, false, true, true, true, mock, build_circuit); -} - -} // namespace bb::join_split_example::proofs::join_split diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.hpp deleted file mode 100644 index e7c1be6c493..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_circuit_data.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once -#include "../compute_circuit_data.hpp" -#include "join_split_tx.hpp" - -namespace bb::join_split_example::proofs::join_split { - -join_split_tx noop_tx(); - -using circuit_data = proofs::circuit_data; - -circuit_data get_circuit_data(std::shared_ptr> const& srs, - bool mock = false); - -} // namespace bb::join_split_example::proofs::join_split \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_signing_data.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_signing_data.cpp index 4e8d063ba52..4c9ec5f5082 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_signing_data.cpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/compute_signing_data.cpp @@ -1,6 +1,6 @@ #include "compute_signing_data.hpp" -#include "../notes/native/index.hpp" #include "barretenberg/crypto/pedersen_hash/pedersen.hpp" +#include "barretenberg/join_split_example/proofs/notes/native/index.hpp" namespace bb::join_split_example::proofs::join_split { diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/create_proof.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/create_proof.hpp deleted file mode 100644 index b0f1ddd6c8f..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/create_proof.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include "../../fixtures/user_context.hpp" -#include "compute_circuit_data.hpp" -#include "join_split_circuit.hpp" -#include "sign_join_split_tx.hpp" - -namespace bb::join_split_example::proofs::join_split { - -inline std::vector create_proof(join_split_tx const& tx, circuit_data const& cd) -{ - Builder builder(cd.num_gates); - join_split_circuit(builder, tx); - - if (builder.failed()) { - info("Join-split circuit logic failed: ", builder.err()); - } - - Composer composer = Composer(cd.proving_key, cd.verification_key); - auto prover = composer.create_prover(builder); - auto proof = prover.construct_proof(); - - return proof.proof_data; -} - -} // namespace bb::join_split_example::proofs::join_split diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/index.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/index.hpp index 03f094fe7f2..344d41b533d 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/index.hpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/index.hpp @@ -1,6 +1,5 @@ #pragma once -#include "compute_circuit_data.hpp" -#include "create_proof.hpp" +#include "barretenberg/join_split_example/fixtures/user_context.hpp" #include "join_split.hpp" #include "join_split_circuit.hpp" #include "join_split_tx.hpp" diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp index 687d4c2c7a7..59ac8a19098 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.cpp @@ -1,7 +1,6 @@ #include "join_split.hpp" #include "barretenberg/join_split_example/types.hpp" #include "barretenberg/plonk/proof_system/commitment_scheme/kate_commitment_scheme.hpp" -#include "compute_circuit_data.hpp" #include "join_split_circuit.hpp" namespace bb::join_split_example::proofs::join_split { @@ -9,48 +8,7 @@ namespace bb::join_split_example::proofs::join_split { using namespace bb::plonk; using namespace bb::crypto::merkle_tree; -static std::shared_ptr proving_key; -static std::shared_ptr verification_key; - -void init_proving_key(bool mock) -{ - if (proving_key) { - return; - } - - // Junk data required just to create proving key. - join_split_tx tx = noop_tx(); - - if (!mock) { - Builder builder; - join_split_circuit(builder, tx); - Composer composer; - proving_key = composer.compute_proving_key(builder); - } else { - Builder builder; - join_split_circuit(builder, tx); - Composer composer; - bb::join_split_example::proofs::mock::mock_circuit(builder, builder.get_public_inputs()); - proving_key = composer.compute_proving_key(builder); - } -} - -void release_proving_key() -{ - proving_key.reset(); -} - -void init_verification_key() -{ - if (!proving_key) { - std::abort(); - } - - verification_key = - bb::plonk::compute_verification_key_common(proving_key, srs::get_bn254_crs_factory()->get_verifier_crs()); -} - -Prover new_join_split_prover(join_split_tx const& tx, bool mock) +Builder new_join_split_circuit(join_split_tx const& tx) { Builder builder; join_split_circuit(builder, tx); @@ -62,37 +20,9 @@ Prover new_join_split_prover(join_split_tx const& tx, bool mock) info("public inputs: ", builder.public_inputs.size()); - Composer composer; - if (!mock) { - info("composer gates: ", builder.get_num_gates()); - return composer.create_prover(builder); - } else { - Composer mock_proof_composer(proving_key, nullptr); - bb::join_split_example::proofs::mock::mock_circuit(builder, builder.get_public_inputs()); - info("mock composer gates: ", builder.get_num_gates()); - return mock_proof_composer.create_prover(builder); - } -} - -bool verify_proof(plonk::proof const& proof) -{ - Verifier verifier(verification_key, Composer::create_manifest(verification_key->num_public_inputs)); - - std::unique_ptr> kate_commitment_scheme = - std::make_unique>(); - verifier.commitment_scheme = std::move(kate_commitment_scheme); + info("num gates before finalization: ", builder.get_num_gates()); - return verifier.verify_proof(proof); -} - -std::shared_ptr get_proving_key() -{ - return proving_key; -} - -std::shared_ptr get_verification_key() -{ - return verification_key; + return builder; } } // namespace bb::join_split_example::proofs::join_split diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp index 42419078aba..3296346cf4b 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.hpp @@ -5,18 +5,6 @@ namespace bb::join_split_example::proofs::join_split { -void init_proving_key(bool mock); - -void release_proving_key(); - -void init_verification_key(); - -Prover new_join_split_prover(join_split_tx const& tx, bool mock); - -bool verify_proof(plonk::proof const& proof); - -std::shared_ptr get_proving_key(); - -std::shared_ptr get_verification_key(); +Builder new_join_split_circuit(join_split_tx const& tx); } // namespace bb::join_split_example::proofs::join_split diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp index 4f3e329acb6..05c99e16d09 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split.test.cpp @@ -1,11 +1,12 @@ #include -#include "../../constants.hpp" -#include "../inner_proof_data/inner_proof_data.hpp" -#include "../notes/native/index.hpp" +#include "barretenberg/circuit_checker/circuit_checker.hpp" #include "barretenberg/common/streams.hpp" #include "barretenberg/common/test.hpp" #include "barretenberg/crypto/merkle_tree/index.hpp" +#include "barretenberg/join_split_example/constants.hpp" +#include "barretenberg/join_split_example/proofs/inner_proof_data/inner_proof_data.hpp" +#include "barretenberg/join_split_example/proofs/notes/native/index.hpp" #include "barretenberg/join_split_example/types.hpp" #include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" #include "index.hpp" @@ -41,14 +42,6 @@ auto create_account_leaf_data(fr const& account_alias_hash, class join_split_tests : public ::testing::Test { protected: static constexpr size_t ACCOUNT_INDEX = 14; - static void SetUpTestCase() - { - srs::init_crs_factory("../srs_db/ignition"); - init_proving_key(false); - auto crs_factory = std::make_unique>("../srs_db/ignition"); - init_verification_key(); - info("vk hash: ", get_verification_key()->sha256_hash()); - } virtual void SetUp() { @@ -264,17 +257,17 @@ class join_split_tests : public ::testing::Test { return tx; } - plonk::proof sign_and_create_proof(join_split_tx& tx, key_pair const& signing_key) + Builder sign_and_create_circuit(join_split_tx& tx, key_pair const& signing_key) { tx.signature = sign_join_split_tx(tx, signing_key); - - auto prover = new_join_split_prover(tx, false); - return prover.construct_proof(); + circuit = new_join_split_circuit(tx); + return circuit; } - bool sign_and_verify(join_split_tx& tx, key_pair const& signing_key) + bool sign_and_check_circuit(join_split_tx& tx, key_pair const& signing_key) { - return verify_proof(sign_and_create_proof(tx, signing_key)); + circuit = sign_and_create_circuit(tx, signing_key); + return CircuitChecker::check(circuit); } struct verify_result { @@ -286,12 +279,12 @@ class join_split_tests : public ::testing::Test { verify_result verify_logic(join_split_tx& tx) { - Builder builder; - join_split_circuit(builder, tx); - if (builder.failed()) { - std::cout << "Logic failed: " << builder.err() << std::endl; + circuit = Builder(); + join_split_circuit(circuit, tx); + if (circuit.failed()) { + info("Logic failed: ", circuit.err()); } - return { !builder.failed(), builder.err(), builder.get_public_inputs(), builder.get_num_gates() }; + return { !circuit.failed(), circuit.err(), circuit.get_public_inputs(), circuit.get_num_gates() }; } verify_result sign_and_verify_logic(join_split_tx& tx, key_pair const& signing_key) @@ -300,6 +293,7 @@ class join_split_tests : public ::testing::Test { return verify_logic(tx); } + Builder circuit; join_split_example::fixtures::user_context user; std::unique_ptr store; std::unique_ptr> tree; @@ -705,25 +699,18 @@ TEST_F(join_split_tests, test_0_input_notes_and_detect_circuit_change) EXPECT_TRUE(result.valid); // The below part detects any changes in the join-split circuit - constexpr uint32_t CIRCUIT_GATE_COUNT = 49492; - constexpr uint32_t GATES_NEXT_POWER_OF_TWO = 65535; - const uint256_t VK_HASH("29f333ac68164d4e079b3d4243c95425432f317aa26ad67fd668ca883b28e236"); + constexpr size_t DYADIC_CIRCUIT_SIZE = 1 << 16; - auto number_of_gates_js = result.number_of_gates; - std::cout << get_verification_key()->sha256_hash() << std::endl; - auto vk_hash_js = get_verification_key()->sha256_hash(); + constexpr uint256_t CIRCUIT_HASH("0x3792ae05102a73979a20d1962e30720ea083f87341a79f7714f356adbe670222"); + const uint256_t circuit_hash = circuit.hash_circuit(); + // circuit is finalized now if (!CIRCUIT_CHANGE_EXPECTED) { - EXPECT_EQ(number_of_gates_js, CIRCUIT_GATE_COUNT) << "The gate count for the join_split circuit is changed."; - EXPECT_EQ(from_buffer(vk_hash_js), VK_HASH) - << "The verification key hash for the join_split circuit is changed: " - << from_buffer(vk_hash_js); + EXPECT_LT(circuit.get_num_gates(), DYADIC_CIRCUIT_SIZE) + << "The gate count for the join-split circuit has crossed a power-of-two boundary."; + EXPECT_EQ(circuit_hash, CIRCUIT_HASH) + << "The circuit hash for the join_split circuit has changed to: " << circuit_hash; } - - // For the next power of two limit, we need to consider that we reserve four gates for adding - // randomness/zero-knowledge - EXPECT_LE(number_of_gates_js, GATES_NEXT_POWER_OF_TWO - Composer::NUM_RESERVED_GATES) - << "You have exceeded the next power of two limit for the join_split circuit."; } // Bespoke test seeking bug. @@ -1101,27 +1088,6 @@ TEST_F(join_split_tests, test_random_output_note_owners) EXPECT_TRUE(sign_and_verify_logic(tx, user.owner).valid); } -TEST_F(join_split_tests, test_tainted_output_owner_fails) -{ - join_split_tx tx = simple_setup(); - tx.proof_id = proof_ids::DEPOSIT; - tx.public_value = 1; - tx.signing_pub_key = user.owner.public_key; - uint8_t public_owner[32] = { 0x01, 0xaa, 0x42, 0xd4, 0x72, 0x88, 0x8e, 0xae, 0xa5, 0x56, 0x39, - 0x46, 0xeb, 0x5c, 0xf5, 0x6c, 0x81, 0x6, 0x4d, 0x80, 0xc6, 0xf5, - 0xa5, 0x38, 0xcc, 0x87, 0xae, 0x54, 0xae, 0xdb, 0x75, 0xd9 }; - tx.public_owner = from_buffer(public_owner); - tx.signature = sign_join_split_tx(tx, user.owner); - - auto prover = new_join_split_prover(tx, false); - auto proof = prover.construct_proof(); - - EXPECT_EQ(proof.proof_data[inner_proof_offsets::PUBLIC_OWNER], 0x01); - proof.proof_data[inner_proof_fields::PUBLIC_OWNER] = 0x02; - - EXPECT_FALSE(verify_proof(proof)); -} - // ************************************************************************************************************* // Signature // ************************************************************************************************************* @@ -2215,11 +2181,10 @@ TEST_F(join_split_tests, test_incorrect_output_note_creator_pubkey_x) } // ************************************************************************************************************* -// Full proofs +// Basic success tests // ************************************************************************************************************* -// Named differently from *_full_proof tests to let us run just this one full proof test in CI with a gtest filter -TEST_F(join_split_tests, test_deposit_construct_proof) +TEST_F(join_split_tests, test_deposit) { join_split_tx tx = zero_input_setup(); tx.proof_id = proof_ids::DEPOSIT; @@ -2234,35 +2199,11 @@ TEST_F(join_split_tests, test_deposit_construct_proof) * - fee = 3 */ - auto proof = sign_and_create_proof(tx, user.owner); - auto proof_data = inner_proof_data(proof.proof_data); - - auto input_note1_commitment = tx.input_note[0].commit(); - auto input_note2_commitment = tx.input_note[1].commit(); - uint256_t nullifier1 = compute_nullifier(input_note1_commitment, user.owner.private_key, false); - uint256_t nullifier2 = compute_nullifier(input_note2_commitment, user.owner.private_key, false); - auto output_note1_commitment = tx.output_note[0].commit(); - auto output_note2_commitment = tx.output_note[1].commit(); - - EXPECT_EQ(proof_data.proof_id, proof_ids::DEPOSIT); - EXPECT_EQ(proof_data.note_commitment1, output_note1_commitment); - EXPECT_EQ(proof_data.note_commitment2, output_note2_commitment); - EXPECT_EQ(proof_data.nullifier1, nullifier1); - EXPECT_EQ(proof_data.nullifier2, nullifier2); - EXPECT_EQ(proof_data.public_value, tx.public_value); - EXPECT_EQ(proof_data.public_owner, tx.public_owner); - EXPECT_EQ(proof_data.asset_id, tx.asset_id); - EXPECT_EQ(proof_data.merkle_root, tree->root()); - EXPECT_EQ(proof_data.tx_fee, uint256_t(3)); - EXPECT_EQ(proof_data.tx_fee_asset_id, tx.asset_id); - EXPECT_EQ(proof_data.bridge_call_data, uint256_t(0)); - EXPECT_EQ(proof_data.defi_deposit_value, uint256_t(0)); - EXPECT_EQ(proof_data.defi_root, fr(0)); - - EXPECT_TRUE(verify_proof(proof)); + Builder circuit = sign_and_create_circuit(tx, user.owner); + EXPECT_TRUE(CircuitChecker::check(circuit)); } -TEST_F(join_split_tests, test_withdraw_full_proof) +TEST_F(join_split_tests, test_withdraw) { join_split_tx tx = simple_setup(); tx.proof_id = proof_ids::WITHDRAW; @@ -2279,35 +2220,11 @@ TEST_F(join_split_tests, test_withdraw_full_proof) * - 3 paid as fee (in1's asset_id) */ - auto proof = sign_and_create_proof(tx, user.owner); - auto proof_data = inner_proof_data(proof.proof_data); - - auto input_note1_commitment = tx.input_note[0].commit(); - auto input_note2_commitment = tx.input_note[1].commit(); - uint256_t nullifier1 = compute_nullifier(input_note1_commitment, user.owner.private_key, true); - uint256_t nullifier2 = compute_nullifier(input_note2_commitment, user.owner.private_key, true); - auto output_note1_commitment = tx.output_note[0].commit(); - auto output_note2_commitment = tx.output_note[1].commit(); - - EXPECT_EQ(proof_data.proof_id, proof_ids::WITHDRAW); - EXPECT_EQ(proof_data.note_commitment1, output_note1_commitment); - EXPECT_EQ(proof_data.note_commitment2, output_note2_commitment); - EXPECT_EQ(proof_data.nullifier1, nullifier1); - EXPECT_EQ(proof_data.nullifier2, nullifier2); - EXPECT_EQ(proof_data.public_value, tx.public_value); - EXPECT_EQ(proof_data.public_owner, tx.public_owner); - EXPECT_EQ(proof_data.asset_id, tx.asset_id); - EXPECT_EQ(proof_data.merkle_root, tree->root()); - EXPECT_EQ(proof_data.tx_fee, uint256_t(3)); - EXPECT_EQ(proof_data.tx_fee_asset_id, tx.asset_id); - EXPECT_EQ(proof_data.bridge_call_data, uint256_t(0)); - EXPECT_EQ(proof_data.defi_deposit_value, uint256_t(0)); - EXPECT_EQ(proof_data.defi_root, fr(0)); - - EXPECT_TRUE(verify_proof(proof)); + Builder circuit = sign_and_create_circuit(tx, user.owner); + EXPECT_TRUE(CircuitChecker::check(circuit)); } -TEST_F(join_split_tests, test_private_send_full_proof) +TEST_F(join_split_tests, test_private_send) { join_split_tx tx = simple_setup(); tx.output_note[0].value -= 3; @@ -2320,37 +2237,12 @@ TEST_F(join_split_tests, test_private_send_full_proof) * - 3 paid as fee (in1's asset_id) */ - auto proof = sign_and_create_proof(tx, user.owner); - auto proof_data = inner_proof_data(proof.proof_data); - - auto input_note1_commitment = tx.input_note[0].commit(); - auto input_note2_commitment = tx.input_note[1].commit(); - auto output_note1_commitment = tx.output_note[0].commit(); - auto output_note2_commitment = tx.output_note[1].commit(); - uint256_t nullifier1 = compute_nullifier(input_note1_commitment, user.owner.private_key, true); - uint256_t nullifier2 = compute_nullifier(input_note2_commitment, user.owner.private_key, true); - - EXPECT_EQ(proof_data.proof_id, proof_ids::SEND); - EXPECT_EQ(proof_data.note_commitment1, output_note1_commitment); - EXPECT_EQ(proof_data.note_commitment2, output_note2_commitment); - EXPECT_EQ(proof_data.nullifier1, nullifier1); - EXPECT_EQ(proof_data.nullifier2, nullifier2); - EXPECT_EQ(proof_data.public_value, uint256_t(0)); - EXPECT_EQ(proof_data.public_owner, fr(0)); - EXPECT_EQ(proof_data.asset_id, uint256_t(0)); - EXPECT_EQ(proof_data.merkle_root, tree->root()); - EXPECT_EQ(proof_data.tx_fee, uint256_t(3)); - EXPECT_EQ(proof_data.tx_fee_asset_id, tx.asset_id); - EXPECT_EQ(proof_data.bridge_call_data, uint256_t(0)); - EXPECT_EQ(proof_data.defi_deposit_value, uint256_t(0)); - EXPECT_EQ(proof_data.defi_root, fr(0)); - EXPECT_EQ(proof_data.backward_link, fr(0)); - EXPECT_EQ(proof_data.allow_chain, uint256_t(0)); - - EXPECT_TRUE(verify_proof(proof)); -} - -TEST_F(join_split_tests, test_defi_deposit_full_proof) + Builder circuit = sign_and_create_circuit(tx, user.owner); + + EXPECT_TRUE(CircuitChecker::check(circuit)); +} + +TEST_F(join_split_tests, test_defi_deposit) { join_split_tx tx = simple_setup(); @@ -2375,44 +2267,11 @@ TEST_F(join_split_tests, test_defi_deposit_full_proof) * - 10 paid as fee (in1's asset_id) */ - auto proof = sign_and_create_proof(tx, user.owner); - EXPECT_TRUE(verify_proof(proof)); - - auto proof_data = inner_proof_data(proof.proof_data); - - auto partial_value_commitment = value::create_partial_commitment( - tx.partial_claim_note.note_secret, tx.input_note[0].owner, tx.input_note[0].account_required, 0); - claim::claim_note claim_note = { - tx.partial_claim_note.deposit_value, tx.partial_claim_note.bridge_call_data, 0, 0, partial_value_commitment, - tx.partial_claim_note.input_nullifier - }; + Builder circuit = sign_and_create_circuit(tx, user.owner); + EXPECT_TRUE(CircuitChecker::check(circuit)); +} - auto input_note1_commitment = tx.input_note[0].commit(); - auto input_note2_commitment = tx.input_note[1].commit(); - auto output_note1_commitment = claim_note.partial_commit(); - auto output_note2_commitment = tx.output_note[1].commit(); - uint256_t nullifier1 = compute_nullifier(input_note1_commitment, user.owner.private_key, true); - uint256_t nullifier2 = compute_nullifier(input_note2_commitment, user.owner.private_key, true); - - EXPECT_EQ(proof_data.proof_id, proof_ids::DEFI_DEPOSIT); - EXPECT_EQ(proof_data.note_commitment1, output_note1_commitment); - EXPECT_EQ(proof_data.note_commitment2, output_note2_commitment); - EXPECT_EQ(proof_data.nullifier1, nullifier1); - EXPECT_EQ(proof_data.nullifier2, nullifier2); - EXPECT_EQ(proof_data.public_value, uint256_t(0)); - EXPECT_EQ(proof_data.public_owner, fr(0)); - EXPECT_EQ(proof_data.asset_id, uint256_t(0)); - EXPECT_EQ(proof_data.merkle_root, tree->root()); - EXPECT_EQ(proof_data.tx_fee, uint256_t(10)); - EXPECT_EQ(proof_data.tx_fee_asset_id, bridge_call_data.input_asset_id_a); - EXPECT_EQ(proof_data.bridge_call_data, tx.partial_claim_note.bridge_call_data); - EXPECT_EQ(proof_data.defi_deposit_value, tx.partial_claim_note.deposit_value); - EXPECT_EQ(proof_data.defi_root, fr(0)); - - EXPECT_TRUE(verify_proof(proof)); -} - -TEST_F(join_split_tests, test_repayment_full_proof) +TEST_F(join_split_tests, test_repayment) { join_split_tx tx = simple_setup({ 0, 11 }); @@ -2439,79 +2298,8 @@ TEST_F(join_split_tests, test_repayment_full_proof) tx.partial_claim_note.bridge_call_data = bridge_call_data.to_uint256_t(); tx.partial_claim_note.input_nullifier = tx.output_note[0].input_nullifier; - auto proof = sign_and_create_proof(tx, user.owner); - auto proof_data = inner_proof_data(proof.proof_data); - - auto partial_commitment = value::create_partial_commitment( - tx.partial_claim_note.note_secret, tx.input_note[0].owner, tx.input_note[0].account_required, 0); - claim::claim_note claim_note = { - tx.partial_claim_note.deposit_value, tx.partial_claim_note.bridge_call_data, 0, 0, partial_commitment, - tx.partial_claim_note.input_nullifier - }; - - auto input_note1_commitment = tx.input_note[0].commit(); - auto input_note2_commitment = tx.input_note[1].commit(); - auto output_note1_commitment = claim_note.partial_commit(); - auto output_note2_commitment = tx.output_note[1].commit(); - uint256_t nullifier1 = compute_nullifier(input_note1_commitment, user.owner.private_key, true); - uint256_t nullifier2 = compute_nullifier(input_note2_commitment, user.owner.private_key, true); - - EXPECT_EQ(proof_data.proof_id, proof_ids::DEFI_DEPOSIT); - EXPECT_EQ(proof_data.note_commitment1, output_note1_commitment); - EXPECT_EQ(proof_data.note_commitment2, output_note2_commitment); - EXPECT_EQ(proof_data.nullifier1, nullifier1); - EXPECT_EQ(proof_data.nullifier2, nullifier2); - EXPECT_EQ(proof_data.public_value, uint256_t(0)); - EXPECT_EQ(proof_data.public_owner, fr(0)); - EXPECT_EQ(proof_data.asset_id, uint256_t(0)); - EXPECT_EQ(proof_data.merkle_root, tree->root()); - EXPECT_EQ(proof_data.tx_fee, uint256_t(0)); - EXPECT_EQ(proof_data.tx_fee_asset_id, bridge_call_data.input_asset_id_a); - EXPECT_EQ(proof_data.bridge_call_data, tx.partial_claim_note.bridge_call_data); - EXPECT_EQ(proof_data.defi_deposit_value, tx.partial_claim_note.deposit_value); - EXPECT_EQ(proof_data.defi_root, fr(0)); - - EXPECT_TRUE(verify_proof(proof)); -} - -TEST_F(join_split_tests, test_send_two_virtual_notes_full_proof) -{ - join_split_tx tx = simple_setup({ 4, 5 }); - - /** - * SEND tx represents: - * - 100 in1 (virtual) - * - 30 in2 (virtual, same asset_id) - * - 130 out1 - * - 0 out2 - */ - - auto proof = sign_and_create_proof(tx, user.owner); - - auto proof_data = inner_proof_data(proof.proof_data); - - auto input_note1_commitment = tx.input_note[0].commit(); - auto input_note2_commitment = tx.input_note[1].commit(); - auto output_note1_commitment = tx.output_note[0].commit(); - auto output_note2_commitment = tx.output_note[1].commit(); - uint256_t nullifier1 = compute_nullifier(input_note1_commitment, user.owner.private_key, true); - uint256_t nullifier2 = compute_nullifier(input_note2_commitment, user.owner.private_key, true); - - EXPECT_EQ(proof_data.proof_id, proof_ids::SEND); - EXPECT_EQ(proof_data.note_commitment1, output_note1_commitment); - EXPECT_EQ(proof_data.note_commitment2, output_note2_commitment); - EXPECT_EQ(proof_data.nullifier1, nullifier1); - EXPECT_EQ(proof_data.nullifier2, nullifier2); - EXPECT_EQ(proof_data.public_value, uint256_t(0)); - EXPECT_EQ(proof_data.public_owner, fr(0)); - EXPECT_EQ(proof_data.asset_id, uint256_t(0)); - EXPECT_EQ(proof_data.merkle_root, tree->root()); - EXPECT_EQ(proof_data.tx_fee, uint256_t(0)); - EXPECT_EQ(proof_data.tx_fee_asset_id, tx.asset_id); - EXPECT_EQ(proof_data.defi_deposit_value, uint256_t(0)); - EXPECT_EQ(proof_data.defi_root, fr(0)); - - EXPECT_TRUE(verify_proof(proof)); + Builder circuit = sign_and_create_circuit(tx, user.owner); + EXPECT_TRUE(CircuitChecker::check(circuit)); } -} // namespace bb::join_split_example::proofs::join_split +} // namespace bb::join_split_example::proofs::join_split \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.cpp index 109deccf829..580f3e7f7a2 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.cpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.cpp @@ -1,10 +1,10 @@ #include "join_split_circuit.hpp" -#include "../../constants.hpp" -#include "../notes/circuit/account/account_note.hpp" -#include "../notes/circuit/claim/claim_note.hpp" -#include "../notes/circuit/value/compute_nullifier.hpp" -#include "../notes/circuit/value/value_note.hpp" #include "barretenberg/crypto/merkle_tree/membership.hpp" +#include "barretenberg/join_split_example/constants.hpp" +#include "barretenberg/join_split_example/proofs/notes/circuit/account/account_note.hpp" +#include "barretenberg/join_split_example/proofs/notes/circuit/claim/claim_note.hpp" +#include "barretenberg/join_split_example/proofs/notes/circuit/value/compute_nullifier.hpp" +#include "barretenberg/join_split_example/proofs/notes/circuit/value/value_note.hpp" #include "barretenberg/join_split_example/types.hpp" #include "verify_signature.hpp" diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.hpp index 799f0228bfd..5aee2888920 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.hpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_circuit.hpp @@ -1,7 +1,7 @@ #pragma once -#include "../notes/circuit/claim/witness_data.hpp" -#include "../notes/circuit/value/witness_data.hpp" #include "barretenberg/crypto/schnorr/schnorr.hpp" +#include "barretenberg/join_split_example/proofs/notes/circuit/claim/witness_data.hpp" +#include "barretenberg/join_split_example/proofs/notes/circuit/value/witness_data.hpp" #include "barretenberg/join_split_example/types.hpp" #include "join_split_tx.hpp" diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_js_parity.test.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_js_parity.test.cpp deleted file mode 100644 index b45627e3db0..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_js_parity.test.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "../../constants.hpp" -#include "../inner_proof_data/inner_proof_data.hpp" -#include "../notes/native/index.hpp" -#include "barretenberg/common/streams.hpp" -#include "barretenberg/common/test.hpp" -#include "barretenberg/crypto/merkle_tree/index.hpp" -#include "barretenberg/crypto/sha256/sha256.hpp" -#include "barretenberg/plonk/proof_system/proving_key/serialize.hpp" -#include "index.hpp" - -namespace bb::join_split_example::proofs::join_split { - -using namespace bb; -// using namespace bb::stdlib::types; -using namespace bb::crypto::merkle_tree; -using namespace bb::join_split_example::proofs::notes::native; -using key_pair = join_split_example::fixtures::grumpkin_key_pair; - -/** - * This test mirrors the test in join_split_prover.test.ts - */ -class join_split_js_parity_tests : public ::testing::Test { - protected: - static void SetUpTestCase() - { - srs::init_crs_factory("../srs_db/ignition"); - init_proving_key(false); - init_verification_key(); - info("vk hash: ", get_verification_key()->sha256_hash()); - } - - virtual void SetUp() - { - store = std::make_unique(); - tree = std::make_unique>(*store, 32); - } - - void append_notes(std::vector const& notes) - { - for (auto note : notes) { - tree->update_element(tree->size(), note.commit()); - } - } - - plonk::proof sign_and_create_proof(join_split_tx& tx, key_pair const& signing_key) - { - tx.signature = sign_join_split_tx(tx, signing_key); - - auto prover = new_join_split_prover(tx, false); - return prover.construct_proof(); - } - - bool sign_and_verify(join_split_tx& tx, key_pair const& signing_key) - { - return verify_proof(sign_and_create_proof(tx, signing_key)); - } - - std::unique_ptr store; - std::unique_ptr> tree; -}; - -TEST_F(join_split_js_parity_tests, test_full_proof) -{ - auto private_key = from_buffer(std::vector{ - 0x0b, 0x9b, 0x3a, 0xde, 0xe6, 0xb3, 0xd8, 0x1b, 0x28, 0xa0, 0x88, 0x6b, 0x2a, 0x84, 0x15, 0xc7, - 0xda, 0x31, 0x29, 0x1a, 0x5e, 0x96, 0xbb, 0x7a, 0x56, 0x63, 0x9e, 0x17, 0x7d, 0x30, 0x1b, 0xeb }); - auto public_key = grumpkin::g1::one * private_key; - auto note_secret = from_buffer(std::vector{ - 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11 }); - auto input_nullifier1 = from_buffer(std::vector{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }); - auto input_nullifier2 = from_buffer(std::vector{ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }); - - value::value_note input_note1 = { - .value = 100, - .asset_id = 0, - .account_required = 0, - .owner = public_key, - .secret = note_secret, - .creator_pubkey = 0, - .input_nullifier = input_nullifier1, - }; - value::value_note input_note2 = { - .value = 50, - .asset_id = 0, - .account_required = 0, - .owner = public_key, - .secret = note_secret, - .creator_pubkey = 0, - .input_nullifier = input_nullifier2, - }; - - append_notes({ input_note1, input_note2 }); - - auto input_note1_nullifier = compute_nullifier(input_note1.commit(), private_key, true); - auto input_note2_nullifier = compute_nullifier(input_note2.commit(), private_key, true); - value::value_note output_note1 = { 80, 0, 0, public_key, note_secret, 0, input_note1_nullifier }; - value::value_note output_note2 = { 50, 0, 0, public_key, note_secret, 0, input_note2_nullifier }; - - join_split_tx tx; - tx.proof_id = proof_ids::SEND; - tx.public_value = 0; - tx.public_owner = 0; - tx.asset_id = 0; - tx.num_input_notes = 2; - tx.input_index = { 0, 1 }; - tx.old_data_root = tree->root(); - tx.input_path = { tree->get_hash_path(0), tree->get_hash_path(1) }; - tx.input_note = { input_note1, input_note2 }; - tx.output_note = { output_note1, output_note2 }; - tx.partial_claim_note.bridge_call_data = 0; - tx.partial_claim_note.deposit_value = 0; - tx.partial_claim_note.note_secret = 0; - tx.partial_claim_note.input_nullifier = 0; - tx.account_private_key = private_key; - tx.alias_hash = join_split_example::fixtures::generate_alias_hash("penguin"); - tx.account_required = false; - tx.account_note_index = 0; - tx.account_note_path = tree->get_hash_path(0); - tx.signing_pub_key = public_key; - tx.backward_link = 0; - tx.allow_chain = 0; - tx.signature.e = { 0 }; - tx.signature.s = { 0 }; - - // To assert that the C++ and TypeScript code produces the same input data. - info("tx buffer hash: ", crypto::sha256(to_buffer(tx))); - - auto proof = sign_and_create_proof(tx, { private_key, public_key }); - auto proof_data = inner_proof_data(proof.proof_data); - - auto output_note1_commitment = tx.output_note[0].commit(); - auto output_note2_commitment = tx.output_note[1].commit(); - - EXPECT_EQ(proof_data.proof_id, proof_ids::SEND); - EXPECT_EQ(proof_data.note_commitment1, output_note1_commitment); - EXPECT_EQ(proof_data.note_commitment2, output_note2_commitment); - EXPECT_EQ(proof_data.nullifier1, uint256_t(input_note1_nullifier)); - EXPECT_EQ(proof_data.nullifier2, uint256_t(input_note2_nullifier)); - EXPECT_EQ(proof_data.public_value, tx.public_value); - EXPECT_EQ(proof_data.public_owner, tx.public_owner); - EXPECT_EQ(proof_data.asset_id, tx.asset_id); - EXPECT_EQ(proof_data.merkle_root, tree->root()); - EXPECT_EQ(proof_data.tx_fee, uint256_t(20)); - EXPECT_EQ(proof_data.tx_fee_asset_id, tx.asset_id); - EXPECT_EQ(proof_data.bridge_call_data, uint256_t(0)); - EXPECT_EQ(proof_data.defi_deposit_value, uint256_t(0)); - EXPECT_EQ(proof_data.defi_root, fr(0)); - - EXPECT_TRUE(verify_proof(proof)); - - // auto& stats = get_proving_key()->underlying_store.get_stats(); - // for (auto& e : stats) { - // info(e.first, ": reads: ", e.second.second, " writes: ", e.second.first); - // } -} - -} // namespace bb::join_split_example::proofs::join_split diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.hpp index 1e164be2687..62c1564425b 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.hpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.hpp @@ -1,8 +1,8 @@ #pragma once -#include "../notes/native/claim/claim_note_tx_data.hpp" -#include "../notes/native/value/value_note.hpp" #include "barretenberg/crypto/merkle_tree/hash_path.hpp" #include "barretenberg/crypto/schnorr/schnorr.hpp" +#include "barretenberg/join_split_example/proofs/notes/native/claim/claim_note_tx_data.hpp" +#include "barretenberg/join_split_example/proofs/notes/native/value/value_note.hpp" #include "barretenberg/join_split_example/types.hpp" namespace bb::join_split_example::proofs::join_split { diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.test.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.test.cpp deleted file mode 100644 index 758ae4c1a30..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/join_split_tx.test.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "../../fixtures/user_context.hpp" - -#include "join_split.hpp" - -#include "barretenberg/common/streams.hpp" -#include "barretenberg/crypto/schnorr/schnorr.hpp" -#include "barretenberg/numeric/random/engine.hpp" -#include "barretenberg/srs/io.hpp" - -#include -#include - -using namespace bb; -using namespace bb::join_split_example::proofs::join_split; - -namespace { -auto& engine = numeric::get_debug_randomness(); -} - -TEST(client_proofs_join_split_tx, test_serialization) -{ - join_split_tx tx = {}; - tx.proof_id = 1; - tx.account_note_index = 0; - tx.signing_pub_key = grumpkin::g1::one * grumpkin::fr::random_element(&engine); - tx.public_value = 10; - tx.public_owner = fr::random_element(&engine); - tx.num_input_notes = 2; - tx.account_private_key = grumpkin::fr::random_element(&engine); - tx.alias_hash = 0; - tx.account_required = true; - tx.old_data_root = fr::random_element(&engine); - for (size_t i = 0; i < 32; ++i) { - tx.account_note_path.push_back(std::make_pair(fr::random_element(&engine), fr::random_element(&engine))); - tx.input_path[0].push_back(std::make_pair(fr::random_element(&engine), fr::random_element(&engine))); - tx.input_path[1].push_back(std::make_pair(fr::random_element(&engine), fr::random_element(&engine))); - } - - for (size_t i = 0; i < 2; ++i) { - tx.input_note[i].owner = tx.signing_pub_key; - tx.input_note[i].value = 123; - tx.input_note[i].secret = fr::random_element(&engine); - tx.input_note[i].input_nullifier = fr::random_element(&engine); - tx.input_note[i].creator_pubkey = fr::random_element(&engine); - tx.input_note[i].account_required = true; - } - - for (size_t i = 0; i < 2; ++i) { - tx.output_note[i].owner = tx.signing_pub_key; - tx.output_note[i].value = 321; - tx.output_note[i].secret = fr::random_element(&engine); - tx.output_note[i].input_nullifier = fr::random_element(&engine); - tx.output_note[i].creator_pubkey = fr::random_element(&engine); - tx.output_note[i].account_required = true; - } - - tx.partial_claim_note.bridge_call_data = 0xdeadbeef; - tx.partial_claim_note.note_secret = 0xcafebabe; - tx.partial_claim_note.deposit_value = 666; - - memset(&tx.signature.e, 1, 32); - memset(&tx.signature.s, 2, 32); - - tx.backward_link = fr::random_element(&engine); - tx.allow_chain = 2; - - auto buffer = to_buffer(tx); - auto tx2 = from_buffer(buffer.data()); - - EXPECT_EQ(tx, tx2); -} diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/sign_join_split_tx.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/sign_join_split_tx.hpp index a02a35f2f29..df0736d208b 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/sign_join_split_tx.hpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/join_split/sign_join_split_tx.hpp @@ -1,6 +1,6 @@ #pragma once -#include "../notes/native/value/value_note.hpp" #include "barretenberg/crypto/schnorr/schnorr.hpp" +#include "barretenberg/join_split_example/proofs/notes/native/value/value_note.hpp" #include "join_split_tx.hpp" namespace bb::join_split_example::proofs::join_split { diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/CMakeLists.txt deleted file mode 100644 index 2edf8f230d4..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -barretenberg_module( - rollup_proofs_mock - stdlib_blake2s - stdlib_sha256 - stdlib_pedersen_commitment - stdlib_primitives) \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/mock_circuit.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/mock_circuit.hpp deleted file mode 100644 index 0bd3b9bb724..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/mock_circuit.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include "barretenberg/common/map.hpp" -#include "barretenberg/stdlib/hash/pedersen/pedersen.hpp" -#include "barretenberg/stdlib/primitives/field/field.hpp" -namespace bb::join_split_example::proofs::mock { - -using namespace bb::plonk; - -template void mock_circuit(Builder& builder, std::vector const& public_inputs_) -{ - const auto public_inputs = - map(public_inputs_, [&](auto& i) { return stdlib::field_t(stdlib::witness_t(&builder, i)); }); - for (auto& p : public_inputs) { - p.set_public(); - } - stdlib::pedersen_hash::hash( - { stdlib::field_t(stdlib::witness_t(&builder, 1)), stdlib::field_t(stdlib::witness_t(&builder, 1)) }); -} - -} // namespace bb::join_split_example::proofs::mock diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/mock_circuit.test.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/mock_circuit.test.cpp deleted file mode 100644 index d0e71937f76..00000000000 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/mock/mock_circuit.test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "mock_circuit.hpp" -#include "../join_split/join_split_tx.hpp" -#include "barretenberg/common/test.hpp" -#include "barretenberg/join_split_example/types.hpp" - -using namespace bb::stdlib; - -namespace rollup::proofs::mock { - -class MockCircuitTests : public ::testing::Test { - protected: - static void SetUpTestSuite() { bb::srs::init_crs_factory("../srs_db/ignition"); } -}; - -TEST_F(MockCircuitTests, test_simple_circuit) -{ - // Dummy public inputs - std::vector public_inputs; - for (size_t i = 0; i < 16; i++) { - public_inputs.push_back(fr::random_element()); - } - - Composer composer = Composer(); - mock_circuit(composer, public_inputs); - - auto prover = composer.create_prover(); - plonk::proof proof = prover.construct_proof(); - - std::cout << "gates: " << composer.get_num_gates() << std::endl; - std::cout << "proof size: " << proof.proof_data.size() << std::endl; - std::cout << "public inputs size: " << composer.public_inputs.size() << std::endl; - - auto verifier = composer.create_verifier(); - bool result = verifier.verify_proof(proof); - - EXPECT_TRUE(result); -} - -} // namespace rollup::proofs::mock diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/notes/circuit/value/value_note.test.cpp b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/notes/circuit/value/value_note.test.cpp index 1353b58e8d7..e06ab6968f2 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/proofs/notes/circuit/value/value_note.test.cpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/proofs/notes/circuit/value/value_note.test.cpp @@ -1,6 +1,7 @@ #include "../../native/value/value_note.hpp" #include "../../../../fixtures/user_context.hpp" #include "../../constants.hpp" +#include "barretenberg/circuit_checker/circuit_checker.hpp" #include "barretenberg/join_split_example/types.hpp" #include "value_note.hpp" #include @@ -19,7 +20,7 @@ class ValueNote : public ::testing::Test { TEST_F(ValueNote, Commits) { auto user = join_split_example::fixtures::create_user_context(); - auto builder = Builder(); + Builder builder; fr note_value = fr::random_element(); note_value.data[3] = note_value.data[3] & 0x0FFFFFFFFFFFFFFFULL; @@ -37,24 +38,14 @@ TEST_F(ValueNote, Commits) auto result = circuit_note.commitment; result.assert_equal(expected); - auto composer = Composer(); - auto prover = composer.create_prover(builder); - EXPECT_FALSE(builder.failed()); - info("composer gates = %zu\n", builder.get_num_gates()); - auto verifier = composer.create_verifier(builder); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); + EXPECT_EQ(CircuitChecker::check(builder), true); } TEST_F(ValueNote, CommitsWith0Value) { - auto builder = Builder(); - auto user = join_split_example::fixtures::create_user_context(); + Builder builder; uint32_t asset_id_value = 0x2abbccddULL; // needs to be less than 30 bits @@ -67,31 +58,20 @@ TEST_F(ValueNote, CommitsWith0Value) .creator_pubkey = 0, .input_nullifier = fr::random_element(), }; + auto expected = note.commit(); auto circuit_note = circuit::value::value_note(witness_data(builder, note)); auto result = circuit_note.commitment; result.assert_equal(expected); - Composer composer = Composer(); - - auto prover = composer.create_prover(builder); - - EXPECT_FALSE(builder.failed()); - info("composer gates = %zu\n", builder.get_num_gates()); - auto verifier = composer.create_verifier(builder); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, true); + EXPECT_EQ(CircuitChecker::check(builder), true); } TEST_F(ValueNote, CommitWithOversizedAssetIdFails) { - auto builder = Builder(); - auto user = join_split_example::fixtures::create_user_context(); + Builder builder; native::value::value_note note = { .value = 0, @@ -108,16 +88,7 @@ TEST_F(ValueNote, CommitWithOversizedAssetIdFails) auto result = circuit_note.commitment; result.assert_equal(expected); - Composer composer = Composer(); - auto prover = composer.create_prover(builder); - EXPECT_TRUE(builder.failed()); - info("composer gates = %zu\n", builder.get_num_gates()); - auto verifier = composer.create_verifier(builder); - - plonk::proof proof = prover.construct_proof(); - - bool proof_result = verifier.verify_proof(proof); - EXPECT_EQ(proof_result, false); + EXPECT_EQ(CircuitChecker::check(builder), false); } } // namespace bb::join_split_example \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/join_split_example/types.hpp b/barretenberg/cpp/src/barretenberg/join_split_example/types.hpp index 392fe9d4790..3d4eae0ecc0 100644 --- a/barretenberg/cpp/src/barretenberg/join_split_example/types.hpp +++ b/barretenberg/cpp/src/barretenberg/join_split_example/types.hpp @@ -1,10 +1,7 @@ #pragma once -#include "barretenberg/plonk/composer/standard_composer.hpp" -#include "barretenberg/plonk/composer/ultra_composer.hpp" - #include "barretenberg/crypto/merkle_tree/hash_path.hpp" -#include "barretenberg/plonk/proof_system/prover/prover.hpp" +#include "barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp" #include "barretenberg/stdlib/commitment/pedersen/pedersen.hpp" #include "barretenberg/stdlib/encryption/schnorr/schnorr.hpp" #include "barretenberg/stdlib/primitives/bool/bool.hpp" @@ -16,28 +13,20 @@ namespace bb::join_split_example { -using Builder = bb::UltraCircuitBuilder; -using Composer = plonk::UltraComposer; - -using Prover = std::conditional_t, plonk::UltraProver, plonk::Prover>; - -using Verifier = - std::conditional_t, plonk::UltraVerifier, plonk::Verifier>; - -using witness_ct = bb::stdlib::witness_t; -using public_witness_ct = bb::stdlib::public_witness_t; -using bool_ct = bb::stdlib::bool_t; -using byte_array_ct = bb::stdlib::byte_array; -using field_ct = bb::stdlib::field_t; -using suint_ct = bb::stdlib::safe_uint_t; -using uint32_ct = bb::stdlib::uint32; -using group_ct = bb::stdlib::cycle_group; -using pedersen_commitment = bb::stdlib::pedersen_commitment; -using pedersen_hash = bb::stdlib::pedersen_hash; -using bn254 = bb::stdlib::bn254; - -using hash_path_ct = bb::crypto::merkle_tree::hash_path; - -using schnorr_signature_bits = bb::stdlib::schnorr_signature_bits; +using Builder = UltraCircuitBuilder; + +using witness_ct = stdlib::witness_t; +using public_witness_ct = stdlib::public_witness_t; +using bool_ct = stdlib::bool_t; +using byte_array_ct = stdlib::byte_array; +using field_ct = stdlib::field_t; +using suint_ct = stdlib::safe_uint_t; +using uint32_ct = stdlib::uint32; +using group_ct = stdlib::cycle_group; +using pedersen_commitment = stdlib::pedersen_commitment; +using pedersen_hash = stdlib::pedersen_hash; +using bn254 = stdlib::bn254; +using hash_path_ct = crypto::merkle_tree::hash_path; +using schnorr_signature_bits = stdlib::schnorr_signature_bits; } // namespace bb::join_split_example diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp index a470905cc8f..127d7ceb1c8 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.cpp @@ -2659,9 +2659,39 @@ template void UltraCircuitBuilder_:: } } +template uint256_t UltraCircuitBuilder_::hash_circuit() +{ + finalize_circuit(); + + size_t sum_of_block_sizes(0); + for (auto& block : blocks.get()) { + sum_of_block_sizes += block.size(); + } + + size_t num_bytes_in_selectors = sizeof(FF) * Arithmetization::NUM_SELECTORS * sum_of_block_sizes; + size_t num_bytes_in_wires_and_copy_constraints = + sizeof(uint32_t) * (Arithmetization::NUM_WIRES * sum_of_block_sizes + this->real_variable_index.size()); + size_t num_bytes_to_hash = num_bytes_in_selectors + num_bytes_in_wires_and_copy_constraints; + + std::vector to_hash(num_bytes_to_hash); + + const auto convert_and_insert = [&to_hash](auto& vector) { + std::vector buffer = to_buffer(vector); + to_hash.insert(to_hash.end(), buffer.begin(), buffer.end()); + }; + + for (auto& block : blocks.get()) { + std::for_each(block.selectors.begin(), block.selectors.end(), convert_and_insert); + std::for_each(block.wires.begin(), block.wires.end(), convert_and_insert); + } + convert_and_insert(this->real_variable_index); + + return from_buffer(crypto::sha256(to_hash)); +} + template class UltraCircuitBuilder_>; template class UltraCircuitBuilder_>; // To enable this we need to template plookup // template class UltraCircuitBuilder_; -} // namespace bb +} // namespace bb \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp index f9f873a8973..55d2acc3757 100644 --- a/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp +++ b/barretenberg/cpp/src/barretenberg/proof_system/circuit_builder/ultra_circuit_builder.hpp @@ -792,6 +792,8 @@ class UltraCircuitBuilder_ : public CircuitBuilderBase>; } // namespace bb