Skip to content
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
5 changes: 2 additions & 3 deletions cpp/src/barretenberg/dsl/acir_format/acir_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ void create_circuit(Composer& composer, const acir_format& constraint_system)
if (std::find(constraint_system.public_inputs.begin(), constraint_system.public_inputs.end(), i) !=
constraint_system.public_inputs.end()) {
composer.add_public_variable(0);

} else {
composer.add_variable(0);
}
Expand Down Expand Up @@ -62,7 +61,7 @@ void create_circuit(Composer& composer, const acir_format& constraint_system)

// Add ECDSA constraints
for (const auto& constraint : constraint_system.ecdsa_constraints) {
create_ecdsa_verify_constraints(composer, constraint);
create_ecdsa_verify_constraints(composer, constraint, false);
}

// Add blake2s constraints
Expand Down Expand Up @@ -145,7 +144,7 @@ Composer create_circuit(const acir_format& constraint_system,

// Add ECDSA constraints
for (const auto& constraint : constraint_system.ecdsa_constraints) {
create_ecdsa_verify_constraints(composer, constraint);
create_ecdsa_verify_constraints(composer, constraint, false);
}

// Add blake2s constraints
Expand Down
58 changes: 57 additions & 1 deletion cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,15 @@ witness_ct ecdsa_index_to_witness(Composer& composer, uint32_t index)
return { &composer, value };
}

void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Constraint& input)
void create_ecdsa_verify_constraints(Composer& composer,
const EcdsaSecp256k1Constraint& input,
bool has_valid_witness_assignments)
Comment thread
kevaundray marked this conversation as resolved.
{

if (has_valid_witness_assignments == false) {
dummy_ecdsa_constraint(composer, input);
}

auto new_sig = ecdsa_convert_signature(composer, input.signature);

auto message = ecdsa_vector_of_bytes_to_byte_array(composer, input.hashed_message);
Expand Down Expand Up @@ -127,4 +133,54 @@ void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Con
composer.assert_equal(signature_result_normalized.witness_index, input.result);
}

// Add dummy constraints for ECDSA because when the verifier creates the
// constraint system, they usually use zeroes for witness values.
//
// This does not work for ECDSA as the signature, r, s and public key need
// to be valid.
void dummy_ecdsa_constraint(Composer& composer, EcdsaSecp256k1Constraint const& input)
{

std::vector<uint32_t> pub_x_indices_;
std::vector<uint32_t> pub_y_indices_;
std::vector<uint32_t> signature_;
signature_.resize(64);

// Create a valid signature with a valid public key
crypto::ecdsa::key_pair<secp256k1_ct::fr, secp256k1_ct::g1> account;
account.private_key = 10;
account.public_key = secp256k1_ct::g1::one * account.private_key;
uint256_t pub_x_value = account.public_key.x;
uint256_t pub_y_value = account.public_key.y;
std::string message_string = "Instructions unclear, ask again later.";
crypto::ecdsa::signature signature =
crypto::ecdsa::construct_signature<Sha256Hasher, secp256k1_ct::fq, secp256k1_ct::fr, secp256k1_ct::g1>(
message_string, account);

// Create new variables which will reference the valid public key and signature.
// We don't use them in a gate, so when we call assert_equal, they will be
// replaced as if they never existed.
for (size_t i = 0; i < 32; ++i) {
uint32_t x_wit = composer.add_variable(pub_x_value.slice(248 - i * 8, 256 - i * 8));
uint32_t y_wit = composer.add_variable(pub_y_value.slice(248 - i * 8, 256 - i * 8));
uint32_t r_wit = composer.add_variable(signature.r[i]);
uint32_t s_wit = composer.add_variable(signature.s[i]);
pub_x_indices_.emplace_back(x_wit);
pub_y_indices_.emplace_back(y_wit);
signature_[i] = r_wit;
signature_[i + 32] = s_wit;
}

// Call assert_equal(from, to) to replace the value in `to` by the value in `from`
for (size_t i = 0; i < input.pub_x_indices.size(); ++i) {
composer.assert_equal(pub_x_indices_[i], input.pub_x_indices[i]);
}
for (size_t i = 0; i < input.pub_y_indices.size(); ++i) {
composer.assert_equal(pub_y_indices_[i], input.pub_y_indices[i]);
}
for (size_t i = 0; i < input.signature.size(); ++i) {
composer.assert_equal(signature_[i], input.signature[i]);
}
}

} // namespace acir_format
6 changes: 5 additions & 1 deletion cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ struct EcdsaSecp256k1Constraint {
friend bool operator==(EcdsaSecp256k1Constraint const& lhs, EcdsaSecp256k1Constraint const& rhs) = default;
};

void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Constraint& input);
void create_ecdsa_verify_constraints(Composer& composer,
const EcdsaSecp256k1Constraint& input,
bool has_valid_witness_assignments = true);

void dummy_ecdsa_constraint(Composer& composer, EcdsaSecp256k1Constraint const& input);

template <typename B> inline void read(B& buf, EcdsaSecp256k1Constraint& constraint)
{
Expand Down
28 changes: 28 additions & 0 deletions cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,34 @@ TEST(ECDSASecp256k1, TestECDSAConstraintSucceed)
EXPECT_EQ(verifier.verify_proof(proof), true);
}

// Test that the verifier can create an ECDSA circuit.
// The ECDSA circuit requires that certain dummy data is valid
// even though we are just building the circuit.
TEST(ECDSASecp256k1, TestECDSACompilesForVerifier)
{
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 = {},
.keccak_constraints = {},
.hash_to_field_constraints = {},
.pedersen_constraints = {},
.compute_merkle_root_constraints = {},
.constraints = {},
};
auto crs_factory = std::make_unique<proof_system::ReferenceStringFactory>();
auto composer = create_circuit(constraint_system, std::move(crs_factory));
Comment thread
kevaundray marked this conversation as resolved.
}

TEST(ECDSASecp256k1, TestECDSAConstraintFail)
{
acir_format::EcdsaSecp256k1Constraint ecdsa_constraint;
Expand Down