Skip to content

Commit

Permalink
Pending bb work for aztec3 (#368)
Browse files Browse the repository at this point in the history
* update js vk (because we now use UP for merkle hashing)

* Helpers for ECDSA in A3 (#364)

* Add `stdlib_keccak` in cmake.

Correct an assertion in `to_byte_array` in bigfield.

* Add `random_element` to affine element.

* negate y conditionally.

* Change pedersen hash c_bind to use `pedersen_hash::lookup`.

* c_binds and other ECDSA related fixes (#407)

* Add v to stdlib ecdsa.

* create an engine if its empty.

* Add ecdsa c_bind.

* print v as a uint32.

* Add secp256k1 cbind.

add c_bind.hpp

Change hpp to h.

remove hpp.

* Add ecdsa in cmakelists.

remove stdlib_ecdsa from build.

* chore: align BARRETENBERG_CRYPTO_GENERATOR_PARAMETERS_HACK usage (#411)

* Update join_split test

* Tweaks to comments

* Add comment for the assertion in bigfield.

* Expanded on ecdsa comment.

---------

Co-authored-by: ludamad <[email protected]>
Co-authored-by: ludamad <[email protected]>
Co-authored-by: codygunton <[email protected]>
  • Loading branch information
4 people authored and maramihali committed May 5, 2023
1 parent eaf6cd4 commit 44d9cfd
Show file tree
Hide file tree
Showing 15 changed files with 246 additions and 10 deletions.
7 changes: 7 additions & 0 deletions cpp/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ if(WASM)
$<TARGET_OBJECTS:crypto_blake2s_objects>
$<TARGET_OBJECTS:crypto_blake3s_objects>
$<TARGET_OBJECTS:crypto_keccak_objects>
$<TARGET_OBJECTS:crypto_ecdsa_objects>
$<TARGET_OBJECTS:crypto_schnorr_objects>
$<TARGET_OBJECTS:crypto_generators_objects>
$<TARGET_OBJECTS:crypto_pedersen_hash_objects>
Expand All @@ -91,6 +92,7 @@ if(WASM)
$<TARGET_OBJECTS:stdlib_pedersen_commitment_objects>
$<TARGET_OBJECTS:stdlib_blake2s_objects>
$<TARGET_OBJECTS:stdlib_blake3s_objects>
$<TARGET_OBJECTS:stdlib_keccak_objects>
$<TARGET_OBJECTS:stdlib_sha256_objects>
$<TARGET_OBJECTS:stdlib_aes128_objects>
$<TARGET_OBJECTS:stdlib_merkle_tree_objects>
Expand Down Expand Up @@ -124,6 +126,7 @@ if(WASM)
$<TARGET_OBJECTS:crypto_blake3s_objects>
$<TARGET_OBJECTS:crypto_generators_objects>
$<TARGET_OBJECTS:crypto_keccak_objects>
$<TARGET_OBJECTS:crypto_ecdsa_objects>
$<TARGET_OBJECTS:crypto_schnorr_objects>
$<TARGET_OBJECTS:crypto_pedersen_hash_objects>
$<TARGET_OBJECTS:crypto_pedersen_commitment_objects>
Expand Down Expand Up @@ -178,6 +181,7 @@ if(WASM)
$<TARGET_OBJECTS:crypto_blake2s_objects>
$<TARGET_OBJECTS:crypto_blake3s_objects>
$<TARGET_OBJECTS:crypto_keccak_objects>
$<TARGET_OBJECTS:crypto_ecdsa_objects>
$<TARGET_OBJECTS:crypto_schnorr_objects>
$<TARGET_OBJECTS:crypto_generators_objects>
$<TARGET_OBJECTS:crypto_pedersen_hash_objects>
Expand All @@ -193,6 +197,7 @@ if(WASM)
$<TARGET_OBJECTS:stdlib_pedersen_commitment_objects>
$<TARGET_OBJECTS:stdlib_blake2s_objects>
$<TARGET_OBJECTS:stdlib_blake3s_objects>
$<TARGET_OBJECTS:stdlib_keccak_objects>
$<TARGET_OBJECTS:stdlib_sha256_objects>
$<TARGET_OBJECTS:stdlib_aes128_objects>
$<TARGET_OBJECTS:stdlib_merkle_tree_objects>
Expand All @@ -213,6 +218,7 @@ else()
$<TARGET_OBJECTS:crypto_blake2s_objects>
$<TARGET_OBJECTS:crypto_blake3s_objects>
$<TARGET_OBJECTS:crypto_keccak_objects>
$<TARGET_OBJECTS:crypto_ecdsa_objects>
$<TARGET_OBJECTS:crypto_schnorr_objects>
$<TARGET_OBJECTS:crypto_generators_objects>
$<TARGET_OBJECTS:crypto_pedersen_hash_objects>
Expand All @@ -228,6 +234,7 @@ else()
$<TARGET_OBJECTS:stdlib_pedersen_commitment_objects>
$<TARGET_OBJECTS:stdlib_blake2s_objects>
$<TARGET_OBJECTS:stdlib_blake3s_objects>
$<TARGET_OBJECTS:stdlib_keccak_objects>
$<TARGET_OBJECTS:stdlib_sha256_objects>
$<TARGET_OBJECTS:stdlib_aes128_objects>
$<TARGET_OBJECTS:stdlib_merkle_tree_objects>
Expand Down
70 changes: 70 additions & 0 deletions cpp/src/barretenberg/crypto/ecdsa/c_bind.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include "ecdsa.hpp"
#include <barretenberg/ecc/curves/secp256k1/secp256k1.hpp>

#define WASM_EXPORT __attribute__((visibility("default")))

extern "C" {

WASM_EXPORT void ecdsa__compute_public_key(uint8_t const* private_key, uint8_t* public_key_buf)
{
auto priv_key = from_buffer<secp256k1::fr>(private_key);
secp256k1::g1::affine_element pub_key = secp256k1::g1::one * priv_key;
write(public_key_buf, pub_key);
}

WASM_EXPORT void ecdsa__construct_signature(uint8_t const* message,
size_t msg_len,
uint8_t const* private_key,
uint8_t* output_sig_r,
uint8_t* output_sig_s,
uint8_t* output_sig_v)
{
using serialize::write;
auto priv_key = from_buffer<secp256k1::fr>(private_key);
secp256k1::g1::affine_element pub_key = secp256k1::g1::one * priv_key;
crypto::ecdsa::key_pair<secp256k1::fr, secp256k1::g1> key_pair = { priv_key, pub_key };

auto sig = crypto::ecdsa::construct_signature<Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
std::string((char*)message, msg_len), key_pair);
write(output_sig_r, sig.r);
write(output_sig_s, sig.s);
write(output_sig_v, sig.v);
}

WASM_EXPORT void ecdsa__recover_public_key_from_signature(uint8_t const* message,
size_t msg_len,
uint8_t const* sig_r,
uint8_t const* sig_s,
uint8_t* sig_v,
uint8_t* output_pub_key)
{
std::array<uint8_t, 32> r, s;
std::copy(sig_r, sig_r + 32, r.begin());
std::copy(sig_s, sig_s + 32, s.begin());
const uint8_t v = *sig_v;

crypto::ecdsa::signature sig = { r, s, v };
auto recovered_pub_key =
crypto::ecdsa::recover_public_key<Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
std::string((char*)message, msg_len), sig);
write(output_pub_key, recovered_pub_key);
}

WASM_EXPORT bool ecdsa__verify_signature(uint8_t const* message,
size_t msg_len,
uint8_t const* pub_key,
uint8_t const* sig_r,
uint8_t const* sig_s,
uint8_t const* sig_v)
{
auto pubk = from_buffer<secp256k1::g1::affine_element>(pub_key);
std::array<uint8_t, 32> r, s;
std::copy(sig_r, sig_r + 32, r.begin());
std::copy(sig_s, sig_s + 32, s.begin());
const uint8_t v = *sig_v;

crypto::ecdsa::signature sig = { r, s, v };
return crypto::ecdsa::verify_signature<Sha256Hasher, secp256k1::fq, secp256k1::fr, secp256k1::g1>(
std::string((char*)message, msg_len), pubk, sig);
}
}
29 changes: 29 additions & 0 deletions cpp/src/barretenberg/crypto/ecdsa/c_bind.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <ecc/curves/secp256k1/secp256k1.hpp>

#define WASM_EXPORT __attribute__((visibility("default")))

extern "C" {

WASM_EXPORT void ecdsa__compute_public_key(uint8_t const* private_key, uint8_t* public_key_buf);

WASM_EXPORT void ecdsa__construct_signature(uint8_t const* message,
size_t msg_len,
uint8_t const* private_key,
uint8_t* output_sig_r,
uint8_t* output_sig_s,
uint8_t* output_sig_v);

WASM_EXPORT void ecdsa__recover_public_key_from_signature(uint8_t const* message,
size_t msg_len,
uint8_t const* sig_r,
uint8_t const* sig_s,
uint8_t* sig_v,
uint8_t* output_pub_key);

WASM_EXPORT bool ecdsa__verify_signature(uint8_t const* message,
size_t msg_len,
uint8_t const* pub_key,
uint8_t const* sig_r,
uint8_t const* sig_s,
uint8_t const* sig_v);
}
6 changes: 4 additions & 2 deletions cpp/src/barretenberg/crypto/ecdsa/ecdsa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,26 @@ bool verify_signature(const std::string& message,

inline bool operator==(signature const& lhs, signature const& rhs)
{
return lhs.r == rhs.r && lhs.s == rhs.s;
return lhs.r == rhs.r && lhs.s == rhs.s && lhs.v == rhs.v;
}

inline std::ostream& operator<<(std::ostream& os, signature const& sig)
{
os << "{ " << sig.r << ", " << sig.s << " }";
os << "{ " << sig.r << ", " << sig.s << ", " << static_cast<uint32_t>(sig.v) << " }";
return os;
}

template <typename B> inline void read(B& it, signature& sig)
{
using serialize::read;
read(it, sig.r);
read(it, sig.s);
read(it, sig.v);
}

template <typename B> inline void write(B& buf, signature const& sig)
{
using serialize::write;
write(buf, sig.r);
write(buf, sig.s);
write(buf, sig.v);
Expand Down
2 changes: 1 addition & 1 deletion cpp/src/barretenberg/crypto/generators/generator_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,4 +294,4 @@ const fixed_base_ladder* generator_data::get_hash_ladder(size_t num_bits) const
}

} // namespace generators
} // namespace crypto
} // namespace crypto
9 changes: 5 additions & 4 deletions cpp/src/barretenberg/crypto/pedersen_hash/c_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,23 @@ extern "C" {

WASM_EXPORT void pedersen_hash__init()
{
// TODO: do we need this if we are using lookup-pedersen in merkle trees?
crypto::generators::init_generator_data();
}

WASM_EXPORT void pedersen__hash_pair(uint8_t const* left, uint8_t const* right, uint8_t* result)
{
auto lhs = barretenberg::fr::serialize_from_buffer(left);
auto rhs = barretenberg::fr::serialize_from_buffer(right);
auto r = crypto::pedersen_hash::hash_multiple({ lhs, rhs });
auto r = crypto::pedersen_hash::lookup::hash_multiple({ lhs, rhs });
barretenberg::fr::serialize_to_buffer(r, result);
}

WASM_EXPORT void pedersen__hash_multiple(uint8_t const* inputs_buffer, uint8_t* output)
{
std::vector<grumpkin::fq> to_compress;
read(inputs_buffer, to_compress);
auto r = crypto::pedersen_hash::hash_multiple(to_compress);
auto r = crypto::pedersen_hash::lookup::hash_multiple(to_compress);
barretenberg::fr::serialize_to_buffer(r, output);
}

Expand All @@ -36,7 +37,7 @@ WASM_EXPORT void pedersen__hash_multiple_with_hash_index(uint8_t const* inputs_b
{
std::vector<grumpkin::fq> to_compress;
read(inputs_buffer, to_compress);
auto r = crypto::pedersen_hash::hash_multiple(to_compress, hash_index);
auto r = crypto::pedersen_hash::lookup::hash_multiple(to_compress, hash_index);
barretenberg::fr::serialize_to_buffer(r, output);
}

Expand All @@ -54,7 +55,7 @@ WASM_EXPORT uint8_t* pedersen__hash_to_tree(uint8_t const* data)
fields.reserve(num_outputs);

for (size_t i = 0; fields.size() < num_outputs; i += 2) {
fields.push_back(crypto::pedersen_hash::hash_multiple({ fields[i], fields[i + 1] }));
fields.push_back(crypto::pedersen_hash::lookup::hash_multiple({ fields[i], fields[i + 1] }));
}

auto buf_size = 4 + num_outputs * sizeof(grumpkin::fq);
Expand Down
4 changes: 3 additions & 1 deletion cpp/src/barretenberg/dsl/acir_format/ecdsa_secp256k1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,11 @@ void create_ecdsa_verify_constraints(Composer& composer, const EcdsaSecp256k1Con

std::vector<uint8_t> rr(new_sig.r.begin(), new_sig.r.end());
std::vector<uint8_t> ss(new_sig.s.begin(), new_sig.s.end());
uint8_t vv = new_sig.v;

stdlib::ecdsa::signature<Composer> sig{ stdlib::byte_array<Composer>(&composer, rr),
stdlib::byte_array<Composer>(&composer, ss) };
stdlib::byte_array<Composer>(&composer, ss),
stdlib::uint8<Composer>(&composer, vv) };

pub_key_x_fq.assert_is_in_field();
pub_key_y_fq.assert_is_in_field();
Expand Down
30 changes: 30 additions & 0 deletions cpp/src/barretenberg/ecc/curves/secp256k1/c_bind.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "secp256k1.hpp"

#define WASM_EXPORT __attribute__((visibility("default")))

extern "C" {

WASM_EXPORT void ecc_secp256k1__mul(uint8_t const* point_buf, uint8_t const* scalar_buf, uint8_t* result)
{
auto point = from_buffer<secp256k1::g1::affine_element>(point_buf);
auto scalar = from_buffer<secp256k1::fr>(scalar_buf);
secp256k1::g1::affine_element r = point * scalar;
write(result, r);
}

WASM_EXPORT void ecc_secp256k1__get_random_scalar_mod_circuit_modulus(uint8_t* result)
{
barretenberg::fr output = barretenberg::fr::random_element();
write(result, output);
}

WASM_EXPORT void ecc_secp256k1__reduce512_buffer_mod_circuit_modulus(uint8_t* input, uint8_t* result)
{
uint512_t bigint_input = from_buffer<uint512_t>(input);

uint512_t barretenberg_modulus(barretenberg::fr::modulus);

uint512_t target_output = bigint_input % barretenberg_modulus;
write(result, target_output.lo);
}
}
12 changes: 12 additions & 0 deletions cpp/src/barretenberg/ecc/curves/secp256k1/c_bind.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#include "secp256k1.hpp"

#define WASM_EXPORT __attribute__((visibility("default")))

extern "C" {

WASM_EXPORT void ecc_secp256k1__mul(uint8_t const* point_buf, uint8_t const* scalar_buf, uint8_t* result);

WASM_EXPORT void ecc_secp256k1__get_random_scalar_mod_circuit_modulus(uint8_t* result);

WASM_EXPORT void ecc_secp256k1__reduce512_buffer_mod_circuit_modulus(uint8_t* input, uint8_t* result);
}
7 changes: 7 additions & 0 deletions cpp/src/barretenberg/ecc/groups/affine_element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ template <typename Fq, typename Fr, typename Params> class alignas(64) affine_el

constexpr bool on_curve() const noexcept;

/**
* @brief Samples a random point on the curve.
*
* @return A randomly chosen point on the curve
*/
static affine_element random_element(numeric::random::Engine* engine = nullptr) noexcept;

/**
* @brief Hash a seed value to curve.
*
Expand Down
33 changes: 33 additions & 0 deletions cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,5 +229,38 @@ affine_element<Fq, Fr, T> affine_element<Fq, Fr, T>::hash_to_curve(const uint64_

return affine_element<Fq, Fr, T>(x_out, y_out_);
}

template <typename Fq, typename Fr, typename T>
affine_element<Fq, Fr, T> affine_element<Fq, Fr, T>::random_element(numeric::random::Engine* engine) noexcept
{
if (engine == nullptr) {
engine = &numeric::random::get_engine();
}

bool found_one = false;
Fq yy;
Fq x;
Fq y;
while (!found_one) {
// Sample a random x-coordinate and check if it satisfies curve equation.
x = Fq::random_element(engine);
yy = x.sqr() * x + T::b;
if constexpr (T::has_a) {
yy += (x * T::a);
}
auto [found_root, y1] = yy.sqrt();
y = y1;

// Negate the y-coordinate based on a randomly sampled bit.
bool random_bit = (engine->get_random_uint8() & 1);
if (random_bit) {
y = -y;
}

found_one = found_root;
}
return affine_element<Fq, Fr, T>(x, y);
}

} // namespace group_elements
} // namespace barretenberg
4 changes: 4 additions & 0 deletions cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "barretenberg/crypto/ecdsa/ecdsa.hpp"
#include "../../primitives/byte_array/byte_array.hpp"
#include "../../primitives/uint/uint.hpp"
#include "../../primitives/composers/composers_fwd.hpp"

namespace proof_system::plonk {
Expand All @@ -11,6 +12,7 @@ namespace ecdsa {
template <typename Composer> struct signature {
stdlib::byte_array<Composer> r;
stdlib::byte_array<Composer> s;
stdlib::uint8<Composer> v;
};

template <typename Composer, typename Curve, typename Fq, typename Fr, typename G1>
Expand All @@ -25,9 +27,11 @@ static signature<Composer> from_witness(Composer* ctx, const crypto::ecdsa::sign
std::vector<uint8_t> s_vec(std::begin(input.s), std::end(input.s));
stdlib::byte_array<Composer> r(ctx, r_vec);
stdlib::byte_array<Composer> s(ctx, s_vec);
stdlib::uint8<Composer> v(ctx, input.v);
signature<Composer> out;
out.r = r;
out.s = s;
out.v = v;
return out;
}

Expand Down
5 changes: 4 additions & 1 deletion cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,11 @@ TEST(stdlib_ecdsa, verify_signature)

std::vector<uint8_t> rr(signature.r.begin(), signature.r.end());
std::vector<uint8_t> ss(signature.s.begin(), signature.s.end());
uint8_t vv = signature.v;

stdlib::ecdsa::signature<Composer> sig{ curve::byte_array_ct(&composer, rr), curve::byte_array_ct(&composer, ss) };
stdlib::ecdsa::signature<Composer> sig{ curve::byte_array_ct(&composer, rr),
curve::byte_array_ct(&composer, ss),
stdlib::uint8<Composer>(&composer, vv) };

curve::byte_array_ct message(&composer, message_string);

Expand Down
Loading

0 comments on commit 44d9cfd

Please sign in to comment.