summaryrefslogtreecommitdiffstats
path: root/src/identity.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-27 01:31:58 +0100
committertv <tv@krebsco.de>2026-10-27 01:31:58 +0100
commit4cdece6d0f8e25ac154c3fd0f30bca604b08c16a (patch)
tree10a6aab1793d1c4fd0bd53c16b600f1adf986cb9 /src/identity.rs
parent5fd686dcd8ddfbdf276c044e5acf03f744e03193 (diff)
add identity layer
Diffstat (limited to 'src/identity.rs')
-rw-r--r--src/identity.rs43
1 files changed, 38 insertions, 5 deletions
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.
@@ -144,6 +166,17 @@ mod tests {
}
#[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();
assert!(is_node_id(&id));