82 BB_ASSERT_EQ(
builder !=
nullptr,
true,
"At least one of the inputs should be non-constant.");
91 "ECDSA input validation: the hash of the message is bigger than the order of the elliptic curve.");
94 public_key.validate_on_curve(
"ECDSA input validation: the public key is not a point on the elliptic curve.");
98 "ECDSA input validation: the public key is the point at infinity.");
102 r.assert_is_in_field(
"ECDSA input validation: the r component of the signature is bigger than the order of the "
104 r.assert_is_not_equal(
Fr::zero(),
"ECDSA input validation: the r component of the signature is zero.");
110 "ECDSA input validation: the s component of the signature is bigger than Fr::modulus - s.");
111 s.assert_is_not_equal(
Fr::zero(),
"ECDSA input validation: the s component of the signature is zero.");
114 Fr u1 = z.div_without_denominator_check(s);
115 Fr u2 = r.div_without_denominator_check(s);
119 result = G1::secp256k1_ecdsa_mul(public_key, u1, u2);
124 if ((public_key.get_value().x == Curve::g1::affine_one.x) && (!
builder->failed())) {
125 builder->failure(
"ECDSA input validation: the public key is equal to plus or minus the generator point.");
127 result = G1::batch_mul({ G1::one(
builder), public_key }, { u1, u2 });
131 result.is_point_at_infinity().assert_equal(
132 bool_t<Builder>(
false),
"ECDSA validation: the result of the batch multiplication is the point at infinity.");
137 result.x.self_reduce();
140 Fr result_x_mod_r = Fr::unsafe_construct_from_limbs(result.x.binary_basis_limbs[0].element,
141 result.x.binary_basis_limbs[1].element,
142 result.x.binary_basis_limbs[2].element,
143 result.x.binary_basis_limbs[3].element);
145 for (
size_t idx = 0; idx < 4; idx++) {
146 result_x_mod_r.binary_basis_limbs[idx].maximum_value = result.x.binary_basis_limbs[idx].maximum_value;
154 vinfo(
"ECDSA signature verification succeeded.");
156 vinfo(
"ECDSA signature verification failed");
159 return is_signature_valid;
174 using FrNative =
typename Curve::fr;
175 using FqNative =
typename Curve::fq;
176 using G1Native =
typename Curve::g1;
179 using Fr =
typename Curve::bigfr_ct;
180 using Fq =
typename Curve::fq_ct;
181 using G1 =
typename Curve::g1_bigfr_ct;
183 std::string message_string =
"Instructions unclear, ask again later.";
186 for (
size_t i = 0; i < num_iterations; i++) {
192 crypto::ecdsa_construct_signature<crypto::Sha256Hasher, FqNative, FrNative, G1Native>(message_string,
195 bool native_verification = crypto::ecdsa_verify_signature<crypto::Sha256Hasher, FqNative, FrNative, G1Native>(
196 message_string, account.
public_key, signature);
197 BB_ASSERT_EQ(native_verification,
true,
"Native ECDSA verification failed while generating test circuit.");
199 std::vector<uint8_t> rr(signature.
r.begin(), signature.
r.end());
200 std::vector<uint8_t> ss(signature.
s.begin(), signature.
s.end());
214 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...