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
4 changes: 4 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 Down Expand Up @@ -125,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 @@ -179,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 Down Expand Up @@ -215,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 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
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);
}
4 changes: 4 additions & 0 deletions cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,10 @@ affine_element<Fq, Fr, T> affine_element<Fq, Fr, T>::hash_to_curve(const uint64_
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;
Expand Down
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
5 changes: 5 additions & 0 deletions cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ bool_t<Composer> verify_signature(const stdlib::byte_array<Composer>& message,
{
Composer* ctx = message.get_context() ? message.get_context() : public_key.x.context;

// Check if revovery id v is either 27 ot 28.
// TODO(Suyash): check with Zac/Kesha/Cody.
field_t<Composer>(sig.v).assert_is_in_set({ field_t<Composer>(27), field_t<Composer>(28) },
"signature is non-standard");

stdlib::byte_array<Composer> hashed_message =
static_cast<stdlib::byte_array<Composer>>(stdlib::sha256<Composer>(message));

Expand Down