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