binius_circuits/ecdsa/
bitcoin.rs1use binius_frontend::{CircuitBuilder, Wire};
4
5use super::scalar_mul::{MSM_WINDOW, msm_strauss_endo};
6use crate::{
7 bignum::{BigUint, biguint_lt},
8 secp256k1::{Secp256k1, Secp256k1Affine},
9 util::all_true,
10};
11
12pub fn verify(
26 b: &CircuitBuilder,
27 pk: Secp256k1Affine,
28 z: &BigUint,
29 r: &BigUint,
30 s: &BigUint,
31) -> Wire {
32 let curve = Secp256k1::new(b);
33
34 curve.assert_on_curve(b, &pk);
36
37 let f_scalar = curve.f_scalar();
38
39 let valid_r = b.band(b.bnot(r.is_zero(b)), biguint_lt(b, r, f_scalar.modulus()));
40 let valid_s = b.band(b.bnot(s.is_zero(b)), biguint_lt(b, s, f_scalar.modulus()));
41
42 let u1 = f_scalar.div(b, z, s, valid_s);
45 let u2 = f_scalar.div(b, r, s, valid_s);
46
47 let g = Secp256k1Affine::generator(b);
49 let nonce = msm_strauss_endo(b, &curve, MSM_WINDOW, &[u1, u2], &[g, pk]);
50 let nonce_not_pai = b.bnot(nonce.is_point_at_infinity);
51 let r_diff = curve.f_p().sub(b, &nonce.x, r);
52
53 let conditions = [valid_r, valid_s, nonce_not_pai, r_diff.is_zero(b)];
54 all_true(b, conditions)
55}