agentic_payments/crypto/
mod.rs

1//! Cryptographic operations for agentic-payments
2//!
3//! This module provides Ed25519 signature operations, key management,
4//! DID support, and batch verification capabilities.
5
6pub mod identity;
7pub mod signature;
8pub mod keys;
9pub mod batch;
10
11pub use identity::{AgentIdentity, DidDocument};
12pub use signature::{SignatureManager, SignatureResult};
13pub use keys::{KeyPair, KeyManager, StoredKey};
14pub use batch::{BatchVerifier, BatchResult, VerificationItem};
15
16use crate::error::{CryptoError, Error, Result};
17use ed25519_dalek::{
18    Signature as Ed25519Signature,
19    Signer,
20    Verifier,
21    VerifyingKey,
22    SigningKey,
23};
24use serde::{Deserialize, Serialize};
25use zeroize::Zeroize;
26
27/// Ed25519 signature wrapper with serialization support
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct Signature {
30    #[serde(with = "signature_serde")]
31    inner: Ed25519Signature,
32}
33
34impl Signature {
35    /// Create a new signature from bytes
36    pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
37        let inner = Ed25519Signature::from_slice(bytes)
38            .map_err(|e| Error::Crypto(CryptoError::InvalidSignature {
39                details: format!("Invalid signature bytes: {}", e),
40            }))?;
41        Ok(Self { inner })
42    }
43
44    /// Get the signature as bytes
45    pub fn to_bytes(&self) -> [u8; 64] {
46        self.inner.to_bytes()
47    }
48
49    /// Get a reference to the inner Ed25519 signature
50    pub fn as_inner(&self) -> &Ed25519Signature {
51        &self.inner
52    }
53
54    /// Convert to inner Ed25519 signature
55    pub fn into_inner(self) -> Ed25519Signature {
56        self.inner
57    }
58}
59
60impl From<Ed25519Signature> for Signature {
61    fn from(inner: Ed25519Signature) -> Self {
62        Self { inner }
63    }
64}
65
66// Note: AsRef<[u8]> removed because Ed25519Signature::to_bytes() returns by value
67// Use Signature::to_bytes() instead
68
69/// Serialization module for Ed25519 signatures
70mod signature_serde {
71    use super::*;
72    use serde::{Deserializer, Serializer};
73
74    pub fn serialize<S>(sig: &Ed25519Signature, serializer: S) -> std::result::Result<S::Ok, S::Error>
75    where
76        S: Serializer,
77    {
78        let bytes = sig.to_bytes();
79        serializer.serialize_bytes(&bytes)
80    }
81
82    pub fn deserialize<'de, D>(deserializer: D) -> std::result::Result<Ed25519Signature, D::Error>
83    where
84        D: Deserializer<'de>,
85    {
86        let bytes: Vec<u8> = serde::Deserialize::deserialize(deserializer)?;
87        Ed25519Signature::from_slice(&bytes)
88            .map_err(|e| serde::de::Error::custom(format!("Invalid signature: {}", e)))
89    }
90}
91
92/// Verify a single Ed25519 signature
93pub fn verify_signature(
94    public_key: &VerifyingKey,
95    message: &[u8],
96    signature: &Signature,
97) -> Result<bool> {
98    match public_key.verify(message, signature.as_inner()) {
99        Ok(_) => Ok(true),
100        Err(_) => Ok(false),
101    }
102}
103
104/// Sign a message with Ed25519
105pub fn sign_message(
106    signing_key: &SigningKey,
107    message: &[u8],
108) -> Result<Signature> {
109    let signature = signing_key.sign(message);
110    Ok(Signature::from(signature))
111}
112
113/// Generate a new Ed25519 keypair
114pub fn generate_keypair() -> Result<(SigningKey, VerifyingKey)> {
115    let mut rng = rand::rngs::OsRng;
116    let signing_key = SigningKey::generate(&mut rng);
117    let verifying_key = signing_key.verifying_key();
118    Ok((signing_key, verifying_key))
119}
120
121#[cfg(test)]
122mod tests {
123    use super::*;
124
125    #[test]
126    fn test_signature_roundtrip() {
127        let (signing_key, verifying_key) = generate_keypair().unwrap();
128        let message = b"test message";
129
130        let signature = sign_message(&signing_key, message).unwrap();
131        let is_valid = verify_signature(&verifying_key, message, &signature).unwrap();
132
133        assert!(is_valid);
134    }
135
136    #[test]
137    fn test_signature_bytes() {
138        let (signing_key, _) = generate_keypair().unwrap();
139        let message = b"test message";
140
141        let signature = sign_message(&signing_key, message).unwrap();
142        let bytes = signature.to_bytes();
143        let restored = Signature::from_bytes(&bytes).unwrap();
144
145        assert_eq!(signature.to_bytes(), restored.to_bytes());
146    }
147
148    #[test]
149    fn test_invalid_signature() {
150        let (_, verifying_key) = generate_keypair().unwrap();
151        let (other_signing_key, _) = generate_keypair().unwrap();
152
153        let message = b"test message";
154        let signature = sign_message(&other_signing_key, message).unwrap();
155
156        let is_valid = verify_signature(&verifying_key, message, &signature).unwrap();
157        assert!(!is_valid);
158    }
159
160    #[test]
161    fn test_signature_serialization() {
162        let (signing_key, _) = generate_keypair().unwrap();
163        let message = b"test message";
164
165        let signature = sign_message(&signing_key, message).unwrap();
166        let json = serde_json::to_string(&signature).unwrap();
167        let restored: Signature = serde_json::from_str(&json).unwrap();
168
169        assert_eq!(signature.to_bytes(), restored.to_bytes());
170    }
171}