mirror of
https://github.com/jmcorgan/fips.git
synced 2026-07-22 07:48:26 +00:00
Add rustfmt.toml with stable defaults and apply cargo fmt to all source files. This establishes a consistent formatting baseline for CI enforcement.
78 lines
2.1 KiB
Rust
78 lines
2.1 KiB
Rust
//! 16-byte node identifier derived from truncated SHA-256(pubkey).
|
|
|
|
use secp256k1::XOnlyPublicKey;
|
|
use sha2::{Digest, Sha256};
|
|
use std::fmt;
|
|
|
|
use super::{IdentityError, hex_encode};
|
|
|
|
/// 16-byte node identifier derived from truncated SHA-256(pubkey).
|
|
///
|
|
/// The node_addr is the first 16 bytes of SHA-256(pubkey), providing 128 bits
|
|
/// of collision resistance. Hashing the public key prevents grinding attacks
|
|
/// that exploit secp256k1's algebraic structure.
|
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
pub struct NodeAddr([u8; 16]);
|
|
|
|
impl NodeAddr {
|
|
/// Create a NodeAddr from a 16-byte array.
|
|
pub fn from_bytes(bytes: [u8; 16]) -> Self {
|
|
Self(bytes)
|
|
}
|
|
|
|
/// Create a NodeAddr from a slice.
|
|
pub fn from_slice(slice: &[u8]) -> Result<Self, IdentityError> {
|
|
if slice.len() != 16 {
|
|
return Err(IdentityError::InvalidNodeAddrLength(slice.len()));
|
|
}
|
|
let mut bytes = [0u8; 16];
|
|
bytes.copy_from_slice(slice);
|
|
Ok(Self(bytes))
|
|
}
|
|
|
|
/// Derive a NodeAddr from an x-only public key (npub).
|
|
///
|
|
/// Computes SHA-256(pubkey) and takes the first 16 bytes.
|
|
pub fn from_pubkey(pubkey: &XOnlyPublicKey) -> Self {
|
|
let mut hasher = Sha256::new();
|
|
hasher.update(pubkey.serialize());
|
|
let hash = hasher.finalize();
|
|
let mut bytes = [0u8; 16];
|
|
bytes.copy_from_slice(&hash[..16]);
|
|
Self(bytes)
|
|
}
|
|
|
|
/// Return the raw bytes.
|
|
pub fn as_bytes(&self) -> &[u8; 16] {
|
|
&self.0
|
|
}
|
|
|
|
/// Return the bytes as a slice.
|
|
pub fn as_slice(&self) -> &[u8] {
|
|
&self.0
|
|
}
|
|
|
|
/// Return a short hex representation: first 4 bytes + "...".
|
|
pub fn short_hex(&self) -> String {
|
|
format!("{}...", hex_encode(&self.0[..4]))
|
|
}
|
|
}
|
|
|
|
impl fmt::Debug for NodeAddr {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "NodeAddr({})", hex_encode(&self.0[..8]))
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for NodeAddr {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", hex_encode(&self.0))
|
|
}
|
|
}
|
|
|
|
impl AsRef<[u8]> for NodeAddr {
|
|
fn as_ref(&self) -> &[u8] {
|
|
&self.0
|
|
}
|
|
}
|