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 SigSubtractionFailure,
482}
483
484impl Error {
485 fn as_str(&self) -> &str {
486 match *self {
487 Error::IncapableContext => "secp: context does not have sufficient capabilities",
488 Error::IncorrectSignature => "secp: signature failed verification",
489 Error::InvalidMessage => "secp: message was not 32 bytes (do you need to hash?)",
490 Error::InvalidPublicKey => "secp: malformed public key",
491 Error::InvalidCommit => "secp: malformed commit",
492 Error::InvalidSignature => "secp: malformed signature",
493 Error::InvalidSecretKey => "secp: malformed or out-of-range secret key",
494 Error::InvalidRecoveryId => "secp: bad recovery id",
495 Error::IncorrectCommitSum => "secp: invalid pedersen commitment sum",
496 Error::InvalidRangeProof => "secp: invalid range proof",
497 Error::PartialSigFailure => "secp: partial sig (aggsig) failure",
498 Error::SigSubtractionFailure => "secp: subtraction (aggsig) did not result in any valid signatures",
499 }
500 }
501}
502
503impl fmt::Display for Error {
505 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
506 f.write_str(self.as_str())
507 }
508}
509
510impl std::error::Error for Error {
511 fn description(&self) -> &str { self.as_str() }
512}
513
514
515pub struct Secp256k1 {
517 ctx: *mut ffi::Context,
518 caps: ContextFlag
519}
520
521unsafe impl Send for Secp256k1 {}
522unsafe impl Sync for Secp256k1 {}
523
524#[derive(PartialEq, Eq, Copy, Clone, Debug)]
527pub enum ContextFlag {
528 None,
531 SignOnly,
533 VerifyOnly,
535 Full,
537 Commit,
539}
540
541impl fmt::Display for ContextFlag {
543 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
544 fmt::Debug::fmt(self, f)
545 }
546}
547
548impl Clone for Secp256k1 {
549 fn clone(&self) -> Secp256k1 {
550 Secp256k1 {
551 ctx: unsafe { ffi::secp256k1_context_clone(self.ctx) },
552 caps: self.caps
553 }
554 }
555}
556
557impl PartialEq for Secp256k1 {
558 fn eq(&self, other: &Secp256k1) -> bool { self.caps == other.caps }
559}
560impl Eq for Secp256k1 { }
561
562impl fmt::Debug for Secp256k1 {
563 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
564 write!(f, "Secp256k1 {{ [private], caps: {:?} }}", self.caps)
565 }
566}
567
568impl Drop for Secp256k1 {
569 fn drop(&mut self) {
570 unsafe { ffi::secp256k1_context_destroy(self.ctx); }
571 }
572}
573
574impl Secp256k1 {
575 #[inline]
577 pub fn new() -> Secp256k1 {
578 Secp256k1::with_caps(ContextFlag::Full)
579 }
580
581 pub fn with_caps(caps: ContextFlag) -> Secp256k1 {
583 let flag = match caps {
584 ContextFlag::None => ffi::SECP256K1_START_NONE,
585 ContextFlag::SignOnly => ffi::SECP256K1_START_SIGN,
586 ContextFlag::VerifyOnly => ffi::SECP256K1_START_VERIFY,
587 ContextFlag::Full | ContextFlag::Commit => {
588 ffi::SECP256K1_START_SIGN | ffi::SECP256K1_START_VERIFY
589 }
590 };
591 Secp256k1 { ctx: unsafe { ffi::secp256k1_context_create(flag) }, caps: caps }
592 }
593
594 pub fn without_caps() -> Secp256k1 {
596 Secp256k1::with_caps(ContextFlag::None)
597 }
598
599 pub fn randomize<R: Rng>(&mut self, rng: &mut R) {
602 let mut seed = [0u8; 32];
603 rng.fill(&mut seed);
604 unsafe {
605 let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_ptr());
606 assert!(err == 1);
615 }
616 }
617
618 #[inline]
622 pub fn generate_keypair<R: Rng>(&self, rng: &mut R)
623 -> Result<(key::SecretKey, key::PublicKey), Error> {
624 let sk = key::SecretKey::new(self, rng);
625 let pk = key::PublicKey::from_secret_key(self, &sk)?;
626 Ok((sk, pk))
627 }
628
629 pub fn sign(&self, msg: &Message, sk: &key::SecretKey)
632 -> Result<Signature, Error> {
633 if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
634 return Err(Error::IncapableContext);
635 }
636
637 let mut ret = unsafe { ffi::Signature::blank() };
638 unsafe {
639 assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_ptr(),
642 sk.as_ptr(), ffi::secp256k1_nonce_function_rfc6979,
643 ptr::null()), 1);
644 }
645 Ok(Signature::from(ret))
646 }
647
648 pub fn sign_recoverable(&self, msg: &Message, sk: &key::SecretKey)
651 -> Result<RecoverableSignature, Error> {
652 if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
653 return Err(Error::IncapableContext);
654 }
655
656 let mut ret = unsafe { ffi::RecoverableSignature::blank() };
657 unsafe {
658 assert_eq!(ffi::secp256k1_ecdsa_sign_recoverable(self.ctx, &mut ret, msg.as_ptr(),
661 sk.as_ptr(), ffi::secp256k1_nonce_function_rfc6979,
662 ptr::null()), 1);
663 }
664 Ok(RecoverableSignature::from(ret))
665 }
666
667 pub fn recover(&self, msg: &Message, sig: &RecoverableSignature)
670 -> Result<key::PublicKey, Error> {
671 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
672 return Err(Error::IncapableContext);
673 }
674
675 let mut pk = unsafe { ffi::PublicKey::blank() };
676
677 unsafe {
678 if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk,
679 sig.as_ptr(), msg.as_ptr()) != 1 {
680 return Err(Error::InvalidSignature);
681 }
682 };
683 Ok(key::PublicKey::from(pk))
684 }
685
686 #[inline]
692 pub fn verify(&self, msg: &Message, sig: &Signature, pk: &key::PublicKey) -> Result<(), Error> {
693 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
694 return Err(Error::IncapableContext);
695 }
696
697 if !pk.is_valid() {
698 Err(Error::InvalidPublicKey)
699 } else if unsafe { ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_ptr(), msg.as_ptr(),
700 pk.as_ptr()) } == 0 {
701 Err(Error::IncorrectSignature)
702 } else {
703 Ok(())
704 }
705 }
706}
707
708#[cfg(test)]
709mod tests {
710 use rand::{Rng, thread_rng};
711 use crate::serialize::hex::FromHex;
712 use crate::key::{SecretKey, PublicKey};
713 use super::constants;
714 use super::{Secp256k1, Signature, RecoverableSignature, Message, RecoveryId, ContextFlag};
715 use super::Error::{InvalidMessage, InvalidPublicKey, IncorrectSignature, InvalidSignature,
716 IncapableContext};
717
718 macro_rules! hex (($hex:expr) => ($hex.from_hex().unwrap()));
719
720 #[test]
721 fn capabilities() {
722 let none = Secp256k1::with_caps(ContextFlag::None);
723 let sign = Secp256k1::with_caps(ContextFlag::SignOnly);
724 let vrfy = Secp256k1::with_caps(ContextFlag::VerifyOnly);
725 let full = Secp256k1::with_caps(ContextFlag::Full);
726
727 let mut msg = [0u8; 32];
728 thread_rng().fill(&mut msg);
729 let msg = Message::from_slice(&msg).unwrap();
730
731 assert_eq!(none.generate_keypair(&mut thread_rng()), Err(IncapableContext));
733 assert_eq!(vrfy.generate_keypair(&mut thread_rng()), Err(IncapableContext));
734 assert!(sign.generate_keypair(&mut thread_rng()).is_ok());
735 assert!(full.generate_keypair(&mut thread_rng()).is_ok());
736 let (sk, pk) = full.generate_keypair(&mut thread_rng()).unwrap();
737
738 assert_eq!(none.sign(&msg, &sk), Err(IncapableContext));
740 assert_eq!(vrfy.sign(&msg, &sk), Err(IncapableContext));
741 assert!(sign.sign(&msg, &sk).is_ok());
742 assert!(full.sign(&msg, &sk).is_ok());
743 assert_eq!(none.sign_recoverable(&msg, &sk), Err(IncapableContext));
744 assert_eq!(vrfy.sign_recoverable(&msg, &sk), Err(IncapableContext));
745 assert!(sign.sign_recoverable(&msg, &sk).is_ok());
746 assert!(full.sign_recoverable(&msg, &sk).is_ok());
747 assert_eq!(sign.sign(&msg, &sk), full.sign(&msg, &sk));
748 assert_eq!(sign.sign_recoverable(&msg, &sk), full.sign_recoverable(&msg, &sk));
749 let sig = full.sign(&msg, &sk).unwrap();
750 let sigr = full.sign_recoverable(&msg, &sk).unwrap();
751
752 assert_eq!(none.verify(&msg, &sig, &pk), Err(IncapableContext));
754 assert_eq!(sign.verify(&msg, &sig, &pk), Err(IncapableContext));
755 assert!(vrfy.verify(&msg, &sig, &pk).is_ok());
756 assert!(full.verify(&msg, &sig, &pk).is_ok());
757
758 assert_eq!(none.recover(&msg, &sigr), Err(IncapableContext));
760 assert_eq!(sign.recover(&msg, &sigr), Err(IncapableContext));
761 assert!(vrfy.recover(&msg, &sigr).is_ok());
762 assert!(full.recover(&msg, &sigr).is_ok());
763
764 assert_eq!(vrfy.recover(&msg, &sigr),
765 full.recover(&msg, &sigr));
766 assert_eq!(full.recover(&msg, &sigr), Ok(pk));
767
768 let (pk_slice, sk_slice) = (&pk.serialize_vec(&none, true), &sk[..]);
770 let new_pk = PublicKey::from_slice(&none, pk_slice).unwrap();
771 let new_sk = SecretKey::from_slice(&none, sk_slice).unwrap();
772 assert_eq!(sk, new_sk);
773 assert_eq!(pk, new_pk);
774 }
775
776 #[test]
777 fn recid_sanity_check() {
778 let one = RecoveryId(1);
779 assert_eq!(one, one.clone());
780 }
781
782 #[test]
783 fn invalid_pubkey() {
784 let s = Secp256k1::new();
785 let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap();
786 let pk = PublicKey::new();
787 let mut msg = [0u8; 32];
788 thread_rng().fill(&mut msg);
789 let msg = Message::from_slice(&msg).unwrap();
790
791 assert_eq!(s.verify(&msg, &sig.to_standard(&s), &pk), Err(InvalidPublicKey));
792 }
793
794 #[test]
795 fn sign() {
796 let mut s = Secp256k1::new();
797 s.randomize(&mut thread_rng());
798 let one = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
799 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
800
801 let sk = SecretKey::from_slice(&s, &one).unwrap();
802 let msg = Message::from_slice(&one).unwrap();
803
804 let sig = s.sign_recoverable(&msg, &sk).unwrap();
805 assert_eq!(Ok(sig), RecoverableSignature::from_compact(&s, &[
806 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
807 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
808 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
809 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
810 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
811 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
812 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
813 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89],
814 RecoveryId(1)))
815 }
816
817 #[test]
818 fn signature_serialize_roundtrip() {
819 let mut s = Secp256k1::new();
820 s.randomize(&mut thread_rng());
821
822 let mut msg = [0; 32];
823 for _ in 0..100 {
824 thread_rng().fill(&mut msg);
825 let msg = Message::from_slice(&msg).unwrap();
826
827 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
828 let sig1 = s.sign(&msg, &sk).unwrap();
829 let der = sig1.serialize_der(&s);
830 let sig2 = Signature::from_der(&s, &der[..]).unwrap();
831 assert_eq!(sig1, sig2);
832
833 let compact = sig1.serialize_compact(&s);
834 let sig2 = Signature::from_compact(&s, &compact[..]).unwrap();
835 assert_eq!(sig1, sig2);
836
837 round_trip_serde!(sig1);
838
839 assert!(Signature::from_compact(&s, &der[..]).is_err());
840 assert!(Signature::from_compact(&s, &compact[0..4]).is_err());
841 assert!(Signature::from_der(&s, &compact[..]).is_err());
842 assert!(Signature::from_der(&s, &der[0..4]).is_err());
843 }
844 }
845
846 #[test]
847 fn signature_lax_der() {
848 macro_rules! check_lax_sig(
849 ($hex:expr) => ({
850 let secp = Secp256k1::without_caps();
851 let sig = hex!($hex);
852 assert!(Signature::from_der_lax(&secp, &sig[..]).is_ok());
853 })
854 );
855
856 check_lax_sig!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c");
857 check_lax_sig!("304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f");
858 check_lax_sig!("3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a");
859 check_lax_sig!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
860 check_lax_sig!("3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1");
861 check_lax_sig!("3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60");
862 check_lax_sig!("3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf");
863 }
864
865 #[test]
866 fn sign_and_verify() {
867 let mut s = Secp256k1::new();
868 s.randomize(&mut thread_rng());
869
870 let mut msg = [0; 32];
871 for _ in 0..100 {
872 thread_rng().fill(&mut msg);
873 let msg = Message::from_slice(&msg).unwrap();
874
875 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
876 let sig = s.sign(&msg, &sk).unwrap();
877 assert_eq!(s.verify(&msg, &sig, &pk), Ok(()));
878 }
879 }
880
881 #[test]
882 fn sign_and_verify_extreme() {
883 let mut s = Secp256k1::new();
884 s.randomize(&mut thread_rng());
885
886 let mut wild_keys = [[0; 32]; 2];
889 let mut wild_msgs = [[0; 32]; 4];
890
891 wild_keys[0][0] = 1;
892 wild_msgs[1][0] = 1;
893
894 use crate::constants;
895 wild_keys[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
896 wild_msgs[1][..].copy_from_slice(&constants::CURVE_ORDER[..]);
897 wild_msgs[2][..].copy_from_slice(&constants::CURVE_ORDER[..]);
898
899 wild_keys[1][0] -= 1;
900 wild_msgs[1][0] -= 1;
901
902 for key in wild_keys.iter().map(|k| SecretKey::from_slice(&s, &k[..]).unwrap()) {
903 for msg in wild_msgs.iter().map(|m| Message::from_slice(&m[..]).unwrap()) {
904 let sig = s.sign(&msg, &key).unwrap();
905 let pk = PublicKey::from_secret_key(&s, &key).unwrap();
906 assert_eq!(s.verify(&msg, &sig, &pk), Ok(()));
907 }
908 }
909 }
910
911 #[test]
912 fn sign_and_verify_fail() {
913 let mut s = Secp256k1::new();
914 s.randomize(&mut thread_rng());
915
916 let mut msg = [0u8; 32];
917 thread_rng().fill(&mut msg);
918 let msg = Message::from_slice(&msg).unwrap();
919
920 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
921
922 let sigr = s.sign_recoverable(&msg, &sk).unwrap();
923 let sig = sigr.to_standard(&s);
924
925 let mut msg = [0u8; 32];
926 thread_rng().fill(&mut msg);
927 let msg = Message::from_slice(&msg).unwrap();
928 assert_eq!(s.verify(&msg, &sig, &pk), Err(IncorrectSignature));
929
930 let recovered_key = s.recover(&msg, &sigr).unwrap();
931 assert!(recovered_key != pk);
932 }
933
934 #[test]
935 fn sign_with_recovery() {
936 let mut s = Secp256k1::new();
937 s.randomize(&mut thread_rng());
938
939 let mut msg = [0u8; 32];
940 thread_rng().fill(&mut msg);
941 let msg = Message::from_slice(&msg).unwrap();
942
943 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
944
945 let sig = s.sign_recoverable(&msg, &sk).unwrap();
946
947 assert_eq!(s.recover(&msg, &sig), Ok(pk));
948 }
949
950 #[test]
951 fn bad_recovery() {
952 let mut s = Secp256k1::new();
953 s.randomize(&mut thread_rng());
954
955 let msg = Message::from_slice(&[0x55; 32]).unwrap();
956
957 let sig = RecoverableSignature::from_compact(&s, &[0; 64], RecoveryId(0)).unwrap();
959 assert_eq!(s.recover(&msg, &sig), Err(InvalidSignature));
960 let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap();
962 assert!(s.recover(&msg, &sig).is_ok());
963 }
964
965 #[test]
966 fn test_bad_slice() {
967 let s = Secp256k1::new();
968 assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE + 1]),
969 Err(InvalidSignature));
970 assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE]),
971 Err(InvalidSignature));
972
973 assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]),
974 Err(InvalidMessage));
975 assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]),
976 Err(InvalidMessage));
977 assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
978 }
979
980 #[test]
981 fn test_debug_output() {
982 let s = Secp256k1::new();
983 let sig = RecoverableSignature::from_compact(&s, &[
984 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
985 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
986 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
987 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
988 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
989 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
990 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
991 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89],
992 RecoveryId(1)).unwrap();
993 assert_eq!(&format!("{:?}", sig), "RecoverableSignature(98882e09f4ed6dc3659e43fc771e0cafa60b1f926f2b77041f744721adff7366898cb609d0ee128d06ae9aa3c48020ff9f705e02f80e1280a8ade05216971a4c01)");
994
995 let msg = Message([1, 2, 3, 4, 5, 6, 7, 8,
996 9, 10, 11, 12, 13, 14, 15, 16,
997 17, 18, 19, 20, 21, 22, 23, 24,
998 25, 26, 27, 28, 29, 30, 31, 255]);
999 assert_eq!(&format!("{:?}", msg), "Message(0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff)");
1000 }
1001
1002 #[test]
1003 fn test_recov_sig_serialize_compact() {
1004 let s = Secp256k1::new();
1005
1006 let recid_in = RecoveryId(1);
1007 let bytes_in = &[
1008 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
1009 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
1010 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
1011 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
1012 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
1013 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
1014 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
1015 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89];
1016 let sig = RecoverableSignature::from_compact(
1017 &s, bytes_in, recid_in).unwrap();
1018 let (recid_out, bytes_out) = sig.serialize_compact(&s);
1019 assert_eq!(recid_in, recid_out);
1020 assert_eq!(&bytes_in[..], &bytes_out[..]);
1021 }
1022
1023 #[test]
1024 fn test_recov_id_conversion_between_i32() {
1025 assert!(RecoveryId::from_i32(-1).is_err());
1026 assert!(RecoveryId::from_i32(0).is_ok());
1027 assert!(RecoveryId::from_i32(1).is_ok());
1028 assert!(RecoveryId::from_i32(2).is_ok());
1029 assert!(RecoveryId::from_i32(3).is_ok());
1030 assert!(RecoveryId::from_i32(4).is_err());
1031 let id0 = RecoveryId::from_i32(0).unwrap();
1032 assert_eq!(id0.to_i32(), 0);
1033 let id1 = RecoveryId(1);
1034 assert_eq!(id1.to_i32(), 1);
1035 }
1036
1037 #[test]
1038 fn test_low_s() {
1039 let sig = hex!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
1043 let pk = hex!("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
1044 let msg = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
1045
1046 let secp = Secp256k1::new();
1047 let mut sig = Signature::from_der(&secp, &sig[..]).unwrap();
1048 let pk = PublicKey::from_slice(&secp, &pk[..]).unwrap();
1049 let msg = Message::from_slice(&msg[..]).unwrap();
1050
1051 assert_eq!(secp.verify(&msg, &sig, &pk), Err(IncorrectSignature));
1053 sig.normalize_s(&secp);
1055 assert_eq!(secp.verify(&msg, &sig, &pk), Ok(()));
1056 }
1057}
1058
1059#[cfg(all(test, feature = "unstable"))]
1060mod benches {
1061 use rand::{Rng, thread_rng};
1062 use test::{Bencher, black_box};
1063
1064 use super::{Secp256k1, Message};
1065
1066 #[bench]
1067 pub fn generate(bh: &mut Bencher) {
1068 struct CounterRng(u32);
1069 impl Rng for CounterRng {
1070 fn next_u32(&mut self) -> u32 { self.0 += 1; self.0 }
1071 }
1072
1073 let s = Secp256k1::new();
1074 let mut r = CounterRng(0);
1075 bh.iter( || {
1076 let (sk, pk) = s.generate_keypair(&mut r).unwrap();
1077 black_box(sk);
1078 black_box(pk);
1079 });
1080 }
1081
1082 #[bench]
1083 pub fn bench_sign(bh: &mut Bencher) {
1084 let s = Secp256k1::new();
1085 let mut msg = [0u8; 32];
1086 thread_rng().fill(&mut msg);
1087 let msg = Message::from_slice(&msg).unwrap();
1088 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
1089
1090 bh.iter(|| {
1091 let sig = s.sign(&msg, &sk).unwrap();
1092 black_box(sig);
1093 });
1094 }
1095
1096 #[bench]
1097 pub fn bench_verify(bh: &mut Bencher) {
1098 let s = Secp256k1::new();
1099 let mut msg = [0u8; 32];
1100 thread_rng().fill(&mut msg);
1101 let msg = Message::from_slice(&msg).unwrap();
1102 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
1103 let sig = s.sign(&msg, &sk).unwrap();
1104
1105 bh.iter(|| {
1106 let res = s.verify(&msg, &sig, &pk).unwrap();
1107 black_box(res);
1108 });
1109 }
1110
1111 #[bench]
1112 pub fn bench_recover(bh: &mut Bencher) {
1113 let s = Secp256k1::new();
1114 let mut msg = [0u8; 32];
1115 thread_rng().fill(&mut msg);
1116 let msg = Message::from_slice(&msg).unwrap();
1117 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
1118 let sig = s.sign_recoverable(&msg, &sk).unwrap();
1119
1120 bh.iter(|| {
1121 let res = s.recover(&msg, &sig).unwrap();
1122 black_box(res);
1123 });
1124 }
1125}