Introduce parity field on XOnlyPublicKey
What changed, and why it matters
This is a routine internal code refactor in a Bitcoin cryptography library. It adds a 'parity' field (a mathematical property of cryptographic keys) to the XOnlyPublicKey type, along with getter and setter functions. There is no indication this change fixes or introduces a security vulnerability.
No security action required. Treat as normal API/internal refactor during code review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors the rust-bitcoin XOnlyPublicKey wrapper from a newtype around secp256k1::XOnlyPublicKey into a struct containing both the inner key and a Parity field. It adds a default even parity in the constructor, a with_parity() builder, and a parity() getter. This is a structural/API change to support later BIP-341 work, not a security patch.
Changed components
bitcoin/src/crypto/key.rsXOnlyPublicKey typeInspect captured patch +25 / −5
diff --git a/bitcoin/src/crypto/key.rs b/bitcoin/src/crypto/key.rs
index ca16f1f9..374eb0c6 100644
--- a/bitcoin/src/crypto/key.rs
+++ b/bitcoin/src/crypto/key.rs
@@ -37,21 +37,41 @@ pub use secp256k1::rand;
/// Encapsulation module to provide a clear barrier for construction/destruction of types.
mod encapsulate {
+ use secp256k1::Parity;
+
/// A Bitcoin Schnorr X-only public key used for BIP-0340 signatures.
+ ///
+ /// This type also holds the parity of the full public key.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
- pub struct XOnlyPublicKey(secp256k1::XOnlyPublicKey);
+ pub struct XOnlyPublicKey {
+ inner: secp256k1::XOnlyPublicKey,
+ parity: Parity,
+ }
impl XOnlyPublicKey {
- /// Constructs a new x-only public key from the provided generic secp256k1 x-only public key.
- pub fn new(key: impl Into<secp256k1::XOnlyPublicKey>) -> Self { Self(key.into()) }
+ /// Constructs a new x-only public key from the provided secp256k1 x-only public key.
+ ///
+ /// This constructor sets an even parity. Use [`XOnlyPublicKey::with_parity`] if you need
+ /// a different parity value.
+ pub fn new(key: impl Into<secp256k1::XOnlyPublicKey>) -> Self {
+ Self { inner: key.into(), parity: Parity::Even }
+ }
+
+ /// Sets the parity of this [`XOnlyPublicKey`].
+ ///
+ /// This returns a new `XOnlyPublicKey` with the same inner value, but the given parity.
+ pub fn with_parity(self, parity: Parity) -> Self { Self { parity, ..self } }
+
+ /// Returns the parity of this x-only public key.
+ pub fn parity(&self) -> Parity { self.parity }
/// Returns a reference to the inner secp256k1 x-only public key.
#[inline]
- pub fn as_inner(&self) -> &secp256k1::XOnlyPublicKey { &self.0 }
+ pub fn as_inner(&self) -> &secp256k1::XOnlyPublicKey { &self.inner }
/// Returns the inner secp256k1 x-only public key.
#[inline]
- pub fn to_inner(self) -> secp256k1::XOnlyPublicKey { self.0 }
+ pub fn to_inner(self) -> secp256k1::XOnlyPublicKey { self.inner }
/// Returns the inner secp256k1 x-only public key.
#[inline]
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.