Skip to main content

rns_embedded_core/
identity.rs

1use crate::{EmbeddedError, EmbeddedResult};
2
3#[derive(Debug, Clone, Eq, PartialEq)]
4pub struct EmbeddedIdentity {
5    pub id: [u8; 32],
6    pub verify_key: [u8; 32],
7}
8
9impl EmbeddedIdentity {
10    pub fn new(id: [u8; 32], verify_key: [u8; 32]) -> EmbeddedResult<Self> {
11        if id == [0; 32] || verify_key == [0; 32] {
12            return Err(EmbeddedError::InvalidInput);
13        }
14        Ok(Self { id, verify_key })
15    }
16}
17
18pub trait IdentityProvider {
19    fn active_identity(&self) -> EmbeddedResult<EmbeddedIdentity>;
20}
21
22#[derive(Debug, Clone, Eq, PartialEq)]
23pub struct Signature(pub [u8; 64]);
24
25pub trait PayloadSigner {
26    fn sign(&self, payload: &[u8]) -> EmbeddedResult<Signature>;
27}
28
29pub trait PayloadVerifier {
30    fn verify(&self, payload: &[u8], signature: &Signature) -> EmbeddedResult<bool>;
31}
32
33pub fn sign_payload(signer: &dyn PayloadSigner, payload: &[u8]) -> EmbeddedResult<Signature> {
34    if payload.is_empty() {
35        return Err(EmbeddedError::InvalidInput);
36    }
37    signer.sign(payload)
38}
39
40pub fn verify_payload(
41    verifier: &dyn PayloadVerifier,
42    payload: &[u8],
43    signature: &Signature,
44) -> EmbeddedResult<bool> {
45    if payload.is_empty() {
46        return Err(EmbeddedError::InvalidInput);
47    }
48    verifier.verify(payload, signature)
49}
50
51#[cfg(test)]
52mod tests {
53    use super::{sign_payload, verify_payload, PayloadSigner, PayloadVerifier, Signature};
54    use crate::{hash::digest32, EmbeddedError, EmbeddedResult};
55
56    struct FakeCrypto;
57
58    impl PayloadSigner for FakeCrypto {
59        fn sign(&self, payload: &[u8]) -> EmbeddedResult<Signature> {
60            let digest = digest32(payload);
61            let mut sig = [0_u8; 64];
62            sig[..32].copy_from_slice(&digest);
63            sig[32..].copy_from_slice(&digest);
64            Ok(Signature(sig))
65        }
66    }
67
68    impl PayloadVerifier for FakeCrypto {
69        fn verify(&self, payload: &[u8], signature: &Signature) -> EmbeddedResult<bool> {
70            let expected = self.sign(payload)?;
71            Ok(signature == &expected)
72        }
73    }
74
75    #[test]
76    fn sign_then_verify() {
77        let crypto = FakeCrypto;
78        let payload = b"embedded-node";
79        let signature = sign_payload(&crypto, payload).expect("sign");
80        assert!(verify_payload(&crypto, payload, &signature).expect("verify"));
81        assert!(!verify_payload(&crypto, b"different", &signature).expect("verify mismatch"));
82    }
83
84    #[test]
85    fn empty_payload_is_rejected() {
86        let crypto = FakeCrypto;
87        let err = sign_payload(&crypto, b"").expect_err("empty payload rejected");
88        assert_eq!(err, EmbeddedError::InvalidInput);
89    }
90}