Skip to main content

ave_identity/keys/
mod.rs

1//! Key and signature primitives.
2//!
3//! The public API is split in two layers:
4//! - [`KeyPair`] for an algorithm-agnostic entry point
5//! - concrete implementations such as [`Ed25519Signer`] when you want the
6//!   algorithm explicitly
7//!
8//! Public keys and signatures carry a one-byte algorithm identifier so they can
9//! be serialized and parsed without extra metadata.
10
11use crate::error::CryptoError;
12use borsh::{BorshDeserialize, BorshSerialize};
13use serde::{Deserialize, Serialize};
14use std::fmt;
15
16// Sub-modules
17mod ed25519;
18mod keypair;
19mod public_key;
20mod signature_identifier;
21
22// Re-exports
23pub use ed25519::{
24    ED25519_ID, ED25519_PUBLIC_KEY_LENGTH, ED25519_SECRET_KEY_LENGTH,
25    ED25519_SIGNATURE_LENGTH, Ed25519Signer,
26};
27pub use keypair::{KeyPair, KeyPairAlgorithm};
28pub use public_key::PublicKey;
29pub use signature_identifier::SignatureIdentifier;
30
31/// Common interface for supported signature algorithms.
32pub trait DSA {
33    /// Returns the one-byte identifier for this algorithm.
34    fn algorithm_id(&self) -> u8;
35
36    /// Returns the signature length, excluding the identifier byte.
37    fn signature_length(&self) -> usize;
38
39    /// Signs `message`.
40    fn sign(&self, message: &[u8]) -> Result<SignatureIdentifier, CryptoError>;
41
42    /// Returns the enum variant for this algorithm.
43    fn algorithm(&self) -> DSAlgorithm;
44
45    /// Returns the raw public key bytes.
46    fn public_key_bytes(&self) -> Vec<u8>;
47}
48
49/// Digital signature algorithms supported by this crate.
50#[derive(
51    Debug,
52    Clone,
53    Copy,
54    PartialEq,
55    Eq,
56    Hash,
57    PartialOrd,
58    Ord,
59    Serialize,
60    Deserialize,
61    BorshSerialize,
62    BorshDeserialize,
63)]
64pub enum DSAlgorithm {
65    Ed25519,
66}
67
68impl DSAlgorithm {
69    /// Returns the one-byte identifier for this algorithm.
70    pub const fn identifier(&self) -> u8 {
71        match self {
72            Self::Ed25519 => ED25519_ID,
73        }
74    }
75
76    /// Returns the signature length, excluding the identifier byte.
77    pub const fn signature_length(&self) -> usize {
78        match self {
79            Self::Ed25519 => ED25519_SIGNATURE_LENGTH,
80        }
81    }
82
83    /// Returns the public key length for this algorithm.
84    pub const fn public_key_length(&self) -> usize {
85        match self {
86            Self::Ed25519 => ED25519_PUBLIC_KEY_LENGTH,
87        }
88    }
89
90    /// Parses an algorithm from its one-byte identifier.
91    pub fn from_identifier(id: u8) -> Result<Self, CryptoError> {
92        match id {
93            ED25519_ID => Ok(Self::Ed25519),
94            _ => Err(CryptoError::UnknownAlgorithm(format!("{}", id as char))),
95        }
96    }
97}
98
99impl fmt::Display for DSAlgorithm {
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101        match self {
102            Self::Ed25519 => write!(f, "Ed25519"),
103        }
104    }
105}
106
107#[cfg(test)]
108mod tests {
109    use super::*;
110
111    #[test]
112    fn test_size_constants() {
113        // Verify our constants match the library constants
114        use ed25519_dalek::{
115            PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH,
116        };
117
118        assert_eq!(ED25519_PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH);
119        assert_eq!(ED25519_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH);
120        assert_eq!(ED25519_SIGNATURE_LENGTH, SIGNATURE_LENGTH);
121    }
122}