miden_testing/mock_chain/
auth.rs

1// AUTH
2// ================================================================================================
3use alloc::vec::Vec;
4
5use miden_lib::account::auth::{
6    AuthEcdsaK256Keccak,
7    AuthEcdsaK256KeccakAcl,
8    AuthEcdsaK256KeccakAclConfig,
9    AuthEcdsaK256KeccakMultisig,
10    AuthEcdsaK256KeccakMultisigConfig,
11    AuthRpoFalcon512,
12    AuthRpoFalcon512Acl,
13    AuthRpoFalcon512AclConfig,
14    AuthRpoFalcon512Multisig,
15    AuthRpoFalcon512MultisigConfig,
16};
17use miden_lib::testing::account_component::{ConditionalAuthComponent, IncrNonceAuthComponent};
18use miden_objects::Word;
19use miden_objects::account::AccountComponent;
20use miden_objects::account::auth::{AuthSecretKey, PublicKeyCommitment};
21use miden_objects::testing::noop_auth_component::NoopAuthComponent;
22use miden_tx::auth::BasicAuthenticator;
23use rand::SeedableRng;
24use rand_chacha::ChaCha20Rng;
25
26/// Specifies which authentication mechanism is desired for accounts
27#[derive(Debug, Clone)]
28pub enum Auth {
29    /// Creates a secret key for the account and creates a [BasicAuthenticator] used to
30    /// authenticate the account with [AuthRpoFalcon512].
31    BasicAuth,
32
33    /// Creates a secret key for the account and creates a [BasicAuthenticator] used to
34    /// authenticate the account with [AuthEcdsaK256Keccak].
35    EcdsaK256KeccakAuth,
36
37    /// Creates a secret key for the account, and creates a [BasicAuthenticator] used to
38    /// authenticate the account with [AuthEcdsaK256KeccakAcl]. Authentication will only be
39    /// triggered if any of the procedures specified in the list are called during execution.
40    EcdsaK256KeccakAcl {
41        auth_trigger_procedures: Vec<Word>,
42        allow_unauthorized_output_notes: bool,
43        allow_unauthorized_input_notes: bool,
44    },
45
46    // Ecsda Multisig
47    EcdsaK256KeccakMultisig {
48        threshold: u32,
49        approvers: Vec<Word>,
50        proc_threshold_map: Vec<(Word, u32)>,
51    },
52
53    /// Multisig
54    Multisig {
55        threshold: u32,
56        approvers: Vec<Word>,
57        proc_threshold_map: Vec<(Word, u32)>,
58    },
59
60    /// Creates a secret key for the account, and creates a [BasicAuthenticator] used to
61    /// authenticate the account with [AuthRpoFalcon512Acl]. Authentication will only be
62    /// triggered if any of the procedures specified in the list are called during execution.
63    Acl {
64        auth_trigger_procedures: Vec<Word>,
65        allow_unauthorized_output_notes: bool,
66        allow_unauthorized_input_notes: bool,
67    },
68
69    /// Creates a mock authentication mechanism for the account that only increments the nonce.
70    IncrNonce,
71
72    /// Creates a mock authentication mechanism for the account that does nothing.
73    Noop,
74
75    /// Creates a mock authentication mechanism for the account that conditionally succeeds and
76    /// conditionally increments the nonce based on the authentication arguments.
77    ///
78    /// The auth procedure expects the first three arguments as [99, 98, 97] to succeed.
79    /// In case it succeeds, it conditionally increments the nonce based on the fourth argument.
80    Conditional,
81}
82
83impl Auth {
84    /// Converts `self` into its corresponding authentication [`AccountComponent`] and an optional
85    /// [`BasicAuthenticator`]. The component is always returned, but the authenticator is only
86    /// `Some` when [`Auth::BasicAuth`] is passed."
87    pub fn build_component(&self) -> (AccountComponent, Option<BasicAuthenticator>) {
88        match self {
89            Auth::BasicAuth => {
90                let mut rng = ChaCha20Rng::from_seed(Default::default());
91                let sec_key = AuthSecretKey::new_rpo_falcon512_with_rng(&mut rng);
92                let pub_key = sec_key.public_key().to_commitment();
93
94                let component = AuthRpoFalcon512::new(pub_key).into();
95                let authenticator = BasicAuthenticator::new(&[sec_key]);
96
97                (component, Some(authenticator))
98            },
99            Auth::EcdsaK256KeccakAuth => {
100                let mut rng = ChaCha20Rng::from_seed(Default::default());
101                let sec_key = AuthSecretKey::new_ecdsa_k256_keccak_with_rng(&mut rng);
102                let pub_key = sec_key.public_key().to_commitment();
103
104                let component = AuthEcdsaK256Keccak::new(pub_key).into();
105                let authenticator = BasicAuthenticator::new(&[sec_key]);
106
107                (component, Some(authenticator))
108            },
109            Auth::EcdsaK256KeccakMultisig { threshold, approvers, proc_threshold_map } => {
110                let pub_keys: Vec<_> =
111                    approvers.iter().map(|word| PublicKeyCommitment::from(*word)).collect();
112
113                let config = AuthEcdsaK256KeccakMultisigConfig::new(pub_keys, *threshold)
114                    .and_then(|cfg| cfg.with_proc_thresholds(proc_threshold_map.clone()))
115                    .expect("invalid multisig config");
116                let component = AuthEcdsaK256KeccakMultisig::new(config)
117                    .expect("multisig component creation failed")
118                    .into();
119
120                (component, None)
121            },
122            Auth::Multisig { threshold, approvers, proc_threshold_map } => {
123                let pub_keys: Vec<_> =
124                    approvers.iter().map(|word| PublicKeyCommitment::from(*word)).collect();
125
126                let config = AuthRpoFalcon512MultisigConfig::new(pub_keys, *threshold)
127                    .and_then(|cfg| cfg.with_proc_thresholds(proc_threshold_map.clone()))
128                    .expect("invalid multisig config");
129                let component = AuthRpoFalcon512Multisig::new(config)
130                    .expect("multisig component creation failed")
131                    .into();
132
133                (component, None)
134            },
135            Auth::Acl {
136                auth_trigger_procedures,
137                allow_unauthorized_output_notes,
138                allow_unauthorized_input_notes,
139            } => {
140                let mut rng = ChaCha20Rng::from_seed(Default::default());
141                let sec_key = AuthSecretKey::new_rpo_falcon512_with_rng(&mut rng);
142                let pub_key = sec_key.public_key().to_commitment();
143
144                let component = AuthRpoFalcon512Acl::new(
145                    pub_key,
146                    AuthRpoFalcon512AclConfig::new()
147                        .with_auth_trigger_procedures(auth_trigger_procedures.clone())
148                        .with_allow_unauthorized_output_notes(*allow_unauthorized_output_notes)
149                        .with_allow_unauthorized_input_notes(*allow_unauthorized_input_notes),
150                )
151                .expect("component creation failed")
152                .into();
153                let authenticator = BasicAuthenticator::new(&[sec_key]);
154
155                (component, Some(authenticator))
156            },
157            Auth::EcdsaK256KeccakAcl {
158                auth_trigger_procedures,
159                allow_unauthorized_output_notes,
160                allow_unauthorized_input_notes,
161            } => {
162                let mut rng = ChaCha20Rng::from_seed(Default::default());
163                let sec_key = AuthSecretKey::new_ecdsa_k256_keccak_with_rng(&mut rng);
164                let pub_key = sec_key.public_key().to_commitment();
165
166                let component = AuthEcdsaK256KeccakAcl::new(
167                    pub_key,
168                    AuthEcdsaK256KeccakAclConfig::new()
169                        .with_auth_trigger_procedures(auth_trigger_procedures.clone())
170                        .with_allow_unauthorized_output_notes(*allow_unauthorized_output_notes)
171                        .with_allow_unauthorized_input_notes(*allow_unauthorized_input_notes),
172                )
173                .expect("component creation failed")
174                .into();
175                let authenticator = BasicAuthenticator::new(&[sec_key]);
176
177                (component, Some(authenticator))
178            },
179            Auth::IncrNonce => (IncrNonceAuthComponent.into(), None),
180            Auth::Noop => (NoopAuthComponent.into(), None),
181            Auth::Conditional => (ConditionalAuthComponent.into(), None),
182        }
183    }
184}
185
186impl From<Auth> for AccountComponent {
187    fn from(auth: Auth) -> Self {
188        let (component, _) = auth.build_component();
189        component
190    }
191}