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 {
50 approver: Approver,
51}
52
53impl AuthSingleSig {
54 pub const NAME: &'static str = "miden::standards::components::auth::singlesig";
56
57 pub const fn name() -> AccountComponentName {
59 AccountComponentName::from_static_str(Self::NAME)
60 }
61
62 pub fn code() -> &'static AccountComponentCode {
64 &SINGLESIG_CODE
65 }
66
67 pub fn new(approver: Approver) -> Self {
69 Self { approver }
70 }
71
72 pub fn falcon512_poseidon2(pub_key: falcon512_poseidon2::PublicKey) -> Self {
76 Self {
77 approver: Approver::new(pub_key.into(), AuthScheme::Falcon512Poseidon2),
78 }
79 }
80
81 pub fn ecdsa_k256_keccak(pub_key: ecdsa_k256_keccak::PublicKey) -> Self {
92 Self {
93 approver: Approver::new(pub_key.into(), AuthScheme::EcdsaK256Keccak),
94 }
95 }
96
97 pub fn from_public_key(pub_key: PublicKey) -> Self {
101 Self {
102 approver: Approver::new(pub_key.to_commitment(), pub_key.auth_scheme()),
103 }
104 }
105
106 pub fn approver(&self) -> Approver {
108 self.approver
109 }
110
111 pub fn public_key_slot() -> &'static StorageSlotName {
113 &PUBKEY_SLOT_NAME
114 }
115
116 pub fn scheme_id_slot() -> &'static StorageSlotName {
118 &SCHEME_ID_SLOT_NAME
119 }
120
121 pub fn public_key_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
123 (
124 Self::public_key_slot().clone(),
125 StorageSlotSchema::value("Public key commitment", SchemaType::pub_key()),
126 )
127 }
128 pub fn auth_scheme_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
130 (
131 Self::scheme_id_slot().clone(),
132 StorageSlotSchema::value("Scheme ID", SchemaType::auth_scheme()),
133 )
134 }
135
136 pub fn component_metadata() -> AccountComponentMetadata {
138 let storage_schema = StorageSchema::new(vec![
139 Self::public_key_slot_schema(),
140 Self::auth_scheme_slot_schema(),
141 ])
142 .expect("storage schema should be valid");
143
144 AccountComponentMetadata::new(Self::NAME)
145 .with_description(
146 "Authentication component using ECDSA K256 Keccak or Falcon512 Poseidon2 signature scheme",
147 )
148 .with_storage_schema(storage_schema)
149 }
150}
151
152impl From<AuthSingleSig> for AccountComponent {
153 fn from(basic_signature: AuthSingleSig) -> Self {
154 let metadata = AuthSingleSig::component_metadata();
155
156 let storage_slots = vec![
157 StorageSlot::with_value(
158 AuthSingleSig::public_key_slot().clone(),
159 basic_signature.approver.pub_key().into(),
160 ),
161 StorageSlot::with_value(
162 AuthSingleSig::scheme_id_slot().clone(),
163 Word::from([basic_signature.approver.auth_scheme().as_u8(), 0, 0, 0]),
164 ),
165 ];
166
167 AccountComponent::new(AuthSingleSig::code().clone(), storage_slots, metadata).expect(
168 "singlesig component should satisfy the requirements of a valid account component",
169 )
170 }
171}