miden_testing/mock_chain/
auth.rs

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