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