1#![crate_type = "lib"]
24#![crate_type = "rlib"]
25#![crate_type = "dylib"]
26#![crate_name = "secp256k1zkp"]
27
28#![deny(non_upper_case_globals)]
30#![deny(non_camel_case_types)]
31#![deny(non_snake_case)]
32#![deny(unused_mut)]
33#![warn(missing_docs)]
34
35#![cfg_attr(feature = "dev", allow(unstable_features))]
36#![cfg_attr(feature = "dev", feature(plugin))]
37#![cfg_attr(feature = "dev", plugin(clippy))]
38
39#![cfg_attr(all(test, feature = "unstable"), feature(test))]
40#[cfg(all(test, feature = "unstable"))] extern crate test;
41
42extern crate arrayvec;
43extern crate rustc_serialize as serialize;
44extern crate serde;
45extern crate serde_json as json;
46
47extern crate libc;
48pub extern crate rand;
49
50extern crate zeroize;
51
52use libc::size_t;
53use std::{fmt, ops, ptr};
54use rand::Rng;
55
56#[macro_use]
57mod macros;
58pub mod constants;
59pub mod ecdh;
60pub mod ffi;
61pub mod key;
62pub mod pedersen;
63pub mod aggsig;
64
65pub use key::SecretKey;
66pub use key::PublicKey;
67
68#[derive(Copy, Clone, PartialEq, Eq, Debug)]
70pub struct RecoveryId(i32);
71
72#[derive(Copy, Clone, PartialEq, Eq, Debug)]
74pub struct Signature(ffi::Signature);
75
76impl std::convert::AsRef<[u8]> for Signature {
77 fn as_ref(&self) -> &[u8] {
78 &self.0.as_ref()
79 }
80}
81
82#[derive(Copy, Clone, PartialEq, Eq, Debug)]
84pub struct AggSigPartialSignature(ffi::AggSigPartialSignature);
85
86impl std::convert::AsRef<[u8]> for AggSigPartialSignature {
87 fn as_ref(&self) -> &[u8] {
88 &self.0.as_ref()
89 }
90}
91
92#[derive(Copy, Clone, PartialEq, Eq, Debug)]
94pub struct RecoverableSignature(ffi::RecoverableSignature);
95
96impl RecoveryId {
97 #[inline]
98 pub fn from_i32(id: i32) -> Result<RecoveryId, Error> {
100 match id {
101 0 | 1 | 2 | 3 => Ok(RecoveryId(id)),
102 _ => Err(Error::InvalidRecoveryId)
103 }
104 }
105
106 #[inline]
107 pub fn to_i32(&self) -> i32 {
109 self.0
110 }
111}
112
113impl Signature {
114 #[inline]
115 pub fn from_der(secp: &Secp256k1, data: &[u8]) -> Result<Signature, Error> {
117 let mut ret = unsafe { ffi::Signature::blank() };
118
119 unsafe {
120 if ffi::secp256k1_ecdsa_signature_parse_der(secp.ctx, &mut ret,
121 data.as_ptr(), data.len() as libc::size_t) == 1 {
122 Ok(Signature(ret))
123 } else {
124 Err(Error::InvalidSignature)
125 }
126 }
127 }
128
129 pub fn from_compact(secp: &Secp256k1, data: &[u8]) -> Result<Signature, Error> {
131 let mut ret = unsafe { ffi::Signature::blank() };
132 if data.len() != 64 {
133 return Err(Error::InvalidSignature)
134 }
135
136 unsafe {
137 if ffi::secp256k1_ecdsa_signature_parse_compact(secp.ctx, &mut ret,
138 data.as_ptr()) == 1 {
139 Ok(Signature(ret))
140 } else {
141 Err(Error::InvalidSignature)
142 }
143 }
144 }
145
146 pub fn from_raw_data(data: &[u8;64]) -> Result<Signature, Error> {
148 Ok(Signature(ffi::Signature::from_data(data.clone())))
149 }
150
151 pub fn from_der_lax(secp: &Secp256k1, data: &[u8]) -> Result<Signature, Error> {
156 unsafe {
157 let mut ret = ffi::Signature::blank();
158 if ffi::ecdsa_signature_parse_der_lax(secp.ctx, &mut ret,
159 data.as_ptr(), data.len() as libc::size_t) == 1 {
160 Ok(Signature(ret))
161 } else {
162 Err(Error::InvalidSignature)
163 }
164 }
165 }
166
167 pub fn normalize_s(&mut self, secp: &Secp256k1) {
185 unsafe {
186 ffi::secp256k1_ecdsa_signature_normalize(secp.ctx, self.as_mut_ptr(),
189 self.as_ptr());
190 }
191 }
192
193 #[inline]
195 pub fn as_ptr(&self) -> *const ffi::Signature {
196 &self.0 as *const _
197 }
198
199 #[inline]
201 pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature {
202 &mut self.0 as *mut _
203 }
204
205 #[inline]
206 pub fn serialize_der(&self, secp: &Secp256k1) -> Vec<u8> {
208 let mut ret = Vec::with_capacity(72);
209 let mut len: size_t = ret.capacity() as size_t;
210 unsafe {
211 let err = ffi::secp256k1_ecdsa_signature_serialize_der(secp.ctx, ret.as_mut_ptr(),
212 &mut len, self.as_ptr());
213 debug_assert!(err == 1);
214 ret.set_len(len as usize);
215 }
216 ret
217 }
218
219 #[inline]
220 pub fn serialize_compact(&self, secp: &Secp256k1) -> [u8; 64] {
222 let mut ret = [0; 64];
223 unsafe {
224 let err = ffi::secp256k1_ecdsa_signature_serialize_compact(secp.ctx, ret.as_mut_ptr(),
225 self.as_ptr());
226 debug_assert!(err == 1);
227 }
228 ret
229 }
230
231 #[inline]
232 pub fn to_raw_data(&self) -> [u8; 64] {
234 (self.0).0.clone()
235 }
236}
237
238impl serde::Serialize for Signature {
239 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
240 where S: serde::Serializer
241 {
242 let secp = Secp256k1::with_caps(crate::ContextFlag::None);
243 (&self.serialize_compact(&secp)[..]).serialize(s)
244 }
245}
246
247impl<'de> serde::Deserialize<'de> for Signature {
248 fn deserialize<D>(d: D) -> Result<Signature, D::Error>
249 where D: serde::Deserializer<'de>
250 {
251 use serde::de;
252 struct Visitor {
253 marker: std::marker::PhantomData<Signature>,
254 }
255 impl<'de> de::Visitor<'de> for Visitor {
256 type Value = Signature;
257
258 #[inline]
259 fn visit_seq<A>(self, mut a: A) -> Result<Signature, A::Error>
260 where A: de::SeqAccess<'de>
261 {
262 let s = Secp256k1::with_caps(crate::ContextFlag::None);
263 unsafe {
264 use std::mem;
265 let mut ret: [u8; constants::COMPACT_SIGNATURE_SIZE] = mem::MaybeUninit::uninit().assume_init();
266
267 for i in 0..constants::COMPACT_SIGNATURE_SIZE {
268 ret[i] = match a.next_element()? {
269 Some(c) => c,
270 None => return Err(::serde::de::Error::invalid_length(i, &self))
271 };
272 }
273 let one_after_last : Option<u8> = a.next_element()?;
274 if one_after_last.is_some() {
275 return Err(serde::de::Error::invalid_length(constants::COMPACT_SIGNATURE_SIZE + 1, &self));
276 }
277
278 Signature::from_compact(&s, &ret).map_err(
279 |e| match e {
280 Error::InvalidSignature => de::Error::invalid_value(de::Unexpected::Seq, &self),
281 _ => de::Error::custom(&e.to_string()),
282 }
283 )
284 }
285 }
286
287 fn expecting(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
288 write!(f, "a sequence of {} bytes representing a syntactically well-formed compact signature",
289 constants::COMPACT_SIGNATURE_SIZE)
290 }
291 }
292
293 d.deserialize_seq(Visitor { marker: std::marker::PhantomData })
295 }
296}
297
298impl From<ffi::Signature> for Signature {
300 #[inline]
301 fn from(sig: ffi::Signature) -> Signature {
302 Signature(sig)
303 }
304}
305
306impl AggSigPartialSignature {
307 #[inline]
309 pub fn as_ptr(&self) -> *const ffi::AggSigPartialSignature {
310 &self.0 as *const _
311 }
312
313 #[inline]
315 pub fn as_mut_ptr(&mut self) -> *mut ffi::AggSigPartialSignature {
316 &mut self.0 as *mut _
317 }
318}
319
320impl From<ffi::AggSigPartialSignature> for AggSigPartialSignature {
322 #[inline]
323 fn from(sig: ffi::AggSigPartialSignature) -> AggSigPartialSignature {
324 AggSigPartialSignature(sig)
325 }
326}
327
328
329impl RecoverableSignature {
330 #[inline]
331 pub fn from_compact(secp: &Secp256k1, data: &[u8], recid: RecoveryId) -> Result<RecoverableSignature, Error> {
335 let mut ret = unsafe { ffi::RecoverableSignature::blank() };
336
337 unsafe {
338 if data.len() != 64 {
339 Err(Error::InvalidSignature)
340 } else if ffi::secp256k1_ecdsa_recoverable_signature_parse_compact(secp.ctx, &mut ret,
341 data.as_ptr(), recid.0) == 1 {
342 Ok(RecoverableSignature(ret))
343 } else {
344 Err(Error::InvalidSignature)
345 }
346 }
347 }
348
349 #[inline]
351 pub fn as_ptr(&self) -> *const ffi::RecoverableSignature {
352 &self.0 as *const _
353 }
354
355 #[inline]
356 pub fn serialize_compact(&self, secp: &Secp256k1) -> (RecoveryId, [u8; 64]) {
358 let mut ret = [0u8; 64];
359 let mut recid = 0i32;
360 unsafe {
361 let err = ffi::secp256k1_ecdsa_recoverable_signature_serialize_compact(
362 secp.ctx, ret.as_mut_ptr(), &mut recid, self.as_ptr());
363 assert!(err == 1);
364 }
365 (RecoveryId(recid), ret)
366 }
367
368 #[inline]
371 pub fn to_standard(&self, secp: &Secp256k1) -> Signature {
372 let mut ret = unsafe { ffi::Signature::blank() };
373 unsafe {
374 let err = ffi::secp256k1_ecdsa_recoverable_signature_convert(secp.ctx, &mut ret, self.as_ptr());
375 assert!(err == 1);
376 }
377 Signature(ret)
378 }
379}
380
381impl From<ffi::RecoverableSignature> for RecoverableSignature {
383 #[inline]
384 fn from(sig: ffi::RecoverableSignature) -> RecoverableSignature {
385 RecoverableSignature(sig)
386 }
387}
388
389impl ops::Index<usize> for Signature {
390 type Output = u8;
391
392 #[inline]
393 fn index(&self, index: usize) -> &u8 {
394 &self.0[index]
395 }
396}
397
398impl ops::Index<ops::Range<usize>> for Signature {
399 type Output = [u8];
400
401 #[inline]
402 fn index(&self, index: ops::Range<usize>) -> &[u8] {
403 &self.0[index]
404 }
405}
406
407impl ops::Index<ops::RangeFrom<usize>> for Signature {
408 type Output = [u8];
409
410 #[inline]
411 fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
412 &self.0[index.start..]
413 }
414}
415
416impl ops::Index<ops::RangeFull> for Signature {
417 type Output = [u8];
418
419 #[inline]
420 fn index(&self, _: ops::RangeFull) -> &[u8] {
421 &self.0[..]
422 }
423}
424
425pub struct Message([u8; constants::MESSAGE_SIZE]);
427impl Copy for Message {}
428impl_array_newtype!(Message, u8, constants::MESSAGE_SIZE);
429impl_pretty_debug!(Message);
430
431impl Message {
432 #[inline]
434 pub fn from_slice(data: &[u8]) -> Result<Message, Error> {
435 match data.len() {
436 constants::MESSAGE_SIZE => {
437 let mut ret = [0; constants::MESSAGE_SIZE];
438 ret[..].copy_from_slice(data);
439 Ok(Message(ret))
440 }
441 _ => Err(Error::InvalidMessage)
442 }
443 }
444}
445
446impl From<[u8; constants::MESSAGE_SIZE]> for Message {
448 fn from(buf: [u8; constants::MESSAGE_SIZE]) -> Message {
449 Message(buf)
450 }
451}
452
453#[derive(Copy, PartialEq, Eq, Clone, Debug, serde::Serialize, serde::Deserialize)]
455pub enum Error {
456 IncapableContext,
459 IncorrectSignature,
461 InvalidMessage,
464 InvalidPublicKey,
466 InvalidCommit,
468 InvalidSignature,
470 InvalidSecretKey,
472 InvalidRecoveryId,
474 IncorrectCommitSum,
476 InvalidRangeProof,
478 PartialSigFailure,
480}
481
482impl Error {
483 fn as_str(&self) -> &str {
484 match *self {
485 Error::IncapableContext => "secp: context does not have sufficient capabilities",
486 Error::IncorrectSignature => "secp: signature failed verification",
487 Error::InvalidMessage => "secp: message was not 32 bytes (do you need to hash?)",
488 Error::InvalidPublicKey => "secp: malformed public key",
489 Error::InvalidCommit => "secp: malformed commit",
490 Error::InvalidSignature => "secp: malformed signature",
491 Error::InvalidSecretKey => "secp: malformed or out-of-range secret key",
492 Error::InvalidRecoveryId => "secp: bad recovery id",
493 Error::IncorrectCommitSum => "secp: invalid pedersen commitment sum",
494 Error::InvalidRangeProof => "secp: invalid range proof",
495 Error::PartialSigFailure => "secp: partial sig (aggsig) failure",
496 }
497 }
498}
499
500impl fmt::Display for Error {
502 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
503 f.write_str(self.as_str())
504 }
505}
506
507impl std::error::Error for Error {
508 fn description(&self) -> &str { self.as_str() }
509}
510
511
512pub struct Secp256k1 {
514 ctx: *mut ffi::Context,
515 caps: ContextFlag
516}
517
518unsafe impl Send for Secp256k1 {}
519unsafe impl Sync for Secp256k1 {}
520
521#[derive(PartialEq, Eq, Copy, Clone, Debug)]
524pub enum ContextFlag {
525 None,
528 SignOnly,
530 VerifyOnly,
532 Full,
534 Commit,
536}
537
538impl fmt::Display for ContextFlag {
540 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
541 fmt::Debug::fmt(self, f)
542 }
543}
544
545impl Clone for Secp256k1 {
546 fn clone(&self) -> Secp256k1 {
547 Secp256k1 {
548 ctx: unsafe { ffi::secp256k1_context_clone(self.ctx) },
549 caps: self.caps
550 }
551 }
552}
553
554impl PartialEq for Secp256k1 {
555 fn eq(&self, other: &Secp256k1) -> bool { self.caps == other.caps }
556}
557impl Eq for Secp256k1 { }
558
559impl fmt::Debug for Secp256k1 {
560 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
561 write!(f, "Secp256k1 {{ [private], caps: {:?} }}", self.caps)
562 }
563}
564
565impl Drop for Secp256k1 {
566 fn drop(&mut self) {
567 unsafe { ffi::secp256k1_context_destroy(self.ctx); }
568 }
569}
570
571impl Secp256k1 {
572 #[inline]
574 pub fn new() -> Secp256k1 {
575 Secp256k1::with_caps(ContextFlag::Full)
576 }
577
578 pub fn with_caps(caps: ContextFlag) -> Secp256k1 {
580 let flag = match caps {
581 ContextFlag::None => ffi::SECP256K1_START_NONE,
582 ContextFlag::SignOnly => ffi::SECP256K1_START_SIGN,
583 ContextFlag::VerifyOnly => ffi::SECP256K1_START_VERIFY,
584 ContextFlag::Full | ContextFlag::Commit => {
585 ffi::SECP256K1_START_SIGN | ffi::SECP256K1_START_VERIFY
586 }
587 };
588 Secp256k1 { ctx: unsafe { ffi::secp256k1_context_create(flag) }, caps: caps }
589 }
590
591 pub fn without_caps() -> Secp256k1 {
593 Secp256k1::with_caps(ContextFlag::None)
594 }
595
596 pub fn randomize<R: Rng>(&mut self, rng: &mut R) {
599 let mut seed = [0u8; 32];
600 rng.fill(&mut seed);
601 unsafe {
602 let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_ptr());
603 assert!(err == 1);
612 }
613 }
614
615 #[inline]
619 pub fn generate_keypair<R: Rng>(&self, rng: &mut R)
620 -> Result<(key::SecretKey, key::PublicKey), Error> {
621 let sk = key::SecretKey::new(self, rng);
622 let pk = key::PublicKey::from_secret_key(self, &sk)?;
623 Ok((sk, pk))
624 }
625
626 pub fn sign(&self, msg: &Message, sk: &key::SecretKey)
629 -> Result<Signature, Error> {
630 if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
631 return Err(Error::IncapableContext);
632 }
633
634 let mut ret = unsafe { ffi::Signature::blank() };
635 unsafe {
636 assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_ptr(),
639 sk.as_ptr(), ffi::secp256k1_nonce_function_rfc6979,
640 ptr::null()), 1);
641 }
642 Ok(Signature::from(ret))
643 }
644
645 pub fn sign_recoverable(&self, msg: &Message, sk: &key::SecretKey)
648 -> Result<RecoverableSignature, Error> {
649 if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
650 return Err(Error::IncapableContext);
651 }
652
653 let mut ret = unsafe { ffi::RecoverableSignature::blank() };
654 unsafe {
655 assert_eq!(ffi::secp256k1_ecdsa_sign_recoverable(self.ctx, &mut ret, msg.as_ptr(),
658 sk.as_ptr(), ffi::secp256k1_nonce_function_rfc6979,
659 ptr::null()), 1);
660 }
661 Ok(RecoverableSignature::from(ret))
662 }
663
664 pub fn recover(&self, msg: &Message, sig: &RecoverableSignature)
667 -> Result<key::PublicKey, Error> {
668 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
669 return Err(Error::IncapableContext);
670 }
671
672 let mut pk = unsafe { ffi::PublicKey::blank() };
673
674 unsafe {
675 if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk,
676 sig.as_ptr(), msg.as_ptr()) != 1 {
677 return Err(Error::InvalidSignature);
678 }
679 };
680 Ok(key::PublicKey::from(pk))
681 }
682
683 #[inline]
689 pub fn verify(&self, msg: &Message, sig: &Signature, pk: &key::PublicKey) -> Result<(), Error> {
690 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
691 return Err(Error::IncapableContext);
692 }
693
694 if !pk.is_valid() {
695 Err(Error::InvalidPublicKey)
696 } else if unsafe { ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_ptr(), msg.as_ptr(),
697 pk.as_ptr()) } == 0 {
698 Err(Error::IncorrectSignature)
699 } else {
700 Ok(())
701 }
702 }
703}
704
705#[cfg(test)]
706mod tests {
707 use rand::{Rng, thread_rng};
708 use crate::serialize::hex::FromHex;
709 use crate::key::{SecretKey, PublicKey};
710 use super::constants;
711 use super::{Secp256k1, Signature, RecoverableSignature, Message, RecoveryId, ContextFlag};
712 use super::Error::{InvalidMessage, InvalidPublicKey, IncorrectSignature, InvalidSignature,
713 IncapableContext};
714
715 macro_rules! hex (($hex:expr) => ($hex.from_hex().unwrap()));
716
717 #[test]
718 fn capabilities() {
719 let none = Secp256k1::with_caps(ContextFlag::None);
720 let sign = Secp256k1::with_caps(ContextFlag::SignOnly);
721 let vrfy = Secp256k1::with_caps(ContextFlag::VerifyOnly);
722 let full = Secp256k1::with_caps(ContextFlag::Full);
723
724 let mut msg = [0u8; 32];
725 thread_rng().fill(&mut msg);
726 let msg = Message::from_slice(&msg).unwrap();
727
728 assert_eq!(none.generate_keypair(&mut thread_rng()), Err(IncapableContext));
730 assert_eq!(vrfy.generate_keypair(&mut thread_rng()), Err(IncapableContext));
731 assert!(sign.generate_keypair(&mut thread_rng()).is_ok());
732 assert!(full.generate_keypair(&mut thread_rng()).is_ok());
733 let (sk, pk) = full.generate_keypair(&mut thread_rng()).unwrap();
734
735 assert_eq!(none.sign(&msg, &sk), Err(IncapableContext));
737 assert_eq!(vrfy.sign(&msg, &sk), Err(IncapableContext));
738 assert!(sign.sign(&msg, &sk).is_ok());
739 assert!(full.sign(&msg, &sk).is_ok());
740 assert_eq!(none.sign_recoverable(&msg, &sk), Err(IncapableContext));
741 assert_eq!(vrfy.sign_recoverable(&msg, &sk), Err(IncapableContext));
742 assert!(sign.sign_recoverable(&msg, &sk).is_ok());
743 assert!(full.sign_recoverable(&msg, &sk).is_ok());
744 assert_eq!(sign.sign(&msg, &sk), full.sign(&msg, &sk));
745 assert_eq!(sign.sign_recoverable(&msg, &sk), full.sign_recoverable(&msg, &sk));
746 let sig = full.sign(&msg, &sk).unwrap();
747 let sigr = full.sign_recoverable(&msg, &sk).unwrap();
748
749 assert_eq!(none.verify(&msg, &sig, &pk), Err(IncapableContext));
751 assert_eq!(sign.verify(&msg, &sig, &pk), Err(IncapableContext));
752 assert!(vrfy.verify(&msg, &sig, &pk).is_ok());
753 assert!(full.verify(&msg, &sig, &pk).is_ok());
754
755 assert_eq!(none.recover(&msg, &sigr), Err(IncapableContext));
757 assert_eq!(sign.recover(&msg, &sigr), Err(IncapableContext));
758 assert!(vrfy.recover(&msg, &sigr).is_ok());
759 assert!(full.recover(&msg, &sigr).is_ok());
760
761 assert_eq!(vrfy.recover(&msg, &sigr),
762 full.recover(&msg, &sigr));
763 assert_eq!(full.recover(&msg, &sigr), Ok(pk));
764
765 let (pk_slice, sk_slice) = (&pk.serialize_vec(&none, true), &sk[..]);
767 let new_pk = PublicKey::from_slice(&none, pk_slice).unwrap();
768 let new_sk = SecretKey::from_slice(&none, sk_slice).unwrap();
769 assert_eq!(sk, new_sk);
770 assert_eq!(pk, new_pk);
771 }
772
773 #[test]
774 fn recid_sanity_check() {
775 let one = RecoveryId(1);
776 assert_eq!(one, one.clone());
777 }
778
779 #[test]
780 fn invalid_pubkey() {
781 let s = Secp256k1::new();
782 let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap();
783 let pk = PublicKey::new();
784 let mut msg = [0u8; 32];
785 thread_rng().fill(&mut msg);
786 let msg = Message::from_slice(&msg).unwrap();
787
788 assert_eq!(s.verify(&msg, &sig.to_standard(&s), &pk), Err(InvalidPublicKey));
789 }
790
791 #[test]
792 fn sign() {
793 let mut s = Secp256k1::new();
794 s.randomize(&mut thread_rng());
795 let one = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
796 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
797
798 let sk = SecretKey::from_slice(&s, &one).unwrap();
799 let msg = Message::from_slice(&one).unwrap();
800
801 let sig = s.sign_recoverable(&msg, &sk).unwrap();
802 assert_eq!(Ok(sig), RecoverableSignature::from_compact(&s, &[
803 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
804 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
805 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
806 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
807 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
808 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
809 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
810 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89],
811 RecoveryId(1)))
812 }
813
814 #[test]
815 fn signature_serialize_roundtrip() {
816 let mut s = Secp256k1::new();
817 s.randomize(&mut thread_rng());
818
819 let mut msg = [0; 32];
820 for _ in 0..100 {
821 thread_rng().fill(&mut msg);
822 let msg = Message::from_slice(&msg).unwrap();
823
824 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
825 let sig1 = s.sign(&msg, &sk).unwrap();
826 let der = sig1.serialize_der(&s);
827 let sig2 = Signature::from_der(&s, &der[..]).unwrap();
828 assert_eq!(sig1, sig2);
829
830 let compact = sig1.serialize_compact(&s);
831 let sig2 = Signature::from_compact(&s, &compact[..]).unwrap();
832 assert_eq!(sig1, sig2);
833
834 round_trip_serde!(sig1);
835
836 assert!(Signature::from_compact(&s, &der[..]).is_err());
837 assert!(Signature::from_compact(&s, &compact[0..4]).is_err());
838 assert!(Signature::from_der(&s, &compact[..]).is_err());
839 assert!(Signature::from_der(&s, &der[0..4]).is_err());
840 }
841 }
842
843 #[test]
844 fn signature_lax_der() {
845 macro_rules! check_lax_sig(
846 ($hex:expr) => ({
847 let secp = Secp256k1::without_caps();
848 let sig = hex!($hex);
849 assert!(Signature::from_der_lax(&secp, &sig[..]).is_ok());
850 })
851 );
852
853 check_lax_sig!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c");
854 check_lax_sig!("304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f");
855 check_lax_sig!("3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a");
856 check_lax_sig!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
857 check_lax_sig!("3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1");
858 check_lax_sig!("3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60");
859 check_lax_sig!("3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf");
860 }
861
862 #[test]
863 fn sign_and_verify() {
864 let mut s = Secp256k1::new();
865 s.randomize(&mut thread_rng());
866
867 let mut msg = [0; 32];
868 for _ in 0..100 {
869 thread_rng().fill(&mut msg);
870 let msg = Message::from_slice(&msg).unwrap();
871
872 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
873 let sig = s.sign(&msg, &sk).unwrap();
874 assert_eq!(s.verify(&msg, &sig, &pk), Ok(()));
875 }
876 }
877
878 #[test]
879 fn sign_and_verify_extreme() {
880 let mut s = Secp256k1::new();
881 s.randomize(&mut thread_rng());
882
883 let mut wild_keys = [[0; 32]; 2];
886 let mut wild_msgs = [[0; 32]; 4];
887
888 wild_keys[0][0] = 1;
889 wild_msgs[1][0] = 1;
890
891 use crate::constants;
892 wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
893 wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
894 wild_msgs[2][..].copy_from_slice(&constants::CURVE_ORDER[..]);
895
896 wild_keys[1][0] -= 1;
897 wild_msgs[1][0] -= 1;
898
899 for key in wild_keys.iter().map(|k| SecretKey::from_slice(&s, &k[..]).unwrap()) {
900 for msg in wild_msgs.iter().map(|m| Message::from_slice(&m[..]).unwrap()) {
901 let sig = s.sign(&msg, &key).unwrap();
902 let pk = PublicKey::from_secret_key(&s, &key).unwrap();
903 assert_eq!(s.verify(&msg, &sig, &pk), Ok(()));
904 }
905 }
906 }
907
908 #[test]
909 fn sign_and_verify_fail() {
910 let mut s = Secp256k1::new();
911 s.randomize(&mut thread_rng());
912
913 let mut msg = [0u8; 32];
914 thread_rng().fill(&mut msg);
915 let msg = Message::from_slice(&msg).unwrap();
916
917 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
918
919 let sigr = s.sign_recoverable(&msg, &sk).unwrap();
920 let sig = sigr.to_standard(&s);
921
922 let mut msg = [0u8; 32];
923 thread_rng().fill(&mut msg);
924 let msg = Message::from_slice(&msg).unwrap();
925 assert_eq!(s.verify(&msg, &sig, &pk), Err(IncorrectSignature));
926
927 let recovered_key = s.recover(&msg, &sigr).unwrap();
928 assert!(recovered_key != pk);
929 }
930
931 #[test]
932 fn sign_with_recovery() {
933 let mut s = Secp256k1::new();
934 s.randomize(&mut thread_rng());
935
936 let mut msg = [0u8; 32];
937 thread_rng().fill(&mut msg);
938 let msg = Message::from_slice(&msg).unwrap();
939
940 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
941
942 let sig = s.sign_recoverable(&msg, &sk).unwrap();
943
944 assert_eq!(s.recover(&msg, &sig), Ok(pk));
945 }
946
947 #[test]
948 fn bad_recovery() {
949 let mut s = Secp256k1::new();
950 s.randomize(&mut thread_rng());
951
952 let msg = Message::from_slice(&[0x55; 32]).unwrap();
953
954 let sig = RecoverableSignature::from_compact(&s, &[0; 64], RecoveryId(0)).unwrap();
956 assert_eq!(s.recover(&msg, &sig), Err(InvalidSignature));
957 let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap();
959 assert!(s.recover(&msg, &sig).is_ok());
960 }
961
962 #[test]
963 fn test_bad_slice() {
964 let s = Secp256k1::new();
965 assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE + 1]),
966 Err(InvalidSignature));
967 assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE]),
968 Err(InvalidSignature));
969
970 assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]),
971 Err(InvalidMessage));
972 assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]),
973 Err(InvalidMessage));
974 assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
975 }
976
977 #[test]
978 fn test_debug_output() {
979 let s = Secp256k1::new();
980 let sig = RecoverableSignature::from_compact(&s, &[
981 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
982 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
983 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
984 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
985 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
986 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
987 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
988 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89],
989 RecoveryId(1)).unwrap();
990 assert_eq!(&format!("{:?}", sig), "RecoverableSignature(98882e09f4ed6dc3659e43fc771e0cafa60b1f926f2b77041f744721adff7366898cb609d0ee128d06ae9aa3c48020ff9f705e02f80e1280a8ade05216971a4c01)");
991
992 let msg = Message([1, 2, 3, 4, 5, 6, 7, 8,
993 9, 10, 11, 12, 13, 14, 15, 16,
994 17, 18, 19, 20, 21, 22, 23, 24,
995 25, 26, 27, 28, 29, 30, 31, 255]);
996 assert_eq!(&format!("{:?}", msg), "Message(0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff)");
997 }
998
999 #[test]
1000 fn test_recov_sig_serialize_compact() {
1001 let s = Secp256k1::new();
1002
1003 let recid_in = RecoveryId(1);
1004 let bytes_in = &[
1005 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
1006 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
1007 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
1008 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
1009 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
1010 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
1011 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
1012 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89];
1013 let sig = RecoverableSignature::from_compact(
1014 &s, bytes_in, recid_in).unwrap();
1015 let (recid_out, bytes_out) = sig.serialize_compact(&s);
1016 assert_eq!(recid_in, recid_out);
1017 assert_eq!(&bytes_in[..], &bytes_out[..]);
1018 }
1019
1020 #[test]
1021 fn test_recov_id_conversion_between_i32() {
1022 assert!(RecoveryId::from_i32(-1).is_err());
1023 assert!(RecoveryId::from_i32(0).is_ok());
1024 assert!(RecoveryId::from_i32(1).is_ok());
1025 assert!(RecoveryId::from_i32(2).is_ok());
1026 assert!(RecoveryId::from_i32(3).is_ok());
1027 assert!(RecoveryId::from_i32(4).is_err());
1028 let id0 = RecoveryId::from_i32(0).unwrap();
1029 assert_eq!(id0.to_i32(), 0);
1030 let id1 = RecoveryId(1);
1031 assert_eq!(id1.to_i32(), 1);
1032 }
1033
1034 #[test]
1035 fn test_low_s() {
1036 let sig = hex!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
1040 let pk = hex!("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
1041 let msg = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
1042
1043 let secp = Secp256k1::new();
1044 let mut sig = Signature::from_der(&secp, &sig[..]).unwrap();
1045 let pk = PublicKey::from_slice(&secp, &pk[..]).unwrap();
1046 let msg = Message::from_slice(&msg[..]).unwrap();
1047
1048 assert_eq!(secp.verify(&msg, &sig, &pk), Err(IncorrectSignature));
1050 sig.normalize_s(&secp);
1052 assert_eq!(secp.verify(&msg, &sig, &pk), Ok(()));
1053 }
1054}
1055
1056#[cfg(all(test, feature = "unstable"))]
1057mod benches {
1058 use rand::{Rng, thread_rng};
1059 use test::{Bencher, black_box};
1060
1061 use super::{Secp256k1, Message};
1062
1063 #[bench]
1064 pub fn generate(bh: &mut Bencher) {
1065 struct CounterRng(u32);
1066 impl Rng for CounterRng {
1067 fn next_u32(&mut self) -> u32 { self.0 += 1; self.0 }
1068 }
1069
1070 let s = Secp256k1::new();
1071 let mut r = CounterRng(0);
1072 bh.iter( || {
1073 let (sk, pk) = s.generate_keypair(&mut r).unwrap();
1074 black_box(sk);
1075 black_box(pk);
1076 });
1077 }
1078
1079 #[bench]
1080 pub fn bench_sign(bh: &mut Bencher) {
1081 let s = Secp256k1::new();
1082 let mut msg = [0u8; 32];
1083 thread_rng().fill(&mut msg);
1084 let msg = Message::from_slice(&msg).unwrap();
1085 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
1086
1087 bh.iter(|| {
1088 let sig = s.sign(&msg, &sk).unwrap();
1089 black_box(sig);
1090 });
1091 }
1092
1093 #[bench]
1094 pub fn bench_verify(bh: &mut Bencher) {
1095 let s = Secp256k1::new();
1096 let mut msg = [0u8; 32];
1097 thread_rng().fill(&mut msg);
1098 let msg = Message::from_slice(&msg).unwrap();
1099 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
1100 let sig = s.sign(&msg, &sk).unwrap();
1101
1102 bh.iter(|| {
1103 let res = s.verify(&msg, &sig, &pk).unwrap();
1104 black_box(res);
1105 });
1106 }
1107
1108 #[bench]
1109 pub fn bench_recover(bh: &mut Bencher) {
1110 let s = Secp256k1::new();
1111 let mut msg = [0u8; 32];
1112 thread_rng().fill(&mut msg);
1113 let msg = Message::from_slice(&msg).unwrap();
1114 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
1115 let sig = s.sign_recoverable(&msg, &sk).unwrap();
1116
1117 bh.iter(|| {
1118 let res = s.recover(&msg, &sig).unwrap();
1119 black_box(res);
1120 });
1121 }
1122}