k256/
ecdsa.rs

1// re-export types that are visible in the k256 crate for API compatibility
2
3// Use these types instead of unpatched k256::ecdsa::{Signature, VerifyingKey}
4// because those are type aliases that use non-zkvm implementations
5
6#[cfg(any(feature = "ecdsa", feature = "sha256"))]
7pub use ecdsa_core::hazmat;
8pub use ecdsa_core::{
9    signature::{self, Error},
10    RecoveryId,
11};
12#[cfg(feature = "ecdsa")]
13use openvm_ecc_guest::ecdsa::VerifyCustomHook;
14#[cfg(feature = "ecdsa")]
15use {
16    super::{Scalar, Secp256k1Point},
17    ecdsa_core::hazmat::{SignPrimitive, VerifyPrimitive},
18    elliptic_curve::{ops::Invert, scalar::IsHigh, subtle::CtOption},
19};
20
21use super::Secp256k1;
22
23/// ECDSA/secp256k1 signature (fixed-size)
24pub type Signature = ecdsa_core::Signature<Secp256k1>;
25
26/// ECDSA/secp256k1 signing key
27#[cfg(feature = "ecdsa")]
28pub type SigningKey = openvm_ecc_guest::ecdsa::SigningKey<Secp256k1>;
29
30/// ECDSA/secp256k1 verification key (i.e. public key)
31#[cfg(feature = "ecdsa")]
32pub type VerifyingKey = openvm_ecc_guest::ecdsa::VerifyingKey<Secp256k1>;
33
34// We implement the trait so that patched libraries can compile when they only need ECDSA
35// verification and not signing
36#[cfg(feature = "ecdsa")]
37impl SignPrimitive<Secp256k1> for Scalar {
38    fn try_sign_prehashed<K>(
39        &self,
40        _k: K,
41        _z: &elliptic_curve::FieldBytes<Secp256k1>,
42    ) -> signature::Result<(Signature, Option<RecoveryId>)>
43    where
44        K: AsRef<Self> + Invert<Output = CtOption<Self>>,
45    {
46        todo!("ECDSA signing from private key is not yet implemented")
47    }
48}
49
50#[cfg(feature = "ecdsa")]
51impl VerifyCustomHook<Secp256k1> for Secp256k1Point {
52    #[inline]
53    fn verify_hook(&self, _z: &[u8], sig: &Signature) -> signature::Result<()> {
54        if sig.s().is_high().into() {
55            return Err(Error::new());
56        }
57        Ok(())
58    }
59}
60
61#[cfg(feature = "ecdsa")]
62impl VerifyPrimitive<Secp256k1> for Secp256k1Point {
63    fn verify_prehashed(
64        &self,
65        z: &crate::point::FieldBytes,
66        sig: &Signature,
67    ) -> Result<(), ecdsa_core::Error> {
68        self.verify_hook(z, sig)?;
69
70        openvm_ecc_guest::ecdsa::verify_prehashed::<Secp256k1>(
71            *self,
72            z.as_slice(),
73            sig.to_bytes().as_slice(),
74        )
75        .map_err(|_| ecdsa_core::Error::new())
76    }
77}