secp256k1/
key.rs

1// SPDX-License-Identifier: CC0-1.0
2
3//! Public and secret keys.
4//!
5
6use core::ops::{self, BitXor};
7use core::{fmt, ptr, str};
8
9#[cfg(feature = "serde")]
10use serde::ser::SerializeTuple;
11
12use crate::ellswift::ElligatorSwift;
13use crate::ffi::types::c_uint;
14use crate::ffi::{self, CPtr};
15use crate::Error::{self, InvalidPublicKey, InvalidPublicKeySum, InvalidSecretKey};
16#[cfg(feature = "hashes")]
17#[allow(deprecated)]
18use crate::ThirtyTwoByteHash;
19#[cfg(feature = "global-context")]
20use crate::SECP256K1;
21use crate::{
22    constants, ecdsa, from_hex, schnorr, Message, Scalar, Secp256k1, Signing, Verification,
23};
24
25/// Secret key - a 256-bit key used to create ECDSA and Taproot signatures.
26///
27/// This value should be generated using a [cryptographically secure pseudorandom number generator].
28///
29/// # Side channel attacks
30///
31/// We have attempted to reduce the side channel attack surface by implementing a constant time `eq`
32/// method. For similar reasons we explicitly do not implement `PartialOrd`, `Ord`, or `Hash` on
33/// `SecretKey`. If you really want to order secret keys then you can use `AsRef` to get at the
34/// underlying bytes and compare them - however this is almost certainly a bad idea.
35///
36/// # Serde support
37///
38/// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
39/// of 32 `u8`s for non-human-readable formats. This representation is optimal for some formats
40/// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
41///
42/// # Examples
43///
44/// Basic usage:
45///
46/// ```
47/// # #[cfg(all(feature = "rand", feature = "std"))] {
48/// use secp256k1::{rand, Secp256k1, SecretKey};
49///
50/// let secp = Secp256k1::new();
51/// let secret_key = SecretKey::new(&mut rand::rng());
52/// # }
53/// ```
54/// [`bincode`]: https://docs.rs/bincode
55/// [`cbor`]: https://docs.rs/cbor
56/// [cryptographically secure pseudorandom number generator]: https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator
57#[derive(Copy, Clone)]
58pub struct SecretKey([u8; constants::SECRET_KEY_SIZE]);
59impl_display_secret!(SecretKey);
60impl_non_secure_erase!(SecretKey, 0, [1u8; constants::SECRET_KEY_SIZE]);
61
62impl PartialEq for SecretKey {
63    /// This implementation is designed to be constant time to help prevent side channel attacks.
64    #[inline]
65    fn eq(&self, other: &Self) -> bool {
66        let accum = self.0.iter().zip(&other.0).fold(0, |accum, (a, b)| accum | a ^ b);
67        unsafe { core::ptr::read_volatile(&accum) == 0 }
68    }
69}
70
71impl Eq for SecretKey {}
72
73impl AsRef<[u8; constants::SECRET_KEY_SIZE]> for SecretKey {
74    /// Gets a reference to the underlying array.
75    ///
76    /// # Side channel attacks
77    ///
78    /// Using ordering functions (`PartialOrd`/`Ord`) on a reference to secret keys leaks data
79    /// because the implementations are not constant time. Doing so will make your code vulnerable
80    /// to side channel attacks. [`SecretKey::eq`] is implemented using a constant time algorithm,
81    /// please consider using it to do comparisons of secret keys.
82    #[inline]
83    fn as_ref(&self) -> &[u8; constants::SECRET_KEY_SIZE] {
84        let SecretKey(dat) = self;
85        dat
86    }
87}
88
89impl<I> ops::Index<I> for SecretKey
90where
91    [u8]: ops::Index<I>,
92{
93    type Output = <[u8] as ops::Index<I>>::Output;
94
95    #[inline]
96    fn index(&self, index: I) -> &Self::Output { &self.0[index] }
97}
98
99impl ffi::CPtr for SecretKey {
100    type Target = u8;
101
102    fn as_c_ptr(&self) -> *const Self::Target {
103        let SecretKey(dat) = self;
104        dat.as_ptr()
105    }
106
107    fn as_mut_c_ptr(&mut self) -> *mut Self::Target {
108        let &mut SecretKey(ref mut dat) = self;
109        dat.as_mut_ptr()
110    }
111}
112
113impl str::FromStr for SecretKey {
114    type Err = Error;
115    fn from_str(s: &str) -> Result<SecretKey, Error> {
116        let mut res = [0u8; constants::SECRET_KEY_SIZE];
117        match from_hex(s, &mut res) {
118            Ok(constants::SECRET_KEY_SIZE) => SecretKey::from_byte_array(res),
119            _ => Err(Error::InvalidSecretKey),
120        }
121    }
122}
123
124/// Public key - used to verify ECDSA signatures and to do Taproot tweaks.
125///
126/// # Serde support
127///
128/// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
129/// of 33 `u8`s for non-human-readable formats. This representation is optimal for some formats
130/// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
131///
132/// # Examples
133///
134/// Basic usage:
135///
136/// ```
137/// # #[cfg(feature =  "alloc")] {
138/// use secp256k1::{SecretKey, Secp256k1, PublicKey};
139///
140/// let secp = Secp256k1::new();
141/// let secret_key = SecretKey::from_byte_array([0xcd; 32]).expect("32 bytes, within curve order");
142/// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
143/// # }
144/// ```
145/// [`bincode`]: https://docs.rs/bincode
146/// [`cbor`]: https://docs.rs/cbor
147#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
148#[repr(transparent)]
149pub struct PublicKey(ffi::PublicKey);
150impl_fast_comparisons!(PublicKey);
151
152impl fmt::LowerHex for PublicKey {
153    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
154        let ser = self.serialize();
155        for ch in &ser[..] {
156            write!(f, "{:02x}", *ch)?;
157        }
158        Ok(())
159    }
160}
161
162impl fmt::Display for PublicKey {
163    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
164}
165
166impl fmt::Debug for PublicKey {
167    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
168}
169
170impl str::FromStr for PublicKey {
171    type Err = Error;
172    fn from_str(s: &str) -> Result<PublicKey, Error> {
173        let mut res = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
174        match from_hex(s, &mut res) {
175            Ok(constants::PUBLIC_KEY_SIZE) => {
176                let bytes: [u8; constants::PUBLIC_KEY_SIZE] =
177                    res[0..constants::PUBLIC_KEY_SIZE].try_into().unwrap();
178                PublicKey::from_byte_array_compressed(bytes)
179            }
180            Ok(constants::UNCOMPRESSED_PUBLIC_KEY_SIZE) =>
181                PublicKey::from_byte_array_uncompressed(res),
182            _ => Err(Error::InvalidPublicKey),
183        }
184    }
185}
186
187impl SecretKey {
188    /// Generates a new random secret key.
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// # #[cfg(all(feature = "std", feature =  "rand"))] {
194    /// use secp256k1::{rand, SecretKey};
195    /// let secret_key = SecretKey::new(&mut rand::rng());
196    /// # }
197    /// ```
198    #[inline]
199    #[cfg(feature = "rand")]
200    pub fn new<R: rand::Rng + ?Sized>(rng: &mut R) -> SecretKey {
201        let mut data = crate::random_32_bytes(rng);
202        unsafe {
203            while ffi::secp256k1_ec_seckey_verify(
204                ffi::secp256k1_context_no_precomp,
205                data.as_c_ptr(),
206            ) == 0
207            {
208                data = crate::random_32_bytes(rng);
209            }
210        }
211        SecretKey(data)
212    }
213
214    /// Converts a 32-byte slice to a secret key.
215    ///
216    /// # Examples
217    ///
218    /// ```
219    /// use secp256k1::SecretKey;
220    /// let sk = SecretKey::from_slice(&[0xcd; 32]).expect("32 bytes, within curve order");
221    /// ```
222    #[deprecated(since = "0.30.0", note = "Use `from_byte_array` instead.")]
223    #[inline]
224    pub fn from_slice(data: &[u8]) -> Result<SecretKey, Error> {
225        match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
226            Ok(data) => Self::from_byte_array(data),
227            Err(_) => Err(InvalidSecretKey),
228        }
229    }
230
231    /// Converts a 32-byte array to a secret key.
232    ///
233    /// # Examples
234    ///
235    /// ```
236    /// use secp256k1::SecretKey;
237    /// let sk = SecretKey::from_byte_array([0xcd; 32]).expect("32 bytes, within curve order");
238    /// ```
239    #[inline]
240    pub fn from_byte_array(data: [u8; constants::SECRET_KEY_SIZE]) -> Result<SecretKey, Error> {
241        unsafe {
242            if ffi::secp256k1_ec_seckey_verify(ffi::secp256k1_context_no_precomp, data.as_c_ptr())
243                == 0
244            {
245                return Err(InvalidSecretKey);
246            }
247        }
248        Ok(SecretKey(data))
249    }
250
251    /// Creates a new secret key using data from BIP-340 [`Keypair`].
252    ///
253    /// # Examples
254    ///
255    /// ```
256    /// # #[cfg(all(feature = "rand", feature = "std"))] {
257    /// use secp256k1::{rand, Secp256k1, SecretKey, Keypair};
258    ///
259    /// let secp = Secp256k1::new();
260    /// let keypair = Keypair::new(&secp, &mut rand::rng());
261    /// let secret_key = SecretKey::from_keypair(&keypair);
262    /// # }
263    /// ```
264    #[inline]
265    pub fn from_keypair(keypair: &Keypair) -> Self {
266        let mut sk = [0u8; constants::SECRET_KEY_SIZE];
267        unsafe {
268            let ret = ffi::secp256k1_keypair_sec(
269                ffi::secp256k1_context_no_precomp,
270                sk.as_mut_c_ptr(),
271                keypair.as_c_ptr(),
272            );
273            debug_assert_eq!(ret, 1);
274        }
275        SecretKey(sk)
276    }
277
278    /// Returns the secret key as a byte value.
279    #[inline]
280    pub fn secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] { self.0 }
281
282    /// Negates the secret key.
283    #[inline]
284    #[must_use = "you forgot to use the negated secret key"]
285    pub fn negate(mut self) -> SecretKey {
286        unsafe {
287            let res = ffi::secp256k1_ec_seckey_negate(
288                ffi::secp256k1_context_no_precomp,
289                self.as_mut_c_ptr(),
290            );
291            debug_assert_eq!(res, 1);
292        }
293        self
294    }
295
296    /// Tweaks a [`SecretKey`] by adding `tweak` modulo the curve order.
297    ///
298    /// # Errors
299    ///
300    /// Returns an error if the resulting key would be invalid.
301    #[inline]
302    pub fn add_tweak(mut self, tweak: &Scalar) -> Result<SecretKey, Error> {
303        unsafe {
304            if ffi::secp256k1_ec_seckey_tweak_add(
305                ffi::secp256k1_context_no_precomp,
306                self.as_mut_c_ptr(),
307                tweak.as_c_ptr(),
308            ) != 1
309            {
310                Err(Error::InvalidTweak)
311            } else {
312                Ok(self)
313            }
314        }
315    }
316
317    /// Tweaks a [`SecretKey`] by multiplying by `tweak` modulo the curve order.
318    ///
319    /// # Errors
320    ///
321    /// Returns an error if the resulting key would be invalid.
322    #[inline]
323    pub fn mul_tweak(mut self, tweak: &Scalar) -> Result<SecretKey, Error> {
324        unsafe {
325            if ffi::secp256k1_ec_seckey_tweak_mul(
326                ffi::secp256k1_context_no_precomp,
327                self.as_mut_c_ptr(),
328                tweak.as_c_ptr(),
329            ) != 1
330            {
331                Err(Error::InvalidTweak)
332            } else {
333                Ok(self)
334            }
335        }
336    }
337
338    /// Constructs an ECDSA signature for `msg` using the global [`SECP256K1`] context.
339    #[inline]
340    #[cfg(feature = "global-context")]
341    pub fn sign_ecdsa(&self, msg: impl Into<Message>) -> ecdsa::Signature {
342        SECP256K1.sign_ecdsa(msg, self)
343    }
344
345    /// Returns the [`Keypair`] for this [`SecretKey`].
346    ///
347    /// This is equivalent to using [`Keypair::from_secret_key`].
348    #[inline]
349    pub fn keypair<C: Signing>(&self, secp: &Secp256k1<C>) -> Keypair {
350        Keypair::from_secret_key(secp, self)
351    }
352
353    /// Returns the [`PublicKey`] for this [`SecretKey`].
354    ///
355    /// This is equivalent to using [`PublicKey::from_secret_key`].
356    #[inline]
357    pub fn public_key<C: Signing>(&self, secp: &Secp256k1<C>) -> PublicKey {
358        PublicKey::from_secret_key(secp, self)
359    }
360
361    /// Returns the [`XOnlyPublicKey`] (and its [`Parity`]) for this [`SecretKey`].
362    ///
363    /// This is equivalent to `XOnlyPublicKey::from_keypair(self.keypair(secp))`.
364    #[inline]
365    pub fn x_only_public_key<C: Signing>(&self, secp: &Secp256k1<C>) -> (XOnlyPublicKey, Parity) {
366        let kp = self.keypair(secp);
367        XOnlyPublicKey::from_keypair(&kp)
368    }
369}
370
371#[cfg(feature = "hashes")]
372#[allow(deprecated)]
373impl<T: ThirtyTwoByteHash> From<T> for SecretKey {
374    /// Converts a 32-byte hash directly to a secret key without error paths.
375    fn from(t: T) -> SecretKey {
376        SecretKey::from_byte_array(t.into_32()).expect("failed to create secret key")
377    }
378}
379
380#[cfg(feature = "serde")]
381impl serde::Serialize for SecretKey {
382    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
383        if s.is_human_readable() {
384            let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2];
385            s.serialize_str(crate::to_hex(&self.0, &mut buf).expect("fixed-size hex serialization"))
386        } else {
387            let mut tuple = s.serialize_tuple(constants::SECRET_KEY_SIZE)?;
388            for byte in self.0.iter() {
389                tuple.serialize_element(byte)?;
390            }
391            tuple.end()
392        }
393    }
394}
395
396#[cfg(feature = "serde")]
397impl<'de> serde::Deserialize<'de> for SecretKey {
398    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
399        if d.is_human_readable() {
400            d.deserialize_str(super::serde_util::FromStrVisitor::new(
401                "a hex string representing 32 byte SecretKey",
402            ))
403        } else {
404            let visitor = super::serde_util::Tuple32Visitor::new(
405                "raw 32 bytes SecretKey",
406                SecretKey::from_byte_array,
407            );
408            d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor)
409        }
410    }
411}
412
413impl PublicKey {
414    /// Obtains a raw const pointer suitable for use with FFI functions.
415    #[inline]
416    #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
417    pub fn as_ptr(&self) -> *const ffi::PublicKey { self.as_c_ptr() }
418
419    /// Obtains a raw mutable pointer suitable for use with FFI functions.
420    #[inline]
421    #[deprecated(
422        since = "0.25.0",
423        note = "Use Self::as_mut_c_ptr if you need to access the FFI layer"
424    )]
425    pub fn as_mut_ptr(&mut self) -> *mut ffi::PublicKey { self.as_mut_c_ptr() }
426
427    /// Creates a new public key from a [`SecretKey`].
428    ///
429    /// # Examples
430    ///
431    /// ```
432    /// # #[cfg(all(feature = "rand", feature = "std"))] {
433    /// use secp256k1::{rand, Secp256k1, SecretKey, PublicKey};
434    ///
435    /// let secp = Secp256k1::new();
436    /// let secret_key = SecretKey::new(&mut rand::rng());
437    /// let public_key = PublicKey::from_secret_key(&secp, &secret_key);
438    /// # }
439    /// ```
440    #[inline]
441    pub fn from_secret_key<C: Signing>(secp: &Secp256k1<C>, sk: &SecretKey) -> PublicKey {
442        unsafe {
443            let mut pk = ffi::PublicKey::new();
444            // We can assume the return value because it's not possible to construct
445            // an invalid `SecretKey` without transmute trickery or something.
446            let res = ffi::secp256k1_ec_pubkey_create(secp.ctx.as_ptr(), &mut pk, sk.as_c_ptr());
447            debug_assert_eq!(res, 1);
448            PublicKey(pk)
449        }
450    }
451    /// Creates a new public key from an [`ElligatorSwift`].
452    #[inline]
453    pub fn from_ellswift(ellswift: ElligatorSwift) -> PublicKey { ElligatorSwift::decode(ellswift) }
454
455    /// Creates a new public key from a [`SecretKey`] and the global [`SECP256K1`] context.
456    #[inline]
457    #[cfg(feature = "global-context")]
458    pub fn from_secret_key_global(sk: &SecretKey) -> PublicKey {
459        PublicKey::from_secret_key(SECP256K1, sk)
460    }
461
462    /// Creates a public key directly from a slice.
463    #[inline]
464    pub fn from_slice(data: &[u8]) -> Result<PublicKey, Error> {
465        match data.len() {
466            constants::PUBLIC_KEY_SIZE => PublicKey::from_byte_array_compressed(
467                <[u8; constants::PUBLIC_KEY_SIZE]>::try_from(data).unwrap(),
468            ),
469            constants::UNCOMPRESSED_PUBLIC_KEY_SIZE => PublicKey::from_byte_array_uncompressed(
470                <[u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]>::try_from(data).unwrap(),
471            ),
472            _ => Err(InvalidPublicKey),
473        }
474    }
475
476    /// Creates a public key from a serialized array in compressed format.
477    #[inline]
478    pub fn from_byte_array_compressed(
479        data: [u8; constants::PUBLIC_KEY_SIZE],
480    ) -> Result<PublicKey, Error> {
481        unsafe {
482            let mut pk = ffi::PublicKey::new();
483            if ffi::secp256k1_ec_pubkey_parse(
484                ffi::secp256k1_context_no_precomp,
485                &mut pk,
486                data.as_c_ptr(),
487                constants::PUBLIC_KEY_SIZE,
488            ) == 1
489            {
490                Ok(PublicKey(pk))
491            } else {
492                Err(InvalidPublicKey)
493            }
494        }
495    }
496
497    /// Creates a public key from a serialized array in uncompressed format.
498    #[inline]
499    pub fn from_byte_array_uncompressed(
500        data: [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE],
501    ) -> Result<PublicKey, Error> {
502        unsafe {
503            let mut pk = ffi::PublicKey::new();
504            if ffi::secp256k1_ec_pubkey_parse(
505                ffi::secp256k1_context_no_precomp,
506                &mut pk,
507                data.as_c_ptr(),
508                constants::UNCOMPRESSED_PUBLIC_KEY_SIZE,
509            ) == 1
510            {
511                Ok(PublicKey(pk))
512            } else {
513                Err(InvalidPublicKey)
514            }
515        }
516    }
517
518    /// Creates a new compressed public key using data from BIP-340 [`Keypair`].
519    ///
520    /// # Examples
521    ///
522    /// ```
523    /// # #[cfg(all(feature = "rand", feature = "std"))] {
524    /// use secp256k1::{rand, Secp256k1, PublicKey, Keypair};
525    ///
526    /// let secp = Secp256k1::new();
527    /// let keypair = Keypair::new(&secp, &mut rand::rng());
528    /// let public_key = PublicKey::from_keypair(&keypair);
529    /// # }
530    /// ```
531    #[inline]
532    pub fn from_keypair(keypair: &Keypair) -> Self {
533        unsafe {
534            let mut pk = ffi::PublicKey::new();
535            let ret = ffi::secp256k1_keypair_pub(
536                ffi::secp256k1_context_no_precomp,
537                &mut pk,
538                keypair.as_c_ptr(),
539            );
540            debug_assert_eq!(ret, 1);
541            PublicKey(pk)
542        }
543    }
544
545    /// Creates a [`PublicKey`] using the key material from `pk` combined with the `parity`.
546    pub fn from_x_only_public_key(pk: XOnlyPublicKey, parity: Parity) -> PublicKey {
547        let mut buf = [0u8; 33];
548
549        // First byte of a compressed key should be `0x02 AND parity`.
550        buf[0] = match parity {
551            Parity::Even => 0x02,
552            Parity::Odd => 0x03,
553        };
554        buf[1..].clone_from_slice(&pk.serialize());
555
556        PublicKey::from_byte_array_compressed(buf).expect("we know the buffer is valid")
557    }
558
559    #[inline]
560    /// Serializes the key as a byte-encoded pair of values. In compressed form the y-coordinate is
561    /// represented by only a single bit, as x determines it up to one bit.
562    pub fn serialize(&self) -> [u8; constants::PUBLIC_KEY_SIZE] {
563        let mut ret = [0u8; constants::PUBLIC_KEY_SIZE];
564        self.serialize_internal(&mut ret, ffi::SECP256K1_SER_COMPRESSED);
565        ret
566    }
567
568    #[inline]
569    /// Serializes the key as a byte-encoded pair of values, in uncompressed form.
570    pub fn serialize_uncompressed(&self) -> [u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE] {
571        let mut ret = [0u8; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE];
572        self.serialize_internal(&mut ret, ffi::SECP256K1_SER_UNCOMPRESSED);
573        ret
574    }
575
576    #[inline(always)]
577    fn serialize_internal(&self, ret: &mut [u8], flag: c_uint) {
578        let mut ret_len = ret.len();
579        let res = unsafe {
580            ffi::secp256k1_ec_pubkey_serialize(
581                ffi::secp256k1_context_no_precomp,
582                ret.as_mut_c_ptr(),
583                &mut ret_len,
584                self.as_c_ptr(),
585                flag,
586            )
587        };
588        debug_assert_eq!(res, 1);
589        debug_assert_eq!(ret_len, ret.len());
590    }
591
592    /// Negates the public key.
593    #[inline]
594    #[must_use = "you forgot to use the negated public key"]
595    pub fn negate<C: Verification>(mut self, secp: &Secp256k1<C>) -> PublicKey {
596        unsafe {
597            let res = ffi::secp256k1_ec_pubkey_negate(secp.ctx.as_ptr(), &mut self.0);
598            debug_assert_eq!(res, 1);
599        }
600        self
601    }
602
603    /// Tweaks a [`PublicKey`] by adding `tweak * G` modulo the curve order.
604    ///
605    /// # Errors
606    ///
607    /// Returns an error if the resulting key would be invalid.
608    #[inline]
609    pub fn add_exp_tweak<C: Verification>(
610        mut self,
611        secp: &Secp256k1<C>,
612        tweak: &Scalar,
613    ) -> Result<PublicKey, Error> {
614        unsafe {
615            if ffi::secp256k1_ec_pubkey_tweak_add(secp.ctx.as_ptr(), &mut self.0, tweak.as_c_ptr())
616                == 1
617            {
618                Ok(self)
619            } else {
620                Err(Error::InvalidTweak)
621            }
622        }
623    }
624
625    /// Tweaks a [`PublicKey`] by multiplying by `tweak` modulo the curve order.
626    ///
627    /// # Errors
628    ///
629    /// Returns an error if the resulting key would be invalid.
630    #[inline]
631    pub fn mul_tweak<C: Verification>(
632        mut self,
633        secp: &Secp256k1<C>,
634        other: &Scalar,
635    ) -> Result<PublicKey, Error> {
636        unsafe {
637            if ffi::secp256k1_ec_pubkey_tweak_mul(secp.ctx.as_ptr(), &mut self.0, other.as_c_ptr())
638                == 1
639            {
640                Ok(self)
641            } else {
642                Err(Error::InvalidTweak)
643            }
644        }
645    }
646
647    /// Adds a second key to this one, returning the sum.
648    ///
649    /// # Errors
650    ///
651    /// If the result would be the point at infinity, i.e. adding this point to its own negation.
652    ///
653    /// # Examples
654    ///
655    /// ```
656    /// # #[cfg(all(feature = "rand", feature = "std"))] {
657    /// use secp256k1::{rand, Secp256k1};
658    ///
659    /// let secp = Secp256k1::new();
660    /// let mut rng = rand::rng();
661    /// let (_, pk1) = secp.generate_keypair(&mut rng);
662    /// let (_, pk2) = secp.generate_keypair(&mut rng);
663    /// let sum = pk1.combine(&pk2).expect("It's improbable to fail for 2 random public keys");
664    /// # }
665    /// ```
666    pub fn combine(&self, other: &PublicKey) -> Result<PublicKey, Error> {
667        PublicKey::combine_keys(&[self, other])
668    }
669
670    /// Adds the keys in the provided slice together, returning the sum.
671    ///
672    /// # Errors
673    ///
674    /// Errors under any of the following conditions:
675    /// - The result would be the point at infinity, i.e. adding a point to its own negation.
676    /// - The provided slice is empty.
677    /// - The number of elements in the provided slice is greater than `i32::MAX`.
678    ///
679    /// # Examples
680    ///
681    /// ```
682    /// # #[cfg(all(feature = "rand", feature = "std"))] {
683    /// use secp256k1::{rand, Secp256k1, PublicKey};
684    ///
685    /// let secp = Secp256k1::new();
686    /// let mut rng = rand::rng();
687    /// let (_, pk1) = secp.generate_keypair(&mut rng);
688    /// let (_, pk2) = secp.generate_keypair(&mut rng);
689    /// let (_, pk3) = secp.generate_keypair(&mut rng);
690    /// let sum = PublicKey::combine_keys(&[&pk1, &pk2, &pk3]).expect("It's improbable to fail for 3 random public keys");
691    /// # }
692    /// ```
693    pub fn combine_keys(keys: &[&PublicKey]) -> Result<PublicKey, Error> {
694        use core::mem::transmute;
695
696        if keys.is_empty() || keys.len() > i32::MAX as usize {
697            return Err(InvalidPublicKeySum);
698        }
699
700        unsafe {
701            let mut ret = ffi::PublicKey::new();
702            let ptrs: &[*const ffi::PublicKey] =
703                transmute::<&[&PublicKey], &[*const ffi::PublicKey]>(keys);
704            if ffi::secp256k1_ec_pubkey_combine(
705                ffi::secp256k1_context_no_precomp,
706                &mut ret,
707                ptrs.as_c_ptr(),
708                keys.len(),
709            ) == 1
710            {
711                Ok(PublicKey(ret))
712            } else {
713                Err(InvalidPublicKeySum)
714            }
715        }
716    }
717
718    /// Returns the [`XOnlyPublicKey`] (and its [`Parity`]) for this [`PublicKey`].
719    #[inline]
720    pub fn x_only_public_key(&self) -> (XOnlyPublicKey, Parity) {
721        let mut pk_parity = 0;
722        unsafe {
723            let mut xonly_pk = ffi::XOnlyPublicKey::new();
724            let ret = ffi::secp256k1_xonly_pubkey_from_pubkey(
725                ffi::secp256k1_context_no_precomp,
726                &mut xonly_pk,
727                &mut pk_parity,
728                self.as_c_ptr(),
729            );
730            debug_assert_eq!(ret, 1);
731            let parity =
732                Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1");
733
734            (XOnlyPublicKey(xonly_pk), parity)
735        }
736    }
737
738    /// Checks that `sig` is a valid ECDSA signature for `msg` using this public key.
739    pub fn verify<C: Verification>(
740        &self,
741        secp: &Secp256k1<C>,
742        msg: impl Into<Message>,
743        sig: &ecdsa::Signature,
744    ) -> Result<(), Error> {
745        secp.verify_ecdsa(msg, sig, self)
746    }
747}
748
749/// This trait enables interaction with the FFI layer and even though it is part of the public API
750/// normal users should never need to directly interact with FFI types.
751impl CPtr for PublicKey {
752    type Target = ffi::PublicKey;
753
754    /// Obtains a const pointer suitable for use with FFI functions.
755    fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
756
757    /// Obtains a mutable pointer suitable for use with FFI functions.
758    fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
759}
760
761/// Creates a new public key from a FFI public key.
762///
763/// Note, normal users should never need to interact directly with FFI types.
764impl From<ffi::PublicKey> for PublicKey {
765    #[inline]
766    fn from(pk: ffi::PublicKey) -> PublicKey { PublicKey(pk) }
767}
768
769#[cfg(feature = "serde")]
770impl serde::Serialize for PublicKey {
771    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
772        if s.is_human_readable() {
773            s.collect_str(self)
774        } else {
775            let mut tuple = s.serialize_tuple(constants::PUBLIC_KEY_SIZE)?;
776            // Serialize in compressed form.
777            for byte in self.serialize().iter() {
778                tuple.serialize_element(&byte)?;
779            }
780            tuple.end()
781        }
782    }
783}
784
785#[cfg(feature = "serde")]
786impl<'de> serde::Deserialize<'de> for PublicKey {
787    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<PublicKey, D::Error> {
788        if d.is_human_readable() {
789            d.deserialize_str(super::serde_util::FromStrVisitor::new(
790                "an ASCII hex string representing a public key",
791            ))
792        } else {
793            let visitor = super::serde_util::Tuple33Visitor::new(
794                "33 bytes compressed public key",
795                PublicKey::from_byte_array_compressed,
796            );
797            d.deserialize_tuple(constants::PUBLIC_KEY_SIZE, visitor)
798        }
799    }
800}
801
802/// Opaque data structure that holds a keypair consisting of a secret and a public key.
803///
804/// # Serde support
805///
806/// Implements de/serialization with the `serde` and `global-context` features enabled. Serializes
807/// the secret bytes only. We treat the byte value as a tuple of 32 `u8`s for non-human-readable
808/// formats. This representation is optimal for some formats (e.g. [`bincode`]) however other
809/// formats may be less optimal (e.g. [`cbor`]). For human-readable formats we use a hex string.
810///
811/// # Examples
812///
813/// Basic usage:
814///
815/// ```
816/// # #[cfg(all(feature = "rand", feature = "std"))] {
817/// use secp256k1::{rand, Keypair, Secp256k1};
818///
819/// let secp = Secp256k1::new();
820/// let (secret_key, public_key) = secp.generate_keypair(&mut rand::rng());
821/// let keypair = Keypair::from_secret_key(&secp, &secret_key);
822/// # }
823/// ```
824/// [`bincode`]: https://docs.rs/bincode
825/// [`cbor`]: https://docs.rs/cbor
826#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
827pub struct Keypair(ffi::Keypair);
828impl_fast_comparisons!(Keypair);
829
830impl Keypair {
831    /// Obtains a raw const pointer suitable for use with FFI functions.
832    #[inline]
833    #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
834    pub fn as_ptr(&self) -> *const ffi::Keypair { self.as_c_ptr() }
835
836    /// Obtains a raw mutable pointer suitable for use with FFI functions.
837    #[inline]
838    #[deprecated(
839        since = "0.25.0",
840        note = "Use Self::as_mut_c_ptr if you need to access the FFI layer"
841    )]
842    pub fn as_mut_ptr(&mut self) -> *mut ffi::Keypair { self.as_mut_c_ptr() }
843
844    /// Creates a [`Keypair`] directly from a Secp256k1 secret key.
845    #[inline]
846    pub fn from_secret_key<C: Signing>(secp: &Secp256k1<C>, sk: &SecretKey) -> Keypair {
847        unsafe {
848            let mut kp = ffi::Keypair::new();
849            if ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, sk.as_c_ptr()) == 1 {
850                Keypair(kp)
851            } else {
852                panic!("the provided secret key is invalid: it is corrupted or was not produced by Secp256k1 library")
853            }
854        }
855    }
856
857    /// Creates a [`Keypair`] directly from a secret key slice.
858    ///
859    /// # Errors
860    ///
861    /// [`Error::InvalidSecretKey`] if the slice is not exactly 32 bytes long,
862    /// or if the encoded number is an invalid scalar.
863    #[deprecated(since = "0.31.0", note = "Use `from_seckey_byte_array` instead.")]
864    #[inline]
865    pub fn from_seckey_slice<C: Signing>(
866        secp: &Secp256k1<C>,
867        data: &[u8],
868    ) -> Result<Keypair, Error> {
869        match <[u8; constants::SECRET_KEY_SIZE]>::try_from(data) {
870            Ok(data) => Self::from_seckey_byte_array(secp, data),
871            Err(_) => Err(Error::InvalidSecretKey),
872        }
873    }
874
875    /// Creates a [`Keypair`] directly from a secret key byte array.
876    ///
877    /// # Errors
878    ///
879    /// [`Error::InvalidSecretKey`] if the encoded number is an invalid scalar.
880    #[inline]
881    pub fn from_seckey_byte_array<C: Signing>(
882        secp: &Secp256k1<C>,
883        data: [u8; constants::SECRET_KEY_SIZE],
884    ) -> Result<Keypair, Error> {
885        unsafe {
886            let mut kp = ffi::Keypair::new();
887            if ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut kp, data.as_c_ptr()) == 1 {
888                Ok(Keypair(kp))
889            } else {
890                Err(Error::InvalidSecretKey)
891            }
892        }
893    }
894
895    /// Creates a [`Keypair`] directly from a secret key string.
896    ///
897    /// # Errors
898    ///
899    /// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
900    /// or if the encoded number is an invalid scalar.
901    #[inline]
902    pub fn from_seckey_str<C: Signing>(secp: &Secp256k1<C>, s: &str) -> Result<Keypair, Error> {
903        let mut res = [0u8; constants::SECRET_KEY_SIZE];
904        match from_hex(s, &mut res) {
905            Ok(constants::SECRET_KEY_SIZE) => Keypair::from_seckey_byte_array(secp, res),
906            _ => Err(Error::InvalidSecretKey),
907        }
908    }
909
910    /// Creates a [`Keypair`] directly from a secret key string and the global [`SECP256K1`] context.
911    ///
912    /// # Errors
913    ///
914    /// [`Error::InvalidSecretKey`] if the string does not consist of exactly 64 hex characters,
915    /// or if the encoded number is an invalid scalar.
916    #[inline]
917    #[cfg(feature = "global-context")]
918    pub fn from_seckey_str_global(s: &str) -> Result<Keypair, Error> {
919        Keypair::from_seckey_str(SECP256K1, s)
920    }
921
922    /// Generates a new random key pair.
923    /// # Examples
924    ///
925    /// ```
926    /// # #[cfg(all(feature = "rand", feature = "std"))] {
927    /// use secp256k1::{rand, Secp256k1, SecretKey, Keypair};
928    ///
929    /// let secp = Secp256k1::new();
930    /// let keypair = Keypair::new(&secp, &mut rand::rng());
931    /// # }
932    /// ```
933    #[inline]
934    #[cfg(feature = "rand")]
935    pub fn new<R: rand::Rng + ?Sized, C: Signing>(secp: &Secp256k1<C>, rng: &mut R) -> Keypair {
936        let mut data = crate::random_32_bytes(rng);
937        unsafe {
938            let mut keypair = ffi::Keypair::new();
939            while ffi::secp256k1_keypair_create(secp.ctx.as_ptr(), &mut keypair, data.as_c_ptr())
940                == 0
941            {
942                data = crate::random_32_bytes(rng);
943            }
944            Keypair(keypair)
945        }
946    }
947
948    /// Generates a new random secret key using the global [`SECP256K1`] context.
949    #[inline]
950    #[cfg(all(feature = "global-context", feature = "rand"))]
951    pub fn new_global<R: ::rand::Rng + ?Sized>(rng: &mut R) -> Keypair {
952        Keypair::new(SECP256K1, rng)
953    }
954
955    /// Returns the secret bytes for this key pair.
956    #[inline]
957    pub fn secret_bytes(&self) -> [u8; constants::SECRET_KEY_SIZE] {
958        *SecretKey::from_keypair(self).as_ref()
959    }
960
961    /// Tweaks a keypair by first converting the public key to an xonly key and tweaking it.
962    ///
963    /// # Errors
964    ///
965    /// Returns an error if the resulting key would be invalid.
966    ///
967    /// NB: Will not error if the tweaked public key has an odd value and can't be used for
968    ///     BIP 340-342 purposes.
969    ///
970    /// # Examples
971    ///
972    /// ```
973    /// # #[cfg(all(feature = "rand", feature = "std"))] {
974    /// use secp256k1::{Secp256k1, Keypair, Scalar};
975    ///
976    /// let secp = Secp256k1::new();
977    /// let tweak = Scalar::random();
978    ///
979    /// let mut keypair = Keypair::new(&secp, &mut rand::rng());
980    /// let tweaked = keypair.add_xonly_tweak(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
981    /// # }
982    /// ```
983    // TODO: Add checked implementation
984    #[inline]
985    pub fn add_xonly_tweak<C: Verification>(
986        mut self,
987        secp: &Secp256k1<C>,
988        tweak: &Scalar,
989    ) -> Result<Keypair, Error> {
990        unsafe {
991            let err = ffi::secp256k1_keypair_xonly_tweak_add(
992                secp.ctx.as_ptr(),
993                &mut self.0,
994                tweak.as_c_ptr(),
995            );
996            if err != 1 {
997                return Err(Error::InvalidTweak);
998            }
999
1000            Ok(self)
1001        }
1002    }
1003
1004    /// Returns the [`SecretKey`] for this [`Keypair`].
1005    ///
1006    /// This is equivalent to using [`SecretKey::from_keypair`].
1007    #[inline]
1008    pub fn secret_key(&self) -> SecretKey { SecretKey::from_keypair(self) }
1009
1010    /// Returns the [`PublicKey`] for this [`Keypair`].
1011    ///
1012    /// This is equivalent to using [`PublicKey::from_keypair`].
1013    #[inline]
1014    pub fn public_key(&self) -> PublicKey { PublicKey::from_keypair(self) }
1015
1016    /// Returns the [`XOnlyPublicKey`] (and its [`Parity`]) for this [`Keypair`].
1017    ///
1018    /// This is equivalent to using [`XOnlyPublicKey::from_keypair`].
1019    #[inline]
1020    pub fn x_only_public_key(&self) -> (XOnlyPublicKey, Parity) {
1021        XOnlyPublicKey::from_keypair(self)
1022    }
1023
1024    /// Constructs a schnorr signature for `msg` using the global [`SECP256K1`] context.
1025    #[inline]
1026    #[cfg(all(feature = "global-context", feature = "rand", feature = "std"))]
1027    pub fn sign_schnorr(&self, msg: &[u8]) -> schnorr::Signature {
1028        SECP256K1.sign_schnorr(msg, self)
1029    }
1030
1031    /// Constructs a schnorr signature without aux rand for `msg` using the global
1032    /// [`SECP256K1`] context.
1033    #[inline]
1034    #[cfg(all(feature = "global-context", feature = "std"))]
1035    pub fn sign_schnorr_no_aux_rand(&self, msg: &[u8]) -> schnorr::Signature {
1036        SECP256K1.sign_schnorr_no_aux_rand(msg, self)
1037    }
1038
1039    /// Attempts to erase the secret within the underlying array.
1040    ///
1041    /// Note, however, that the compiler is allowed to freely copy or move the contents
1042    /// of this array to other places in memory. Preventing this behavior is very subtle.
1043    /// For more discussion on this, please see the documentation of the
1044    /// [`zeroize`](https://docs.rs/zeroize) crate.
1045    #[inline]
1046    pub fn non_secure_erase(&mut self) { self.0.non_secure_erase(); }
1047}
1048
1049impl fmt::Debug for Keypair {
1050    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
1051        f.debug_struct("Keypair")
1052            .field("pubkey", &self.public_key())
1053            .field("secret", &"<hidden>")
1054            .finish()
1055    }
1056}
1057
1058impl From<Keypair> for SecretKey {
1059    #[inline]
1060    fn from(pair: Keypair) -> Self { SecretKey::from_keypair(&pair) }
1061}
1062
1063impl<'a> From<&'a Keypair> for SecretKey {
1064    #[inline]
1065    fn from(pair: &'a Keypair) -> Self { SecretKey::from_keypair(pair) }
1066}
1067
1068impl From<Keypair> for PublicKey {
1069    #[inline]
1070    fn from(pair: Keypair) -> Self { PublicKey::from_keypair(&pair) }
1071}
1072
1073impl<'a> From<&'a Keypair> for PublicKey {
1074    #[inline]
1075    fn from(pair: &'a Keypair) -> Self { PublicKey::from_keypair(pair) }
1076}
1077
1078#[cfg(any(feature = "global-context", feature = "alloc"))]
1079impl str::FromStr for Keypair {
1080    type Err = Error;
1081
1082    #[allow(unused_variables, unreachable_code)] // When built with no default features.
1083    fn from_str(s: &str) -> Result<Self, Self::Err> {
1084        #[cfg(feature = "global-context")]
1085        let ctx = SECP256K1;
1086
1087        #[cfg(all(not(feature = "global-context"), feature = "alloc"))]
1088        let ctx = Secp256k1::signing_only();
1089
1090        #[allow(clippy::needless_borrow)]
1091        Keypair::from_seckey_str(&ctx, s)
1092    }
1093}
1094
1095#[cfg(feature = "serde")]
1096impl serde::Serialize for Keypair {
1097    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1098        if s.is_human_readable() {
1099            let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2];
1100            s.serialize_str(
1101                crate::to_hex(&self.secret_bytes(), &mut buf)
1102                    .expect("fixed-size hex serialization"),
1103            )
1104        } else {
1105            let mut tuple = s.serialize_tuple(constants::SECRET_KEY_SIZE)?;
1106            for byte in self.secret_bytes().iter() {
1107                tuple.serialize_element(&byte)?;
1108            }
1109            tuple.end()
1110        }
1111    }
1112}
1113
1114#[cfg(feature = "serde")]
1115#[allow(unused_variables)] // For `data` under some feature combinations (the unconditional panic below).
1116#[cfg(all(feature = "serde", any(feature = "global-context", feature = "alloc")))]
1117impl<'de> serde::Deserialize<'de> for Keypair {
1118    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
1119        if d.is_human_readable() {
1120            d.deserialize_str(super::serde_util::FromStrVisitor::new(
1121                "a hex string representing 32 byte Keypair",
1122            ))
1123        } else {
1124            let visitor = super::serde_util::Tuple32Visitor::new("raw 32 bytes Keypair", |data| {
1125                #[cfg(feature = "global-context")]
1126                let ctx = SECP256K1;
1127
1128                #[cfg(all(not(feature = "global-context"), feature = "alloc"))]
1129                let ctx = Secp256k1::signing_only();
1130
1131                #[allow(clippy::needless_borrow)]
1132                Keypair::from_seckey_byte_array(&ctx, data)
1133            });
1134            d.deserialize_tuple(constants::SECRET_KEY_SIZE, visitor)
1135        }
1136    }
1137}
1138
1139impl CPtr for Keypair {
1140    type Target = ffi::Keypair;
1141    fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
1142
1143    fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
1144}
1145
1146/// An x-only public key, used for verification of Taproot signatures and serialized according to BIP-340.
1147///
1148/// # Serde support
1149///
1150/// Implements de/serialization with the `serde` feature enabled. We treat the byte value as a tuple
1151/// of 32 `u8`s for non-human-readable formats. This representation is optimal for some formats
1152/// (e.g. [`bincode`]) however other formats may be less optimal (e.g. [`cbor`]).
1153///
1154/// # Examples
1155///
1156/// Basic usage:
1157///
1158/// ```
1159/// # #[cfg(all(feature = "rand", feature = "std"))] {
1160/// use secp256k1::{rand, Secp256k1, Keypair, XOnlyPublicKey};
1161///
1162/// let secp = Secp256k1::new();
1163/// let keypair = Keypair::new(&secp, &mut rand::rng());
1164/// let xonly = XOnlyPublicKey::from_keypair(&keypair);
1165/// # }
1166/// ```
1167/// [`bincode`]: https://docs.rs/bincode
1168/// [`cbor`]: https://docs.rs/cbor
1169#[derive(Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
1170pub struct XOnlyPublicKey(ffi::XOnlyPublicKey);
1171impl_fast_comparisons!(XOnlyPublicKey);
1172
1173impl fmt::LowerHex for XOnlyPublicKey {
1174    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1175        let ser = self.serialize();
1176        for ch in &ser[..] {
1177            write!(f, "{:02x}", *ch)?;
1178        }
1179        Ok(())
1180    }
1181}
1182
1183impl fmt::Display for XOnlyPublicKey {
1184    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
1185}
1186
1187impl fmt::Debug for XOnlyPublicKey {
1188    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
1189}
1190
1191impl str::FromStr for XOnlyPublicKey {
1192    type Err = Error;
1193    fn from_str(s: &str) -> Result<XOnlyPublicKey, Error> {
1194        let mut res = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
1195        match from_hex(s, &mut res) {
1196            Ok(constants::SCHNORR_PUBLIC_KEY_SIZE) => XOnlyPublicKey::from_byte_array(res),
1197            _ => Err(Error::InvalidPublicKey),
1198        }
1199    }
1200}
1201
1202impl XOnlyPublicKey {
1203    /// Obtains a raw const pointer suitable for use with FFI functions.
1204    #[inline]
1205    #[deprecated(since = "0.25.0", note = "Use Self::as_c_ptr if you need to access the FFI layer")]
1206    pub fn as_ptr(&self) -> *const ffi::XOnlyPublicKey { self.as_c_ptr() }
1207
1208    /// Obtains a raw mutable pointer suitable for use with FFI functions.
1209    #[inline]
1210    #[deprecated(
1211        since = "0.25.0",
1212        note = "Use Self::as_mut_c_ptr if you need to access the FFI layer"
1213    )]
1214    pub fn as_mut_ptr(&mut self) -> *mut ffi::XOnlyPublicKey { self.as_mut_c_ptr() }
1215
1216    /// Returns the [`XOnlyPublicKey`] (and its [`Parity`]) for `keypair`.
1217    #[inline]
1218    pub fn from_keypair(keypair: &Keypair) -> (XOnlyPublicKey, Parity) {
1219        let mut pk_parity = 0;
1220        unsafe {
1221            let mut xonly_pk = ffi::XOnlyPublicKey::new();
1222            let ret = ffi::secp256k1_keypair_xonly_pub(
1223                ffi::secp256k1_context_no_precomp,
1224                &mut xonly_pk,
1225                &mut pk_parity,
1226                keypair.as_c_ptr(),
1227            );
1228            debug_assert_eq!(ret, 1);
1229            let parity =
1230                Parity::from_i32(pk_parity).expect("should not panic, pk_parity is 0 or 1");
1231
1232            (XOnlyPublicKey(xonly_pk), parity)
1233        }
1234    }
1235
1236    /// Creates a schnorr public key directly from a slice.
1237    ///
1238    /// # Errors
1239    ///
1240    /// Returns [`Error::InvalidPublicKey`] if the length of the data slice is not 32 bytes or the
1241    /// slice does not represent a valid Secp256k1 point x coordinate.
1242    #[deprecated(since = "0.30.0", note = "Use `from_byte_array` instead.")]
1243    #[inline]
1244    pub fn from_slice(data: &[u8]) -> Result<XOnlyPublicKey, Error> {
1245        match <[u8; constants::SCHNORR_PUBLIC_KEY_SIZE]>::try_from(data) {
1246            Ok(data) => Self::from_byte_array(data),
1247            Err(_) => Err(InvalidPublicKey),
1248        }
1249    }
1250
1251    /// Creates a schnorr public key directly from a byte array.
1252    ///
1253    /// # Errors
1254    ///
1255    /// Returns [`Error::InvalidPublicKey`] if the array does not represent a valid Secp256k1 point
1256    /// x coordinate.
1257    #[inline]
1258    pub fn from_byte_array(
1259        data: [u8; constants::SCHNORR_PUBLIC_KEY_SIZE],
1260    ) -> Result<XOnlyPublicKey, Error> {
1261        unsafe {
1262            let mut pk = ffi::XOnlyPublicKey::new();
1263            if ffi::secp256k1_xonly_pubkey_parse(
1264                ffi::secp256k1_context_no_precomp,
1265                &mut pk,
1266                data.as_c_ptr(),
1267            ) == 1
1268            {
1269                Ok(XOnlyPublicKey(pk))
1270            } else {
1271                Err(Error::InvalidPublicKey)
1272            }
1273        }
1274    }
1275
1276    #[inline]
1277    /// Serializes the key as a byte-encoded x coordinate value (32 bytes).
1278    pub fn serialize(&self) -> [u8; constants::SCHNORR_PUBLIC_KEY_SIZE] {
1279        let mut ret = [0u8; constants::SCHNORR_PUBLIC_KEY_SIZE];
1280
1281        unsafe {
1282            let err = ffi::secp256k1_xonly_pubkey_serialize(
1283                ffi::secp256k1_context_no_precomp,
1284                ret.as_mut_c_ptr(),
1285                self.as_c_ptr(),
1286            );
1287            debug_assert_eq!(err, 1);
1288        }
1289        ret
1290    }
1291
1292    /// Tweaks an [`XOnlyPublicKey`] by adding the generator multiplied with the given tweak to it.
1293    ///
1294    /// # Returns
1295    ///
1296    /// The newly tweaked key plus an opaque type representing the parity of the tweaked key, this
1297    /// should be provided to `tweak_add_check` which can be used to verify a tweak more efficiently
1298    /// than regenerating it and checking equality.
1299    ///
1300    /// # Errors
1301    ///
1302    /// If the resulting key would be invalid.
1303    ///
1304    /// # Examples
1305    ///
1306    /// ```
1307    /// # #[cfg(all(feature = "rand", feature = "std"))] {
1308    /// use secp256k1::{Secp256k1, Keypair, Scalar, XOnlyPublicKey};
1309    ///
1310    /// let secp = Secp256k1::new();
1311    /// let tweak = Scalar::random();
1312    ///
1313    /// let mut keypair = Keypair::new(&secp, &mut rand::rng());
1314    /// let (xonly, _parity) = keypair.x_only_public_key();
1315    /// let tweaked = xonly.add_tweak(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
1316    /// # }
1317    /// ```
1318    pub fn add_tweak<V: Verification>(
1319        mut self,
1320        secp: &Secp256k1<V>,
1321        tweak: &Scalar,
1322    ) -> Result<(XOnlyPublicKey, Parity), Error> {
1323        let mut pk_parity = 0;
1324        unsafe {
1325            let mut pubkey = ffi::PublicKey::new();
1326            let mut err = ffi::secp256k1_xonly_pubkey_tweak_add(
1327                secp.ctx.as_ptr(),
1328                &mut pubkey,
1329                self.as_c_ptr(),
1330                tweak.as_c_ptr(),
1331            );
1332            if err != 1 {
1333                return Err(Error::InvalidTweak);
1334            }
1335
1336            err = ffi::secp256k1_xonly_pubkey_from_pubkey(
1337                secp.ctx.as_ptr(),
1338                &mut self.0,
1339                &mut pk_parity,
1340                &pubkey,
1341            );
1342            if err == 0 {
1343                return Err(Error::InvalidPublicKey);
1344            }
1345
1346            let parity = Parity::from_i32(pk_parity)?;
1347            Ok((self, parity))
1348        }
1349    }
1350
1351    /// Verifies that a tweak produced by [`XOnlyPublicKey::add_tweak`] was computed correctly.
1352    ///
1353    /// Should be called on the original untweaked key. Takes the tweaked key and output parity from
1354    /// [`XOnlyPublicKey::add_tweak`] as input.
1355    ///
1356    /// Currently this is not much more efficient than just recomputing the tweak and checking
1357    /// equality. However, in future this API will support batch verification, which is
1358    /// significantly faster, so it is wise to design protocols with this in mind.
1359    ///
1360    /// # Returns
1361    ///
1362    /// True if tweak and check is successful, false otherwise.
1363    ///
1364    /// # Examples
1365    ///
1366    /// ```
1367    /// # #[cfg(all(feature = "rand", feature = "std"))] {
1368    /// use secp256k1::{Secp256k1, Keypair, Scalar};
1369    ///
1370    /// let secp = Secp256k1::new();
1371    /// let tweak = Scalar::random();
1372    ///
1373    /// let mut keypair = Keypair::new(&secp, &mut rand::rng());
1374    /// let (mut public_key, _) = keypair.x_only_public_key();
1375    /// let original = public_key;
1376    /// let (tweaked, parity) = public_key.add_tweak(&secp, &tweak).expect("Improbable to fail with a randomly generated tweak");
1377    /// assert!(original.tweak_add_check(&secp, &tweaked, parity, tweak));
1378    /// # }
1379    /// ```
1380    pub fn tweak_add_check<V: Verification>(
1381        &self,
1382        secp: &Secp256k1<V>,
1383        tweaked_key: &Self,
1384        tweaked_parity: Parity,
1385        tweak: Scalar,
1386    ) -> bool {
1387        let tweaked_ser = tweaked_key.serialize();
1388        unsafe {
1389            let err = ffi::secp256k1_xonly_pubkey_tweak_add_check(
1390                secp.ctx.as_ptr(),
1391                tweaked_ser.as_c_ptr(),
1392                tweaked_parity.to_i32(),
1393                &self.0,
1394                tweak.as_c_ptr(),
1395            );
1396
1397            err == 1
1398        }
1399    }
1400
1401    /// Returns the [`PublicKey`] for this [`XOnlyPublicKey`].
1402    ///
1403    /// This is equivalent to using [`PublicKey::from_xonly_and_parity(self, parity)`].
1404    #[inline]
1405    pub fn public_key(&self, parity: Parity) -> PublicKey {
1406        PublicKey::from_x_only_public_key(*self, parity)
1407    }
1408
1409    /// Checks that `sig` is a valid schnorr signature for `msg` using this public key.
1410    pub fn verify<C: Verification>(
1411        &self,
1412        secp: &Secp256k1<C>,
1413        msg: &[u8],
1414        sig: &schnorr::Signature,
1415    ) -> Result<(), Error> {
1416        secp.verify_schnorr(sig, msg, self)
1417    }
1418}
1419
1420/// Represents the parity passed between FFI function calls.
1421#[derive(Copy, Clone, PartialEq, Eq, Debug, PartialOrd, Ord, Hash)]
1422pub enum Parity {
1423    /// Even parity.
1424    Even = 0,
1425    /// Odd parity.
1426    Odd = 1,
1427}
1428
1429impl Parity {
1430    /// Converts parity into an integer (byte) value.
1431    ///
1432    /// This returns `0` for even parity and `1` for odd parity.
1433    pub fn to_u8(self) -> u8 { self as u8 }
1434
1435    /// Converts parity into an integer value.
1436    ///
1437    /// This returns `0` for even parity and `1` for odd parity.
1438    pub fn to_i32(self) -> i32 { self as i32 }
1439
1440    /// Constructs a [`Parity`] from a byte.
1441    ///
1442    /// The only allowed values are `0` meaning even parity and `1` meaning odd.
1443    /// Other values result in error being returned.
1444    pub fn from_u8(parity: u8) -> Result<Parity, InvalidParityValue> {
1445        Parity::from_i32(parity.into())
1446    }
1447
1448    /// Constructs a [`Parity`] from a signed integer.
1449    ///
1450    /// The only allowed values are `0` meaning even parity and `1` meaning odd.
1451    /// Other values result in error being returned.
1452    pub fn from_i32(parity: i32) -> Result<Parity, InvalidParityValue> {
1453        match parity {
1454            0 => Ok(Parity::Even),
1455            1 => Ok(Parity::Odd),
1456            _ => Err(InvalidParityValue(parity)),
1457        }
1458    }
1459}
1460
1461/// `Even` for `0`, `Odd` for `1`, error for anything else
1462impl TryFrom<i32> for Parity {
1463    type Error = InvalidParityValue;
1464
1465    fn try_from(parity: i32) -> Result<Self, Self::Error> { Self::from_i32(parity) }
1466}
1467
1468/// `Even` for `0`, `Odd` for `1`, error for anything else
1469impl TryFrom<u8> for Parity {
1470    type Error = InvalidParityValue;
1471
1472    fn try_from(parity: u8) -> Result<Self, Self::Error> { Self::from_u8(parity) }
1473}
1474
1475/// The conversion returns `0` for even parity and `1` for odd.
1476impl From<Parity> for i32 {
1477    fn from(parity: Parity) -> i32 { parity.to_i32() }
1478}
1479
1480/// The conversion returns `0` for even parity and `1` for odd.
1481impl From<Parity> for u8 {
1482    fn from(parity: Parity) -> u8 { parity.to_u8() }
1483}
1484
1485/// Returns even parity if the operands are equal, odd otherwise.
1486impl BitXor for Parity {
1487    type Output = Parity;
1488
1489    fn bitxor(self, rhs: Parity) -> Self::Output {
1490        // This works because Parity has only two values (i.e. only 1 bit of information).
1491        if self == rhs {
1492            Parity::Even // 1^1==0 and 0^0==0
1493        } else {
1494            Parity::Odd // 1^0==1 and 0^1==1
1495        }
1496    }
1497}
1498
1499/// Error returned when conversion from an integer to `Parity` fails.
1500//
1501// Note that we don't allow inspecting the value because we may change the type.
1502// Yes, this comment is intentionally NOT doc comment.
1503// Too many derives for compatibility with current Error type.
1504#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
1505pub struct InvalidParityValue(i32);
1506
1507impl fmt::Display for InvalidParityValue {
1508    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1509        write!(f, "invalid value {} for Parity - must be 0 or 1", self.0)
1510    }
1511}
1512
1513#[cfg(feature = "std")]
1514impl std::error::Error for InvalidParityValue {}
1515
1516impl From<InvalidParityValue> for Error {
1517    fn from(error: InvalidParityValue) -> Self { Error::InvalidParityValue(error) }
1518}
1519
1520/// The parity is serialized as `u8` - `0` for even, `1` for odd.
1521#[cfg(feature = "serde")]
1522impl serde::Serialize for Parity {
1523    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1524        s.serialize_u8(self.to_u8())
1525    }
1526}
1527
1528/// The parity is deserialized as `u8` - `0` for even, `1` for odd.
1529#[cfg(feature = "serde")]
1530impl<'de> serde::Deserialize<'de> for Parity {
1531    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
1532        struct Visitor;
1533
1534        impl serde::de::Visitor<'_> for Visitor {
1535            type Value = Parity;
1536
1537            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
1538                formatter.write_str("8-bit integer (byte) with value 0 or 1")
1539            }
1540
1541            fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
1542            where
1543                E: serde::de::Error,
1544            {
1545                use serde::de::Unexpected;
1546
1547                Parity::from_u8(v)
1548                    .map_err(|_| E::invalid_value(Unexpected::Unsigned(v.into()), &"0 or 1"))
1549            }
1550        }
1551
1552        d.deserialize_u8(Visitor)
1553    }
1554}
1555
1556impl CPtr for XOnlyPublicKey {
1557    type Target = ffi::XOnlyPublicKey;
1558    fn as_c_ptr(&self) -> *const Self::Target { &self.0 }
1559
1560    fn as_mut_c_ptr(&mut self) -> *mut Self::Target { &mut self.0 }
1561}
1562
1563/// Creates a new schnorr public key from a FFI x-only public key.
1564impl From<ffi::XOnlyPublicKey> for XOnlyPublicKey {
1565    #[inline]
1566    fn from(pk: ffi::XOnlyPublicKey) -> XOnlyPublicKey { XOnlyPublicKey(pk) }
1567}
1568
1569impl From<PublicKey> for XOnlyPublicKey {
1570    fn from(src: PublicKey) -> XOnlyPublicKey {
1571        unsafe {
1572            let mut pk = ffi::XOnlyPublicKey::new();
1573            assert_eq!(
1574                1,
1575                ffi::secp256k1_xonly_pubkey_from_pubkey(
1576                    ffi::secp256k1_context_no_precomp,
1577                    &mut pk,
1578                    ptr::null_mut(),
1579                    src.as_c_ptr(),
1580                )
1581            );
1582            XOnlyPublicKey(pk)
1583        }
1584    }
1585}
1586
1587#[cfg(feature = "serde")]
1588impl serde::Serialize for XOnlyPublicKey {
1589    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
1590        if s.is_human_readable() {
1591            s.collect_str(self)
1592        } else {
1593            let mut tuple = s.serialize_tuple(constants::SCHNORR_PUBLIC_KEY_SIZE)?;
1594            for byte in self.serialize().iter() {
1595                tuple.serialize_element(&byte)?;
1596            }
1597            tuple.end()
1598        }
1599    }
1600}
1601
1602#[cfg(feature = "serde")]
1603impl<'de> serde::Deserialize<'de> for XOnlyPublicKey {
1604    fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
1605        if d.is_human_readable() {
1606            d.deserialize_str(super::serde_util::FromStrVisitor::new(
1607                "a hex string representing 32 byte schnorr public key",
1608            ))
1609        } else {
1610            let visitor = super::serde_util::Tuple32Visitor::new(
1611                "raw 32 bytes schnorr public key",
1612                XOnlyPublicKey::from_byte_array,
1613            );
1614            d.deserialize_tuple(constants::SCHNORR_PUBLIC_KEY_SIZE, visitor)
1615        }
1616    }
1617}
1618
1619#[cfg(test)]
1620#[allow(unused_imports)]
1621mod test {
1622    use core::str::FromStr;
1623
1624    #[cfg(not(secp256k1_fuzz))]
1625    use hex_lit::hex;
1626    #[cfg(feature = "rand")]
1627    use rand::{self, rngs::mock::StepRng, RngCore};
1628    use serde_test::{Configure, Token};
1629    #[cfg(target_arch = "wasm32")]
1630    use wasm_bindgen_test::wasm_bindgen_test as test;
1631
1632    use super::{Keypair, Parity, PublicKey, Secp256k1, SecretKey, XOnlyPublicKey, *};
1633    use crate::Error::{InvalidPublicKey, InvalidSecretKey};
1634    use crate::{constants, from_hex, to_hex, Scalar};
1635
1636    #[test]
1637    #[allow(deprecated)]
1638    fn skey_from_slice() {
1639        let sk = SecretKey::from_slice(&[1; 31]);
1640        assert_eq!(sk, Err(InvalidSecretKey));
1641
1642        let sk = SecretKey::from_slice(&[1; 32]);
1643        assert!(sk.is_ok());
1644    }
1645
1646    #[test]
1647    fn pubkey_from_slice() {
1648        assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey));
1649        assert_eq!(PublicKey::from_slice(&[1, 2, 3]), Err(InvalidPublicKey));
1650
1651        let uncompressed = PublicKey::from_slice(&[
1652            4, 54, 57, 149, 239, 162, 148, 175, 246, 254, 239, 75, 154, 152, 10, 82, 234, 224, 85,
1653            220, 40, 100, 57, 121, 30, 162, 94, 156, 135, 67, 74, 49, 179, 57, 236, 53, 162, 124,
1654            149, 144, 168, 77, 74, 30, 72, 211, 229, 110, 111, 55, 96, 193, 86, 227, 183, 152, 195,
1655            155, 51, 247, 123, 113, 60, 228, 188,
1656        ]);
1657        assert!(uncompressed.is_ok());
1658
1659        let compressed = PublicKey::from_slice(&[
1660            3, 23, 183, 225, 206, 31, 159, 148, 195, 42, 67, 115, 146, 41, 248, 140, 11, 3, 51, 41,
1661            111, 180, 110, 143, 114, 134, 88, 73, 198, 174, 52, 184, 78,
1662        ]);
1663        assert!(compressed.is_ok());
1664    }
1665
1666    #[test]
1667    #[cfg(all(feature = "rand", feature = "std"))]
1668    fn keypair_slice_round_trip() {
1669        let s = Secp256k1::new();
1670
1671        let (sk1, pk1) = s.generate_keypair(&mut rand::rng());
1672        assert_eq!(SecretKey::from_byte_array(sk1.secret_bytes()), Ok(sk1));
1673        assert_eq!(PublicKey::from_slice(&pk1.serialize()[..]), Ok(pk1));
1674        assert_eq!(PublicKey::from_slice(&pk1.serialize_uncompressed()[..]), Ok(pk1));
1675    }
1676
1677    #[test]
1678    #[cfg(all(feature = "std", not(secp256k1_fuzz)))]
1679    fn erased_keypair_is_valid() {
1680        let s = Secp256k1::new();
1681        let kp = Keypair::from_seckey_byte_array(&s, [1u8; constants::SECRET_KEY_SIZE])
1682            .expect("valid secret key");
1683        let mut kp2 = kp;
1684        kp2.non_secure_erase();
1685        assert!(kp.eq_fast_unstable(&kp2));
1686    }
1687
1688    #[test]
1689    #[rustfmt::skip]
1690    fn invalid_secret_key() {
1691        // Zero
1692        assert_eq!(SecretKey::from_byte_array([0; 32]), Err(InvalidSecretKey));
1693        assert_eq!(
1694            SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000000"),
1695            Err(InvalidSecretKey)
1696        );
1697        // -1
1698        assert_eq!(SecretKey::from_byte_array([0xff; 32]), Err(InvalidSecretKey));
1699        // Top of range
1700        assert!(SecretKey::from_byte_array([
1701            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1702            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
1703            0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
1704            0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40,
1705        ]).is_ok());
1706        // One past top of range
1707        assert!(SecretKey::from_byte_array([
1708            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
1709            0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
1710            0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B,
1711            0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41,
1712        ]).is_err());
1713    }
1714
1715    #[test]
1716    #[cfg(all(feature = "rand", feature = "alloc"))]
1717    fn test_out_of_range() {
1718        struct BadRng(u8);
1719        impl RngCore for BadRng {
1720            fn next_u32(&mut self) -> u32 { unimplemented!() }
1721            fn next_u64(&mut self) -> u64 { unimplemented!() }
1722            // This will set a secret key to a little over the
1723            // group order, then decrement with repeated calls
1724            // until it returns a valid key
1725            fn fill_bytes(&mut self, data: &mut [u8]) {
1726                #[rustfmt::skip]
1727                let group_order: [u8; 32] = [
1728                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
1729                    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
1730                    0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b,
1731                    0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41];
1732                assert_eq!(data.len(), 32);
1733                data.copy_from_slice(&group_order[..]);
1734                data[31] = self.0;
1735                self.0 -= 1;
1736            }
1737        }
1738
1739        let s = Secp256k1::new();
1740        s.generate_keypair(&mut BadRng(0xff));
1741    }
1742
1743    #[test]
1744    fn test_pubkey_from_bad_slice() {
1745        // Bad sizes
1746        assert_eq!(
1747            PublicKey::from_slice(&[0; constants::PUBLIC_KEY_SIZE - 1]),
1748            Err(InvalidPublicKey)
1749        );
1750        assert_eq!(
1751            PublicKey::from_slice(&[0; constants::PUBLIC_KEY_SIZE + 1]),
1752            Err(InvalidPublicKey)
1753        );
1754        assert_eq!(
1755            PublicKey::from_slice(&[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE - 1]),
1756            Err(InvalidPublicKey)
1757        );
1758        assert_eq!(
1759            PublicKey::from_slice(&[0; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE + 1]),
1760            Err(InvalidPublicKey)
1761        );
1762
1763        // Bad parse
1764        assert_eq!(
1765            PublicKey::from_slice(&[0xff; constants::UNCOMPRESSED_PUBLIC_KEY_SIZE]),
1766            Err(InvalidPublicKey)
1767        );
1768        assert_eq!(
1769            PublicKey::from_slice(&[0x55; constants::PUBLIC_KEY_SIZE]),
1770            Err(InvalidPublicKey)
1771        );
1772        assert_eq!(PublicKey::from_slice(&[]), Err(InvalidPublicKey));
1773    }
1774
1775    #[test]
1776    #[allow(deprecated)]
1777    fn test_seckey_from_bad_slice() {
1778        // Bad sizes
1779        assert_eq!(
1780            SecretKey::from_slice(&[0; constants::SECRET_KEY_SIZE - 1]),
1781            Err(InvalidSecretKey)
1782        );
1783        assert_eq!(
1784            SecretKey::from_slice(&[0; constants::SECRET_KEY_SIZE + 1]),
1785            Err(InvalidSecretKey)
1786        );
1787        // Bad parse
1788        assert_eq!(
1789            SecretKey::from_slice(&[0xff; constants::SECRET_KEY_SIZE]),
1790            Err(InvalidSecretKey)
1791        );
1792        assert_eq!(
1793            SecretKey::from_slice(&[0x00; constants::SECRET_KEY_SIZE]),
1794            Err(InvalidSecretKey)
1795        );
1796        assert_eq!(SecretKey::from_slice(&[]), Err(InvalidSecretKey));
1797    }
1798
1799    #[test]
1800    #[cfg(all(feature = "rand", feature = "alloc", not(feature = "hashes")))]
1801    fn test_debug_output() {
1802        let s = Secp256k1::new();
1803        let (sk, _) = s.generate_keypair(&mut StepRng::new(1, 1));
1804
1805        assert_eq!(
1806            &format!("{:?}", sk),
1807            "<secret key; enable `hashes` feature of `secp256k1` to display fingerprint>"
1808        );
1809
1810        let mut buf = [0u8; constants::SECRET_KEY_SIZE * 2];
1811        assert_eq!(
1812            to_hex(&sk[..], &mut buf).unwrap(),
1813            "0100000000000000020000000000000003000000000000000400000000000000"
1814        );
1815    }
1816
1817    #[test]
1818    #[cfg(feature = "alloc")]
1819    fn test_display_output() {
1820        #[rustfmt::skip]
1821        static SK_BYTES: [u8; 32] = [
1822            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
1823            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
1824            0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
1825            0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
1826        ];
1827
1828        #[cfg(not(secp256k1_fuzz))]
1829        let s = Secp256k1::signing_only();
1830        let sk = SecretKey::from_byte_array(SK_BYTES).expect("sk");
1831
1832        // In fuzzing mode secret->public key derivation is different, so
1833        // hard-code the expected result.
1834        #[cfg(not(secp256k1_fuzz))]
1835        let pk = PublicKey::from_secret_key(&s, &sk);
1836        #[cfg(secp256k1_fuzz)]
1837        let pk = PublicKey::from_slice(&[
1838            0x02, 0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f, 0x1c, 0x97, 0x09, 0xe2, 0x30,
1839            0x92, 0x06, 0x7d, 0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54, 0x4a, 0xc8, 0x87,
1840            0xfe, 0x91, 0xdd, 0xd1, 0x66,
1841        ])
1842        .expect("pk");
1843
1844        assert_eq!(
1845            sk.display_secret().to_string(),
1846            "01010101010101010001020304050607ffff0000ffff00006363636363636363"
1847        );
1848        assert_eq!(
1849            SecretKey::from_str("01010101010101010001020304050607ffff0000ffff00006363636363636363")
1850                .unwrap(),
1851            sk
1852        );
1853        assert_eq!(
1854            pk.to_string(),
1855            "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
1856        );
1857        assert_eq!(
1858            PublicKey::from_str(
1859                "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166"
1860            )
1861            .unwrap(),
1862            pk
1863        );
1864        assert_eq!(
1865            PublicKey::from_str(
1866                "04\
1867                18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166\
1868                84B84DB303A340CD7D6823EE88174747D12A67D2F8F2F9BA40846EE5EE7A44F6"
1869            )
1870            .unwrap(),
1871            pk
1872        );
1873
1874        assert!(SecretKey::from_str(
1875            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
1876        )
1877        .is_err());
1878        assert!(SecretKey::from_str(
1879            "01010101010101010001020304050607ffff0000ffff0000636363636363636363"
1880        )
1881        .is_err());
1882        assert!(SecretKey::from_str(
1883            "01010101010101010001020304050607ffff0000ffff0000636363636363636"
1884        )
1885        .is_err());
1886        assert!(SecretKey::from_str(
1887            "01010101010101010001020304050607ffff0000ffff000063636363636363"
1888        )
1889        .is_err());
1890        assert!(SecretKey::from_str(
1891            "01010101010101010001020304050607ffff0000ffff000063636363636363xx"
1892        )
1893        .is_err());
1894        assert!(PublicKey::from_str(
1895            "0300000000000000000000000000000000000000000000000000000000000000000"
1896        )
1897        .is_err());
1898        assert!(PublicKey::from_str(
1899            "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16601"
1900        )
1901        .is_err());
1902        assert!(PublicKey::from_str(
1903            "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd16"
1904        )
1905        .is_err());
1906        assert!(PublicKey::from_str(
1907            "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
1908        )
1909        .is_err());
1910        assert!(PublicKey::from_str(
1911            "xx0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd1"
1912        )
1913        .is_err());
1914
1915        let long_str = "a".repeat(1024 * 1024);
1916        assert!(SecretKey::from_str(&long_str).is_err());
1917        assert!(PublicKey::from_str(&long_str).is_err());
1918    }
1919
1920    #[test]
1921    // In fuzzing mode the Y coordinate is expected to match the X, so this
1922    // test uses invalid public keys.
1923    #[cfg(not(secp256k1_fuzz))]
1924    #[cfg(all(feature = "alloc", feature = "rand"))]
1925    fn test_pubkey_serialize() {
1926        let s = Secp256k1::new();
1927        let (_, pk1) = s.generate_keypair(&mut StepRng::new(1, 1));
1928        assert_eq!(
1929            &pk1.serialize_uncompressed()[..],
1930            &[
1931                4, 124, 121, 49, 14, 253, 63, 197, 50, 39, 194, 107, 17, 193, 219, 108, 154, 126,
1932                9, 181, 248, 2, 12, 149, 233, 198, 71, 149, 134, 250, 184, 154, 229, 185, 28, 165,
1933                110, 27, 3, 162, 126, 238, 167, 157, 242, 221, 76, 251, 237, 34, 231, 72, 39, 245,
1934                3, 191, 64, 111, 170, 117, 103, 82, 28, 102, 163
1935            ][..]
1936        );
1937        assert_eq!(
1938            &pk1.serialize()[..],
1939            &[
1940                3, 124, 121, 49, 14, 253, 63, 197, 50, 39, 194, 107, 17, 193, 219, 108, 154, 126,
1941                9, 181, 248, 2, 12, 149, 233, 198, 71, 149, 134, 250, 184, 154, 229
1942            ][..]
1943        );
1944    }
1945
1946    #[test]
1947    #[cfg(all(feature = "rand", feature = "std"))]
1948    fn tweak_add_arbitrary_data() {
1949        let s = Secp256k1::new();
1950
1951        let (sk, pk) = s.generate_keypair(&mut rand::rng());
1952        assert_eq!(PublicKey::from_secret_key(&s, &sk), pk); // Sanity check.
1953
1954        // TODO: This would be better tested with a _lot_ of different tweaks.
1955        let tweak = Scalar::random();
1956
1957        let tweaked_sk = sk.add_tweak(&tweak).unwrap();
1958        assert_ne!(sk, tweaked_sk); // Make sure we did something.
1959        let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
1960        assert_ne!(pk, tweaked_pk);
1961
1962        assert_eq!(PublicKey::from_secret_key(&s, &tweaked_sk), tweaked_pk);
1963    }
1964
1965    #[test]
1966    #[cfg(all(feature = "rand", feature = "std"))]
1967    fn tweak_add_zero() {
1968        let s = Secp256k1::new();
1969
1970        let (sk, pk) = s.generate_keypair(&mut rand::rng());
1971
1972        let tweak = Scalar::ZERO;
1973
1974        let tweaked_sk = sk.add_tweak(&tweak).unwrap();
1975        assert_eq!(sk, tweaked_sk); // Tweak by zero does nothing.
1976        let tweaked_pk = pk.add_exp_tweak(&s, &tweak).unwrap();
1977        assert_eq!(pk, tweaked_pk);
1978    }
1979
1980    #[test]
1981    #[cfg(all(feature = "rand", feature = "std"))]
1982    fn tweak_mul_arbitrary_data() {
1983        let s = Secp256k1::new();
1984
1985        let (sk, pk) = s.generate_keypair(&mut rand::rng());
1986        assert_eq!(PublicKey::from_secret_key(&s, &sk), pk); // Sanity check.
1987
1988        // TODO: This would be better tested with a _lot_ of different tweaks.
1989        let tweak = Scalar::random();
1990
1991        let tweaked_sk = sk.mul_tweak(&tweak).unwrap();
1992        assert_ne!(sk, tweaked_sk); // Make sure we did something.
1993        let tweaked_pk = pk.mul_tweak(&s, &tweak).unwrap();
1994        assert_ne!(pk, tweaked_pk);
1995
1996        assert_eq!(PublicKey::from_secret_key(&s, &tweaked_sk), tweaked_pk);
1997    }
1998
1999    #[test]
2000    #[cfg(all(feature = "rand", feature = "std"))]
2001    fn tweak_mul_zero() {
2002        let s = Secp256k1::new();
2003        let (sk, _) = s.generate_keypair(&mut rand::rng());
2004
2005        let tweak = Scalar::ZERO;
2006        assert!(sk.mul_tweak(&tweak).is_err())
2007    }
2008
2009    #[test]
2010    #[cfg(all(feature = "rand", feature = "std"))]
2011    fn test_negation() {
2012        let s = Secp256k1::new();
2013
2014        let (sk, pk) = s.generate_keypair(&mut rand::rng());
2015
2016        assert_eq!(PublicKey::from_secret_key(&s, &sk), pk); // Sanity check.
2017
2018        let neg = sk.negate();
2019        assert_ne!(sk, neg);
2020        let back_sk = neg.negate();
2021        assert_eq!(sk, back_sk);
2022
2023        let neg = pk.negate(&s);
2024        assert_ne!(pk, neg);
2025        let back_pk = neg.negate(&s);
2026        assert_eq!(pk, back_pk);
2027
2028        assert_eq!(PublicKey::from_secret_key(&s, &back_sk), pk);
2029    }
2030
2031    #[test]
2032    #[cfg(all(feature = "rand", feature = "std"))]
2033    fn pubkey_hash() {
2034        use std::collections::hash_map::DefaultHasher;
2035        use std::collections::HashSet;
2036        use std::hash::{Hash, Hasher};
2037
2038        fn hash<T: Hash>(t: &T) -> u64 {
2039            let mut s = DefaultHasher::new();
2040            t.hash(&mut s);
2041            s.finish()
2042        }
2043
2044        let s = Secp256k1::new();
2045        let mut set = HashSet::new();
2046        const COUNT: usize = 1024;
2047        for _ in 0..COUNT {
2048            let (_, pk) = s.generate_keypair(&mut rand::rng());
2049            let hash = hash(&pk);
2050            assert!(!set.contains(&hash));
2051            set.insert(hash);
2052        }
2053        assert_eq!(set.len(), COUNT);
2054    }
2055
2056    #[test]
2057    #[cfg(not(secp256k1_fuzz))]
2058    fn pubkey_combine() {
2059        let compressed1 = PublicKey::from_slice(&hex!(
2060            "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"
2061        ))
2062        .unwrap();
2063        let compressed2 = PublicKey::from_slice(&hex!(
2064            "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
2065        ))
2066        .unwrap();
2067        let exp_sum = PublicKey::from_slice(&hex!(
2068            "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07"
2069        ))
2070        .unwrap();
2071
2072        let sum1 = compressed1.combine(&compressed2);
2073        assert!(sum1.is_ok());
2074        let sum2 = compressed2.combine(&compressed1);
2075        assert!(sum2.is_ok());
2076        assert_eq!(sum1, sum2);
2077        assert_eq!(sum1.unwrap(), exp_sum);
2078    }
2079
2080    #[test]
2081    #[cfg(not(secp256k1_fuzz))]
2082    fn pubkey_combine_keys() {
2083        let compressed1 = PublicKey::from_slice(&hex!(
2084            "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"
2085        ))
2086        .unwrap();
2087        let compressed2 = PublicKey::from_slice(&hex!(
2088            "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
2089        ))
2090        .unwrap();
2091        let compressed3 = PublicKey::from_slice(&hex!(
2092            "03e74897d8644eb3e5b391ca2ab257aec2080f4d1a95cad57e454e47f021168eb0"
2093        ))
2094        .unwrap();
2095        let exp_sum = PublicKey::from_slice(&hex!(
2096            "0252d73a47f66cf341e5651542f0348f452b7c793af62a6d8bff75ade703a451ad"
2097        ))
2098        .unwrap();
2099
2100        let sum1 = PublicKey::combine_keys(&[&compressed1, &compressed2, &compressed3]);
2101        assert!(sum1.is_ok());
2102        let sum2 = PublicKey::combine_keys(&[&compressed1, &compressed2, &compressed3]);
2103        assert!(sum2.is_ok());
2104        assert_eq!(sum1, sum2);
2105        assert_eq!(sum1.unwrap(), exp_sum);
2106    }
2107
2108    #[test]
2109    #[cfg(not(secp256k1_fuzz))]
2110    fn pubkey_combine_keys_empty_slice() {
2111        assert!(PublicKey::combine_keys(&[]).is_err());
2112    }
2113
2114    #[test]
2115    #[cfg(all(feature = "rand", feature = "std"))]
2116    fn create_pubkey_combine() {
2117        let s = Secp256k1::new();
2118
2119        let (sk1, pk1) = s.generate_keypair(&mut rand::rng());
2120        let (sk2, pk2) = s.generate_keypair(&mut rand::rng());
2121
2122        let sum1 = pk1.combine(&pk2);
2123        assert!(sum1.is_ok());
2124        let sum2 = pk2.combine(&pk1);
2125        assert!(sum2.is_ok());
2126        assert_eq!(sum1, sum2);
2127
2128        let tweaked = sk1.add_tweak(&Scalar::from(sk2)).unwrap();
2129        let sksum = PublicKey::from_secret_key(&s, &tweaked);
2130        assert_eq!(Ok(sksum), sum1);
2131    }
2132
2133    #[cfg(not(secp256k1_fuzz))]
2134    #[test]
2135    #[allow(clippy::nonminimal_bool)]
2136    fn pubkey_equal() {
2137        let pk1 = PublicKey::from_slice(&hex!(
2138            "0241cc121c419921942add6db6482fb36243faf83317c866d2a28d8c6d7089f7ba"
2139        ))
2140        .unwrap();
2141        let pk2 = pk1;
2142        let pk3 = PublicKey::from_slice(&hex!(
2143            "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443"
2144        ))
2145        .unwrap();
2146
2147        assert_eq!(pk1, pk2);
2148        assert!(pk1 <= pk2);
2149        assert!(pk2 <= pk1);
2150        assert!(!(pk2 < pk1));
2151        assert!(!(pk1 < pk2));
2152
2153        assert!(pk3 > pk1);
2154        assert!(pk1 < pk3);
2155        assert!(pk3 >= pk1);
2156        assert!(pk1 <= pk3);
2157    }
2158
2159    #[test]
2160    #[cfg(all(feature = "serde", feature = "alloc"))]
2161    fn test_serde() {
2162        use serde_test::{assert_tokens, Configure, Token};
2163        #[rustfmt::skip]
2164        static SK_BYTES: [u8; 32] = [
2165            1, 1, 1, 1, 1, 1, 1, 1,
2166            0, 1, 2, 3, 4, 5, 6, 7,
2167            0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
2168            99, 99, 99, 99, 99, 99, 99, 99
2169        ];
2170        static SK_STR: &str = "01010101010101010001020304050607ffff0000ffff00006363636363636363";
2171
2172        #[cfg(secp256k1_fuzz)]
2173        #[rustfmt::skip]
2174        static PK_BYTES: [u8; 33] = [
2175            0x02,
2176            0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f,
2177            0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d,
2178            0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54,
2179            0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66,
2180        ];
2181        static PK_STR: &str = "0218845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
2182
2183        #[cfg(not(secp256k1_fuzz))]
2184        let s = Secp256k1::new();
2185        let sk = SecretKey::from_byte_array(SK_BYTES).unwrap();
2186
2187        // In fuzzing mode secret->public key derivation is different, so
2188        // hard-code the expected result.
2189        #[cfg(not(secp256k1_fuzz))]
2190        let pk = PublicKey::from_secret_key(&s, &sk);
2191        #[cfg(secp256k1_fuzz)]
2192        let pk = PublicKey::from_slice(&PK_BYTES).expect("pk");
2193
2194        #[rustfmt::skip]
2195        assert_tokens(&sk.compact(), &[
2196            Token::Tuple{ len: 32 },
2197            Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1),
2198            Token::U8(0), Token::U8(1), Token::U8(2), Token::U8(3), Token::U8(4), Token::U8(5), Token::U8(6), Token::U8(7),
2199            Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0), Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0),
2200            Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99),
2201            Token::TupleEnd
2202        ]);
2203
2204        assert_tokens(&sk.readable(), &[Token::BorrowedStr(SK_STR)]);
2205        assert_tokens(&sk.readable(), &[Token::Str(SK_STR)]);
2206        assert_tokens(&sk.readable(), &[Token::String(SK_STR)]);
2207
2208        #[rustfmt::skip]
2209        assert_tokens(&pk.compact(), &[
2210            Token::Tuple{ len: 33 },
2211            Token::U8(0x02),
2212            Token::U8(0x18), Token::U8(0x84), Token::U8(0x57), Token::U8(0x81), Token::U8(0xf6), Token::U8(0x31), Token::U8(0xc4), Token::U8(0x8f),
2213            Token::U8(0x1c), Token::U8(0x97), Token::U8(0x09), Token::U8(0xe2), Token::U8(0x30), Token::U8(0x92), Token::U8(0x06), Token::U8(0x7d),
2214            Token::U8(0x06), Token::U8(0x83), Token::U8(0x7f), Token::U8(0x30), Token::U8(0xaa), Token::U8(0x0c), Token::U8(0xd0), Token::U8(0x54),
2215            Token::U8(0x4a), Token::U8(0xc8), Token::U8(0x87), Token::U8(0xfe), Token::U8(0x91), Token::U8(0xdd), Token::U8(0xd1), Token::U8(0x66),
2216            Token::TupleEnd
2217        ]);
2218
2219        assert_tokens(&pk.readable(), &[Token::BorrowedStr(PK_STR)]);
2220        assert_tokens(&pk.readable(), &[Token::Str(PK_STR)]);
2221        assert_tokens(&pk.readable(), &[Token::String(PK_STR)]);
2222    }
2223
2224    #[test]
2225    #[cfg(all(feature = "rand", feature = "std"))]
2226    fn test_tweak_add_then_tweak_add_check() {
2227        let s = Secp256k1::new();
2228
2229        // TODO: 10 times is arbitrary, we should test this a _lot_ of times.
2230        for _ in 0..10 {
2231            let tweak = Scalar::random();
2232
2233            let kp = Keypair::new(&s, &mut rand::rng());
2234            let (xonly, _) = XOnlyPublicKey::from_keypair(&kp);
2235
2236            let tweaked_kp = kp.add_xonly_tweak(&s, &tweak).expect("keypair tweak add failed");
2237            let (tweaked_xonly, parity) =
2238                xonly.add_tweak(&s, &tweak).expect("xonly pubkey tweak failed");
2239
2240            let (want_tweaked_xonly, tweaked_kp_parity) = XOnlyPublicKey::from_keypair(&tweaked_kp);
2241
2242            assert_eq!(tweaked_xonly, want_tweaked_xonly);
2243            assert_eq!(parity, tweaked_kp_parity);
2244
2245            assert!(xonly.tweak_add_check(&s, &tweaked_xonly, parity, tweak));
2246        }
2247    }
2248
2249    #[test]
2250    fn test_from_key_pubkey() {
2251        let kpk1 = PublicKey::from_str(
2252            "02e6642fd69bd211f93f7f1f36ca51a26a5290eb2dd1b0d8279a87bb0d480c8443",
2253        )
2254        .unwrap();
2255        let kpk2 = PublicKey::from_str(
2256            "0384526253c27c7aef56c7b71a5cd25bebb66dddda437826defc5b2568bde81f07",
2257        )
2258        .unwrap();
2259
2260        let pk1 = XOnlyPublicKey::from(kpk1);
2261        let pk2 = XOnlyPublicKey::from(kpk2);
2262
2263        assert_eq!(pk1.serialize()[..], kpk1.serialize()[1..]);
2264        assert_eq!(pk2.serialize()[..], kpk2.serialize()[1..]);
2265    }
2266
2267    #[test]
2268    #[cfg(all(feature = "global-context", feature = "serde"))]
2269    fn test_serde_keypair() {
2270        use serde::{Deserialize, Deserializer, Serialize, Serializer};
2271        use serde_test::{assert_tokens, Configure, Token};
2272
2273        use crate::key::Keypair;
2274        use crate::SECP256K1;
2275
2276        #[rustfmt::skip]
2277        static SK_BYTES: [u8; 32] = [
2278            1, 1, 1, 1, 1, 1, 1, 1,
2279            0, 1, 2, 3, 4, 5, 6, 7,
2280            0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
2281            99, 99, 99, 99, 99, 99, 99, 99
2282        ];
2283        static SK_STR: &str = "01010101010101010001020304050607ffff0000ffff00006363636363636363";
2284
2285        let sk = Keypair::from_seckey_byte_array(SECP256K1, SK_BYTES).unwrap();
2286        #[rustfmt::skip]
2287        assert_tokens(&sk.compact(), &[
2288            Token::Tuple{ len: 32 },
2289            Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1), Token::U8(1),
2290            Token::U8(0), Token::U8(1), Token::U8(2), Token::U8(3), Token::U8(4), Token::U8(5), Token::U8(6), Token::U8(7),
2291            Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0), Token::U8(0xff), Token::U8(0xff), Token::U8(0), Token::U8(0),
2292            Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99), Token::U8(99),
2293            Token::TupleEnd
2294        ]);
2295
2296        assert_tokens(&sk.readable(), &[Token::BorrowedStr(SK_STR)]);
2297        assert_tokens(&sk.readable(), &[Token::Str(SK_STR)]);
2298        assert_tokens(&sk.readable(), &[Token::String(SK_STR)]);
2299    }
2300
2301    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2302    fn keys() -> (SecretKey, PublicKey, Keypair, XOnlyPublicKey) {
2303        let secp = Secp256k1::new();
2304
2305        #[rustfmt::skip]
2306        static SK_BYTES: [u8; 32] = [
2307            0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
2308            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
2309            0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
2310            0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
2311        ];
2312
2313        #[rustfmt::skip]
2314        static PK_BYTES: [u8; 32] = [
2315            0x18, 0x84, 0x57, 0x81, 0xf6, 0x31, 0xc4, 0x8f,
2316            0x1c, 0x97, 0x09, 0xe2, 0x30, 0x92, 0x06, 0x7d,
2317            0x06, 0x83, 0x7f, 0x30, 0xaa, 0x0c, 0xd0, 0x54,
2318            0x4a, 0xc8, 0x87, 0xfe, 0x91, 0xdd, 0xd1, 0x66
2319        ];
2320
2321        let mut pk_bytes = [0u8; 33];
2322        pk_bytes[0] = 0x02; // Use positive Y co-ordinate.
2323        pk_bytes[1..].clone_from_slice(&PK_BYTES);
2324
2325        let sk = SecretKey::from_byte_array(SK_BYTES).expect("failed to parse sk bytes");
2326        let pk = PublicKey::from_slice(&pk_bytes).expect("failed to create pk from iterator");
2327        let kp = Keypair::from_secret_key(&secp, &sk);
2328        let xonly =
2329            XOnlyPublicKey::from_byte_array(PK_BYTES).expect("failed to get xonly from slice");
2330
2331        (sk, pk, kp, xonly)
2332    }
2333
2334    #[test]
2335    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2336    fn convert_public_key_to_xonly_public_key() {
2337        let (_sk, pk, _kp, want) = keys();
2338        let (got, parity) = pk.x_only_public_key();
2339
2340        assert_eq!(parity, Parity::Even);
2341        assert_eq!(got, want)
2342    }
2343
2344    #[test]
2345    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2346    fn convert_secret_key_to_public_key() {
2347        let secp = Secp256k1::new();
2348
2349        let (sk, want, _kp, _xonly) = keys();
2350        let got = sk.public_key(&secp);
2351
2352        assert_eq!(got, want)
2353    }
2354
2355    #[test]
2356    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2357    fn convert_secret_key_to_x_only_public_key() {
2358        let secp = Secp256k1::new();
2359
2360        let (sk, _pk, _kp, want) = keys();
2361        let (got, parity) = sk.x_only_public_key(&secp);
2362
2363        assert_eq!(parity, Parity::Even);
2364        assert_eq!(got, want)
2365    }
2366
2367    #[test]
2368    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2369    fn convert_keypair_to_public_key() {
2370        let (_sk, want, kp, _xonly) = keys();
2371        let got = kp.public_key();
2372
2373        assert_eq!(got, want)
2374    }
2375
2376    #[test]
2377    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2378    fn convert_keypair_to_x_only_public_key() {
2379        let (_sk, _pk, kp, want) = keys();
2380        let (got, parity) = kp.x_only_public_key();
2381
2382        assert_eq!(parity, Parity::Even);
2383        assert_eq!(got, want)
2384    }
2385
2386    // SecretKey -> Keypair -> SecretKey
2387    #[test]
2388    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2389    fn roundtrip_secret_key_via_keypair() {
2390        let secp = Secp256k1::new();
2391        let (sk, _pk, _kp, _xonly) = keys();
2392
2393        let kp = sk.keypair(&secp);
2394        let back = kp.secret_key();
2395
2396        assert_eq!(back, sk)
2397    }
2398
2399    // Keypair -> SecretKey -> Keypair
2400    #[test]
2401    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2402    fn roundtrip_keypair_via_secret_key() {
2403        let secp = Secp256k1::new();
2404        let (_sk, _pk, kp, _xonly) = keys();
2405
2406        let sk = kp.secret_key();
2407        let back = sk.keypair(&secp);
2408
2409        assert_eq!(back, kp)
2410    }
2411
2412    // XOnlyPublicKey -> PublicKey -> XOnlyPublicKey
2413    #[test]
2414    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2415    fn roundtrip_x_only_public_key_via_public_key() {
2416        let (_sk, _pk, _kp, xonly) = keys();
2417
2418        let pk = xonly.public_key(Parity::Even);
2419        let (back, parity) = pk.x_only_public_key();
2420
2421        assert_eq!(parity, Parity::Even);
2422        assert_eq!(back, xonly)
2423    }
2424
2425    // PublicKey -> XOnlyPublicKey -> PublicKey
2426    #[test]
2427    #[cfg(all(not(secp256k1_fuzz), feature = "alloc"))]
2428    fn roundtrip_public_key_via_x_only_public_key() {
2429        let (_sk, pk, _kp, _xonly) = keys();
2430
2431        let (xonly, parity) = pk.x_only_public_key();
2432        let back = xonly.public_key(parity);
2433
2434        assert_eq!(back, pk)
2435    }
2436
2437    #[test]
2438    fn public_key_from_x_only_public_key_and_odd_parity() {
2439        let s = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
2440        let mut want = String::from("03");
2441        want.push_str(s);
2442
2443        let xonly = XOnlyPublicKey::from_str(s).expect("failed to parse xonly pubkey string");
2444        let pk = xonly.public_key(Parity::Odd);
2445        let got = format!("{}", pk);
2446
2447        assert_eq!(got, want)
2448    }
2449
2450    #[test]
2451    #[cfg(not(secp256k1_fuzz))]
2452    #[cfg(all(feature = "global-context", feature = "serde"))]
2453    fn test_serde_x_only_pubkey() {
2454        use serde_test::{assert_tokens, Configure, Token};
2455
2456        #[rustfmt::skip]
2457        static SK_BYTES: [u8; 32] = [
2458            1, 1, 1, 1, 1, 1, 1, 1,
2459            0, 1, 2, 3, 4, 5, 6, 7,
2460            0xff, 0xff, 0, 0, 0xff, 0xff, 0, 0,
2461            99, 99, 99, 99, 99, 99, 99, 99
2462        ];
2463
2464        static PK_STR: &str = "18845781f631c48f1c9709e23092067d06837f30aa0cd0544ac887fe91ddd166";
2465
2466        let kp = Keypair::from_seckey_byte_array(crate::SECP256K1, SK_BYTES).unwrap();
2467        let (pk, _parity) = XOnlyPublicKey::from_keypair(&kp);
2468
2469        #[rustfmt::skip]
2470        assert_tokens(&pk.compact(), &[
2471            Token::Tuple{ len: 32 },
2472            Token::U8(0x18), Token::U8(0x84), Token::U8(0x57), Token::U8(0x81), Token::U8(0xf6), Token::U8(0x31), Token::U8(0xc4), Token::U8(0x8f),
2473            Token::U8(0x1c), Token::U8(0x97), Token::U8(0x09), Token::U8(0xe2), Token::U8(0x30), Token::U8(0x92), Token::U8(0x06), Token::U8(0x7d),
2474            Token::U8(0x06), Token::U8(0x83), Token::U8(0x7f), Token::U8(0x30), Token::U8(0xaa), Token::U8(0x0c), Token::U8(0xd0), Token::U8(0x54),
2475            Token::U8(0x4a), Token::U8(0xc8), Token::U8(0x87), Token::U8(0xfe), Token::U8(0x91), Token::U8(0xdd), Token::U8(0xd1), Token::U8(0x66),
2476            Token::TupleEnd
2477        ]);
2478
2479        assert_tokens(&pk.readable(), &[Token::BorrowedStr(PK_STR)]);
2480        assert_tokens(&pk.readable(), &[Token::Str(PK_STR)]);
2481        assert_tokens(&pk.readable(), &[Token::String(PK_STR)]);
2482    }
2483
2484    #[test]
2485    #[cfg(all(feature = "rand", feature = "std"))]
2486    fn test_keypair_from_str() {
2487        let ctx = crate::Secp256k1::new();
2488        let keypair = Keypair::new(&ctx, &mut rand::rng());
2489        let mut buf = [0_u8; constants::SECRET_KEY_SIZE * 2]; // Holds hex digits.
2490        let s = to_hex(&keypair.secret_key().secret_bytes(), &mut buf).unwrap();
2491        let parsed_key = Keypair::from_str(s).unwrap();
2492        assert_eq!(parsed_key, keypair);
2493    }
2494
2495    #[test]
2496    #[cfg(all(any(feature = "alloc", feature = "global-context"), feature = "serde"))]
2497    fn test_keypair_deserialize_serde() {
2498        let ctx = crate::Secp256k1::new();
2499        let sec_key_str = "4242424242424242424242424242424242424242424242424242424242424242";
2500        let keypair = Keypair::from_seckey_str(&ctx, sec_key_str).unwrap();
2501
2502        serde_test::assert_tokens(&keypair.readable(), &[Token::String(sec_key_str)]);
2503
2504        let sec_key_bytes = keypair.secret_key().secret_bytes();
2505        let tokens = std::iter::once(Token::Tuple { len: 32 })
2506            .chain(sec_key_bytes.iter().copied().map(Token::U8))
2507            .chain(std::iter::once(Token::TupleEnd))
2508            .collect::<Vec<_>>();
2509        serde_test::assert_tokens(&keypair.compact(), &tokens);
2510    }
2511}
2512
2513#[cfg(bench)]
2514mod benches {
2515    use std::collections::BTreeSet;
2516
2517    use test::Bencher;
2518
2519    use crate::constants::GENERATOR_X;
2520    use crate::PublicKey;
2521
2522    #[bench]
2523    fn bench_pk_ordering(b: &mut Bencher) {
2524        let mut map = BTreeSet::new();
2525        let mut g_slice = [02u8; 33];
2526        g_slice[1..].copy_from_slice(&GENERATOR_X);
2527        let g = PublicKey::from_slice(&g_slice).unwrap();
2528        let mut pk = g;
2529        b.iter(|| {
2530            map.insert(pk);
2531            pk = pk.combine(&pk).unwrap();
2532        })
2533    }
2534}