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

feat: DSL recursion changes #383

Closed
wants to merge 48 commits into from
Closed
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
69eba2d
Added recursion constraint into dsl + tests
zac-williamson Apr 13, 2023
7a80056
fix dsl ecdsa constraint. Added ecdsa dsl tests
zac-williamson Apr 13, 2023
2436dcf
changed dsl recursion to pass proof/key as witnesses
zac-williamson Apr 16, 2023
292f626
recursive verification key no longer encapsulates a native key
zac-williamson Apr 16, 2023
bc02eff
added serialization test for acir_proofs
zac-williamson Apr 16, 2023
d9656e9
Added serialization methods into dsl for recursive proof composition
zac-williamson Apr 18, 2023
209f813
added verificaiton key hash into RecursionConstraint
zac-williamson Apr 18, 2023
6496228
fixed compiler errors in stdlib_recursion_tests
zac-williamson Apr 18, 2023
5f21e22
feat(dsl)!: Noir recursion updates (#379)
vezenovm Apr 25, 2023
f4253ad
master merge conflicts
vezenovm Apr 25, 2023
25f5574
EnvReferenceString undefined reference to error workaround
vezenovm Apr 25, 2023
1c8cc77
add missing recursion_constraint field from acir_format tests
vezenovm Apr 25, 2023
6109828
add recursion_constraints field back in acir_proofs.test inner circuit
vezenovm Apr 25, 2023
8358741
fix inner circuit in RecursionConstraint.TestRecursionConstraint
vezenovm Apr 25, 2023
b65c442
merge conflictss w/ master
vezenovm Apr 25, 2023
551277b
Empty-Commit
vezenovm Apr 25, 2023
ce46c01
add verify_recursive_proof method for simulating recursive verificati…
vezenovm Apr 28, 2023
87d7b40
master merge conflicts in acir_format and updates to generate method …
vezenovm Apr 28, 2023
11e97be
add ecc module to env package to fix linking of ennv_load_prover_crs …
vezenovm Apr 28, 2023
941b275
add back reference strinng to stdlib recursion key to pass sol verifi…
vezenovm May 1, 2023
6d86e39
remove prints from recursive verifier test
vezenovm May 1, 2023
5a458d6
fix dirty free for when serializing vk to fields, was working on macb…
vezenovm May 3, 2023
7399ea7
Merge branch 'master' into mv/noir-recursion
vezenovm May 5, 2023
07a22f6
fix ecdsa tests after master merge
vezenovm May 5, 2023
74a8327
missing keccak constraints fields in acir format and proofs tests
vezenovm May 5, 2023
18cfb94
one more missing keccak constraint
vezenovm May 5, 2023
7de20cd
merge conflicts w/ master
vezenovm May 15, 2023
155903e
mismatched acir format structs for gcc build
vezenovm May 15, 2023
683a875
missing block constraints in acir tests
vezenovm May 15, 2023
7ecb574
feat(dsl)!: Arbitrary depth recursion (#433)
vezenovm May 16, 2023
a2f6cbb
move export key into dsl package
vezenovm May 22, 2023
b56d3ca
chore: remove unused export key in recursion format from main proof s…
vezenovm May 22, 2023
97ede2e
pr review: moved from_witness comment and renamed from_field_pt_vector
vezenovm May 22, 2023
c64d8b5
moved export transcript in recursion format to DSL package
vezenovm May 22, 2023
a590470
use false for clang-format SortIncludes
vezenovm May 22, 2023
4d262e3
Merge branch 'master' into mv/noir-recursion
vezenovm May 22, 2023
f3baab0
move order of acir functions
vezenovm May 22, 2023
a793b2d
remove ecc bb_module declaration in env package
vezenovm May 22, 2023
f954266
chore: remove usage of magic numbers when slicing g1::affine_element …
vezenovm May 22, 2023
0f0d519
introduce NUM_AGGREGATION_ELEMENTS constant and use it through recurs…
vezenovm May 23, 2023
294c1fa
nit ASSERT(result != -1) in get_public_input_index
vezenovm May 23, 2023
517ed2c
remove unused found var
vezenovm May 23, 2023
92159e0
cast -1
vezenovm May 23, 2023
d8ee388
fix up verify_recursive_proof and add a test for it
vezenovm May 23, 2023
cf9bdd6
moved from tempalte for has_valid_witness_assignments to a flag
vezenovm May 23, 2023
2096676
chore: add comments to AcirProofs.TestVerifyRecursiveProofPass
vezenovm May 23, 2023
bb4404f
Merge branch 'master' into mv/noir-recursion
vezenovm May 24, 2023
5f551ea
minor formatting changes to remove files from PR
zac-williamson May 26, 2023
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
24 changes: 24 additions & 0 deletions cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ void create_circuit(Composer& composer, const acir_format& constraint_system)
for (const auto& constraint : constraint_system.hash_to_field_constraints) {
create_hash_to_field_constraints(composer, constraint);
}

// Add recursion constraints
for (const auto& constraint : constraint_system.recursion_constraints) {
create_recursion_constraints<false, false>(composer, constraint);
}
}

Composer create_circuit(const acir_format& constraint_system,
Expand All @@ -112,6 +117,7 @@ Composer create_circuit(const acir_format& constraint_system,
composer.add_variable(0);
}
}

// Add arithmetic gates
for (const auto& constraint : constraint_system.constraints) {
composer.create_poly_gate(constraint);
Expand Down Expand Up @@ -173,6 +179,11 @@ Composer create_circuit(const acir_format& constraint_system,
create_hash_to_field_constraints(composer, constraint);
}

// Add recursion constraints
for (const auto& constraint : constraint_system.recursion_constraints) {
create_recursion_constraints<false, false>(composer, constraint);
}

return composer;
}

Expand Down Expand Up @@ -262,6 +273,10 @@ Composer create_circuit_with_witness(const acir_format& constraint_system,
create_hash_to_field_constraints(composer, constraint);
}

// Add recursion constraints
for (const auto& constraint : constraint_system.recursion_constraints) {
create_recursion_constraints<true, false>(composer, constraint);
}
return composer;
}
Composer create_circuit_with_witness(const acir_format& constraint_system, std::vector<fr> witness)
Expand Down Expand Up @@ -348,6 +363,10 @@ Composer create_circuit_with_witness(const acir_format& constraint_system, std::
create_hash_to_field_constraints(composer, constraint);
}

// Add recursion constraints
for (const auto& constraint : constraint_system.recursion_constraints) {
create_recursion_constraints<true, false>(composer, constraint);
}
return composer;
}
void create_circuit_with_witness(Composer& composer, const acir_format& constraint_system, std::vector<fr> witness)
Expand Down Expand Up @@ -431,6 +450,11 @@ void create_circuit_with_witness(Composer& composer, const acir_format& constrai
for (const auto& constraint : constraint_system.hash_to_field_constraints) {
create_hash_to_field_constraints(composer, constraint);
}

// Add recursion constraints
for (const auto& constraint : constraint_system.recursion_constraints) {
create_recursion_constraints<true, false>(composer, constraint);
}
}

} // namespace acir_format
4 changes: 4 additions & 0 deletions cpp/src/barretenberg/dsl/acir_format/acir_format.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "schnorr_verify.hpp"
#include "ecdsa_secp256k1.hpp"
#include "compute_merkle_root_constraint.hpp"
#include "recursion_constraint.hpp"
#include "pedersen.hpp"
#include "hash_to_field.hpp"
#include "barretenberg/dsl/types.hpp"
Expand All @@ -31,6 +32,7 @@ struct acir_format {
std::vector<HashToFieldConstraint> hash_to_field_constraints;
std::vector<PedersenConstraint> pedersen_constraints;
std::vector<ComputeMerkleRootConstraint> compute_merkle_root_constraints;
std::vector<RecursionConstraint> recursion_constraints;
// A standard plonk arithmetic constraint, as defined in the poly_triple struct, consists of selector values
// for q_M,q_L,q_R,q_O,q_C and indices of three variables taking the role of left, right and output wire
std::vector<poly_triple> constraints;
Expand Down Expand Up @@ -70,6 +72,7 @@ template <typename B> inline void read(B& buf, acir_format& data)
read(buf, data.pedersen_constraints);
read(buf, data.hash_to_field_constraints);
read(buf, data.fixed_base_scalar_mul_constraints);
read(buf, data.recursion_constraints);
read(buf, data.constraints);
}

Expand All @@ -89,6 +92,7 @@ template <typename B> inline void write(B& buf, acir_format const& data)
write(buf, data.pedersen_constraints);
write(buf, data.hash_to_field_constraints);
write(buf, data.fixed_base_scalar_mul_constraints);
write(buf, data.recursion_constraints);
write(buf, data.constraints);
}

Expand Down
44 changes: 44 additions & 0 deletions cpp/src/barretenberg/dsl/acir_format/acir_format.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,47 @@
#include <vector>
#include "barretenberg/common/streams.hpp"

TEST(acir_format, test_a_single_constraint_no_pub_inputs)
{

poly_triple constraint{
.a = 1,
.b = 2,
.c = 3,
.q_m = 0,
.q_l = 1,
.q_r = 1,
.q_o = -1,
.q_c = 0,
};

acir_format::acir_format constraint_system{
.varnum = 4,
.public_inputs = {},
.fixed_base_scalar_mul_constraints = {},
.logic_constraints = {},
.range_constraints = {},
.schnorr_constraints = {},
.ecdsa_constraints = {},
.sha256_constraints = {},
.blake2s_constraints = {},
.hash_to_field_constraints = {},
.pedersen_constraints = {},
.compute_merkle_root_constraints = {},
.recursion_constraints = {},
.constraints = { constraint },
};

auto composer = acir_format::create_circuit_with_witness(constraint_system, { 0, 0, 1 });

auto prover = composer.create_ultra_with_keccak_prover();
auto proof = prover.construct_proof();

auto verifier = composer.create_ultra_with_keccak_verifier();

EXPECT_EQ(verifier.verify_proof(proof), false);
}

TEST(acir_format, test_logic_gate_from_noir_circuit)
{
/**
Expand Down Expand Up @@ -90,6 +131,7 @@ TEST(acir_format, test_logic_gate_from_noir_circuit)
.hash_to_field_constraints = {},
.pedersen_constraints = {},
.compute_merkle_root_constraints = {},
.recursion_constraints = {},
.constraints = { expr_a, expr_b, expr_c, expr_d },
};

Expand Down Expand Up @@ -155,6 +197,7 @@ TEST(acir_format, test_schnorr_verify_pass)
.hash_to_field_constraints = {},
.pedersen_constraints = {},
.compute_merkle_root_constraints = {},
.recursion_constraints = {},
.constraints = { poly_triple{
.a = schnorr_constraint.result,
.b = schnorr_constraint.result,
Expand Down Expand Up @@ -225,6 +268,7 @@ TEST(acir_format, test_schnorr_verify_small_range)
.hash_to_field_constraints = {},
.pedersen_constraints = {},
.compute_merkle_root_constraints = {},
.recursion_constraints = {},
.constraints = { poly_triple{
.a = schnorr_constraint.result,
.b = schnorr_constraint.result,
Expand Down
23 changes: 15 additions & 8 deletions cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,24 @@ void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Con

pub_key_x_fq.assert_is_in_field();
pub_key_y_fq.assert_is_in_field();

secp256k1_ct::g1_bigfr_ct public_key = secp256k1_ct::g1_bigfr_ct(pub_key_x_fq, pub_key_y_fq);
for (size_t i = 0; i < 32; ++i) {
sig.r[i].assert_equal(field_ct::from_witness_index(&composer, input.signature[i]));
sig.s[i].assert_equal(field_ct::from_witness_index(&composer, input.signature[i + 32]));
pub_key_x_byte_arr[i].assert_equal(field_ct::from_witness_index(&composer, input.pub_x_indices[i]));
pub_key_y_byte_arr[i].assert_equal(field_ct::from_witness_index(&composer, input.pub_y_indices[i]));
}
for (size_t i = 0; i < input.message.size(); ++i) {
message[i].assert_equal(field_ct::from_witness_index(&composer, input.message[i]));
}

bool_ct signature_result = stdlib::ecdsa::verify_signature<Composer,
secp256k1_ct,
secp256k1_ct::fq_ct,
secp256k1_ct::bigfr_ct,
secp256k1_ct::g1_bigfr_ct>(message, public_key, sig);

bool_ct signature_result =
stdlib::ecdsa::verify_signature_noassert<Composer,
secp256k1_ct,
secp256k1_ct::fq_ct,
secp256k1_ct::bigfr_ct,
secp256k1_ct::g1_bigfr_ct>(message, public_key, sig);
bool_ct signature_result_normalized = signature_result.normalize();

composer.assert_equal(signature_result_normalized.witness_index, input.result);
}

Expand Down
145 changes: 145 additions & 0 deletions cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include "acir_format.hpp"
#include "ecdsa_secp256k1.hpp"
#include "barretenberg/plonk/proof_system/types/proof.hpp"
#include "barretenberg/plonk/proof_system/verification_key/verification_key.hpp"
#include "barretenberg/crypto/ecdsa/ecdsa.hpp"

#include <gtest/gtest.h>
#include <vector>

using namespace proof_system::plonk;
using curve = stdlib::secp256k1<acir_format::Composer>;

size_t generate_ecdsa_constraint(acir_format::EcdsaSecp256k1Constraint& ecdsa_constraint,
std::vector<fr>& witness_values)
{
std::string message_string = "Instructions unclear, ask again later.";

crypto::ecdsa::key_pair<curve::fr, curve::g1> account;
account.private_key = curve::fr::random_element();
account.public_key = curve::g1::one * account.private_key;

crypto::ecdsa::signature signature =
crypto::ecdsa::construct_signature<Sha256Hasher, curve::fq, curve::fr, curve::g1>(message_string, account);

uint256_t pub_x_value = account.public_key.x;
uint256_t pub_y_value = account.public_key.y;

std::vector<uint32_t> message_in;
std::vector<uint32_t> pub_x_indices_in;
std::vector<uint32_t> pub_y_indices_in;
std::vector<uint32_t> signature_in;
size_t offset = 1;
for (size_t i = 0; i < message_string.size(); ++i) {
message_in.emplace_back(i + offset);
const auto byte = static_cast<uint8_t>(message_string[i]);
witness_values.emplace_back(byte);
}
offset += message_in.size();

for (size_t i = 0; i < 32; ++i) {
pub_x_indices_in.emplace_back(i + offset);
witness_values.emplace_back(pub_x_value.slice(248 - i * 8, 256 - i * 8));
}
offset += pub_x_indices_in.size();
for (size_t i = 0; i < 32; ++i) {
pub_y_indices_in.emplace_back(i + offset);
witness_values.emplace_back(pub_y_value.slice(248 - i * 8, 256 - i * 8));
}
offset += pub_y_indices_in.size();
for (size_t i = 0; i < 32; ++i) {
signature_in.emplace_back(i + offset);
witness_values.emplace_back(signature.r[i]);
}
offset += signature.r.size();
for (size_t i = 0; i < 32; ++i) {
signature_in.emplace_back(i + offset);
witness_values.emplace_back(signature.s[i]);
}
offset += signature.s.size();

witness_values.emplace_back(1);
const auto result_in = static_cast<uint32_t>(offset);
offset += 1;
witness_values.emplace_back(1);

ecdsa_constraint = acir_format::EcdsaSecp256k1Constraint{
.message = message_in,
.pub_x_indices = pub_x_indices_in,
.pub_y_indices = pub_y_indices_in,
.result = result_in,
.signature = signature_in,
};
return offset;
}

TEST(ECDSASecp256k1, TestECDSAConstraintSucceed)
{
acir_format::EcdsaSecp256k1Constraint ecdsa_constraint;
std::vector<fr> witness_values;
size_t num_variables = generate_ecdsa_constraint(ecdsa_constraint, witness_values);
acir_format::acir_format constraint_system{
.varnum = static_cast<uint32_t>(num_variables),
.public_inputs = {},
.fixed_base_scalar_mul_constraints = {},
.logic_constraints = {},
.range_constraints = {},
.schnorr_constraints = {},
.ecdsa_constraints = { ecdsa_constraint },
.sha256_constraints = {},
.blake2s_constraints = {},
.hash_to_field_constraints = {},
.pedersen_constraints = {},
.compute_merkle_root_constraints = {},
.recursion_constraints = {},
.constraints = {},
};

auto composer = acir_format::create_circuit_with_witness(constraint_system, witness_values);

EXPECT_EQ(composer.get_variable(ecdsa_constraint.result), 1);
auto prover = composer.create_prover();

auto proof = prover.construct_proof();
auto verifier = composer.create_verifier();
EXPECT_EQ(verifier.verify_proof(proof), true);
}

TEST(ECDSASecp256k1, TestECDSAConstraintFail)
{
acir_format::EcdsaSecp256k1Constraint ecdsa_constraint;
std::vector<fr> witness_values;
size_t num_variables = generate_ecdsa_constraint(ecdsa_constraint, witness_values);

// set result value to be false
witness_values[witness_values.size() - 1] = 0;

// tamper with signature
witness_values[witness_values.size() - 20] += 1;

acir_format::acir_format constraint_system{
.varnum = static_cast<uint32_t>(num_variables),
.public_inputs = {},
.fixed_base_scalar_mul_constraints = {},
.logic_constraints = {},
.range_constraints = {},
.schnorr_constraints = {},
.ecdsa_constraints = { ecdsa_constraint },
.sha256_constraints = {},
.blake2s_constraints = {},
.hash_to_field_constraints = {},
.pedersen_constraints = {},
.compute_merkle_root_constraints = {},
.recursion_constraints = {},
.constraints = {},
};

auto composer = acir_format::create_circuit_with_witness(constraint_system, witness_values);

EXPECT_EQ(composer.get_variable(ecdsa_constraint.result), 0);
auto prover = composer.create_prover();

auto proof = prover.construct_proof();
auto verifier = composer.create_verifier();
EXPECT_EQ(verifier.verify_proof(proof), true);
}
Loading