secp256k1/ecdsa/
mod.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Structs and functionality related to the ECDSA signature algorithm.
4//!
5
6#[cfg(feature = "recovery")]
7mod recovery;
8pub mod serialized_signature;
9
10use core::{fmt, ptr, str};
11
12#[cfg(feature = "recovery")]
13pub use self::recovery::{RecoverableSignature, RecoveryId};
14pub use self::serialized_signature::SerializedSignature;
15use crate::ffi::CPtr;
16use crate::{
17    ecdsa, ffi, from_hex, Error, Message, PublicKey, Secp256k1, SecretKey, Signing, Verification,
18};
19
20/// An ECDSA signature
21#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
22pub struct Signature(pub(crate) ffi::Signature);
23impl_fast_comparisons!(Signature);
24
25impl fmt::Debug for Signature {
26    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::Display::fmt(self, f) }
27}
28
29impl fmt::Display for Signature {
30    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
31        let sig = self.serialize_der();
32        sig.fmt(f)
33    }
34}
35
36impl str::FromStr for Signature {
37    type Err = Error;
38    fn from_str(s: &str) -> Result<Signature, Error> {
39        let mut res = [0u8; 72];
40        match from_hex(s, &mut res) {
41            Ok(x) => Signature::from_der(&res[0..x]),
42            _ => Err(Error::InvalidSignature),
43        }
44    }
45}
46
47impl Signature {
48    #[inline]
49    /// Converts a DER-encoded byte slice to a signature
50    pub fn from_der(data: &[u8]) -> Result<Signature, Error> {
51        if data.is_empty() {
52            return Err(Error::InvalidSignature);
53        }
54
55        unsafe {
56            let mut ret = ffi::Signature::new();
57            if ffi::secp256k1_ecdsa_signature_parse_der(
58                ffi::secp256k1_context_no_precomp,
59                &mut ret,
60                data.as_c_ptr(),
61                data.len(),
62            ) == 1
63            {
64                Ok(Signature(ret))
65            } else {
66                Err(Error::InvalidSignature)
67            }
68        }
69    }
70
71    /// Converts a 64-byte compact-encoded byte slice to a signature
72    pub fn from_compact(data: &[u8]) -> Result<Signature, Error> {
73        if data.len() != 64 {
74            return Err(Error::InvalidSignature);
75        }
76
77        unsafe {
78            let mut ret = ffi::Signature::new();
79            if ffi::secp256k1_ecdsa_signature_parse_compact(
80                ffi::secp256k1_context_no_precomp,
81                &mut ret,
82                data.as_c_ptr(),
83            ) == 1
84            {
85                Ok(Signature(ret))
86            } else {
87                Err(Error::InvalidSignature)
88            }
89        }
90    }
91
92    /// Converts a "lax DER"-encoded byte slice to a signature. This is basically
93    /// only useful for validating signatures in the Bitcoin blockchain from before
94    /// 2016. It should never be used in new applications. This library does not
95    /// support serializing to this "format"
96    pub fn from_der_lax(data: &[u8]) -> Result<Signature, Error> {
97        if data.is_empty() {
98            return Err(Error::InvalidSignature);
99        }
100
101        unsafe {
102            let mut ret = ffi::Signature::new();
103            if ffi::ecdsa_signature_parse_der_lax(
104                ffi::secp256k1_context_no_precomp,
105                &mut ret,
106                data.as_c_ptr(),
107                data.len(),
108            ) == 1
109            {
110                Ok(Signature(ret))
111            } else {
112                Err(Error::InvalidSignature)
113            }
114        }
115    }
116
117    /// Normalizes a signature to a "low S" form. In ECDSA, signatures are
118    /// of the form (r, s) where r and s are numbers lying in some finite
119    /// field. The verification equation will pass for (r, s) iff it passes
120    /// for (r, -s), so it is possible to ``modify'' signatures in transit
121    /// by flipping the sign of s. This does not constitute a forgery since
122    /// the signed message still cannot be changed, but for some applications,
123    /// changing even the signature itself can be a problem. Such applications
124    /// require a "strong signature". It is believed that ECDSA is a strong
125    /// signature except for this ambiguity in the sign of s, so to accommodate
126    /// these applications libsecp256k1 considers signatures for which s is in
127    /// the upper half of the field range invalid. This eliminates the
128    /// ambiguity.
129    ///
130    /// However, for some systems, signatures with high s-values are considered
131    /// valid. (For example, parsing the historic Bitcoin blockchain requires
132    /// this.) For these applications we provide this normalization function,
133    /// which ensures that the s value lies in the lower half of its range.
134    pub fn normalize_s(&mut self) {
135        unsafe {
136            // Ignore return value, which indicates whether the sig
137            // was already normalized. We don't care.
138            ffi::secp256k1_ecdsa_signature_normalize(
139                ffi::secp256k1_context_no_precomp,
140                self.as_mut_c_ptr(),
141                self.as_c_ptr(),
142            );
143        }
144    }
145
146    #[inline]
147    /// Serializes the signature in DER format
148    pub fn serialize_der(&self) -> SerializedSignature {
149        let mut data = [0u8; serialized_signature::MAX_LEN];
150        let mut len: usize = serialized_signature::MAX_LEN;
151        unsafe {
152            let err = ffi::secp256k1_ecdsa_signature_serialize_der(
153                ffi::secp256k1_context_no_precomp,
154                data.as_mut_ptr(),
155                &mut len,
156                self.as_c_ptr(),
157            );
158            debug_assert!(err == 1);
159            SerializedSignature::from_raw_parts(data, len)
160        }
161    }
162
163    #[inline]
164    /// Serializes the signature in compact format
165    pub fn serialize_compact(&self) -> [u8; 64] {
166        let mut ret = [0u8; 64];
167        unsafe {
168            let err = ffi::secp256k1_ecdsa_signature_serialize_compact(
169                ffi::secp256k1_context_no_precomp,
170                ret.as_mut_c_ptr(),
171                self.as_c_ptr(),
172            );
173            debug_assert!(err == 1);
174        }
175        ret
176    }
177
178    /// Verifies an ECDSA signature for `msg` using `pk`.
179    ///
180    /// The signature must be normalized or verification will fail (see [`Signature::normalize_s`]).
181    #[inline]
182    pub fn verify(&self, msg: impl Into<Message>, pk: &PublicKey) -> Result<(), Error> {
183        ecdsa::verify(self, msg, pk)
184    }
185}
186
187impl CPtr for Signature {
188    type Target = ffi::Signature;
189
190    fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
191
192    fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
193}
194
195/// Creates a new signature from a FFI signature
196impl From<ffi::Signature> for Signature {
197    #[inline]
198    fn from(sig: ffi::Signature) -> Signature { Signature(sig) }
199}
200
201#[cfg(feature = "serde")]
202impl serde::Serialize for Signature {
203    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
204        if s.is_human_readable() {
205            s.collect_str(self)
206        } else {
207            s.serialize_bytes(&self.serialize_der())
208        }
209    }
210}
211
212#[cfg(feature = "serde")]
213impl<'de> serde::Deserialize<'de> for Signature {
214    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
215        if d.is_human_readable() {
216            d.deserialize_str(crate::serde_util::FromStrVisitor::new(
217                "a hex string representing a DER encoded Signature",
218            ))
219        } else {
220            d.deserialize_bytes(crate::serde_util::BytesVisitor::new(
221                "raw byte stream, that represents a DER encoded Signature",
222                Signature::from_der,
223            ))
224        }
225    }
226}
227
228fn sign_ecdsa_with_noncedata_pointer(
229    msg: impl Into<Message>,
230    sk: &SecretKey,
231    noncedata: Option<&[u8; 32]>,
232) -> Signature {
233    let msg = msg.into();
234    unsafe {
235        let mut ret = ffi::Signature::new();
236        let noncedata_ptr = match noncedata {
237            Some(arr) => arr.as_c_ptr() as *const _,
238            None => ptr::null(),
239        };
240        // We can assume the return value because it's not possible to construct
241        // an invalid signature from a valid `Message` and `SecretKey`
242        let res = crate::with_global_context(
243            |secp: &Secp256k1<crate::AllPreallocated>| {
244                ffi::secp256k1_ecdsa_sign(
245                    secp.ctx.as_ptr(),
246                    &mut ret,
247                    msg.as_c_ptr(),
248                    sk.as_c_ptr(),
249                    ffi::secp256k1_nonce_function_rfc6979,
250                    noncedata_ptr,
251                )
252            },
253            Some(&sk.to_secret_bytes()),
254        );
255
256        assert_eq!(res, 1);
257
258        Signature::from(ret)
259    }
260}
261
262/// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
263/// Requires a signing-capable context.
264pub fn sign(msg: impl Into<Message>, sk: &SecretKey) -> Signature {
265    sign_ecdsa_with_noncedata_pointer(msg, sk, None)
266}
267
268/// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
269/// and includes 32 bytes of noncedata in the nonce generation via inclusion in
270/// one of the hash operations during nonce generation. This is useful when multiple
271/// signatures are needed for the same Message and SecretKey while still using RFC6979.
272/// Requires a signing-capable context.
273pub fn sign_with_noncedata(
274    msg: impl Into<Message>,
275    sk: &SecretKey,
276    noncedata: &[u8; 32],
277) -> Signature {
278    sign_ecdsa_with_noncedata_pointer(msg, sk, Some(noncedata))
279}
280
281fn sign_grind_with_check(
282    msg: impl Into<Message>,
283    sk: &SecretKey,
284    check: impl Fn(&ffi::Signature) -> bool,
285) -> Signature {
286    let mut entropy_p: *const ffi::types::c_void = ptr::null();
287    let mut counter: u32 = 0;
288    let mut extra_entropy = [0u8; 32];
289    let msg = msg.into();
290    loop {
291        unsafe {
292            let mut ret = ffi::Signature::new();
293            // We can assume the return value because it's not possible to construct
294            // an invalid signature from a valid `Message` and `SecretKey`
295            let res = crate::with_global_context(
296                |secp: &Secp256k1<crate::AllPreallocated>| {
297                    ffi::secp256k1_ecdsa_sign(
298                        secp.ctx.as_ptr(),
299                        &mut ret,
300                        msg.as_c_ptr(),
301                        sk.as_c_ptr(),
302                        ffi::secp256k1_nonce_function_rfc6979,
303                        entropy_p,
304                    )
305                },
306                Some(&sk.to_secret_bytes()),
307            );
308            assert_eq!(res, 1);
309
310            if check(&ret) {
311                return Signature::from(ret);
312            }
313
314            counter += 1;
315            extra_entropy[..4].copy_from_slice(&counter.to_le_bytes());
316            entropy_p = extra_entropy.as_c_ptr().cast::<ffi::types::c_void>();
317
318            // When fuzzing, these checks will usually spinloop forever, so just short-circuit them.
319            #[cfg(secp256k1_fuzz)]
320            return Signature::from(ret);
321        }
322    }
323}
324
325/// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce
326/// and "grinds" the nonce by passing extra entropy if necessary to produce
327/// a signature that is less than 71 - `bytes_to_grind` bytes. The number
328/// of signing operation performed by this function is exponential in the
329/// number of bytes grinded.
330/// Requires a signing capable context.
331pub fn sign_grind_r(msg: impl Into<Message>, sk: &SecretKey, bytes_to_grind: usize) -> Signature {
332    let len_check = |s: &ffi::Signature| der_length_check(s, 71 - bytes_to_grind);
333    sign_grind_with_check(msg, sk, len_check)
334}
335
336/// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce
337/// and "grinds" the nonce by passing extra entropy if necessary to produce
338/// a signature that is less than 71 bytes and compatible with the low r
339/// signature implementation of bitcoin core. In average, this function
340/// will perform two signing operations.
341/// Requires a signing capable context.
342pub fn sign_low_r(msg: impl Into<Message>, sk: &SecretKey) -> Signature {
343    sign_grind_with_check(msg, sk, compact_sig_has_zero_first_bit)
344}
345
346impl<C: Signing> Secp256k1<C> {
347    /// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
348    /// Requires a signing-capable context.
349    #[deprecated(since = "0.32.0", note = "use ecdsa::sign instead")]
350    pub fn sign_ecdsa(&self, msg: impl Into<Message>, sk: &SecretKey) -> Signature {
351        self::sign(msg, sk)
352    }
353
354    /// Constructs a signature for `msg` using the secret key `sk` and RFC6979 nonce
355    /// and includes 32 bytes of noncedata in the nonce generation via inclusion in
356    /// one of the hash operations during nonce generation. This is useful when multiple
357    /// signatures are needed for the same Message and SecretKey while still using RFC6979.
358    /// Requires a signing-capable context.
359    #[deprecated(since = "0.32.0", note = "use ecdsa::sign_with_noncedata instead")]
360    pub fn sign_ecdsa_with_noncedata(
361        &self,
362        msg: impl Into<Message>,
363        sk: &SecretKey,
364        noncedata: &[u8; 32],
365    ) -> Signature {
366        self::sign_with_noncedata(msg, sk, noncedata)
367    }
368
369    /// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce
370    /// and "grinds" the nonce by passing extra entropy if necessary to produce
371    /// a signature that is less than 71 - `bytes_to_grind` bytes. The number
372    /// of signing operation performed by this function is exponential in the
373    /// number of bytes grinded.
374    /// Requires a signing capable context.
375    #[deprecated(since = "0.32.0", note = "use ecdsa::sign_grind_r instead")]
376    pub fn sign_ecdsa_grind_r(
377        &self,
378        msg: impl Into<Message>,
379        sk: &SecretKey,
380        bytes_to_grind: usize,
381    ) -> Signature {
382        self::sign_grind_r(msg, sk, bytes_to_grind)
383    }
384
385    /// Constructs a signature for `msg` using the secret key `sk`, RFC6979 nonce
386    /// and "grinds" the nonce by passing extra entropy if necessary to produce
387    /// a signature that is less than 71 bytes and compatible with the low r
388    /// signature implementation of bitcoin core. In average, this function
389    /// will perform two signing operations.
390    /// Requires a signing capable context.
391    #[deprecated(since = "0.32.0", note = "use ecdsa::sign_low_r instead")]
392    pub fn sign_ecdsa_low_r(&self, msg: impl Into<Message>, sk: &SecretKey) -> Signature {
393        self::sign_low_r(msg, sk)
394    }
395}
396
397impl<C: Verification> Secp256k1<C> {
398    /// Checks that `sig` is a valid ECDSA signature for `msg` using the public
399    /// key `pubkey`. Returns `Ok(())` on success. Note that this function cannot
400    /// be used for Bitcoin consensus checking since there may exist signatures
401    /// which OpenSSL would verify but not libsecp256k1, or vice-versa. Requires a
402    /// verify-capable context.
403    ///
404    /// ```rust
405    /// # #[cfg(all(feature = "rand", feature = "std"))] {
406    /// # use secp256k1::{rand, Secp256k1, Message, Error};
407    /// #
408    /// # let secp = Secp256k1::new();
409    /// # let (secret_key, public_key) = secp.generate_keypair(&mut rand::rng());
410    /// #
411    /// let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
412    /// let sig = secp.sign_ecdsa(message, &secret_key);
413    /// assert_eq!(secp.verify_ecdsa(message, &sig, &public_key), Ok(()));
414    ///
415    /// let message = Message::from_digest_slice(&[0xcd; 32]).expect("32 bytes");
416    /// assert_eq!(secp.verify_ecdsa(message, &sig, &public_key), Err(Error::IncorrectSignature));
417    /// # }
418    /// ```
419    #[inline]
420    #[deprecated(since = "0.32.0", note = "use ecdsa::verify instead")]
421    pub fn verify_ecdsa(
422        &self,
423        msg: impl Into<Message>,
424        sig: &Signature,
425        pk: &PublicKey,
426    ) -> Result<(), Error> {
427        self::verify(sig, msg, pk)
428    }
429}
430
431/// Checks that `sig` is a valid ECDSA signature for `msg` using the public
432/// key `pubkey`. Returns `Ok(())` on success. Note that this function cannot
433/// be used for Bitcoin consensus checking since there may exist signatures
434/// which OpenSSL would verify but not libsecp256k1, or vice-versa. Requires a
435/// verify-capable context.
436///
437/// ```rust
438/// # #[cfg(all(feature = "rand", feature = "std"))] {
439/// # use secp256k1::{rand, ecdsa, Message, Error};
440/// #
441/// # let (secret_key, public_key) = secp256k1::generate_keypair(&mut rand::rng());
442/// #
443/// let message = Message::from_digest_slice(&[0xab; 32]).expect("32 bytes");
444/// let sig = ecdsa::sign(message, &secret_key);
445/// assert_eq!(ecdsa::verify(&sig, message, &public_key), Ok(()));
446///
447/// let message = Message::from_digest_slice(&[0xcd; 32]).expect("32 bytes");
448/// assert_eq!(ecdsa::verify(&sig, message, &public_key), Err(Error::IncorrectSignature));
449/// # }
450/// ```
451#[inline]
452pub fn verify(sig: &Signature, msg: impl Into<Message>, pk: &PublicKey) -> Result<(), Error> {
453    let msg = msg.into();
454    unsafe {
455        let res = crate::with_global_context(
456            |secp: &Secp256k1<crate::AllPreallocated>| {
457                ffi::secp256k1_ecdsa_verify(
458                    secp.ctx.as_ptr(),
459                    sig.as_c_ptr(),
460                    msg.as_c_ptr(),
461                    pk.as_c_ptr(),
462                )
463            },
464            None,
465        );
466        if res == 0 {
467            Err(Error::IncorrectSignature)
468        } else {
469            Ok(())
470        }
471    }
472}
473
474pub(crate) fn compact_sig_has_zero_first_bit(sig: &ffi::Signature) -> bool {
475    let mut compact = [0u8; 64];
476    unsafe {
477        let err = ffi::secp256k1_ecdsa_signature_serialize_compact(
478            ffi::secp256k1_context_no_precomp,
479            compact.as_mut_c_ptr(),
480            sig,
481        );
482        debug_assert!(err == 1);
483    }
484    compact[0] < 0x80
485}
486
487pub(crate) fn der_length_check(sig: &ffi::Signature, max_len: usize) -> bool {
488    let mut ser_ret = [0u8; 72];
489    let mut len: usize = ser_ret.len();
490    unsafe {
491        let err = ffi::secp256k1_ecdsa_signature_serialize_der(
492            ffi::secp256k1_context_no_precomp,
493            ser_ret.as_mut_c_ptr(),
494            &mut len,
495            sig,
496        );
497        debug_assert!(err == 1);
498    }
499    len <= max_len
500}
501
502#[cfg(test)]
503mod tests {
504    use crate::ecdsa::Signature;
505    use crate::Scalar;
506
507    #[test]
508    fn test_from_compact_min_r_and_min_s() {
509        // From libsecp256k1: "The signature must consist of a 32-byte big endian R value, followed
510        // by a 32-byte big endian S value. If R or S fall outside of [0..order-1], the encoding is
511        // invalid. R and S with value 0 are allowed in the encoding."
512        let r = Scalar::ZERO;
513        let s = Scalar::ZERO;
514        let mut bytes: [u8; 64] = [0; 64];
515        bytes[..32].copy_from_slice(&r.to_be_bytes());
516        bytes[32..].copy_from_slice(&s.to_be_bytes());
517
518        assert!(Signature::from_compact(&bytes).is_ok())
519    }
520
521    #[test]
522    fn test_from_compact_max_r_and_max_s() {
523        let r = Scalar::MAX;
524        let s = Scalar::MAX;
525        let mut bytes: [u8; 64] = [0; 64];
526        bytes[..32].copy_from_slice(&r.to_be_bytes());
527        bytes[32..].copy_from_slice(&s.to_be_bytes());
528
529        assert!(Signature::from_compact(&bytes).is_ok())
530    }
531
532    #[test]
533    fn test_from_compact_invalid_r() {
534        let r = Scalar::MAX;
535        let s = Scalar::MAX;
536        let mut bytes: [u8; 64] = [0; 64];
537        bytes[..32].copy_from_slice(&r.to_be_bytes());
538        bytes[32..].copy_from_slice(&s.to_be_bytes());
539        bytes[31] += 1;
540
541        assert!(Signature::from_compact(&bytes).is_err())
542    }
543
544    #[test]
545    fn test_from_compact_invalid_s() {
546        let r = Scalar::MAX;
547        let s = Scalar::MAX;
548        let mut bytes: [u8; 64] = [0; 64];
549        bytes[..32].copy_from_slice(&r.to_be_bytes());
550        bytes[32..].copy_from_slice(&s.to_be_bytes());
551        bytes[63] += 1;
552
553        assert!(Signature::from_compact(&bytes).is_err())
554    }
555}