agentic_payments/crypto/
mod.rs1pub 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#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct Signature {
30 #[serde(with = "signature_serde")]
31 inner: Ed25519Signature,
32}
33
34impl Signature {
35 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 pub fn to_bytes(&self) -> [u8; 64] {
46 self.inner.to_bytes()
47 }
48
49 pub fn as_inner(&self) -> &Ed25519Signature {
51 &self.inner
52 }
53
54 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
66mod 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
92pub 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
104pub 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
113pub 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}