miden_tx/auth/
tx_authenticator.rs1use alloc::{collections::BTreeMap, string::ToString, sync::Arc, vec::Vec};
2
3use miden_lib::utils::sync::RwLock;
4use miden_objects::account::{AccountDelta, AuthSecretKey};
5use rand::Rng;
6use vm_processor::{Digest, Felt, Word};
7
8use super::signatures::get_falcon_signature;
9use crate::errors::AuthenticationError;
10
11pub trait TransactionAuthenticator {
22 fn get_signature(
34 &self,
35 pub_key: Word,
36 message: Word,
37 account_delta: &AccountDelta,
38 ) -> Result<Vec<Felt>, AuthenticationError>;
39}
40
41#[derive(Clone, Debug)]
45pub struct BasicAuthenticator<R> {
47 keys: BTreeMap<Digest, AuthSecretKey>,
49 rng: Arc<RwLock<R>>,
50}
51
52impl<R: Rng> BasicAuthenticator<R> {
53 #[cfg(feature = "std")]
54 pub fn new(keys: &[(Word, AuthSecretKey)]) -> BasicAuthenticator<rand::rngs::StdRng> {
55 use rand::{SeedableRng, rngs::StdRng};
56
57 let rng = StdRng::from_os_rng();
58 BasicAuthenticator::<StdRng>::new_with_rng(keys, rng)
59 }
60
61 pub fn new_with_rng(keys: &[(Word, AuthSecretKey)], rng: R) -> Self {
62 let mut key_map = BTreeMap::new();
63 for (word, secret_key) in keys {
64 key_map.insert(word.into(), secret_key.clone());
65 }
66
67 BasicAuthenticator {
68 keys: key_map,
69 rng: Arc::new(RwLock::new(rng)),
70 }
71 }
72}
73
74impl<R: Rng> TransactionAuthenticator for BasicAuthenticator<R> {
75 fn get_signature(
85 &self,
86 pub_key: Word,
87 message: Word,
88 account_delta: &AccountDelta,
89 ) -> Result<Vec<Felt>, AuthenticationError> {
90 let _ = account_delta;
91 let mut rng = self.rng.write();
92
93 match self.keys.get(&pub_key.into()) {
94 Some(key) => match key {
95 AuthSecretKey::RpoFalcon512(falcon_key) => {
96 get_falcon_signature(falcon_key, message, &mut *rng)
97 },
98 },
99 None => Err(AuthenticationError::UnknownPublicKey(format!(
100 "public key {} is not contained in the authenticator's keys",
101 Digest::from(pub_key)
102 ))),
103 }
104 }
105}
106
107impl TransactionAuthenticator for () {
111 fn get_signature(
112 &self,
113 _pub_key: Word,
114 _message: Word,
115 _account_delta: &AccountDelta,
116 ) -> Result<Vec<Felt>, AuthenticationError> {
117 Err(AuthenticationError::RejectedSignature(
118 "default authenticator cannot provide signatures".to_string(),
119 ))
120 }
121}
122
123#[cfg(test)]
124mod test {
125 use miden_lib::utils::{Deserializable, Serializable};
126 use miden_objects::{account::AuthSecretKey, crypto::dsa::rpo_falcon512::SecretKey};
127
128 #[test]
129 fn serialize_auth_key() {
130 let secret_key = SecretKey::new();
131 let auth_key = AuthSecretKey::RpoFalcon512(secret_key.clone());
132 let serialized = auth_key.to_bytes();
133 let deserialized = AuthSecretKey::read_from_bytes(&serialized).unwrap();
134
135 match deserialized {
136 AuthSecretKey::RpoFalcon512(key) => assert_eq!(secret_key.to_bytes(), key.to_bytes()),
137 }
138 }
139}