1mod secret;
7
8use core::ops::BitXor;
9use core::{fmt, ptr, str};
10
11#[cfg(feature = "arbitrary")]
12use arbitrary::{Arbitrary, Unstructured};
13#[cfg(feature = "serde")]
14use serde::ser::SerializeTuple;
15
16pub use self::secret::SecretKey;
17use crate::ellswift::ElligatorSwift;
18use crate::ffi::types::c_uint;
19use crate::ffi::{self, CPtr};
20use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum};
21use crate::{constants, ecdsa, from_hex, schnorr, Message, Scalar, Secp256k1, Verification};
22
23#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
46#[repr(transparent)]
47pub struct PublicKey(ffi::PublicKey);
48impl_fast_comparisons!(PublicKey);
49
50impl fmt::LowerHex for PublicKey {
51 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52 let ser = self.serialize();
53 for ch in &ser[..] {
54 write!(f, "{:02x}", *ch)?;
55 }
56 Ok(())
57 }
58}
59
60impl fmt::Display for PublicKey {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
62}
63
64impl fmt::Debug for PublicKey {
65 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
66}
67
68impl str::FromStr for PublicKey {
69 type Err = Error;
70 fn from_str(s: &str) -> Result<PublicKey, Error> {
71 let mut res = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
72 match from_hex(s, &mut res) {
73 Ok(constants::PUBLIC_KEY_SIZE) => {
74 let bytes: [u8; constants::PUBLIC_KEY_SIZE] =
75 res[0..constants::PUBLIC_KEY_SIZE].try_into().unwrap();
76 PublicKey::from_byte_array_compressed(bytes)
77 }
78 Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) =>
79 PublicKey::from_byte_array_uncompressed(res),
80 _ => Err(Error::InvalidPublicKey),
81 }
82 }
83}
84
85impl PublicKey {
86 #[inline]
99 pub fn from_secret_key(sk: &SecretKey) -> PublicKey {
100 unsafe {
101 let mut pk = ffi::PublicKey::new();
102 let res = crate::with_global_context(
105 |secp: &Secp256k1<crate::AllPreallocated>| {
106 ffi::secp256k1_ec_pubkey_create(secp.ctx.as_ptr(), &mut pk, sk.as_c_ptr())
107 },
108 Some(&sk.to_secret_bytes()),
109 );
110 debug_assert_eq!(res, 1);
111 PublicKey(pk)
112 }
113 }
114 #[inline]
116 pub fn from_ellswift(ellswift: ElligatorSwift) -> PublicKey { ElligatorSwift::decode(ellswift) }
117
118 #[inline]
120 #[cfg(feature = "global-context")]
121 #[deprecated(since = "TBD", note = "use from_secret_key instead")]
122 pub fn from_secret_key_global(sk: &SecretKey) -> PublicKey { PublicKey::from_secret_key(sk) }
123
124 #[inline]
126 pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> {
127 match data.len() {
128 constants::PUBLIC_KEY_SIZE => PublicKey::from_byte_array_compressed(
129 <[u8; constants::PUBLIC_KEY_SIZE]>::try_from(data).unwrap(),
130 ),
131 constants::UNCOMPRESSED_PUBLIC_KEY_SIZE => PublicKey::from_byte_array_uncompressed(
132 <[u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]>::try_from(data).unwrap(),
133 ),
134 _ => Err(InvalidPublicKey),
135 }
136 }
137
138 #[inline]
140 pub fn from_byte_array_compressed(
141 data: [u8; constants::PUBLIC_KEY_SIZE],
142 ) -> Result<PublicKey, Error> {
143 unsafe {
144 let mut pk = ffi::PublicKey::new();
145 if ffi::secp256k1_ec_pubkey_parse(
146 ffi::secp256k1_context_no_precomp,
147 &mut pk,
148 data.as_c_ptr(),
149 constants::PUBLIC_KEY_SIZE,
150 ) == 1
151 {
152 Ok(PublicKey(pk))
153 } else {
154 Err(InvalidPublicKey)
155 }
156 }
157 }
158
159 #[inline]
161 pub fn from_byte_array_uncompressed(
162 data: [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE],
163 ) -> Result<PublicKey, Error> {
164 unsafe {
165 let mut pk = ffi::PublicKey::new();
166 if ffi::secp256k1_ec_pubkey_parse(
167 ffi::secp256k1_context_no_precomp,
168 &mut pk,
169 data.as_c_ptr(),
170 constants::UNCOMPRESSED_PUBLIC_KEY_SIZE,
171 ) == 1
172 {
173 Ok(PublicKey(pk))
174 } else {
175 Err(InvalidPublicKey)
176 }
177 }
178 }
179
180 #[inline]
193 pub fn from_keypair(keypair: &Keypair) -> Self {
194 unsafe {
195 let mut pk = ffi::PublicKey::new();
196 let ret = ffi::secp256k1_keypair_pub(
197 ffi::secp256k1_context_no_precomp,
198 &mut pk,
199 keypair.as_c_ptr(),
200 );
201 debug_assert_eq!(ret, 1);
202 PublicKey(pk)
203 }
204 }
205
206 pub fn from_x_only_public_key(pk: XOnlyPublicKey, parity: Parity) -> PublicKey {
208 let mut buf = [0u8; 33];
209
210 buf[0] = match parity {
212 Parity::Even => 0x02,
213 Parity::Odd => 0x03,
214 };
215 buf[1..].clone_from_slice(&pk.serialize());
216
217 PublicKey::from_byte_array_compressed(buf).expect("we know the buffer is valid")
218 }
219
220 #[inline]
221 pub fn serialize(&self) -> [u8; constants::PUBLIC_KEY_SIZE] {
224 let mut ret = [0u8; constants::PUBLIC_KEY_SIZE];
225 self.serialize_internal(&mut ret, ffi::SECP256K1_SER_COMPRESSED);
226 ret
227 }
228
229 #[inline]
230 pub fn serialize_uncompressed(&self) -> [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE] {
232 let mut ret = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
233 self.serialize_internal(&mut ret, ffi::SECP256K1_SER_UNCOMPRESSED);
234 ret
235 }
236
237 #[inline(always)]
238 fn serialize_internal(&self, ret: &mut [u8], flag: c_uint) {
239 let mut ret_len = ret.len();
240 let res = unsafe {
241 ffi::secp256k1_ec_pubkey_serialize(
242 ffi::secp256k1_context_no_precomp,
243 ret.as_mut_c_ptr(),
244 &mut ret_len,
245 self.as_c_ptr(),
246 flag,
247 )
248 };
249 debug_assert_eq!(res, 1);
250 debug_assert_eq!(ret_len, ret.len());
251 }
252
253 #[inline]
255 #[must_use = "you forgot to use the negated public key"]
256 pub fn negate(mut self) -> PublicKey {
257 let res = crate::with_raw_global_context(
258 |ctx| unsafe { ffi::secp256k1_ec_pubkey_negate(ctx.as_ptr(), &mut self.0) },
259 None,
260 );
261 debug_assert_eq!(res, 1);
262 self
263 }
264
265 #[inline]
271 pub fn add_exp_tweak(mut self, tweak: &Scalar) -> Result<PublicKey, Error> {
272 if crate::with_raw_global_context(
273 |ctx| unsafe {
274 ffi::secp256k1_ec_pubkey_tweak_add(ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
275 },
276 None,
277 ) == 1
278 {
279 Ok(self)
280 } else {
281 Err(Error::InvalidTweak)
282 }
283 }
284
285 #[inline]
291 pub fn mul_tweak(mut self, other: &Scalar) -> Result<PublicKey, Error> {
292 unsafe {
293 let res = crate::with_global_context(
294 |secp: &Secp256k1<crate::AllPreallocated>| {
295 ffi::secp256k1_ec_pubkey_tweak_mul(
296 secp.ctx.as_ptr(),
297 &mut self.0,
298 other.as_c_ptr(),
299 )
300 },
301 None,
302 );
303 if res == 1 {
304 Ok(self)
305 } else {
306 Err(Error::InvalidTweak)
307 }
308 }
309 }
310
311 pub fn combine(&self, other: &PublicKey) -> Result<PublicKey, Error> {
330 PublicKey::combine_keys(&[self, other])
331 }
332
333 pub fn combine_keys(keys: &[&PublicKey]) -> Result<PublicKey, Error> {
356 use core::mem::transmute;
357
358 if keys.is_empty() || keys.len() > i32::MAX as usize {
359 return Err(InvalidPublicKeySum);
360 }
361
362 unsafe {
363 let mut ret = ffi::PublicKey::new();
364 let ptrs: &[*const ffi::PublicKey] =
365 transmute::<&[&PublicKey], &[*const ffi::PublicKey]>(keys);
366 if ffi::secp256k1_ec_pubkey_combine(
367 ffi::secp256k1_context_no_precomp,
368 &mut ret,
369 ptrs.as_c_ptr(),
370 keys.len(),
371 ) == 1
372 {
373 Ok(PublicKey(ret))
374 } else {
375 Err(InvalidPublicKeySum)
376 }
377 }
378 }
379
380 #[inline]
382 pub fn x_only_public_key(&self) -> (XOnlyPublicKey, Parity) {
383 let mut pk_parity = 0;
384 unsafe {
385 let mut xonly_pk = ffi::XOnlyPublicKey::new();
386 let ret = ffi::secp256k1_xonly_pubkey_from_pubkey(
387 ffi::secp256k1_context_no_precomp,
388 &mut xonly_pk,
389 &mut pk_parity,
390 self.as_c_ptr(),
391 );
392 debug_assert_eq!(ret, 1);
393 let parity =
394 Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1");
395
396 (XOnlyPublicKey(xonly_pk), parity)
397 }
398 }
399
400 pub fn verify(&self, msg: impl Into<Message>, sig: &ecdsa::Signature) -> Result<(), Error> {
402 ecdsa::verify(sig, msg, self)
403 }
404}
405
406impl CPtr for PublicKey {
409 type Target = ffi::PublicKey;
410
411 fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
413
414 fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
416}
417
418impl From<ffi::PublicKey> for PublicKey {
422 #[inline]
423 fn from(pk: ffi::PublicKey) -> PublicKey { PublicKey(pk) }
424}
425
426#[cfg(feature = "serde")]
427impl serde::Serialize for PublicKey {
428 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
429 if s.is_human_readable() {
430 s.collect_str(self)
431 } else {
432 let mut tuple = s.serialize_tuple(constants::PUBLIC_KEY_SIZE)?;
433 for byte in self.serialize().iter() {
435 tuple.serialize_element(&byte)?;
436 }
437 tuple.end()
438 }
439 }
440}
441
442#[cfg(feature = "serde")]
443impl<'de> serde::Deserialize<'de> for PublicKey {
444 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<PublicKey, D::Error> {
445 if d.is_human_readable() {
446 d.deserialize_str(super::serde_util::FromStrVisitor::new(
447 "an ASCII hex string representing a public key",
448 ))
449 } else {
450 let visitor = super::serde_util::Tuple33Visitor::new(
451 "33 bytes compressed public key",
452 PublicKey::from_byte_array_compressed,
453 );
454 d.deserialize_tuple(constants::PUBLIC_KEY_SIZE, visitor)
455 }
456 }
457}
458
459#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
483pub struct Keypair(ffi::Keypair);
484impl_fast_comparisons!(Keypair);
485
486impl Keypair {
487 #[inline]
489 pub fn from_secret_key(sk: &SecretKey) -> Keypair {
490 unsafe {
491 let mut kp = ffi::Keypair::new();
492 let res = crate::with_global_context(
493 |secp: &Secp256k1<crate::AllPreallocated>| {
494 ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, sk.as_c_ptr())
495 },
496 Some(&sk.to_secret_bytes()),
497 );
498
499 if res == 1 {
500 Keypair(kp)
501 } else {
502 panic!("the provided secret key is invalid: it is corrupted or was not produced by Secp256k1 library")
503 }
504 }
505 }
506
507 #[deprecated(since = "0.31.0", note = "Use `from_seckey_byte_array` instead.")]
514 #[inline]
515 pub fn from_seckey_slice(data: &[u8]) -> Result<Keypair, Error> {
516 match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
517 Ok(data) => Self::from_seckey_byte_array(data),
518 Err(_) => Err(Error::InvalidSecretKey),
519 }
520 }
521
522 #[inline]
528 pub fn from_seckey_byte_array(
529 data: [u8; constants::SECRET_KEY_SIZE],
530 ) -> Result<Keypair, Error> {
531 unsafe {
532 let mut kp = ffi::Keypair::new();
533 if crate::with_raw_global_context(
534 |ctx| ffi::secp256k1_keypair_create(ctx.as_ptr(), &mut kp, data.as_c_ptr()),
535 Some(&data),
536 ) == 1
537 {
538 Ok(Keypair(kp))
539 } else {
540 Err(Error::InvalidSecretKey)
541 }
542 }
543 }
544
545 #[inline]
552 #[deprecated(note = "use FromStr or parse instead")]
553 pub fn from_seckey_str(s: &str) -> Result<Self, Error> { s.parse() }
554
555 #[inline]
562 #[deprecated(note = "use FromStr or parse instead")]
563 pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> { s.parse() }
564
565 #[inline]
576 #[cfg(feature = "rand")]
577 pub fn new<R: rand::Rng + ?Sized>(rng: &mut R) -> Keypair {
578 let mut data = crate::random_32_bytes(rng);
579 let mut ret = 0;
580
581 unsafe {
582 let mut keypair = ffi::Keypair::new();
583
584 while ret == 0 {
585 ret = crate::with_global_context(
586 |secp: &Secp256k1<crate::AllPreallocated>| {
587 ffi::secp256k1_keypair_create(
588 secp.ctx.as_ptr(),
589 &mut keypair,
590 data.as_c_ptr(),
591 )
592 },
593 Some(&data),
594 );
595
596 if ret != 0 {
597 break;
598 }
599
600 data = crate::random_32_bytes(rng);
601 }
602
603 Keypair(keypair)
604 }
605 }
606
607 #[inline]
609 #[cfg(all(feature = "global-context", feature = "rand"))]
610 #[deprecated(since = "TBD", note = "use Keypair::new instead")]
611 pub fn new_global<R: ::rand::Rng + ?Sized>(rng: &mut R) -> Keypair { Keypair::new(rng) }
612
613 #[inline]
615 pub fn to_secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] {
616 *SecretKey::from_keypair(self).as_ref()
617 }
618
619 #[deprecated(since = "TBD", note = "use to_secret_bytes instead")]
621 #[inline]
622 pub fn secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] { self.to_secret_bytes() }
623
624 #[inline]
647 pub fn add_xonly_tweak(mut self, tweak: &Scalar) -> Result<Keypair, Error> {
648 unsafe {
649 let err = crate::with_global_context(
650 |secp: &Secp256k1<crate::AllPreallocated>| {
651 ffi::secp256k1_keypair_xonly_tweak_add(
652 secp.ctx.as_ptr(),
653 &mut self.0,
654 tweak.as_c_ptr(),
655 )
656 },
657 None,
658 );
659 if err != 1 {
660 return Err(Error::InvalidTweak);
661 }
662
663 Ok(self)
664 }
665 }
666
667 #[inline]
671 pub fn secret_key(&self) -> SecretKey { SecretKey::from_keypair(self) }
672
673 #[inline]
677 pub fn public_key(&self) -> PublicKey { PublicKey::from_keypair(self) }
678
679 #[inline]
683 pub fn x_only_public_key(&self) -> (XOnlyPublicKey, Parity) {
684 XOnlyPublicKey::from_keypair(self)
685 }
686
687 #[inline]
689 #[cfg(all(feature = "rand", feature = "std"))]
690 pub fn sign_schnorr(&self, msg: &[u8]) -> schnorr::Signature { schnorr::sign(msg, self) }
691
692 #[inline]
694 pub fn sign_schnorr_no_aux_rand(&self, msg: &[u8]) -> schnorr::Signature {
695 schnorr::sign_no_aux_rand(msg, self)
696 }
697
698 #[inline]
705 pub fn non_secure_erase(&mut self) { self.0.non_secure_erase(); }
706
707 #[cfg(test)]
709 pub fn test_random() -> Self {
710 let sk = SecretKey::test_random();
711 Self::from_secret_key(&sk)
712 }
713}
714
715impl fmt::Debug for Keypair {
716 fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
717 f.debug_struct("Keypair")
718 .field("pubkey", &self.public_key())
719 .field("secret", &"<hidden>")
720 .finish()
721 }
722}
723
724impl From<Keypair> for SecretKey {
725 #[inline]
726 fn from(pair: Keypair) -> Self { SecretKey::from_keypair(&pair) }
727}
728
729impl<'a> From<&'a Keypair> for SecretKey {
730 #[inline]
731 fn from(pair: &'a Keypair) -> Self { SecretKey::from_keypair(pair) }
732}
733
734impl From<Keypair> for PublicKey {
735 #[inline]
736 fn from(pair: Keypair) -> Self { PublicKey::from_keypair(&pair) }
737}
738
739impl<'a> From<&'a Keypair> for PublicKey {
740 #[inline]
741 fn from(pair: &'a Keypair) -> Self { PublicKey::from_keypair(pair) }
742}
743
744impl str::FromStr for Keypair {
745 type Err = Error;
746
747 fn from_str(s: &str) -> Result<Self, Self::Err> {
748 let mut res = [0u8; constants::SECRET_KEY_SIZE];
749 match from_hex(s, &mut res) {
750 Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(res),
751 _ => Err(Error::InvalidSecretKey),
752 }
753 }
754}
755
756#[cfg(feature = "serde")]
757impl serde::Serialize for Keypair {
758 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
759 if s.is_human_readable() {
760 let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2];
761 s.serialize_str(
762 crate::to_hex(&self.secret_bytes(), &mut buf)
763 .expect("fixed-size hex serialization"),
764 )
765 } else {
766 let mut tuple = s.serialize_tuple(constants::SECRET_KEY_SIZE)?;
767 for byte in self.secret_bytes().iter() {
768 tuple.serialize_element(&byte)?;
769 }
770 tuple.end()
771 }
772 }
773}
774
775#[cfg(feature = "serde")]
776impl<'de> serde::Deserialize<'de> for Keypair {
777 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
778 if d.is_human_readable() {
779 d.deserialize_str(super::serde_util::FromStrVisitor::new(
780 "a hex string representing 32 byte Keypair",
781 ))
782 } else {
783 let visitor = super::serde_util::Tuple32Visitor::new(
784 "raw 32 bytes Keypair",
785 Keypair::from_seckey_byte_array,
786 );
787 d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor)
788 }
789 }
790}
791
792impl CPtr for Keypair {
793 type Target = ffi::Keypair;
794 fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
795
796 fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
797}
798
799#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
822pub struct XOnlyPublicKey(ffi::XOnlyPublicKey);
823impl_fast_comparisons!(XOnlyPublicKey);
824
825impl fmt::LowerHex for XOnlyPublicKey {
826 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
827 let ser = self.serialize();
828 for ch in &ser[..] {
829 write!(f, "{:02x}", *ch)?;
830 }
831 Ok(())
832 }
833}
834
835impl fmt::Display for XOnlyPublicKey {
836 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
837}
838
839impl fmt::Debug for XOnlyPublicKey {
840 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
841}
842
843impl str::FromStr for XOnlyPublicKey {
844 type Err = Error;
845 fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
846 let mut res = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
847 match from_hex(s, &mut res) {
848 Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) => XOnlyPublicKey::from_byte_array(res),
849 _ => Err(Error::InvalidPublicKey),
850 }
851 }
852}
853
854impl XOnlyPublicKey {
855 #[inline]
857 pub fn from_keypair(keypair: &Keypair) -> (XOnlyPublicKey, Parity) {
858 let mut pk_parity = 0;
859 unsafe {
860 let mut xonly_pk = ffi::XOnlyPublicKey::new();
861 let ret = ffi::secp256k1_keypair_xonly_pub(
862 ffi::secp256k1_context_no_precomp,
863 &mut xonly_pk,
864 &mut pk_parity,
865 keypair.as_c_ptr(),
866 );
867 debug_assert_eq!(ret, 1);
868 let parity =
869 Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1");
870
871 (XOnlyPublicKey(xonly_pk), parity)
872 }
873 }
874
875 #[deprecated(since = "0.31.0", note = "Use `from_byte_array` instead.")]
882 #[inline]
883 pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
884 match <[u8; constants::SCHNORR_PUBLIC_KEY_SIZE]>::try_from(data) {
885 Ok(data) => Self::from_byte_array(data),
886 Err(_) => Err(InvalidPublicKey),
887 }
888 }
889
890 #[inline]
897 pub fn from_byte_array(
898 data: [u8; constants::SCHNORR_PUBLIC_KEY_SIZE],
899 ) -> Result<XOnlyPublicKey, Error> {
900 unsafe {
901 let mut pk = ffi::XOnlyPublicKey::new();
902 if ffi::secp256k1_xonly_pubkey_parse(
903 ffi::secp256k1_context_no_precomp,
904 &mut pk,
905 data.as_c_ptr(),
906 ) == 1
907 {
908 Ok(XOnlyPublicKey(pk))
909 } else {
910 Err(Error::InvalidPublicKey)
911 }
912 }
913 }
914
915 #[inline]
916 pub fn serialize(&self) -> [u8; constants::SCHNORR_PUBLIC_KEY_SIZE] {
918 let mut ret = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
919
920 unsafe {
921 let err = ffi::secp256k1_xonly_pubkey_serialize(
922 ffi::secp256k1_context_no_precomp,
923 ret.as_mut_c_ptr(),
924 self.as_c_ptr(),
925 );
926 debug_assert_eq!(err, 1);
927 }
928 ret
929 }
930
931 pub fn add_tweak(mut self, tweak: &Scalar) -> Result<(XOnlyPublicKey, Parity), Error> {
957 let mut pk_parity = 0;
958 unsafe {
959 let mut pubkey = ffi::PublicKey::new();
960 let mut err = crate::with_global_context(
961 |secp: &Secp256k1<crate::AllPreallocated>| {
962 ffi::secp256k1_xonly_pubkey_tweak_add(
963 secp.ctx.as_ptr(),
964 &mut pubkey,
965 self.as_c_ptr(),
966 tweak.as_c_ptr(),
967 )
968 },
969 None,
970 );
971 if err != 1 {
972 return Err(Error::InvalidTweak);
973 }
974
975 err = crate::with_global_context(
976 |secp: &Secp256k1<crate::AllPreallocated>| {
977 ffi::secp256k1_xonly_pubkey_from_pubkey(
978 secp.ctx.as_ptr(),
979 &mut self.0,
980 &mut pk_parity,
981 &pubkey,
982 )
983 },
984 None,
985 );
986 if err == 0 {
987 return Err(Error::InvalidPublicKey);
988 }
989
990 let parity = Parity::from_i32(pk_parity)?;
991 Ok((self, parity))
992 }
993 }
994
995 pub fn tweak_add_check(
1024 &self,
1025 tweaked_key: &Self,
1026 tweaked_parity: Parity,
1027 tweak: Scalar,
1028 ) -> bool {
1029 let tweaked_ser = tweaked_key.serialize();
1030 unsafe {
1031 let err = crate::with_global_context(
1032 |secp: &Secp256k1<crate::AllPreallocated>| {
1033 ffi::secp256k1_xonly_pubkey_tweak_add_check(
1034 secp.ctx.as_ptr(),
1035 tweaked_ser.as_c_ptr(),
1036 tweaked_parity.to_i32(),
1037 &self.0,
1038 tweak.as_c_ptr(),
1039 )
1040 },
1041 None,
1042 );
1043
1044 err == 1
1045 }
1046 }
1047
1048 #[inline]
1052 pub fn public_key(&self, parity: Parity) -> PublicKey {
1053 PublicKey::from_x_only_public_key(*self, parity)
1054 }
1055
1056 pub fn verify<C: Verification>(
1058 &self,
1059 msg: &[u8],
1060 sig: &schnorr::Signature,
1061 ) -> Result<(), Error> {
1062 schnorr::verify(sig, msg, self)
1063 }
1064}
1065
1066#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
1068pub enum Parity {
1069 Even = 0,
1071 Odd = 1,
1073}
1074
1075impl Parity {
1076 pub fn to_u8(self) -> u8 { self as u8 }
1080
1081 pub fn to_i32(self) -> i32 { self as i32 }
1085
1086 pub fn from_u8(parity: u8) -> Result<Parity, InvalidParityValue> {
1091 Parity::from_i32(parity.into())
1092 }
1093
1094 pub fn from_i32(parity: i32) -> Result<Parity, InvalidParityValue> {
1099 match parity {
1100 0 => Ok(Parity::Even),
1101 1 => Ok(Parity::Odd),
1102 _ => Err(InvalidParityValue(parity)),
1103 }
1104 }
1105}
1106
1107impl TryFrom<i32> for Parity {
1109 type Error = InvalidParityValue;
1110
1111 fn try_from(parity: i32) -> Result<Self, Self::Error> { Self::from_i32(parity) }
1112}
1113
1114impl TryFrom<u8> for Parity {
1116 type Error = InvalidParityValue;
1117
1118 fn try_from(parity: u8) -> Result<Self, Self::Error> { Self::from_u8(parity) }
1119}
1120
1121impl From<Parity> for i32 {
1123 fn from(parity: Parity) -> i32 { parity.to_i32() }
1124}
1125
1126impl From<Parity> for u8 {
1128 fn from(parity: Parity) -> u8 { parity.to_u8() }
1129}
1130
1131impl BitXor for Parity {
1133 type Output = Parity;
1134
1135 fn bitxor(self, rhs: Parity) -> Self::Output {
1136 if self == rhs {
1138 Parity::Even } else {
1140 Parity::Odd }
1142 }
1143}
1144
1145#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
1151pub struct InvalidParityValue(i32);
1152
1153impl fmt::Display for InvalidParityValue {
1154 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1155 write!(f, "invalid value {} for Parity - must be 0 or 1", self.0)
1156 }
1157}
1158
1159#[cfg(feature = "std")]
1160impl std::error::Error for InvalidParityValue {}
1161
1162impl From<InvalidParityValue> for Error {
1163 fn from(error: InvalidParityValue) -> Self { Error::InvalidParityValue(error) }
1164}
1165
1166#[cfg(feature = "serde")]
1168impl serde::Serialize for Parity {
1169 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1170 s.serialize_u8(self.to_u8())
1171 }
1172}
1173
1174#[cfg(feature = "serde")]
1176impl<'de> serde::Deserialize<'de> for Parity {
1177 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
1178 struct Visitor;
1179
1180 impl serde::de::Visitor<'_> for Visitor {
1181 type Value = Parity;
1182
1183 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1184 formatter.write_str("8-bit integer (byte) with value 0 or 1")
1185 }
1186
1187 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
1188 where
1189 E: serde::de::Error,
1190 {
1191 use serde::de::Unexpected;
1192
1193 Parity::from_u8(v)
1194 .map_err(|_| E::invalid_value(Unexpected::Unsigned(v.into()), &"0 or 1"))
1195 }
1196 }
1197
1198 d.deserialize_u8(Visitor)
1199 }
1200}
1201
1202impl CPtr for XOnlyPublicKey {
1203 type Target = ffi::XOnlyPublicKey;
1204 fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
1205
1206 fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
1207}
1208
1209impl From<ffi::XOnlyPublicKey> for XOnlyPublicKey {
1211 #[inline]
1212 fn from(pk: ffi::XOnlyPublicKey) -> XOnlyPublicKey { XOnlyPublicKey(pk) }
1213}
1214
1215impl From<PublicKey> for XOnlyPublicKey {
1216 fn from(src: PublicKey) -> XOnlyPublicKey {
1217 unsafe {
1218 let mut pk = ffi::XOnlyPublicKey::new();
1219 assert_eq!(
1220 1,
1221 ffi::secp256k1_xonly_pubkey_from_pubkey(
1222 ffi::secp256k1_context_no_precomp,
1223 &mut pk,
1224 ptr::null_mut(),
1225 src.as_c_ptr(),
1226 )
1227 );
1228 XOnlyPublicKey(pk)
1229 }
1230 }
1231}
1232
1233#[cfg(feature = "serde")]
1234impl serde::Serialize for XOnlyPublicKey {
1235 fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1236 if s.is_human_readable() {
1237 s.collect_str(self)
1238 } else {
1239 let mut tuple = s.serialize_tuple(constants::SCHNORR_PUBLIC_KEY_SIZE)?;
1240 for byte in self.serialize().iter() {
1241 tuple.serialize_element(&byte)?;
1242 }
1243 tuple.end()
1244 }
1245 }
1246}
1247
1248#[cfg(feature = "serde")]
1249impl<'de> serde::Deserialize<'de> for XOnlyPublicKey {
1250 fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
1251 if d.is_human_readable() {
1252 d.deserialize_str(super::serde_util::FromStrVisitor::new(
1253 "a hex string representing 32 byte schnorr public key",
1254 ))
1255 } else {
1256 let visitor = super::serde_util::Tuple32Visitor::new(
1257 "raw 32 bytes schnorr public key",
1258 XOnlyPublicKey::from_byte_array,
1259 );
1260 d.deserialize_tuple(constants::SCHNORR_PUBLIC_KEY_SIZE, visitor)
1261 }
1262 }
1263}
1264
1265pub fn sort_pubkeys(pubkeys: &mut [&PublicKey]) {
1288 unsafe {
1289 let pubkeys_ptr = pubkeys.as_mut_c_ptr() as *mut *const ffi::PublicKey;
1291
1292 let ret = crate::with_global_context(
1293 |secp: &Secp256k1<crate::AllPreallocated>| {
1294 ffi::secp256k1_ec_pubkey_sort(secp.ctx.as_ptr(), pubkeys_ptr, pubkeys.len())
1295 },
1296 None,
1297 );
1298
1299 if ret == 0 {
1300 unreachable!("Invalid public keys for sorting function")
1301 }
1302 }
1303}
1304
1305#[cfg(feature = "arbitrary")]
1306impl<'a> Arbitrary<'a> for PublicKey {
1307 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1308 Ok(PublicKey::from_x_only_public_key(u.arbitrary()?, u.arbitrary()?))
1309 }
1310}
1311
1312#[cfg(feature = "arbitrary")]
1313impl<'a> Arbitrary<'a> for Parity {
1314 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1315 match bool::arbitrary(u)? {
1316 true => Ok(Parity::Even),
1317 false => Ok(Parity::Odd),
1318 }
1319 }
1320}
1321
1322#[cfg(feature = "arbitrary")]
1323impl<'a> Arbitrary<'a> for SecretKey {
1324 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1325 let mut bytes = [0u8; constants::SECRET_KEY_SIZE];
1326 loop {
1327 if u.len() < constants::SECRET_KEY_SIZE {
1329 return Err(arbitrary::Error::NotEnoughData);
1330 }
1331 u.fill_buffer(&mut bytes[..])?;
1332
1333 if let Ok(sk) = SecretKey::from_secret_bytes(bytes) {
1334 return Ok(sk);
1335 }
1336 }
1337 }
1338}
1339
1340#[cfg(feature = "arbitrary")]
1341impl<'a> Arbitrary<'a> for XOnlyPublicKey {
1342 fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
1343 let mut bytes = [0u8; 32];
1344 loop {
1345 if u.len() < 32 {
1347 return Err(arbitrary::Error::NotEnoughData);
1348 }
1349
1350 u.fill_buffer(&mut bytes[..])?;
1351 if let Ok(pk) = XOnlyPublicKey::from_byte_array(bytes) {
1352 return Ok(pk);
1353 }
1354 }
1355 }
1356}
1357
1358#[cfg(test)]
1359#[allow(unused_imports)]
1360mod test {
1361 use core::str::FromStr;
1362
1363 #[cfg(not(secp256k1_fuzz))]
1364 use hex_lit::hex;
1365 #[cfg(feature = "rand")]
1366 use rand::{self, RngCore, SeedableRng as _};
1367 #[cfg(feature = "rand")]
1368 use rand_xoshiro::Xoshiro128PlusPlus as SmallRng;
1369 use serde_test::{Configure, Token};
1370 #[cfg(target_arch = "wasm32")]
1371 use wasm_bindgen_test::wasm_bindgen_test as test;
1372
1373 use super::*;
1374 use crate::Error::{InvalidPublicKey, InvalidSecretKey};
1375 use crate::{constants, from_hex, to_hex, Scalar};
1376
1377 #[test]
1378 fn pubkey_from_slice() {
1379 assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey));
1380 assert_eq!(PublicKey::from_slice(&[1, 2, 3]), Err(InvalidPublicKey));
1381
1382 let uncompressed = PublicKey::from_slice(&[
1383 4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85,
1384 220, 40, 100, 57, 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124,
1385 149, 144, 168, 77, 74, 30, 72, 211, 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195,
1386 155, 51, 247, 123, 113, 60, 228, 188,
1387 ]);
1388 assert!(uncompressed.is_ok());
1389
1390 let compressed = PublicKey::from_slice(&[
1391 3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41,
1392 111, 180, 110, 143, 114, 134, 88, 73, 198, 174, 52, 184, 78,
1393 ]);
1394 assert!(compressed.is_ok());
1395 }
1396
1397 #[test]
1398 fn keypair_slice_round_trip() {
1399 let (sk1, pk1) = crate::test_random_keypair();
1400 assert_eq!(SecretKey::from_secret_bytes(sk1.to_secret_bytes()), Ok(sk1));
1401 assert_eq!(PublicKey::from_slice(&pk1.serialize()[..]), Ok(pk1));
1402 assert_eq!(PublicKey::from_slice(&pk1.serialize_uncompressed()[..]), Ok(pk1));
1403 }
1404
1405 #[test]
1406 #[cfg(not(secp256k1_fuzz))]
1407 fn erased_keypair_is_valid() {
1408 let kp = Keypair::from_seckey_byte_array([1u8; constants::SECRET_KEY_SIZE])
1409 .expect("valid secret key");
1410 let mut kp2 = kp;
1411 kp2.non_secure_erase();
1412 assert!(kp.eq_fast_unstable(&kp2));
1413 }
1414
1415 #[test]
1416 #[rustfmt::skip]
1417 fn invalid_secret_key() {
1418 assert_eq!(SecretKey::from_secret_bytes([0; 32]), Err(InvalidSecretKey));
1420 assert_eq!(
1421 SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000000"),
1422 Err(InvalidSecretKey)
1423 );
1424 assert_eq!(SecretKey::from_secret_bytes([0xff; 32]), Err(InvalidSecretKey));
1426 assert!(SecretKey::from_secret_bytes([
1428 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1429 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
1430 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
1431 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40,
1432 ]).is_ok());
1433 assert!(SecretKey::from_secret_bytes([
1435 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1436 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
1437 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
1438 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41,
1439 ]).is_err());
1440 }
1441
1442 #[test]
1443 #[cfg(all(feature = "rand", feature = "alloc"))]
1444 fn test_out_of_range() {
1445 struct BadRng(u8);
1446 impl RngCore for BadRng {
1447 fn next_u32(&mut self) -> u32 { unimplemented!() }
1448 fn next_u64(&mut self) -> u64 { unimplemented!() }
1449 fn fill_bytes(&mut self, data: &mut [u8]) {
1453 #[rustfmt::skip]
1454 let group_order: [u8; 32] = [
1455 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1456 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
1457 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
1458 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41];
1459 assert_eq!(data.len(), 32);
1460 data.copy_from_slice(&group_order[..]);
1461 data[31] = self.0;
1462 self.0 -= 1;
1463 }
1464 }
1465
1466 crate::generate_keypair(&mut BadRng(0xff));
1467 }
1468
1469 #[test]
1470 fn test_pubkey_from_bad_slice() {
1471 assert_eq!(
1473 PublicKey::from_slice(&[0; constants::PUBLIC_KEY_SIZE - 1]),
1474 Err(InvalidPublicKey)
1475 );
1476 assert_eq!(
1477 PublicKey::from_slice(&[0; constants::PUBLIC_KEY_SIZE + 1]),
1478 Err(InvalidPublicKey)
1479 );
1480 assert_eq!(
1481 PublicKey::from_slice(&[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE - 1]),
1482 Err(InvalidPublicKey)
1483 );
1484 assert_eq!(
1485 PublicKey::from_slice(&[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE + 1]),
1486 Err(InvalidPublicKey)
1487 );
1488
1489 assert_eq!(
1491 PublicKey::from_slice(&[0xff; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]),
1492 Err(InvalidPublicKey)
1493 );
1494 assert_eq!(
1495 PublicKey::from_slice(&[0x55; constants::PUBLIC_KEY_SIZE]),
1496 Err(InvalidPublicKey)
1497 );
1498 assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey));
1499 }
1500
1501 #[test]
1502 #[cfg(all(feature = "rand", feature = "alloc"))]
1503 fn test_debug_output() {
1504 let (sk, _) = crate::generate_keypair(&mut SmallRng::from_seed([0; 16]));
1505
1506 assert_eq!(&format!("{:?}", sk), "SecretKey(55f970894288f83a)");
1507
1508 let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2];
1509 assert_eq!(
1510 to_hex(&sk[..], &mut buf).unwrap(),
1511 "a3da5346582b9273dd4a2bb83bbdfad9c398863cff589b1c4646accc16fde327"
1512 );
1513 }
1514
1515 #[test]
1516 #[cfg(feature = "alloc")]
1517 fn test_display_output() {
1518 #[rustfmt::skip]
1519 static SK_BYTES: [u8; 32] = [
1520 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1521 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1522 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
1523 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1524 ];
1525
1526 let sk = SecretKey::from_secret_bytes(SK_BYTES).expect("sk");
1527
1528 #[cfg(not(secp256k1_fuzz))]
1531 let pk = PublicKey::from_secret_key(&sk);
1532 #[cfg(secp256k1_fuzz)]
1533 let pk = PublicKey::from_slice(&[
1534 0x02, 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30,
1535 0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87,
1536 0xfe, 0x91, 0xdd, 0xd1, 0x66,
1537 ])
1538 .expect("pk");
1539
1540 assert_eq!(
1541 sk.display_secret().to_string(),
1542 "01010101010101010001020304050607ffff0000ffff00006363636363636363"
1543 );
1544 assert_eq!(
1545 SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363")
1546 .unwrap(),
1547 sk
1548 );
1549 assert_eq!(
1550 pk.to_string(),
1551 "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
1552 );
1553 assert_eq!(
1554 PublicKey::from_str(
1555 "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
1556 )
1557 .unwrap(),
1558 pk
1559 );
1560 assert_eq!(
1561 PublicKey::from_str(
1562 "04\
1563 18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166\
1564 84B84DB303A340CD7D6823EE88174747D12A67D2F8F2F9BA40846EE5EE7A44F6"
1565 )
1566 .unwrap(),
1567 pk
1568 );
1569
1570 assert!(SecretKey::from_str(
1571 "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1572 )
1573 .is_err());
1574 assert!(SecretKey::from_str(
1575 "01010101010101010001020304050607ffff0000ffff0000636363636363636363"
1576 )
1577 .is_err());
1578 assert!(SecretKey::from_str(
1579 "01010101010101010001020304050607ffff0000ffff0000636363636363636"
1580 )
1581 .is_err());
1582 assert!(SecretKey::from_str(
1583 "01010101010101010001020304050607ffff0000ffff000063636363636363"
1584 )
1585 .is_err());
1586 assert!(SecretKey::from_str(
1587 "01010101010101010001020304050607ffff0000ffff000063636363636363xx"
1588 )
1589 .is_err());
1590 assert!(PublicKey::from_str(
1591 "0300000000000000000000000000000000000000000000000000000000000000000"
1592 )
1593 .is_err());
1594 assert!(PublicKey::from_str(
1595 "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601"
1596 )
1597 .is_err());
1598 assert!(PublicKey::from_str(
1599 "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16"
1600 )
1601 .is_err());
1602 assert!(PublicKey::from_str(
1603 "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
1604 )
1605 .is_err());
1606 assert!(PublicKey::from_str(
1607 "xx0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
1608 )
1609 .is_err());
1610
1611 let long_str = "a".repeat(1024 * 1024);
1612 assert!(SecretKey::from_str(&long_str).is_err());
1613 assert!(PublicKey::from_str(&long_str).is_err());
1614 }
1615
1616 #[test]
1617 #[cfg(not(secp256k1_fuzz))]
1618 #[cfg(all(feature = "alloc", feature = "rand"))]
1619 fn test_pubkey_serialize() {
1620 let (_, pk1) = crate::generate_keypair(&mut SmallRng::from_seed([1; 16]));
1621 assert_eq!(
1622 &pk1.serialize_uncompressed()[..],
1623 &[
1624 4, 56, 223, 70, 19, 126, 3, 194, 155, 88, 167, 37, 54, 98, 138, 203, 136, 98, 66,
1625 247, 172, 101, 50, 193, 106, 108, 55, 252, 115, 176, 125, 88, 41, 21, 0, 223, 206,
1626 246, 198, 43, 80, 189, 247, 183, 48, 90, 209, 30, 195, 64, 214, 36, 109, 251, 121,
1627 60, 160, 172, 76, 9, 164, 224, 180, 189, 228
1628 ]
1629 );
1630 assert_eq!(
1631 &pk1.serialize()[..],
1632 &[
1633 2, 56, 223, 70, 19, 126, 3, 194, 155, 88, 167, 37, 54, 98, 138, 203, 136, 98, 66,
1634 247, 172, 101, 50, 193, 106, 108, 55, 252, 115, 176, 125, 88, 41
1635 ]
1636 );
1637 }
1638
1639 #[test]
1640 #[cfg(feature = "std")]
1641 fn tweak_add_arbitrary_data() {
1642 let (sk, pk) = crate::test_random_keypair();
1643 assert_eq!(PublicKey::from_secret_key(&sk), pk); let tweak = Scalar::test_random();
1647
1648 let tweaked_sk = sk.add_tweak(&tweak).unwrap();
1649 assert_ne!(sk, tweaked_sk); let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
1651 assert_ne!(pk, tweaked_pk);
1652
1653 assert_eq!(PublicKey::from_secret_key(&tweaked_sk), tweaked_pk);
1654 }
1655
1656 #[test]
1657 fn tweak_add_zero() {
1658 let (sk, pk) = crate::test_random_keypair();
1659
1660 let tweak = Scalar::ZERO;
1661
1662 let tweaked_sk = sk.add_tweak(&tweak).unwrap();
1663 assert_eq!(sk, tweaked_sk); let tweaked_pk = pk.add_exp_tweak(&tweak).unwrap();
1665 assert_eq!(pk, tweaked_pk);
1666 }
1667
1668 #[test]
1669 #[cfg(feature = "std")]
1670 fn tweak_mul_arbitrary_data() {
1671 let (sk, pk) = crate::test_random_keypair();
1672 assert_eq!(PublicKey::from_secret_key(&sk), pk); for _ in 0..10 {
1675 let tweak = Scalar::test_random();
1676
1677 let tweaked_sk = sk.mul_tweak(&tweak).unwrap();
1678 assert_ne!(sk, tweaked_sk); let tweaked_pk = pk.mul_tweak(&tweak).unwrap();
1680 assert_ne!(pk, tweaked_pk);
1681 assert_eq!(PublicKey::from_secret_key(&tweaked_sk), tweaked_pk);
1682 }
1683 }
1684
1685 #[test]
1686 fn tweak_mul_zero() {
1687 let (sk, _) = crate::test_random_keypair();
1688
1689 let tweak = Scalar::ZERO;
1690 assert!(sk.mul_tweak(&tweak).is_err())
1691 }
1692
1693 #[test]
1694 #[cfg(feature = "std")]
1695 fn test_negation() {
1696 let (sk, pk) = crate::test_random_keypair();
1697
1698 assert_eq!(PublicKey::from_secret_key(&sk), pk); let neg = sk.negate();
1701 assert_ne!(sk, neg);
1702 let back_sk = neg.negate();
1703 assert_eq!(sk, back_sk);
1704
1705 let neg = pk.negate();
1706 assert_ne!(pk, neg);
1707 let back_pk = neg.negate();
1708 assert_eq!(pk, back_pk);
1709
1710 assert_eq!(PublicKey::from_secret_key(&back_sk), pk);
1711 }
1712
1713 #[test]
1714 #[cfg(feature = "std")]
1715 fn pubkey_hash() {
1716 use std::collections::hash_map::DefaultHasher;
1717 use std::collections::HashSet;
1718 use std::hash::{Hash, Hasher};
1719
1720 fn hash<T: Hash>(t: &T) -> u64 {
1721 let mut s = DefaultHasher::new();
1722 t.hash(&mut s);
1723 s.finish()
1724 }
1725
1726 let mut set = HashSet::new();
1727 const COUNT: usize = 1024;
1728 for _ in 0..COUNT {
1729 let (_, pk) = crate::test_random_keypair();
1730 let hash = hash(&pk);
1731 assert!(!set.contains(&hash));
1732 set.insert(hash);
1733 }
1734 assert_eq!(set.len(), COUNT);
1735 }
1736
1737 #[test]
1738 #[cfg(not(secp256k1_fuzz))]
1739 fn pubkey_combine() {
1740 let compressed1 = PublicKey::from_slice(&hex!(
1741 "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"
1742 ))
1743 .unwrap();
1744 let compressed2 = PublicKey::from_slice(&hex!(
1745 "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
1746 ))
1747 .unwrap();
1748 let exp_sum = PublicKey::from_slice(&hex!(
1749 "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"
1750 ))
1751 .unwrap();
1752
1753 let sum1 = compressed1.combine(&compressed2);
1754 assert!(sum1.is_ok());
1755 let sum2 = compressed2.combine(&compressed1);
1756 assert!(sum2.is_ok());
1757 assert_eq!(sum1, sum2);
1758 assert_eq!(sum1.unwrap(), exp_sum);
1759 }
1760
1761 #[test]
1762 #[cfg(not(secp256k1_fuzz))]
1763 fn pubkey_combine_keys() {
1764 let compressed1 = PublicKey::from_slice(&hex!(
1765 "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"
1766 ))
1767 .unwrap();
1768 let compressed2 = PublicKey::from_slice(&hex!(
1769 "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
1770 ))
1771 .unwrap();
1772 let compressed3 = PublicKey::from_slice(&hex!(
1773 "03e74897d8644eb3e5b391ca2ab257aec2080f4d1a95cad57e454e47f021168eb0"
1774 ))
1775 .unwrap();
1776 let exp_sum = PublicKey::from_slice(&hex!(
1777 "0252d73a47f66cf341e5651542f0348f452b7c793af62a6d8bff75ade703a451ad"
1778 ))
1779 .unwrap();
1780
1781 let sum1 = PublicKey::combine_keys(&[&compressed1, &compressed2, &compressed3]);
1782 assert!(sum1.is_ok());
1783 let sum2 = PublicKey::combine_keys(&[&compressed1, &compressed2, &compressed3]);
1784 assert!(sum2.is_ok());
1785 assert_eq!(sum1, sum2);
1786 assert_eq!(sum1.unwrap(), exp_sum);
1787 }
1788
1789 #[test]
1790 #[cfg(not(secp256k1_fuzz))]
1791 fn pubkey_combine_keys_empty_slice() {
1792 assert!(PublicKey::combine_keys(&[]).is_err());
1793 }
1794
1795 #[test]
1796 #[cfg(feature = "std")]
1797 fn create_pubkey_combine() {
1798 let (sk1, pk1) = crate::test_random_keypair();
1799 let (sk2, pk2) = crate::test_random_keypair();
1800
1801 let sum1 = pk1.combine(&pk2);
1802 assert!(sum1.is_ok());
1803 let sum2 = pk2.combine(&pk1);
1804 assert!(sum2.is_ok());
1805 assert_eq!(sum1, sum2);
1806
1807 let tweaked = sk1.add_tweak(&Scalar::from(sk2)).unwrap();
1808 let sksum = PublicKey::from_secret_key(&tweaked);
1809 assert_eq!(Ok(sksum), sum1);
1810 }
1811
1812 #[cfg(not(secp256k1_fuzz))]
1813 #[test]
1814 #[allow(clippy::nonminimal_bool)]
1815 fn pubkey_equal() {
1816 let pk1 = PublicKey::from_slice(&hex!(
1817 "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"
1818 ))
1819 .unwrap();
1820 let pk2 = pk1;
1821 let pk3 = PublicKey::from_slice(&hex!(
1822 "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
1823 ))
1824 .unwrap();
1825
1826 assert_eq!(pk1, pk2);
1827 assert!(pk1 <= pk2);
1828 assert!(pk2 <= pk1);
1829 assert!(!(pk2 < pk1));
1830 assert!(!(pk1 < pk2));
1831
1832 assert!(pk3 > pk1);
1833 assert!(pk1 < pk3);
1834 assert!(pk3 >= pk1);
1835 assert!(pk1 <= pk3);
1836 }
1837
1838 #[test]
1839 #[cfg(all(feature = "serde", feature = "alloc"))]
1840 fn test_serde() {
1841 use serde_test::{assert_tokens, Configure, Token};
1842 #[rustfmt::skip]
1843 static SK_BYTES: [u8; 32] = [
1844 1, 1, 1, 1, 1, 1, 1, 1,
1845 0, 1, 2, 3, 4, 5, 6, 7,
1846 0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
1847 99, 99, 99, 99, 99, 99, 99, 99
1848 ];
1849 static SK_STR: &str = "01010101010101010001020304050607ffff0000ffff00006363636363636363";
1850
1851 #[cfg(secp256k1_fuzz)]
1852 #[rustfmt::skip]
1853 static PK_BYTES: [u8; 33] = [
1854 0x02,
1855 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f,
1856 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d,
1857 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54,
1858 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66,
1859 ];
1860 static PK_STR: &str = "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
1861
1862 let sk = SecretKey::from_secret_bytes(SK_BYTES).unwrap();
1863
1864 #[cfg(not(secp256k1_fuzz))]
1867 let pk = PublicKey::from_secret_key(&sk);
1868 #[cfg(secp256k1_fuzz)]
1869 let pk = PublicKey::from_slice(&PK_BYTES).expect("pk");
1870
1871 #[rustfmt::skip]
1872 assert_tokens(&sk.compact(), &[
1873 Token::Tuple{ len: 32 },
1874 Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1),
1875 Token::U8(0), Token::U8(1), Token::U8(2), Token::U8(3), Token::U8(4), Token::U8(5), Token::U8(6), Token::U8(7),
1876 Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0), Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0),
1877 Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99),
1878 Token::TupleEnd
1879 ]);
1880
1881 assert_tokens(&sk.readable(), &[Token::BorrowedStr(SK_STR)]);
1882 assert_tokens(&sk.readable(), &[Token::Str(SK_STR)]);
1883 assert_tokens(&sk.readable(), &[Token::String(SK_STR)]);
1884
1885 #[rustfmt::skip]
1886 assert_tokens(&pk.compact(), &[
1887 Token::Tuple{ len: 33 },
1888 Token::U8(0x02),
1889 Token::U8(0x18), Token::U8(0x84), Token::U8(0x57), Token::U8(0x81), Token::U8(0xf6), Token::U8(0x31), Token::U8(0xc4), Token::U8(0x8f),
1890 Token::U8(0x1c), Token::U8(0x97), Token::U8(0x09), Token::U8(0xe2), Token::U8(0x30), Token::U8(0x92), Token::U8(0x06), Token::U8(0x7d),
1891 Token::U8(0x06), Token::U8(0x83), Token::U8(0x7f), Token::U8(0x30), Token::U8(0xaa), Token::U8(0x0c), Token::U8(0xd0), Token::U8(0x54),
1892 Token::U8(0x4a), Token::U8(0xc8), Token::U8(0x87), Token::U8(0xfe), Token::U8(0x91), Token::U8(0xdd), Token::U8(0xd1), Token::U8(0x66),
1893 Token::TupleEnd
1894 ]);
1895
1896 assert_tokens(&pk.readable(), &[Token::BorrowedStr(PK_STR)]);
1897 assert_tokens(&pk.readable(), &[Token::Str(PK_STR)]);
1898 assert_tokens(&pk.readable(), &[Token::String(PK_STR)]);
1899 }
1900
1901 #[test]
1902 #[cfg(feature = "std")]
1903 fn test_tweak_add_then_tweak_add_check() {
1904 for _ in 0..10 {
1905 let tweak = Scalar::test_random();
1906
1907 let kp = Keypair::test_random();
1908 let (xonly, _) = XOnlyPublicKey::from_keypair(&kp);
1909
1910 let tweaked_kp = kp.add_xonly_tweak(&tweak).expect("keypair tweak add failed");
1911 let (tweaked_xonly, parity) =
1912 xonly.add_tweak(&tweak).expect("xonly pubkey tweak failed");
1913
1914 let (want_tweaked_xonly, tweaked_kp_parity) = XOnlyPublicKey::from_keypair(&tweaked_kp);
1915
1916 assert_eq!(tweaked_xonly, want_tweaked_xonly);
1917 assert_eq!(parity, tweaked_kp_parity);
1918
1919 assert!(xonly.tweak_add_check(&tweaked_xonly, parity, tweak));
1920 }
1921 }
1922
1923 #[test]
1924 fn test_from_key_pubkey() {
1925 let kpk1 = PublicKey::from_str(
1926 "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
1927 )
1928 .unwrap();
1929 let kpk2 = PublicKey::from_str(
1930 "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07",
1931 )
1932 .unwrap();
1933
1934 let pk1 = XOnlyPublicKey::from(kpk1);
1935 let pk2 = XOnlyPublicKey::from(kpk2);
1936
1937 assert_eq!(pk1.serialize()[..], kpk1.serialize()[1..]);
1938 assert_eq!(pk2.serialize()[..], kpk2.serialize()[1..]);
1939 }
1940
1941 #[test]
1942 #[cfg(all(feature = "global-context", feature = "serde"))]
1943 fn test_serde_keypair() {
1944 use serde::{Deserialize, Deserializer, Serialize, Serializer};
1945 use serde_test::{assert_tokens, Configure, Token};
1946
1947 use crate::key::Keypair;
1948 use crate::SECP256K1;
1949
1950 #[rustfmt::skip]
1951 static SK_BYTES: [u8; 32] = [
1952 1, 1, 1, 1, 1, 1, 1, 1,
1953 0, 1, 2, 3, 4, 5, 6, 7,
1954 0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
1955 99, 99, 99, 99, 99, 99, 99, 99
1956 ];
1957 static SK_STR: &str = "01010101010101010001020304050607ffff0000ffff00006363636363636363";
1958
1959 let sk = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
1960 #[rustfmt::skip]
1961 assert_tokens(&sk.compact(), &[
1962 Token::Tuple{ len: 32 },
1963 Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1),
1964 Token::U8(0), Token::U8(1), Token::U8(2), Token::U8(3), Token::U8(4), Token::U8(5), Token::U8(6), Token::U8(7),
1965 Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0), Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0),
1966 Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99),
1967 Token::TupleEnd
1968 ]);
1969
1970 assert_tokens(&sk.readable(), &[Token::BorrowedStr(SK_STR)]);
1971 assert_tokens(&sk.readable(), &[Token::Str(SK_STR)]);
1972 assert_tokens(&sk.readable(), &[Token::String(SK_STR)]);
1973 }
1974
1975 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
1976 fn keys() -> (SecretKey, PublicKey, Keypair, XOnlyPublicKey) {
1977 #[rustfmt::skip]
1978 static SK_BYTES: [u8; 32] = [
1979 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1980 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1981 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
1982 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1983 ];
1984
1985 #[rustfmt::skip]
1986 static PK_BYTES: [u8; 32] = [
1987 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f,
1988 0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d,
1989 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54,
1990 0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66
1991 ];
1992
1993 let mut pk_bytes = [0u8; 33];
1994 pk_bytes[0] = 0x02; pk_bytes[1..].clone_from_slice(&PK_BYTES);
1996
1997 let sk = SecretKey::from_secret_bytes(SK_BYTES).expect("failed to parse sk bytes");
1998 let pk = PublicKey::from_slice(&pk_bytes).expect("failed to create pk from iterator");
1999 let kp = Keypair::from_secret_key(&sk);
2000 let xonly =
2001 XOnlyPublicKey::from_byte_array(PK_BYTES).expect("failed to get xonly from slice");
2002
2003 (sk, pk, kp, xonly)
2004 }
2005
2006 #[test]
2007 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2008 fn convert_public_key_to_xonly_public_key() {
2009 let (_sk, pk, _kp, want) = keys();
2010 let (got, parity) = pk.x_only_public_key();
2011
2012 assert_eq!(parity, Parity::Even);
2013 assert_eq!(got, want)
2014 }
2015
2016 #[test]
2017 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2018 fn convert_secret_key_to_public_key() {
2019 let (sk, want, _kp, _xonly) = keys();
2020 let got = sk.public_key();
2021
2022 assert_eq!(got, want)
2023 }
2024
2025 #[test]
2026 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2027 fn convert_secret_key_to_x_only_public_key() {
2028 let (sk, _pk, _kp, want) = keys();
2029 let (got, parity) = sk.x_only_public_key();
2030
2031 assert_eq!(parity, Parity::Even);
2032 assert_eq!(got, want)
2033 }
2034
2035 #[test]
2036 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2037 fn convert_keypair_to_public_key() {
2038 let (_sk, want, kp, _xonly) = keys();
2039 let got = kp.public_key();
2040
2041 assert_eq!(got, want)
2042 }
2043
2044 #[test]
2045 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2046 fn convert_keypair_to_x_only_public_key() {
2047 let (_sk, _pk, kp, want) = keys();
2048 let (got, parity) = kp.x_only_public_key();
2049
2050 assert_eq!(parity, Parity::Even);
2051 assert_eq!(got, want)
2052 }
2053
2054 #[test]
2056 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2057 fn roundtrip_secret_key_via_keypair() {
2058 let (sk, _pk, _kp, _xonly) = keys();
2059
2060 let kp = sk.keypair();
2061 let back = kp.secret_key();
2062
2063 assert_eq!(back, sk)
2064 }
2065
2066 #[test]
2068 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2069 fn roundtrip_keypair_via_secret_key() {
2070 let (_sk, _pk, kp, _xonly) = keys();
2071
2072 let sk = kp.secret_key();
2073 let back = sk.keypair();
2074
2075 assert_eq!(back, kp)
2076 }
2077
2078 #[test]
2080 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2081 fn roundtrip_x_only_public_key_via_public_key() {
2082 let (_sk, _pk, _kp, xonly) = keys();
2083
2084 let pk = xonly.public_key(Parity::Even);
2085 let (back, parity) = pk.x_only_public_key();
2086
2087 assert_eq!(parity, Parity::Even);
2088 assert_eq!(back, xonly)
2089 }
2090
2091 #[test]
2093 #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2094 fn roundtrip_public_key_via_x_only_public_key() {
2095 let (_sk, pk, _kp, _xonly) = keys();
2096
2097 let (xonly, parity) = pk.x_only_public_key();
2098 let back = xonly.public_key(parity);
2099
2100 assert_eq!(back, pk)
2101 }
2102
2103 #[test]
2104 fn public_key_from_x_only_public_key_and_odd_parity() {
2105 let s = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
2106 let mut want = String::from("03");
2107 want.push_str(s);
2108
2109 let xonly = XOnlyPublicKey::from_str(s).expect("failed to parse xonly pubkey string");
2110 let pk = xonly.public_key(Parity::Odd);
2111 let got = format!("{}", pk);
2112
2113 assert_eq!(got, want)
2114 }
2115
2116 #[test]
2117 #[cfg(not(secp256k1_fuzz))]
2118 #[cfg(all(feature = "global-context", feature = "serde"))]
2119 fn test_serde_x_only_pubkey() {
2120 use serde_test::{assert_tokens, Configure, Token};
2121
2122 #[rustfmt::skip]
2123 static SK_BYTES: [u8; 32] = [
2124 1, 1, 1, 1, 1, 1, 1, 1,
2125 0, 1, 2, 3, 4, 5, 6, 7,
2126 0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
2127 99, 99, 99, 99, 99, 99, 99, 99
2128 ];
2129
2130 static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
2131
2132 let kp = Keypair::from_seckey_byte_array(SK_BYTES).unwrap();
2133 let (pk, _parity) = XOnlyPublicKey::from_keypair(&kp);
2134
2135 #[rustfmt::skip]
2136 assert_tokens(&pk.compact(), &[
2137 Token::Tuple{ len: 32 },
2138 Token::U8(0x18), Token::U8(0x84), Token::U8(0x57), Token::U8(0x81), Token::U8(0xf6), Token::U8(0x31), Token::U8(0xc4), Token::U8(0x8f),
2139 Token::U8(0x1c), Token::U8(0x97), Token::U8(0x09), Token::U8(0xe2), Token::U8(0x30), Token::U8(0x92), Token::U8(0x06), Token::U8(0x7d),
2140 Token::U8(0x06), Token::U8(0x83), Token::U8(0x7f), Token::U8(0x30), Token::U8(0xaa), Token::U8(0x0c), Token::U8(0xd0), Token::U8(0x54),
2141 Token::U8(0x4a), Token::U8(0xc8), Token::U8(0x87), Token::U8(0xfe), Token::U8(0x91), Token::U8(0xdd), Token::U8(0xd1), Token::U8(0x66),
2142 Token::TupleEnd
2143 ]);
2144
2145 assert_tokens(&pk.readable(), &[Token::BorrowedStr(PK_STR)]);
2146 assert_tokens(&pk.readable(), &[Token::Str(PK_STR)]);
2147 assert_tokens(&pk.readable(), &[Token::String(PK_STR)]);
2148 }
2149
2150 #[test]
2151 fn test_keypair_from_str() {
2152 let keypair = Keypair::test_random();
2153 let mut buf = [0_u8; constants::SECRET_KEY_SIZE * 2]; let s = to_hex(&keypair.secret_key().to_secret_bytes(), &mut buf).unwrap();
2155 let parsed_key = Keypair::from_str(s).unwrap();
2156 assert_eq!(parsed_key, keypair);
2157 }
2158
2159 #[test]
2160 #[cfg(feature = "serde")]
2161 fn test_keypair_deserialize_serde() {
2162 let sec_key_str = "4242424242424242424242424242424242424242424242424242424242424242";
2163 let keypair = Keypair::from_str(sec_key_str).unwrap();
2164
2165 serde_test::assert_tokens(&keypair.readable(), &[Token::String(sec_key_str)]);
2166
2167 let sec_key_bytes = keypair.secret_key().to_secret_bytes();
2168 let tokens = std::iter::once(Token::Tuple { len: 32 })
2169 .chain(sec_key_bytes.iter().copied().map(Token::U8))
2170 .chain(std::iter::once(Token::TupleEnd))
2171 .collect::<Vec<_>>();
2172 serde_test::assert_tokens(&keypair.compact(), &tokens);
2173 }
2174}
2175
2176#[cfg(bench)]
2177mod benches {
2178 use std::collections::BTreeSet;
2179
2180 use test::Bencher;
2181
2182 use crate::constants::GENERATOR_X;
2183 use crate::PublicKey;
2184
2185 #[bench]
2186 fn bench_pk_ordering(b: &mut Bencher) {
2187 let mut map = BTreeSet::new();
2188 let mut g_slice = [02u8; 33];
2189 g_slice[1..].copy_from_slice(&GENERATOR_X);
2190 let g = PublicKey::from_slice(&g_slice).unwrap();
2191 let mut pk = g;
2192 b.iter(|| {
2193 map.insert(pk);
2194 pk = pk.combine(&pk).unwrap();
2195 })
2196 }
2197}