1#[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#[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 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 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 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 pub fn normalize_s(&mut self) {
137 unsafe {
138 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 #[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 #[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 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 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 #[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
210impl 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 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 pub fn sign_ecdsa(&self, msg: &Message, sk: &SecretKey) -> Signature {
276 self.sign_ecdsa_with_noncedata_pointer(msg, sk, None)
277 }
278
279 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 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 #[cfg(secp256k1_fuzz)]
328 return Signature::from(ret);
329 }
330 }
331 }
332
333 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 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 #[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}