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