Skip to main content

ave_identity/keys/
mod.rs

1//! Cryptographic keys and digital signatures with algorithm identification
2//!
3//! This module provides a generic interface for digital signature algorithms with automatic
4//! algorithm identification via 1-byte prefixes.
5//!
6//! ## Example
7//!
8//! ```rust
9//! use ave_identity::keys::{KeyPair, KeyPairAlgorithm, DSA};
10//!
11//! // Generate a key pair (algorithm-agnostic)
12//! let keypair = KeyPair::generate(KeyPairAlgorithm::Ed25519).expect("Failed to generate key pair");
13//!
14//! let message = b"Hello, World!";
15//!
16//! // Sign message using generic interface
17//! let signature = keypair.sign(message).unwrap();
18//!
19//! // Convert to string (includes algorithm identifier)
20//! let sig_str = signature.to_string();
21//!
22//! // Get public key
23//! let public_key = keypair.public_key();
24//!
25//! // Verify signature
26//! assert!(public_key.verify(message, &signature).is_ok());
27//! ```
28//!
29//! ## Direct Algorithm Usage
30//!
31//! You can also use specific algorithm implementations directly:
32//!
33//! ```rust
34//! use ave_identity::keys::{DSA, Ed25519Signer};
35//!
36//! let signer = Ed25519Signer::generate().unwrap();
37//! let signature = signer.sign(b"message").unwrap();
38//! ```
39
40use crate::error::CryptoError;
41use borsh::{BorshDeserialize, BorshSerialize};
42use serde::{Deserialize, Serialize};
43use std::fmt;
44
45// Sub-modules
46mod ed25519;
47mod keypair;
48mod public_key;
49mod signature_identifier;
50
51// Re-exports
52pub use ed25519::{
53    ED25519_ID, ED25519_PUBLIC_KEY_LENGTH, ED25519_SECRET_KEY_LENGTH,
54    ED25519_SIGNATURE_LENGTH, Ed25519Signer,
55};
56pub use keypair::{KeyPair, KeyPairAlgorithm};
57pub use public_key::PublicKey;
58pub use signature_identifier::SignatureIdentifier;
59
60/// Trait for digital signature algorithms with algorithm identification
61pub trait DSA {
62    /// Get the algorithm identifier (1 byte)
63    fn algorithm_id(&self) -> u8;
64
65    /// Get the expected signature length in bytes (excluding identifier)
66    fn signature_length(&self) -> usize;
67
68    /// Sign the message
69    fn sign(&self, message: &[u8]) -> Result<SignatureIdentifier, CryptoError>;
70
71    /// Get the algorithm enum variant
72    fn algorithm(&self) -> DSAlgorithm;
73
74    /// Get the public key bytes
75    fn public_key_bytes(&self) -> Vec<u8>;
76}
77
78/// Enumeration of supported digital signature algorithms
79#[derive(
80    Debug,
81    Clone,
82    Copy,
83    PartialEq,
84    Eq,
85    Hash,
86    PartialOrd,
87    Ord,
88    Serialize,
89    Deserialize,
90    BorshSerialize,
91    BorshDeserialize,
92)]
93pub enum DSAlgorithm {
94    Ed25519,
95}
96
97impl DSAlgorithm {
98    /// Get the 1-byte identifier for this algorithm
99    pub fn identifier(&self) -> u8 {
100        match self {
101            DSAlgorithm::Ed25519 => ED25519_ID,
102        }
103    }
104
105    /// Get the signature length for this algorithm (excluding identifier)
106    pub fn signature_length(&self) -> usize {
107        match self {
108            DSAlgorithm::Ed25519 => ED25519_SIGNATURE_LENGTH,
109        }
110    }
111
112    /// Get the public key length for this algorithm
113    pub fn public_key_length(&self) -> usize {
114        match self {
115            DSAlgorithm::Ed25519 => ED25519_PUBLIC_KEY_LENGTH,
116        }
117    }
118
119    /// Parse algorithm from 1-byte identifier
120    pub fn from_identifier(id: u8) -> Result<Self, CryptoError> {
121        match id {
122            ED25519_ID => Ok(DSAlgorithm::Ed25519),
123            _ => Err(CryptoError::UnknownAlgorithm(format!("{}", id as char))),
124        }
125    }
126}
127
128impl fmt::Display for DSAlgorithm {
129    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
130        match self {
131            DSAlgorithm::Ed25519 => write!(f, "Ed25519"),
132        }
133    }
134}
135
136#[cfg(test)]
137mod tests {
138    use super::*;
139
140    #[test]
141    fn test_size_constants() {
142        // Verify our constants match the library constants
143        use ed25519_dalek::{
144            PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, SIGNATURE_LENGTH,
145        };
146
147        assert_eq!(ED25519_PUBLIC_KEY_LENGTH, PUBLIC_KEY_LENGTH);
148        assert_eq!(ED25519_SECRET_KEY_LENGTH, SECRET_KEY_LENGTH);
149        assert_eq!(ED25519_SIGNATURE_LENGTH, SIGNATURE_LENGTH);
150    }
151}