diff --git a/src/identity/peer.rs b/src/identity/peer.rs index b6a7fce..06f65f7 100644 --- a/src/identity/peer.rs +++ b/src/identity/peer.rs @@ -24,12 +24,22 @@ impl PeerIdentity { /// /// Note: When only the x-only key is available, the full public key /// will be derived assuming even parity for ECDH operations. + /// + /// Precomputes the even-parity full pubkey eagerly so `pubkey_full()` + /// is a constant-time field load. Without this, every send-side + /// hot-path caller (per-packet) re-derived the full key, spending + /// ~6% of CPU on a secp256k1 EC point parse (`fe_sqrt` + `fe_mul` + + /// `ge_set_xo_var`) for what should be a memoized lookup. The same + /// EC point parse already runs at construction inside + /// `NodeAddr::from_pubkey`, so the cost is paid where it would be + /// paid anyway. pub fn from_pubkey(pubkey: XOnlyPublicKey) -> Self { let node_addr = NodeAddr::from_pubkey(&pubkey); let address = FipsAddress::from_node_addr(&node_addr); + let pubkey_full = pubkey.public_key(Parity::Even); Self { pubkey, - pubkey_full: None, + pubkey_full: Some(pubkey_full), node_addr, address, }