extrakeys: check invariant that x-only pubkeys have even Y
What changed, and why it matters
This commit adds a debug-only safety check inside a Bitcoin cryptography library. It verifies that when an x-only public key (a compressed public key format that omits the Y coordinate) is saved, the internal representation has an even Y value, as the protocol definition requires. The check only runs in VERIFY builds and does not change production behavior. It is a defensive invariant, not a fix for a known exploitable bug.
No urgent action required. Treat as a minor hardening commit. Review whether the invariant could be violated by any caller and consider adding a runtime check if the invariant is safety-critical outside debug builds. Users on release builds are unaffected.
Security signals we found
Defensive invariant assertion added under VERIFY macro
X-only public key parity invariant enforced
No functional code path change in non-VERIFY builds
No input validation or parsing logic modified
Evidence from the diff
In secp256k1’s extrakeys module, secp256k1_xonly_pubkey_save() now asserts under #ifdef VERIFY that the group element ge has an even Y coordinate. X-only public keys are defined to encode the point with even Y (BIP340), so this invariant should always hold. The check uses secp256k1_fe_normalize_var and secp256k1_fe_is_odd, then calls VERIFY_CHECK. It is purely defensive and active only in verification builds; release builds are unaffected.
Changed components
src/modules/extrakeys/main_impl.hsecp256k1_xonly_pubkey_save functionBIP340 x-only public key serialization pathInspect captured patch +7 / −0
diff --git a/src/modules/extrakeys/main_impl.h b/src/modules/extrakeys/main_impl.h
index 0c7e266..163ea28 100644
--- a/src/modules/extrakeys/main_impl.h
+++ b/src/modules/extrakeys/main_impl.h
@@ -16,6 +16,13 @@ static SECP256K1_INLINE int secp256k1_xonly_pubkey_load(const secp256k1_context*
}
static SECP256K1_INLINE void secp256k1_xonly_pubkey_save(secp256k1_xonly_pubkey *pubkey, secp256k1_ge *ge) {
+#ifdef VERIFY
+ /* ensure that the group element's Y coordinate is even, as per definition of x-only public keys */
+ secp256k1_fe y = ge->y;
+ secp256k1_fe_normalize_var(&y);
+ VERIFY_CHECK(!secp256k1_fe_is_odd(&y));
+#endif
+
secp256k1_pubkey_save((secp256k1_pubkey *) pubkey, ge);
}
Why this scored 26/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.