From 4cdece6d0f8e25ac154c3fd0f30bca604b08c16a Mon Sep 17 00:00:00 2001 From: tv Date: Tue, 27 Oct 2026 01:31:58 +0100 Subject: add identity layer --- src/identity.rs | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) (limited to 'src/identity.rs') diff --git a/src/identity.rs b/src/identity.rs index 8f7fdda..93d8739 100644 --- a/src/identity.rs +++ b/src/identity.rs @@ -59,7 +59,8 @@ impl NodeKey { Ok(Self::from_seed(seed)) } - fn from_seed(seed: [u8; KEY_BYTES]) -> Self { + /// A key from its 32 secret bytes: for simulated nodes, which have no key files. + pub(crate) fn from_seed(seed: [u8; KEY_BYTES]) -> Self { Self { signing: SigningKey::from_bytes(&seed), } @@ -87,11 +88,32 @@ impl NodeKey { /// This node's ID. pub(crate) fn id(&self) -> String { - format!( - "{NODE_ID_PREFIX}{}", - Hex(self.signing.verifying_key().as_bytes()) - ) + node_id_of(&self.public()) } + + /// The public key, as others check signatures with it. + pub(crate) fn public(&self) -> [u8; 32] { + self.signing.verifying_key().to_bytes() + } + + pub(crate) fn sign(&self, message: &[u8]) -> [u8; 64] { + use ed25519_dalek::Signer; + self.signing.sign(message).to_bytes() + } +} + +/// The node ID of the node with public key `key`. +pub(crate) fn node_id_of(key: &[u8; 32]) -> String { + format!("{NODE_ID_PREFIX}{}", Hex(key)) +} + +/// Whether `signature` is `key`'s over `message`. +pub(crate) fn verify(key: &[u8; 32], message: &[u8], signature: &[u8; 64]) -> bool { + let Ok(key) = ed25519_dalek::VerifyingKey::from_bytes(key) else { + return false; + }; + key.verify_strict(message, &ed25519_dalek::Signature::from_bytes(signature)) + .is_ok() } /// Whether `id` has the form of a node ID. @@ -143,6 +165,17 @@ mod tests { assert!(NodeKey::load(&path, true).is_err()); } + #[test] + fn signatures() { + let key = NodeKey::from_seed([2; KEY_BYTES]); + let signature = key.sign(b"message"); + assert!(verify(&key.public(), b"message", &signature)); + assert!(!verify(&key.public(), b"massage", &signature)); + let other = NodeKey::from_seed([3; KEY_BYTES]); + assert!(!verify(&other.public(), b"message", &signature)); + assert_eq!(node_id_of(&key.public()), key.id()); + } + #[test] fn node_ids() { let id = NodeKey::from_seed([1; KEY_BYTES]).id(); -- cgit v1.3.1