miden_standards/account/auth/
singlesig.rs1use miden_protocol::Word;
2use miden_protocol::account::auth::{AuthScheme, PublicKey};
3use miden_protocol::account::component::{
4 AccountComponentCode,
5 AccountComponentMetadata,
6 SchemaType,
7 StorageSchema,
8 StorageSlotSchema,
9};
10use miden_protocol::account::{
11 AccountComponent,
12 AccountComponentName,
13 StorageSlot,
14 StorageSlotName,
15};
16use miden_protocol::crypto::dsa::{ecdsa_k256_keccak, falcon512_poseidon2};
17use miden_protocol::utils::sync::LazyLock;
18
19use super::Approver;
20use crate::account::account_component_code;
21
22account_component_code!(SINGLESIG_CODE, "miden-standards-auth-singlesig.masp");
23
24static PUBKEY_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
28 StorageSlotName::new("miden::standards::auth::singlesig::pub_key")
29 .expect("storage slot name should be valid")
30});
31
32static SCHEME_ID_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
33 StorageSlotName::new("miden::standards::auth::singlesig::scheme")
34 .expect("storage slot name should be valid")
35});
36
37pub struct AuthSingleSig {
59 approver: Approver,
60}
61
62impl AuthSingleSig {
63 pub const NAME: &'static str = "miden::standards::auth::singlesig";
65
66 pub const fn name() -> AccountComponentName {
68 AccountComponentName::from_static_str(Self::NAME)
69 }
70
71 pub fn code() -> &'static AccountComponentCode {
73 &SINGLESIG_CODE
74 }
75
76 pub fn new(approver: Approver) -> Self {
78 Self { approver }
79 }
80
81 pub fn falcon512_poseidon2(pub_key: falcon512_poseidon2::PublicKey) -> Self {
85 Self {
86 approver: Approver::new(pub_key.into(), AuthScheme::Falcon512Poseidon2),
87 }
88 }
89
90 pub fn ecdsa_k256_keccak(pub_key: ecdsa_k256_keccak::PublicKey) -> Self {
101 Self {
102 approver: Approver::new(pub_key.into(), AuthScheme::EcdsaK256Keccak),
103 }
104 }
105
106 pub fn from_public_key(pub_key: PublicKey) -> Self {
110 Self {
111 approver: Approver::new(pub_key.to_commitment(), pub_key.auth_scheme()),
112 }
113 }
114
115 pub fn approver(&self) -> Approver {
117 self.approver
118 }
119
120 pub fn public_key_slot() -> &'static StorageSlotName {
122 &PUBKEY_SLOT_NAME
123 }
124
125 pub fn scheme_id_slot() -> &'static StorageSlotName {
127 &SCHEME_ID_SLOT_NAME
128 }
129
130 pub fn public_key_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
132 (
133 Self::public_key_slot().clone(),
134 StorageSlotSchema::value("Public key commitment", SchemaType::pub_key()),
135 )
136 }
137 pub fn auth_scheme_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
139 (
140 Self::scheme_id_slot().clone(),
141 StorageSlotSchema::value("Scheme ID", SchemaType::auth_scheme()),
142 )
143 }
144
145 pub fn component_metadata() -> AccountComponentMetadata {
147 let storage_schema = StorageSchema::new(vec![
148 Self::public_key_slot_schema(),
149 Self::auth_scheme_slot_schema(),
150 ])
151 .expect("storage schema should be valid");
152
153 AccountComponentMetadata::new(Self::NAME)
154 .with_description(
155 "Authentication component using ECDSA K256 Keccak or Falcon512 Poseidon2 signature scheme",
156 )
157 .with_storage_schema(storage_schema)
158 }
159}
160
161impl From<AuthSingleSig> for AccountComponent {
162 fn from(basic_signature: AuthSingleSig) -> Self {
163 let metadata = AuthSingleSig::component_metadata();
164
165 let storage_slots = vec![
166 StorageSlot::with_value(
167 AuthSingleSig::public_key_slot().clone(),
168 basic_signature.approver.pub_key().into(),
169 ),
170 StorageSlot::with_value(
171 AuthSingleSig::scheme_id_slot().clone(),
172 Word::from([basic_signature.approver.auth_scheme().as_u8(), 0, 0, 0]),
173 ),
174 ];
175
176 AccountComponent::new(AuthSingleSig::code().clone(), storage_slots, metadata).expect(
177 "singlesig component should satisfy the requirements of a valid account component",
178 )
179 }
180}