85 BB_ASSERT_EQ(
builder !=
nullptr,
true,
"At least one of the inputs should be non-constant.");
93 public_key.assert_coordinates_in_field(
94 "ECDSA input validation: coordinate(s) of the public key bigger than the base field modulus.");
97 public_key.validate_on_curve(
"ECDSA input validation: the public key is not a point on the elliptic curve.");
101 "ECDSA input validation: the public key is the point at infinity.");
105 r.assert_is_in_field(
"ECDSA input validation: the r component of the signature is bigger than the order of the "
107 r.assert_is_not_equal(
Fr::zero(),
"ECDSA input validation: the r component of the signature is zero.");
113 "ECDSA input validation: the s component of the signature is bigger than (Fr::modulus + 1)/2.");
114 s.assert_is_not_equal(
Fr::zero(),
"ECDSA input validation: the s component of the signature is zero.");
117 Fr u1 = z.div_without_denominator_check(s);
118 Fr u2 = r.div_without_denominator_check(s);
122 result = G1::secp256k1_ecdsa_mul(public_key, u1, u2);
127 if ((public_key.get_value().x == Curve::g1::affine_one.x) && (!
builder->failed())) {
128 builder->failure(
"ECDSA input validation: the public key is equal to plus or minus the generator point.");
130 result = G1::batch_mul({ G1::one(
builder), public_key }, { u1, u2 });
134 result.is_point_at_infinity().assert_equal(
135 bool_t<Builder>(
false),
"ECDSA validation: the result of the batch multiplication is the point at infinity.");
140 result.x().reduce_mod_target_modulus();
143 Fr result_x_mod_r = Fr::unsafe_construct_from_limbs(result.x().binary_basis_limbs[0].element,
144 result.x().binary_basis_limbs[1].element,
145 result.x().binary_basis_limbs[2].element,
146 result.x().binary_basis_limbs[3].element);
148 for (
size_t idx = 0; idx < 4; idx++) {
149 result_x_mod_r.binary_basis_limbs[idx].maximum_value = result.x().binary_basis_limbs[idx].maximum_value;
157 vinfo(
"ECDSA signature verification succeeded.");
159 vinfo(
"ECDSA signature verification failed");
162 return is_signature_valid;
177 using FrNative =
typename Curve::fr;
178 using FqNative =
typename Curve::fq;
179 using G1Native =
typename Curve::g1;
182 using Fr =
typename Curve::bigfr_ct;
183 using Fq =
typename Curve::fq_ct;
184 using G1 =
typename Curve::g1_bigfr_ct;
186 std::string message_string =
"Instructions unclear, ask again later.";
189 for (
size_t i = 0; i < num_iterations; i++) {
195 crypto::ecdsa_construct_signature<crypto::Sha256Hasher, FqNative, FrNative, G1Native>(message_string,
198 bool native_verification = crypto::ecdsa_verify_signature<crypto::Sha256Hasher, FqNative, FrNative, G1Native>(
199 message_string, account.
public_key, signature);
200 BB_ASSERT_EQ(native_verification,
true,
"Native ECDSA verification failed while generating test circuit.");
202 std::vector<uint8_t> rr(signature.
r.begin(), signature.
r.end());
203 std::vector<uint8_t> ss(signature.
s.begin(), signature.
s.end());
210 auto hash_arr =
crypto::sha256(std::vector<uint8_t>(message_string.begin(), message_string.end()));
215 stdlib::ecdsa_verify_signature<Builder, Curve, Fq, Fr, G1>(hashed_message, public_key, sig);
bool_t< Builder > ecdsa_verify_signature(const stdlib::byte_array< Builder > &hashed_message, const G1 &public_key, const ecdsa_signature< Builder > &sig)
Verify ECDSA signature. Returns bool_t(true/false) depending on whether the signature is valid or not...