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