Skip to content

Commit

Permalink
chore: remove some templates in templates (#11698)
Browse files Browse the repository at this point in the history
Clean up some functionality for generating solidity test circuits as we
don't have any utility of creating `StandardCircuits`
  • Loading branch information
maramihali authored Feb 3, 2025
1 parent 6d0bad7 commit 61614b1
Show file tree
Hide file tree
Showing 13 changed files with 61 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,6 @@ inline void output_vk_sol(std::ostream& os, std::shared_ptr<plonk::verification_
{
CircuitType circuit_type = static_cast<CircuitType>(key->circuit_type);
switch (circuit_type) {
case CircuitType::STANDARD: {
return output_vk_sol_standard(os, key, class_name);
break;
}
case CircuitType::ULTRA: {
return output_vk_sol_ultra(os, key, class_name);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#include "barretenberg/stdlib/primitives/field/field.hpp"
#include "barretenberg/stdlib/primitives/witness/witness.hpp"

template <typename Builder> class Add2Circuit {
class Add2Circuit {
public:
using Builder = bb::UltraCircuitBuilder;
using public_witness_ct = bb::stdlib::public_witness_t<Builder>;
using field_ct = bb::stdlib::field_t<Builder>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
#include "barretenberg/stdlib/primitives/field/field.hpp"
#include "barretenberg/stdlib/primitives/witness/witness.hpp"

template <typename Builder> class BlakeCircuit {
class BlakeCircuit {
public:
using Builder = bb::UltraCircuitBuilder;
using field_ct = bb::stdlib::field_t<Builder>;
using public_witness_ct = bb::stdlib::public_witness_t<Builder>;
using byte_array_ct = bb::stdlib::byte_array<Builder>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
#include "barretenberg/stdlib/primitives/witness/witness.hpp"

namespace bb {

template <typename Builder> class EcdsaCircuit {
class EcdsaCircuit {
public:
using Builder = bb::UltraCircuitBuilder;
using field_ct = stdlib::field_t<Builder>;
using bool_ct = stdlib::bool_t<Builder>;
using public_witness_ct = stdlib::public_witness_t<Builder>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ using namespace bb::plonk;
using namespace stdlib;
using numeric::uint256_t;

template <typename OuterBuilder> class RecursiveCircuit {
class RecursiveCircuit {
using InnerComposer = UltraComposer;
using InnerBuilder = typename InnerComposer::CircuitBuilder;
using Builder = UltraCircuitBuilder;

using inner_curve = bn254<InnerBuilder>;
using outer_curve = bn254<OuterBuilder>;
using inner_curve = bn254<Builder>;
using outer_curve = bn254<Builder>;

using verification_key_pt = recursion::verification_key<outer_curve>;
using recursive_settings = recursion::recursive_ultra_verifier_settings<outer_curve>;
Expand All @@ -34,20 +34,15 @@ template <typename OuterBuilder> class RecursiveCircuit {
using inner_scalar_field = typename inner_curve::ScalarFieldNative;
using outer_scalar_field = typename outer_curve::BaseFieldNative;
using pairing_target_field = bb::fq12;
static constexpr bool is_ultra_to_ultra = std::is_same_v<OuterBuilder, bb::UltraCircuitBuilder>;
using ProverOfInnerCircuit =
std::conditional_t<is_ultra_to_ultra, plonk::UltraProver, plonk::UltraToStandardProver>;
using VerifierOfInnerProof =
std::conditional_t<is_ultra_to_ultra, plonk::UltraVerifier, plonk::UltraToStandardVerifier>;
using RecursiveSettings =
std::conditional_t<is_ultra_to_ultra, recursive_settings, ultra_to_standard_recursive_settings>;
using ProverOfInnerCircuit = plonk::UltraProver;
using VerifierOfInnerProof = plonk::UltraVerifier;

struct circuit_outputs {
stdlib::recursion::aggregation_state<outer_curve> aggregation_state;
std::shared_ptr<verification_key_pt> verification_key;
};

static void create_inner_circuit_no_tables(InnerBuilder& builder, uint256_t public_inputs[])
static void create_inner_circuit_no_tables(Builder& builder, uint256_t public_inputs[])
{
// A nice Pythagorean triples circuit example: "I know a & b s.t. a^2 + b^2 = c^2".
inner_scalar_field_ct a(witness_ct(&builder, public_inputs[0]));
Expand All @@ -61,15 +56,11 @@ template <typename OuterBuilder> class RecursiveCircuit {
c_sq.set_public();
};

static circuit_outputs create_outer_circuit(InnerBuilder& inner_circuit, OuterBuilder& outer_builder)
static circuit_outputs create_outer_circuit(Builder& inner_circuit, Builder& outer_builder)
{
ProverOfInnerCircuit prover;
InnerComposer inner_composer;
if constexpr (is_ultra_to_ultra) {
prover = inner_composer.create_prover(inner_circuit);
} else {
prover = inner_composer.create_ultra_to_standard_prover(inner_circuit);
}
prover = inner_composer.create_prover(inner_circuit);

const auto verification_key_native = inner_composer.compute_verification_key(inner_circuit);
// Convert the verification key's elements into _circuit_ types, using the OUTER composer.
Expand All @@ -82,27 +73,23 @@ template <typename OuterBuilder> class RecursiveCircuit {
// Native check is mainly for comparison vs circuit version of the verifier.
VerifierOfInnerProof native_verifier;

if constexpr (is_ultra_to_ultra) {
native_verifier = inner_composer.create_verifier(inner_circuit);
} else {
native_verifier = inner_composer.create_ultra_to_standard_verifier(inner_circuit);
}
native_verifier = inner_composer.create_verifier(inner_circuit);

auto native_result = native_verifier.verify_proof(proof_to_recursively_verify);
if (native_result == false) {
bool native_result = native_verifier.verify_proof(proof_to_recursively_verify);
if (!native_result) {
throw_or_abort("Native verification failed");
}
}

transcript::Manifest recursive_manifest = InnerComposer::create_manifest(prover.key->num_public_inputs);

auto output = recursion::verify_proof<outer_curve, RecursiveSettings>(
auto output = recursion::verify_proof<outer_curve, recursive_settings>(
&outer_builder, verification_key, recursive_manifest, proof_to_recursively_verify);

return { output, verification_key };
};

static bool check_pairing_point_accum_public_inputs(OuterBuilder& builder, const bb::pairing::miller_lines* lines)
static bool check_pairing_point_accum_public_inputs(Builder& builder, const bb::pairing::miller_lines* lines)
{
if (builder.contains_pairing_point_accumulator &&
builder.pairing_point_accumulator_public_input_indices.size() == 16) {
Expand Down Expand Up @@ -166,10 +153,10 @@ template <typename OuterBuilder> class RecursiveCircuit {
}

public:
static OuterBuilder generate(uint256_t inputs[])
static Builder generate(uint256_t inputs[])
{
InnerBuilder inner_circuit;
OuterBuilder outer_circuit;
Builder inner_circuit;
Builder outer_circuit;

create_inner_circuit_no_tables(inner_circuit, inputs);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ using namespace bb;
using DeciderProvingKey = DeciderProvingKey_<UltraKeccakFlavor>;
using VerificationKey = UltraKeccakFlavor::VerificationKey;

template <template <typename> typename Circuit>
void generate_keys_honk(const std::string& output_path, std::string circuit_name)
template <typename Circuit> void generate_keys_honk(const std::string& output_path, std::string circuit_name)
{
uint256_t public_inputs[4] = { 0, 0, 0, 0 };
UltraCircuitBuilder builder = Circuit<UltraCircuitBuilder>::generate(public_inputs);
UltraCircuitBuilder builder = Circuit::generate(public_inputs);

auto proving_key = std::make_shared<DeciderProvingKey>(builder);
UltraKeccakProver prover(proving_key);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ using namespace bb;
using numeric::uint256_t;

// Get rid of the inner typename
template <template <typename> typename Circuit, typename Flavor> void generate_proof(uint256_t inputs[])
template <typename Circuit, typename Flavor> void generate_proof(uint256_t inputs[])
{
using DeciderProvingKey = DeciderProvingKey_<Flavor>;
using VerificationKey = typename Flavor::VerificationKey;
using Prover = UltraProver_<Flavor>;
using Verifier = UltraVerifier_<Flavor>;

UltraCircuitBuilder builder = Circuit<UltraCircuitBuilder>::generate(inputs);
UltraCircuitBuilder builder = Circuit::generate(inputs);

auto instance = std::make_shared<DeciderProvingKey>(builder);
Prover prover(instance);
Expand Down
35 changes: 14 additions & 21 deletions barretenberg/cpp/src/barretenberg/solidity_helpers/key_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
#include "utils/instance_sol_gen.hpp"
#include "utils/utils.hpp"

template <typename Composer, template <typename> typename Circuit>
void generate_keys(std::string output_path, std::string flavor_prefix, std::string circuit_name)
template <typename Circuit> void generate_keys(std::string output_path, std::string circuit_name)
{
uint256_t public_inputs[4] = { 0, 0, 0, 0 };
auto circuit = Circuit<typename Composer::CircuitBuilder>::generate(public_inputs);
auto circuit = Circuit::generate(public_inputs);

Composer composer;
UltraComposer composer;
std::shared_ptr<plonk::verification_key> vkey = composer.compute_verification_key(circuit);

// Make verification key file upper case
circuit_name.at(0) = static_cast<char>(std::toupper(static_cast<unsigned char>(circuit_name.at(0))));
flavor_prefix.at(0) = static_cast<char>(std::toupper(static_cast<unsigned char>(flavor_prefix.at(0))));
std::string flavor_prefix = "Ultra";

std::string vk_class_name = circuit_name + flavor_prefix + "VerificationKey";
std::string base_class_name = "Base" + flavor_prefix + "Verifier";
Expand Down Expand Up @@ -54,34 +53,28 @@ int main(int argc, char** argv)
{
std::vector<std::string> args(argv, argv + argc);

if (args.size() < 5) {
info("usage: ", args[0], "[plonk flavor] [circuit flavor] [output path] [srs path]");
if (args.size() < 4) {
info("usage: ", args[0], "[circuit type] [output path] [srs path]");
return 1;
}

const std::string plonk_flavor = args[1];
const std::string circuit_flavor = args[2];
const std::string output_path = args[3];
const std::string srs_path = args[4];
const std::string circuit_flavor = args[1];
const std::string output_path = args[2];
const std::string srs_path = args[3];

bb::srs::init_crs_factory(srs_path);
// @todo - Add support for unrolled standard verifier. Needs a new solidity verifier contract.

if (plonk_flavor != "ultra") {
info("Flavor must be ultra");
return 1;
}

info("Generating ", plonk_flavor, " keys for ", circuit_flavor, " circuit");
info("Generating keys for ", circuit_flavor, " circuit");

if (circuit_flavor == "blake") {
generate_keys<bb::plonk::UltraComposer, BlakeCircuit>(output_path, plonk_flavor, circuit_flavor);
generate_keys<BlakeCircuit>(output_path, circuit_flavor);
} else if (circuit_flavor == "add2") {
generate_keys<bb::plonk::UltraComposer, Add2Circuit>(output_path, plonk_flavor, circuit_flavor);
generate_keys<Add2Circuit>(output_path, circuit_flavor);
} else if (circuit_flavor == "recursive") {
generate_keys<bb::plonk::UltraComposer, RecursiveCircuit>(output_path, plonk_flavor, circuit_flavor);
generate_keys<RecursiveCircuit>(output_path, circuit_flavor);
} else if (circuit_flavor == "ecdsa") {
generate_keys<bb::plonk::UltraComposer, EcdsaCircuit>(output_path, plonk_flavor, circuit_flavor);
generate_keys<EcdsaCircuit>(output_path, circuit_flavor);
} else {
info("Unsupported circuit");
return 1;
Expand Down
20 changes: 10 additions & 10 deletions barretenberg/cpp/src/barretenberg/solidity_helpers/proof_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
using namespace bb::numeric;
using numeric::uint256_t;

template <typename Composer, template <typename> typename Circuit> void generate_proof(uint256_t inputs[])
template <typename Circuit> void generate_proof(uint256_t inputs[])
{
auto builder = Circuit<typename Composer::CircuitBuilder>::generate(inputs);
UltraCircuitBuilder builder = Circuit::generate(inputs);

Composer composer;
UltraComposer composer;
// @todo this only works for ultra! Why is ultra part of function name on ultra composer?
auto prover = composer.create_ultra_with_keccak_prover(builder);
auto proof = prover.construct_proof();
Expand Down Expand Up @@ -58,9 +58,9 @@ int main(int argc, char** argv)
}

const std::string plonk_flavor = args[1];
const std::string circuit_flavor = args[2];
const std::string srs_path = args[3];
const std::string string_input = args[4];
const std::string circuit_flavor = args[1];
const std::string srs_path = args[2];
const std::string string_input = args[3];

bb::srs::init_crs_factory(srs_path);

Expand All @@ -85,13 +85,13 @@ int main(int argc, char** argv)
}

if (circuit_flavor == "blake") {
generate_proof<UltraComposer, BlakeCircuit>(inputs);
generate_proof<BlakeCircuit>(inputs);
} else if (circuit_flavor == "add2") {
generate_proof<UltraComposer, Add2Circuit>(inputs);
generate_proof<Add2Circuit>(inputs);
} else if (circuit_flavor == "ecdsa") {
generate_proof<UltraComposer, EcdsaCircuit>(inputs);
generate_proof<EcdsaCircuit>(inputs);
} else if (circuit_flavor == "recursive") {
generate_proof<UltraComposer, RecursiveCircuit>(inputs);
generate_proof<RecursiveCircuit>(inputs);
} else {
info("Invalid circuit flavor: " + circuit_flavor);
return 1;
Expand Down
10 changes: 4 additions & 6 deletions barretenberg/sol/scripts/init.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#!/usr/bin/env bash


PLONK_FLAVOUR="ultra"
SRS_PATH="../cpp/srs_db/ignition"
OUTPUT_PATH="./src/ultra"

../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR add2 $OUTPUT_PATH $SRS_PATH
../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR blake $OUTPUT_PATH $SRS_PATH
../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR ecdsa $OUTPUT_PATH $SRS_PATH
../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR recursive $OUTPUT_PATH $SRS_PATH
../cpp/build/bin/solidity_key_gen add2 $OUTPUT_PATH $SRS_PATH
../cpp/build/bin/solidity_key_gen blake $OUTPUT_PATH $SRS_PATH
../cpp/build/bin/solidity_key_gen ecdsa $OUTPUT_PATH $SRS_PATH
../cpp/build/bin/solidity_key_gen recursive $OUTPUT_PATH $SRS_PATH
4 changes: 2 additions & 2 deletions barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Verification Key Hash: 35075d72ebcadda27f270f249615b163ee9b368feb3e481a43da7d265d3882aa
// Verification Key Hash: 594d0af354947ea7aa13eece55ec3ccdce54dff437d9354a8a50cb2a0438a86a
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec
pragma solidity >=0.8.4;

library Add2UltraVerificationKey {
function verificationKeyHash() internal pure returns (bytes32) {
return 0x35075d72ebcadda27f270f249615b163ee9b368feb3e481a43da7d265d3882aa;
return 0x594d0af354947ea7aa13eece55ec3ccdce54dff437d9354a8a50cb2a0438a86a;
}

function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure {
Expand Down
4 changes: 2 additions & 2 deletions barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Verification Key Hash: a1a6bc0ef32c16cad98318142e333ba99cf5d47bd499dd54341842a761cee8e1
// Verification Key Hash: 6c68aa62aa452a4dbb84e1246b10262e6fb6ff860b59d906db6fb0807d11b872
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec
pragma solidity >=0.8.4;

library BlakeUltraVerificationKey {
function verificationKeyHash() internal pure returns (bytes32) {
return 0xa1a6bc0ef32c16cad98318142e333ba99cf5d47bd499dd54341842a761cee8e1;
return 0x6c68aa62aa452a4dbb84e1246b10262e6fb6ff860b59d906db6fb0807d11b872;
}

function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure {
Expand Down
4 changes: 2 additions & 2 deletions barretenberg/sol/src/ultra/keys/EcdsaUltraVerificationKey.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// Verification Key Hash: c24940ebcac32ad1f759cedc6005b1ff4de4eb135c3db1d2cebb6f20ab2bd19f
// Verification Key Hash: 7d146c779845c11f731974db664e09fa3d3f98c34d1a982e72f0e76a747b59fc
// SPDX-License-Identifier: Apache-2.0
// Copyright 2022 Aztec
pragma solidity >=0.8.4;

library EcdsaUltraVerificationKey {
function verificationKeyHash() internal pure returns (bytes32) {
return 0xc24940ebcac32ad1f759cedc6005b1ff4de4eb135c3db1d2cebb6f20ab2bd19f;
return 0x7d146c779845c11f731974db664e09fa3d3f98c34d1a982e72f0e76a747b59fc;
}

function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure {
Expand Down

1 comment on commit 61614b1

@AztecBot
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'C++ Benchmark'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.05.

Benchmark suite Current: 61614b1 Previous: 6d0bad7 Ratio
wasmClientIVCBench/Full/6 83475.813774 ms/iter 73549.513516 ms/iter 1.13
commit(t) 3190324190 ns/iter 3023646061 ns/iter 1.06

This comment was automatically generated by workflow using github-action-benchmark.

CC: @ludamad @codygunton

Please sign in to comment.