1#![crate_type = "lib"]
24#![crate_type = "rlib"]
25#![crate_type = "dylib"]
26#![crate_name = "secp256k1"]
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#[cfg(feature = "singleton")] #[macro_use] extern crate lazy_static;
42
43extern crate arrayvec;
44extern crate rustc_serialize as serialize;
45
46extern crate libc;
47extern crate rand;
48
49use libc::size_t;
50use std::{error, fmt, ops, ptr};
51use rand::Rng;
52
53#[cfg(feature = "singleton")]
54lazy_static! {
55 pub static ref SECP256K1: Secp256k1 = Secp256k1::new();
57}
58
59#[macro_use]
60mod macros;
61pub mod constants;
62pub mod ecdh;
63pub mod ffi;
64pub mod key;
65pub mod schnorr;
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
75#[derive(Copy, Clone, PartialEq, Eq, Debug)]
77pub struct RecoverableSignature(ffi::RecoverableSignature);
78
79impl RecoveryId {
80 #[inline]
81 pub fn from_i32(id: i32) -> Result<RecoveryId, Error> {
83 match id {
84 0 | 1 | 2 | 3 => Ok(RecoveryId(id)),
85 _ => Err(Error::InvalidRecoveryId)
86 }
87 }
88
89 #[inline]
90 pub fn to_i32(&self) -> i32 {
92 self.0
93 }
94}
95
96impl Signature {
97 #[inline]
98 pub fn from_der(secp: &Secp256k1, data: &[u8]) -> Result<Signature, Error> {
100 let mut ret = unsafe { ffi::Signature::blank() };
101
102 unsafe {
103 if ffi::secp256k1_ecdsa_signature_parse_der(secp.ctx, &mut ret,
104 data.as_ptr(), data.len() as libc::size_t) == 1 {
105 Ok(Signature(ret))
106 } else {
107 Err(Error::InvalidSignature)
108 }
109 }
110 }
111
112 pub fn from_der_lax(secp: &Secp256k1, data: &[u8]) -> Result<Signature, Error> {
117 unsafe {
118 let mut ret = ffi::Signature::blank();
119 if ffi::ecdsa_signature_parse_der_lax(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 normalize_s(&mut self, secp: &Secp256k1) {
146 unsafe {
147 ffi::secp256k1_ecdsa_signature_normalize(secp.ctx, self.as_mut_ptr(),
150 self.as_ptr());
151 }
152 }
153
154 #[inline]
156 pub fn as_ptr(&self) -> *const ffi::Signature {
157 &self.0 as *const _
158 }
159
160 #[inline]
162 pub fn as_mut_ptr(&mut self) -> *mut ffi::Signature {
163 &mut self.0 as *mut _
164 }
165
166 #[inline]
167 pub fn serialize_der(&self, secp: &Secp256k1) -> Vec<u8> {
169 let mut ret = Vec::with_capacity(72);
170 let mut len: size_t = ret.capacity() as size_t;
171 unsafe {
172 let err = ffi::secp256k1_ecdsa_signature_serialize_der(secp.ctx, ret.as_mut_ptr(),
173 &mut len, self.as_ptr());
174 debug_assert!(err == 1);
175 ret.set_len(len as usize);
176 }
177 ret
178 }
179}
180
181impl From<ffi::Signature> for Signature {
183 #[inline]
184 fn from(sig: ffi::Signature) -> Signature {
185 Signature(sig)
186 }
187}
188
189
190impl RecoverableSignature {
191 #[inline]
192 pub fn from_compact(secp: &Secp256k1, data: &[u8], recid: RecoveryId) -> Result<RecoverableSignature, Error> {
196 let mut ret = unsafe { ffi::RecoverableSignature::blank() };
197
198 unsafe {
199 if data.len() != 64 {
200 Err(Error::InvalidSignature)
201 } else if ffi::secp256k1_ecdsa_recoverable_signature_parse_compact(secp.ctx, &mut ret,
202 data.as_ptr(), recid.0) == 1 {
203 Ok(RecoverableSignature(ret))
204 } else {
205 Err(Error::InvalidSignature)
206 }
207 }
208 }
209
210 #[inline]
212 pub fn as_ptr(&self) -> *const ffi::RecoverableSignature {
213 &self.0 as *const _
214 }
215
216 #[inline]
217 pub fn serialize_compact(&self, secp: &Secp256k1) -> (RecoveryId, [u8; 64]) {
219 let mut ret = [0u8; 64];
220 let mut recid = 0i32;
221 unsafe {
222 let err = ffi::secp256k1_ecdsa_recoverable_signature_serialize_compact(
223 secp.ctx, ret.as_mut_ptr(), &mut recid, self.as_ptr());
224 assert!(err == 1);
225 }
226 (RecoveryId(recid), ret)
227 }
228
229 #[inline]
232 pub fn to_standard(&self, secp: &Secp256k1) -> Signature {
233 let mut ret = unsafe { ffi::Signature::blank() };
234 unsafe {
235 let err = ffi::secp256k1_ecdsa_recoverable_signature_convert(secp.ctx, &mut ret, self.as_ptr());
236 assert!(err == 1);
237 }
238 Signature(ret)
239 }
240}
241
242impl From<ffi::RecoverableSignature> for RecoverableSignature {
244 #[inline]
245 fn from(sig: ffi::RecoverableSignature) -> RecoverableSignature {
246 RecoverableSignature(sig)
247 }
248}
249
250impl ops::Index<usize> for Signature {
251 type Output = u8;
252
253 #[inline]
254 fn index(&self, index: usize) -> &u8 {
255 &self.0[index]
256 }
257}
258
259impl ops::Index<ops::Range<usize>> for Signature {
260 type Output = [u8];
261
262 #[inline]
263 fn index(&self, index: ops::Range<usize>) -> &[u8] {
264 &self.0[index]
265 }
266}
267
268impl ops::Index<ops::RangeFrom<usize>> for Signature {
269 type Output = [u8];
270
271 #[inline]
272 fn index(&self, index: ops::RangeFrom<usize>) -> &[u8] {
273 &self.0[index.start..]
274 }
275}
276
277impl ops::Index<ops::RangeFull> for Signature {
278 type Output = [u8];
279
280 #[inline]
281 fn index(&self, _: ops::RangeFull) -> &[u8] {
282 &self.0[..]
283 }
284}
285
286pub struct Message([u8; constants::MESSAGE_SIZE]);
288impl_array_newtype!(Message, u8, constants::MESSAGE_SIZE);
289impl_pretty_debug!(Message);
290
291impl Message {
292 #[inline]
294 pub fn from_slice(data: &[u8]) -> Result<Message, Error> {
295 match data.len() {
296 constants::MESSAGE_SIZE => {
297 let mut ret = [0; constants::MESSAGE_SIZE];
298 unsafe {
299 ptr::copy_nonoverlapping(data.as_ptr(),
300 ret.as_mut_ptr(),
301 data.len());
302 }
303 Ok(Message(ret))
304 }
305 _ => Err(Error::InvalidMessage)
306 }
307 }
308}
309
310#[derive(Copy, PartialEq, Eq, Clone, Debug)]
312pub enum Error {
313 IncapableContext,
316 IncorrectSignature,
318 InvalidMessage,
320 InvalidPublicKey,
322 InvalidSignature,
324 InvalidSecretKey,
326 InvalidRecoveryId,
328}
329
330impl fmt::Display for Error {
332 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
333 f.write_str(error::Error::description(self))
334 }
335}
336
337impl error::Error for Error {
338 fn cause(&self) -> Option<&error::Error> { None }
339
340 fn description(&self) -> &str {
341 match *self {
342 Error::IncapableContext => "secp: context does not have sufficient capabilities",
343 Error::IncorrectSignature => "secp: signature failed verification",
344 Error::InvalidMessage => "secp: message was not 32 bytes (do you need to hash?)",
345 Error::InvalidPublicKey => "secp: malformed public key",
346 Error::InvalidSignature => "secp: malformed signature",
347 Error::InvalidSecretKey => "secp: malformed or out-of-range secret key",
348 Error::InvalidRecoveryId => "secp: bad recovery id"
349 }
350 }
351}
352
353pub struct Secp256k1 {
355 ctx: *mut ffi::Context,
356 caps: ContextFlag
357}
358
359unsafe impl Send for Secp256k1 {}
360unsafe impl Sync for Secp256k1 {}
361
362#[derive(PartialEq, Eq, Copy, Clone, Debug)]
365pub enum ContextFlag {
366 None,
369 SignOnly,
371 VerifyOnly,
373 Full
375}
376
377impl fmt::Display for ContextFlag {
379 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
380 fmt::Debug::fmt(self, f)
381 }
382}
383
384impl Clone for Secp256k1 {
385 fn clone(&self) -> Secp256k1 {
386 Secp256k1 {
387 ctx: unsafe { ffi::secp256k1_context_clone(self.ctx) },
388 caps: self.caps
389 }
390 }
391}
392
393impl PartialEq for Secp256k1 {
394 fn eq(&self, other: &Secp256k1) -> bool { self.caps == other.caps }
395}
396impl Eq for Secp256k1 { }
397
398impl fmt::Debug for Secp256k1 {
399 fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
400 write!(f, "Secp256k1 {{ [private], caps: {:?} }}", self.caps)
401 }
402}
403
404impl Drop for Secp256k1 {
405 fn drop(&mut self) {
406 unsafe { ffi::secp256k1_context_destroy(self.ctx); }
407 }
408}
409
410impl Secp256k1 {
411 #[inline]
413 pub fn new() -> Secp256k1 {
414 Secp256k1::with_caps(ContextFlag::Full)
415 }
416
417 pub fn with_caps(caps: ContextFlag) -> Secp256k1 {
419 let flag = match caps {
420 ContextFlag::None => ffi::SECP256K1_START_NONE,
421 ContextFlag::SignOnly => ffi::SECP256K1_START_SIGN,
422 ContextFlag::VerifyOnly => ffi::SECP256K1_START_VERIFY,
423 ContextFlag::Full => ffi::SECP256K1_START_SIGN | ffi::SECP256K1_START_VERIFY
424 };
425 Secp256k1 { ctx: unsafe { ffi::secp256k1_context_create(flag) }, caps: caps }
426 }
427
428 pub fn without_caps() -> Secp256k1 {
430 Secp256k1::with_caps(ContextFlag::None)
431 }
432
433 pub fn randomize<R: Rng>(&mut self, rng: &mut R) {
436 let mut seed = [0; 32];
437 rng.fill_bytes(&mut seed);
438 unsafe {
439 let err = ffi::secp256k1_context_randomize(self.ctx, seed.as_ptr());
440 assert!(err == 1);
449 }
450 }
451
452 #[inline]
456 pub fn generate_keypair<R: Rng>(&self, rng: &mut R)
457 -> Result<(key::SecretKey, key::PublicKey), Error> {
458 let sk = key::SecretKey::new(self, rng);
459 let pk = try!(key::PublicKey::from_secret_key(self, &sk));
460 Ok((sk, pk))
461 }
462
463 pub fn sign(&self, msg: &Message, sk: &key::SecretKey)
466 -> Result<Signature, Error> {
467 if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
468 return Err(Error::IncapableContext);
469 }
470
471 let mut ret = unsafe { ffi::Signature::blank() };
472 unsafe {
473 assert_eq!(ffi::secp256k1_ecdsa_sign(self.ctx, &mut ret, msg.as_ptr(),
476 sk.as_ptr(), ffi::secp256k1_nonce_function_rfc6979,
477 ptr::null()), 1);
478 }
479 Ok(Signature::from(ret))
480 }
481
482 pub fn sign_recoverable(&self, msg: &Message, sk: &key::SecretKey)
485 -> Result<RecoverableSignature, Error> {
486 if self.caps == ContextFlag::VerifyOnly || self.caps == ContextFlag::None {
487 return Err(Error::IncapableContext);
488 }
489
490 let mut ret = unsafe { ffi::RecoverableSignature::blank() };
491 unsafe {
492 assert_eq!(ffi::secp256k1_ecdsa_sign_recoverable(self.ctx, &mut ret, msg.as_ptr(),
495 sk.as_ptr(), ffi::secp256k1_nonce_function_rfc6979,
496 ptr::null()), 1);
497 }
498 Ok(RecoverableSignature::from(ret))
499 }
500
501 pub fn recover(&self, msg: &Message, sig: &RecoverableSignature)
504 -> Result<key::PublicKey, Error> {
505 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
506 return Err(Error::IncapableContext);
507 }
508
509 let mut pk = unsafe { ffi::PublicKey::blank() };
510
511 unsafe {
512 if ffi::secp256k1_ecdsa_recover(self.ctx, &mut pk,
513 sig.as_ptr(), msg.as_ptr()) != 1 {
514 return Err(Error::InvalidSignature);
515 }
516 };
517 Ok(key::PublicKey::from(pk))
518 }
519
520 #[inline]
526 pub fn verify(&self, msg: &Message, sig: &Signature, pk: &key::PublicKey) -> Result<(), Error> {
527 if self.caps == ContextFlag::SignOnly || self.caps == ContextFlag::None {
528 return Err(Error::IncapableContext);
529 }
530
531 if !pk.is_valid() {
532 Err(Error::InvalidPublicKey)
533 } else if unsafe { ffi::secp256k1_ecdsa_verify(self.ctx, sig.as_ptr(), msg.as_ptr(),
534 pk.as_ptr()) } == 0 {
535 Err(Error::IncorrectSignature)
536 } else {
537 Ok(())
538 }
539 }
540}
541
542
543#[cfg(test)]
544mod tests {
545 use rand::{Rng, thread_rng};
546 use std::ptr;
547 use serialize::hex::FromHex;
548
549 use key::{SecretKey, PublicKey};
550 use super::constants;
551 use super::{Secp256k1, Signature, RecoverableSignature, Message, RecoveryId, ContextFlag};
552 use super::Error::{InvalidMessage, InvalidPublicKey, IncorrectSignature, InvalidSignature,
553 IncapableContext};
554
555 macro_rules! hex (($hex:expr) => ($hex.from_hex().unwrap()));
556
557 #[test]
558 fn capabilities() {
559 let none = Secp256k1::with_caps(ContextFlag::None);
560 let sign = Secp256k1::with_caps(ContextFlag::SignOnly);
561 let vrfy = Secp256k1::with_caps(ContextFlag::VerifyOnly);
562 let full = Secp256k1::with_caps(ContextFlag::Full);
563
564 let mut msg = [0u8; 32];
565 thread_rng().fill_bytes(&mut msg);
566 let msg = Message::from_slice(&msg).unwrap();
567
568 assert_eq!(none.generate_keypair(&mut thread_rng()), Err(IncapableContext));
570 assert_eq!(vrfy.generate_keypair(&mut thread_rng()), Err(IncapableContext));
571 assert!(sign.generate_keypair(&mut thread_rng()).is_ok());
572 assert!(full.generate_keypair(&mut thread_rng()).is_ok());
573 let (sk, pk) = full.generate_keypair(&mut thread_rng()).unwrap();
574
575 assert_eq!(none.sign(&msg, &sk), Err(IncapableContext));
577 assert_eq!(vrfy.sign(&msg, &sk), Err(IncapableContext));
578 assert!(sign.sign(&msg, &sk).is_ok());
579 assert!(full.sign(&msg, &sk).is_ok());
580 assert_eq!(none.sign_recoverable(&msg, &sk), Err(IncapableContext));
581 assert_eq!(vrfy.sign_recoverable(&msg, &sk), Err(IncapableContext));
582 assert!(sign.sign_recoverable(&msg, &sk).is_ok());
583 assert!(full.sign_recoverable(&msg, &sk).is_ok());
584 assert_eq!(sign.sign(&msg, &sk), full.sign(&msg, &sk));
585 assert_eq!(sign.sign_recoverable(&msg, &sk), full.sign_recoverable(&msg, &sk));
586 let sig = full.sign(&msg, &sk).unwrap();
587 let sigr = full.sign_recoverable(&msg, &sk).unwrap();
588
589 assert_eq!(none.verify(&msg, &sig, &pk), Err(IncapableContext));
591 assert_eq!(sign.verify(&msg, &sig, &pk), Err(IncapableContext));
592 assert!(vrfy.verify(&msg, &sig, &pk).is_ok());
593 assert!(full.verify(&msg, &sig, &pk).is_ok());
594
595 assert_eq!(none.recover(&msg, &sigr), Err(IncapableContext));
597 assert_eq!(sign.recover(&msg, &sigr), Err(IncapableContext));
598 assert!(vrfy.recover(&msg, &sigr).is_ok());
599 assert!(full.recover(&msg, &sigr).is_ok());
600
601 assert_eq!(vrfy.recover(&msg, &sigr),
602 full.recover(&msg, &sigr));
603 assert_eq!(full.recover(&msg, &sigr), Ok(pk));
604
605 let (pk_slice, sk_slice) = (&pk.serialize_vec(&none, true), &sk[..]);
607 let new_pk = PublicKey::from_slice(&none, pk_slice).unwrap();
608 let new_sk = SecretKey::from_slice(&none, sk_slice).unwrap();
609 assert_eq!(sk, new_sk);
610 assert_eq!(pk, new_pk);
611 }
612
613 #[test]
614 fn recid_sanity_check() {
615 let one = RecoveryId(1);
616 assert_eq!(one, one.clone());
617 }
618
619 #[test]
620 fn invalid_pubkey() {
621 let s = Secp256k1::new();
622 let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap();
623 let pk = PublicKey::new();
624 let mut msg = [0u8; 32];
625 thread_rng().fill_bytes(&mut msg);
626 let msg = Message::from_slice(&msg).unwrap();
627
628 assert_eq!(s.verify(&msg, &sig.to_standard(&s), &pk), Err(InvalidPublicKey));
629 }
630
631 #[test]
632 fn sign() {
633 let mut s = Secp256k1::new();
634 s.randomize(&mut thread_rng());
635 let one = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
636 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
637
638 let sk = SecretKey::from_slice(&s, &one).unwrap();
639 let msg = Message::from_slice(&one).unwrap();
640
641 let sig = s.sign_recoverable(&msg, &sk).unwrap();
642 assert_eq!(Ok(sig), RecoverableSignature::from_compact(&s, &[
643 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
644 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
645 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
646 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
647 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
648 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
649 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
650 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89],
651 RecoveryId(1)))
652 }
653
654 #[test]
655 fn signature_der_roundtrip() {
656 let mut s = Secp256k1::new();
657 s.randomize(&mut thread_rng());
658
659 let mut msg = [0; 32];
660 for _ in 0..100 {
661 thread_rng().fill_bytes(&mut msg);
662 let msg = Message::from_slice(&msg).unwrap();
663
664 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
665 let sig1 = s.sign(&msg, &sk).unwrap();
666 let der = sig1.serialize_der(&s);
667 let sig2 = Signature::from_der(&s, &der[..]).unwrap();
668 assert_eq!(sig1, sig2);
669 }
670 }
671
672 #[test]
673 fn signature_lax_der() {
674 macro_rules! check_lax_sig(
675 ($hex:expr) => ({
676 let secp = Secp256k1::without_caps();
677 let sig = hex!($hex);
678 assert!(Signature::from_der_lax(&secp, &sig[..]).is_ok());
679 })
680 );
681
682 check_lax_sig!("304402204c2dd8a9b6f8d425fcd8ee9a20ac73b619906a6367eac6cb93e70375225ec0160220356878eff111ff3663d7e6bf08947f94443845e0dcc54961664d922f7660b80c");
683 check_lax_sig!("304402202ea9d51c7173b1d96d331bd41b3d1b4e78e66148e64ed5992abd6ca66290321c0220628c47517e049b3e41509e9d71e480a0cdc766f8cdec265ef0017711c1b5336f");
684 check_lax_sig!("3045022100bf8e050c85ffa1c313108ad8c482c4849027937916374617af3f2e9a881861c9022023f65814222cab09d5ec41032ce9c72ca96a5676020736614de7b78a4e55325a");
685 check_lax_sig!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
686 check_lax_sig!("3046022100eaa5f90483eb20224616775891397d47efa64c68b969db1dacb1c30acdfc50aa022100cf9903bbefb1c8000cf482b0aeeb5af19287af20bd794de11d82716f9bae3db1");
687 check_lax_sig!("3045022047d512bc85842ac463ca3b669b62666ab8672ee60725b6c06759e476cebdc6c102210083805e93bd941770109bcc797784a71db9e48913f702c56e60b1c3e2ff379a60");
688 check_lax_sig!("3044022023ee4e95151b2fbbb08a72f35babe02830d14d54bd7ed1320e4751751d1baa4802206235245254f58fd1be6ff19ca291817da76da65c2f6d81d654b5185dd86b8acf");
689 }
690
691 #[test]
692 fn sign_and_verify() {
693 let mut s = Secp256k1::new();
694 s.randomize(&mut thread_rng());
695
696 let mut msg = [0; 32];
697 for _ in 0..100 {
698 thread_rng().fill_bytes(&mut msg);
699 let msg = Message::from_slice(&msg).unwrap();
700
701 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
702 let sig = s.sign(&msg, &sk).unwrap();
703 assert_eq!(s.verify(&msg, &sig, &pk), Ok(()));
704 }
705 }
706
707 #[test]
708 fn sign_and_verify_extreme() {
709 let mut s = Secp256k1::new();
710 s.randomize(&mut thread_rng());
711
712 let mut wild_keys = [[0; 32]; 2];
715 let mut wild_msgs = [[0; 32]; 4];
716
717 wild_keys[0][0] = 1;
718 wild_msgs[1][0] = 1;
719 unsafe {
720 use constants;
721 ptr::copy_nonoverlapping(constants::CURVE_ORDER.as_ptr(),
722 wild_keys[1].as_mut_ptr(),
723 32);
724 ptr::copy_nonoverlapping(constants::CURVE_ORDER.as_ptr(),
725 wild_msgs[1].as_mut_ptr(),
726 32);
727 ptr::copy_nonoverlapping(constants::CURVE_ORDER.as_ptr(),
728 wild_msgs[2].as_mut_ptr(),
729 32);
730 wild_keys[1][0] -= 1;
731 wild_msgs[1][0] -= 1;
732 }
733
734 for key in wild_keys.iter().map(|k| SecretKey::from_slice(&s, &k[..]).unwrap()) {
735 for msg in wild_msgs.iter().map(|m| Message::from_slice(&m[..]).unwrap()) {
736 let sig = s.sign(&msg, &key).unwrap();
737 let pk = PublicKey::from_secret_key(&s, &key).unwrap();
738 assert_eq!(s.verify(&msg, &sig, &pk), Ok(()));
739 }
740 }
741 }
742
743 #[test]
744 fn sign_and_verify_fail() {
745 let mut s = Secp256k1::new();
746 s.randomize(&mut thread_rng());
747
748 let mut msg = [0u8; 32];
749 thread_rng().fill_bytes(&mut msg);
750 let msg = Message::from_slice(&msg).unwrap();
751
752 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
753
754 let sigr = s.sign_recoverable(&msg, &sk).unwrap();
755 let sig = sigr.to_standard(&s);
756
757 let mut msg = [0u8; 32];
758 thread_rng().fill_bytes(&mut msg);
759 let msg = Message::from_slice(&msg).unwrap();
760 assert_eq!(s.verify(&msg, &sig, &pk), Err(IncorrectSignature));
761
762 let recovered_key = s.recover(&msg, &sigr).unwrap();
763 assert!(recovered_key != pk);
764 }
765
766 #[test]
767 fn sign_with_recovery() {
768 let mut s = Secp256k1::new();
769 s.randomize(&mut thread_rng());
770
771 let mut msg = [0u8; 32];
772 thread_rng().fill_bytes(&mut msg);
773 let msg = Message::from_slice(&msg).unwrap();
774
775 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
776
777 let sig = s.sign_recoverable(&msg, &sk).unwrap();
778
779 assert_eq!(s.recover(&msg, &sig), Ok(pk));
780 }
781
782 #[test]
783 fn bad_recovery() {
784 let mut s = Secp256k1::new();
785 s.randomize(&mut thread_rng());
786
787 let msg = Message::from_slice(&[0x55; 32]).unwrap();
788
789 let sig = RecoverableSignature::from_compact(&s, &[0; 64], RecoveryId(0)).unwrap();
791 assert_eq!(s.recover(&msg, &sig), Err(InvalidSignature));
792 let sig = RecoverableSignature::from_compact(&s, &[1; 64], RecoveryId(0)).unwrap();
794 assert!(s.recover(&msg, &sig).is_ok());
795 }
796
797 #[test]
798 fn test_bad_slice() {
799 let s = Secp256k1::new();
800 assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE + 1]),
801 Err(InvalidSignature));
802 assert_eq!(Signature::from_der(&s, &[0; constants::MAX_SIGNATURE_SIZE]),
803 Err(InvalidSignature));
804
805 assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE - 1]),
806 Err(InvalidMessage));
807 assert_eq!(Message::from_slice(&[0; constants::MESSAGE_SIZE + 1]),
808 Err(InvalidMessage));
809 assert!(Message::from_slice(&[0; constants::MESSAGE_SIZE]).is_ok());
810 }
811
812 #[test]
813 fn test_debug_output() {
814 let s = Secp256k1::new();
815 let sig = RecoverableSignature::from_compact(&s, &[
816 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
817 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
818 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
819 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
820 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
821 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
822 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
823 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89],
824 RecoveryId(1)).unwrap();
825 assert_eq!(&format!("{:?}", sig), "RecoverableSignature(98882e09f4ed6dc3659e43fc771e0cafa60b1f926f2b77041f744721adff7366898cb609d0ee128d06ae9aa3c48020ff9f705e02f80e1280a8ade05216971a4c01)");
826
827 let msg = Message([1, 2, 3, 4, 5, 6, 7, 8,
828 9, 10, 11, 12, 13, 14, 15, 16,
829 17, 18, 19, 20, 21, 22, 23, 24,
830 25, 26, 27, 28, 29, 30, 31, 255]);
831 assert_eq!(&format!("{:?}", msg), "Message(0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1fff)");
832 }
833
834 #[test]
835 fn test_recov_sig_serialize_compact() {
836 let s = Secp256k1::new();
837
838 let recid_in = RecoveryId(1);
839 let bytes_in = &[
840 0x66, 0x73, 0xff, 0xad, 0x21, 0x47, 0x74, 0x1f,
841 0x04, 0x77, 0x2b, 0x6f, 0x92, 0x1f, 0x0b, 0xa6,
842 0xaf, 0x0c, 0x1e, 0x77, 0xfc, 0x43, 0x9e, 0x65,
843 0xc3, 0x6d, 0xed, 0xf4, 0x09, 0x2e, 0x88, 0x98,
844 0x4c, 0x1a, 0x97, 0x16, 0x52, 0xe0, 0xad, 0xa8,
845 0x80, 0x12, 0x0e, 0xf8, 0x02, 0x5e, 0x70, 0x9f,
846 0xff, 0x20, 0x80, 0xc4, 0xa3, 0x9a, 0xae, 0x06,
847 0x8d, 0x12, 0xee, 0xd0, 0x09, 0xb6, 0x8c, 0x89];
848 let sig = RecoverableSignature::from_compact(
849 &s, bytes_in, recid_in).unwrap();
850 let (recid_out, bytes_out) = sig.serialize_compact(&s);
851 assert_eq!(recid_in, recid_out);
852 assert_eq!(&bytes_in[..], &bytes_out[..]);
853 }
854
855 #[test]
856 fn test_recov_id_conversion_between_i32() {
857 assert!(RecoveryId::from_i32(-1).is_err());
858 assert!(RecoveryId::from_i32(0).is_ok());
859 assert!(RecoveryId::from_i32(1).is_ok());
860 assert!(RecoveryId::from_i32(2).is_ok());
861 assert!(RecoveryId::from_i32(3).is_ok());
862 assert!(RecoveryId::from_i32(4).is_err());
863 let id0 = RecoveryId::from_i32(0).unwrap();
864 assert_eq!(id0.to_i32(), 0);
865 let id1 = RecoveryId(1);
866 assert_eq!(id1.to_i32(), 1);
867 }
868
869 #[test]
870 fn test_low_s() {
871 let sig = hex!("3046022100839c1fbc5304de944f697c9f4b1d01d1faeba32d751c0f7acb21ac8a0f436a72022100e89bd46bb3a5a62adc679f659b7ce876d83ee297c7a5587b2011c4fcc72eab45");
875 let pk = hex!("031ee99d2b786ab3b0991325f2de8489246a6a3fdb700f6d0511b1d80cf5f4cd43");
876 let msg = hex!("a4965ca63b7d8562736ceec36dfa5a11bf426eb65be8ea3f7a49ae363032da0d");
877
878 let secp = Secp256k1::new();
879 let mut sig = Signature::from_der(&secp, &sig[..]).unwrap();
880 let pk = PublicKey::from_slice(&secp, &pk[..]).unwrap();
881 let msg = Message::from_slice(&msg[..]).unwrap();
882
883 assert_eq!(secp.verify(&msg, &sig, &pk), Err(IncorrectSignature));
885 sig.normalize_s(&secp);
887 assert_eq!(secp.verify(&msg, &sig, &pk), Ok(()));
888 }
889}
890
891#[cfg(all(test, feature = "unstable"))]
892mod benches {
893 use rand::{Rng, thread_rng};
894 use test::{Bencher, black_box};
895
896 use super::{Secp256k1, Message};
897
898 #[bench]
899 pub fn generate(bh: &mut Bencher) {
900 struct CounterRng(u32);
901 impl Rng for CounterRng {
902 fn next_u32(&mut self) -> u32 { self.0 += 1; self.0 }
903 }
904
905 let s = Secp256k1::new();
906 let mut r = CounterRng(0);
907 bh.iter( || {
908 let (sk, pk) = s.generate_keypair(&mut r).unwrap();
909 black_box(sk);
910 black_box(pk);
911 });
912 }
913
914 #[bench]
915 pub fn bench_sign(bh: &mut Bencher) {
916 let s = Secp256k1::new();
917 let mut msg = [0u8; 32];
918 thread_rng().fill_bytes(&mut msg);
919 let msg = Message::from_slice(&msg).unwrap();
920 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
921
922 bh.iter(|| {
923 let sig = s.sign(&msg, &sk).unwrap();
924 black_box(sig);
925 });
926 }
927
928 #[bench]
929 pub fn bench_verify(bh: &mut Bencher) {
930 let s = Secp256k1::new();
931 let mut msg = [0u8; 32];
932 thread_rng().fill_bytes(&mut msg);
933 let msg = Message::from_slice(&msg).unwrap();
934 let (sk, pk) = s.generate_keypair(&mut thread_rng()).unwrap();
935 let sig = s.sign(&msg, &sk).unwrap();
936
937 bh.iter(|| {
938 let res = s.verify(&msg, &sig, &pk).unwrap();
939 black_box(res);
940 });
941 }
942
943 #[bench]
944 pub fn bench_recover(bh: &mut Bencher) {
945 let s = Secp256k1::new();
946 let mut msg = [0u8; 32];
947 thread_rng().fill_bytes(&mut msg);
948 let msg = Message::from_slice(&msg).unwrap();
949 let (sk, _) = s.generate_keypair(&mut thread_rng()).unwrap();
950 let sig = s.sign_recoverable(&msg, &sk).unwrap();
951
952 bh.iter(|| {
953 let res = s.recover(&msg, &sig).unwrap();
954 black_box(res);
955 });
956 }
957}
958