Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: acir format cleanup #2779

Merged
merged 14 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 25 additions & 109 deletions barretenberg/cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,30 @@ void read_witness(Builder& builder, WitnessVector const& witness)
}
}

void create_circuit(Builder& builder, acir_format const& constraint_system)
void add_public_vars(Builder& builder, acir_format const& constraint_system)
{
if (constraint_system.public_inputs.size() > constraint_system.varnum) {
info("create_circuit: too many public inputs!");
}

for (size_t i = 1; i < constraint_system.varnum; ++i) {
// If the index is in the public inputs vector, then we add it as a public input

if (std::find(constraint_system.public_inputs.begin(), constraint_system.public_inputs.end(), i) !=
constraint_system.public_inputs.end()) {

builder.add_public_variable(0);

} else {
builder.add_variable(0);
}
}
}

void build_constraints(Builder& builder, acir_format const& constraint_system, bool has_valid_witness_assignments)
{
// Add arithmetic gates
for (const auto& constraint : constraint_system.constraints) {
builder.create_poly_gate(constraint);
}

// Add and constraint
// Add logic constraint
for (const auto& constraint : constraint_system.logic_constraints) {
create_logic_gate(
builder, constraint.a, constraint.b, constraint.result, constraint.num_bits, constraint.is_xor_gate);
Expand All @@ -54,14 +55,14 @@ void create_circuit(Builder& builder, acir_format const& constraint_system)
create_schnorr_verify_constraints(builder, constraint);
}

// Add ECDSA K1 constraints
// Add ECDSA k1 constraints
for (const auto& constraint : constraint_system.ecdsa_k1_constraints) {
create_ecdsa_k1_verify_constraints(builder, constraint, false);
create_ecdsa_k1_verify_constraints(builder, constraint, has_valid_witness_assignments);
}

// Add ECDSA R1 constraints
// Add ECDSA r1 constraints
for (const auto& constraint : constraint_system.ecdsa_r1_constraints) {
create_ecdsa_r1_verify_constraints(builder, constraint, false);
create_ecdsa_r1_verify_constraints(builder, constraint, has_valid_witness_assignments);
}

// Add blake2s constraints
Expand Down Expand Up @@ -94,13 +95,13 @@ void create_circuit(Builder& builder, acir_format const& constraint_system)

// Add block constraints
for (const auto& constraint : constraint_system.block_constraints) {
create_block_constraints(builder, constraint, false);
create_block_constraints(builder, constraint, has_valid_witness_assignments);
}

// Add recursion constraints
for (size_t i = 0; i < constraint_system.recursion_constraints.size(); ++i) {
auto& constraint = constraint_system.recursion_constraints[i];
create_recursion_constraints(builder, constraint);
create_recursion_constraints(builder, constraint, has_valid_witness_assignments);

// make sure the verification key records the public input indices of the final recursion output
// (N.B. up to the ACIR description to make sure that the final output aggregation object wires are public
Expand All @@ -113,6 +114,16 @@ void create_circuit(Builder& builder, acir_format const& constraint_system)
}
}

void create_circuit(Builder& builder, acir_format const& constraint_system)
{
if (constraint_system.public_inputs.size() > constraint_system.varnum) {
info("create_circuit: too many public inputs!");
}

add_public_vars(builder, constraint_system);
build_constraints(builder, constraint_system, false);
}

Builder create_circuit(const acir_format& constraint_system, size_t size_hint)
{
Builder builder(size_hint);
Expand All @@ -135,104 +146,9 @@ void create_circuit_with_witness(Builder& builder, acir_format const& constraint
info("create_circuit_with_witness: too many public inputs!");
}

for (size_t i = 1; i < constraint_system.varnum; ++i) {
// If the index is in the public inputs vector, then we add it as a public input

if (std::find(constraint_system.public_inputs.begin(), constraint_system.public_inputs.end(), i) !=
constraint_system.public_inputs.end()) {

builder.add_public_variable(0);

} else {
builder.add_variable(0);
}
}

add_public_vars(builder, constraint_system);
read_witness(builder, witness);

// Add arithmetic gates
for (const auto& constraint : constraint_system.constraints) {
builder.create_poly_gate(constraint);
}

// Add logic constraint
for (const auto& constraint : constraint_system.logic_constraints) {
create_logic_gate(
builder, constraint.a, constraint.b, constraint.result, constraint.num_bits, constraint.is_xor_gate);
}

// Add range constraint
for (const auto& constraint : constraint_system.range_constraints) {
builder.create_range_constraint(constraint.witness, constraint.num_bits, "");
}

// Add sha256 constraints
for (const auto& constraint : constraint_system.sha256_constraints) {
create_sha256_constraints(builder, constraint);
}

// Add schnorr constraints
for (const auto& constraint : constraint_system.schnorr_constraints) {
create_schnorr_verify_constraints(builder, constraint);
}

// Add ECDSA k1 constraints
for (const auto& constraint : constraint_system.ecdsa_k1_constraints) {
create_ecdsa_k1_verify_constraints(builder, constraint);
}

// Add ECDSA r1 constraints
for (const auto& constraint : constraint_system.ecdsa_r1_constraints) {
create_ecdsa_r1_verify_constraints(builder, constraint);
}

// Add blake2s constraints
for (const auto& constraint : constraint_system.blake2s_constraints) {
create_blake2s_constraints(builder, constraint);
}

// Add keccak constraints
for (const auto& constraint : constraint_system.keccak_constraints) {
create_keccak_constraints(builder, constraint);
}
for (const auto& constraint : constraint_system.keccak_var_constraints) {
create_keccak_var_constraints(builder, constraint);
}

// Add pedersen constraints
for (const auto& constraint : constraint_system.pedersen_constraints) {
create_pedersen_constraint(builder, constraint);
}

// Add fixed base scalar mul constraints
for (const auto& constraint : constraint_system.fixed_base_scalar_mul_constraints) {
create_fixed_base_constraint(builder, constraint);
}

// Add hash to field constraints
for (const auto& constraint : constraint_system.hash_to_field_constraints) {
create_hash_to_field_constraints(builder, constraint);
}

// Add block constraints
for (const auto& constraint : constraint_system.block_constraints) {
create_block_constraints(builder, constraint);
}

// Add recursion constraints
for (size_t i = 0; i < constraint_system.recursion_constraints.size(); ++i) {
auto& constraint = constraint_system.recursion_constraints[i];
create_recursion_constraints(builder, constraint, true);

// make sure the verification key records the public input indices of the final recursion output
// (N.B. up to the ACIR description to make sure that the final output aggregation object wires are public
// inputs!)
if (i == constraint_system.recursion_constraints.size() - 1) {
std::vector<uint32_t> proof_output_witness_indices(constraint.output_aggregation_object.begin(),
constraint.output_aggregation_object.end());
builder.set_recursive_proof(proof_output_witness_indices);
}
}
build_constraints(builder, constraint_system, true);
}

} // namespace acir_format
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void create_block_constraints(Builder& builder, const BlockConstraint constraint
field_ct value = poly_to_field_ct(op.value, builder);
field_ct index = poly_to_field_ct(op.index, builder);
if (has_valid_witness_assignments == false) {
index = field_ct(0);
index = field_ct::from_witness(&builder, 0);
}
if (op.access_type == 0) {
value.assert_equal(table.read(index));
Expand Down
76 changes: 29 additions & 47 deletions barretenberg/cpp/src/barretenberg/dsl/acir_proofs/acir_composer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,83 +12,60 @@
namespace acir_proofs {

AcirComposer::AcirComposer(size_t size_hint, bool verbose)
: composer_(/*p_key=*/0, /*v_key=*/0)
, size_hint_(size_hint)
: size_hint_(size_hint)
, verbose_(verbose)
{}

void AcirComposer::create_circuit(acir_format::acir_format& constraint_system)
{
if (builder_.get_num_gates() > 1) {
return;
}
vinfo("building circuit...");
builder_ = acir_format::create_circuit(constraint_system, size_hint_);

// We are done with the constraint system at this point, and we need the memory slab back.
constraint_system.constraints.clear();
constraint_system.constraints.shrink_to_fit();

exact_circuit_size_ = builder_.get_num_gates();
total_circuit_size_ = builder_.get_total_circuit_size();
circuit_subgroup_size_ = builder_.get_circuit_subgroup_size(total_circuit_size_);
size_hint_ = circuit_subgroup_size_;
vinfo("gates: ", builder_.get_total_circuit_size());
}

void AcirComposer::init_proving_key(acir_format::acir_format& constraint_system)
{
vinfo("building circuit... ", size_hint_);
builder_ = acir_format::Builder(size_hint_);
acir_format::create_circuit(builder_, constraint_system);

// We are done with the constraint system at this point, and we need the memory slab back.
constraint_system.constraints.clear();
constraint_system.constraints.shrink_to_fit();

exact_circuit_size_ = builder_.get_num_gates();
total_circuit_size_ = builder_.get_total_circuit_size();
circuit_subgroup_size_ = builder_.get_circuit_subgroup_size(total_circuit_size_);

composer_ = acir_format::Composer();
create_circuit(constraint_system);
acir_format::Composer composer;
vinfo("computing proving key...");
proving_key_ = composer_.compute_proving_key(builder_);
proving_key_ = composer.compute_proving_key(builder_);
}

std::vector<uint8_t> AcirComposer::create_proof(acir_format::acir_format& constraint_system,
acir_format::WitnessVector& witness,
bool is_recursive)
{
// Release prior memory first.
composer_ = acir_format::Composer(/*p_key=*/0, /*v_key=*/0);

vinfo("building circuit...");
vinfo("building circuit with witness...");
builder_ = acir_format::Builder(size_hint_);
create_circuit_with_witness(builder_, constraint_system, witness);
vinfo("gates: ", builder_.get_total_circuit_size());

composer_ = [&]() {
auto composer = [&]() {
if (proving_key_) {
auto composer = acir_format::Composer(proving_key_, nullptr);
return composer;
} else {
return acir_format::Composer();
return acir_format::Composer(proving_key_, nullptr);
}
}();
if (!proving_key_) {

acir_format::Composer composer;
vinfo("computing proving key...");
proving_key_ = composer_.compute_proving_key(builder_);
proving_key_ = composer.compute_proving_key(builder_);
vinfo("done.");
}

// We are done with the constraint system at this point, and we need the memory slab back.
constraint_system.constraints.clear();
constraint_system.constraints.shrink_to_fit();
witness.clear();
witness.shrink_to_fit();
return composer;
}();

vinfo("creating proof...");
std::vector<uint8_t> proof;
if (is_recursive) {
auto prover = composer_.create_prover(builder_);
auto prover = composer.create_prover(builder_);
proof = prover.construct_proof().proof_data;
} else {
auto prover = composer_.create_ultra_with_keccak_prover(builder_);
auto prover = composer.create_ultra_with_keccak_prover(builder_);
proof = prover.construct_proof().proof_data;
}
vinfo("done.");
Expand All @@ -97,8 +74,12 @@ std::vector<uint8_t> AcirComposer::create_proof(acir_format::acir_format& constr

std::shared_ptr<proof_system::plonk::verification_key> AcirComposer::init_verification_key()
{
if (!proving_key_) {
throw_or_abort("Compute proving key first.");
}
vinfo("computing verification key...");
verification_key_ = composer_.compute_verification_key(builder_);
acir_format::Composer composer(proving_key_, nullptr);
verification_key_ = composer.compute_verification_key(builder_);
vinfo("done.");
return verification_key_;
}
Expand All @@ -107,25 +88,26 @@ void AcirComposer::load_verification_key(proof_system::plonk::verification_key_d
{
verification_key_ = std::make_shared<proof_system::plonk::verification_key>(
std::move(data), srs::get_crs_factory()->get_verifier_crs());
composer_ = acir_format::Composer(proving_key_, verification_key_);
}

bool AcirComposer::verify_proof(std::vector<uint8_t> const& proof, bool is_recursive)
{
acir_format::Composer composer(proving_key_, verification_key_);

if (!verification_key_) {
vinfo("computing verification key...");
verification_key_ = composer_.compute_verification_key(builder_);
verification_key_ = composer.compute_verification_key(builder_);
vinfo("done.");
}

// Hack. Shouldn't need to do this. 2144 is size with no public inputs.
builder_.public_inputs.resize((proof.size() - 2144) / 32);

if (is_recursive) {
auto verifier = composer_.create_verifier(builder_);
auto verifier = composer.create_verifier(builder_);
return verifier.verify_proof({ proof });
} else {
auto verifier = composer_.create_ultra_with_keccak_verifier(builder_);
auto verifier = composer.create_ultra_with_keccak_verifier(builder_);
return verifier.verify_proof({ proof });
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class AcirComposer {

private:
acir_format::Builder builder_;
acir_format::Composer composer_;
size_t size_hint_;
size_t exact_circuit_size_;
size_t total_circuit_size_;
Expand Down