miden_standards/account/auth/
singlesig.rs1use miden_protocol::Word;
2use miden_protocol::account::auth::{AuthScheme, PublicKey, PublicKeyCommitment};
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 crate::account::account_component_code;
20
21account_component_code!(SINGLESIG_CODE, "auth/singlesig.masl");
22
23static PUBKEY_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
27 StorageSlotName::new("miden::standards::auth::singlesig::pub_key")
28 .expect("storage slot name should be valid")
29});
30
31static SCHEME_ID_SLOT_NAME: LazyLock<StorageSlotName> = LazyLock::new(|| {
32 StorageSlotName::new("miden::standards::auth::singlesig::scheme")
33 .expect("storage slot name should be valid")
34});
35
36pub struct AuthSingleSig {
49 pub_key: PublicKeyCommitment,
50 auth_scheme: AuthScheme,
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(pub_key: PublicKeyCommitment, auth_scheme: AuthScheme) -> Self {
69 Self { pub_key, auth_scheme }
70 }
71
72 pub fn falcon512_poseidon2(pub_key: falcon512_poseidon2::PublicKey) -> Self {
76 Self {
77 pub_key: pub_key.into(),
78 auth_scheme: AuthScheme::Falcon512Poseidon2,
79 }
80 }
81
82 pub fn ecdsa_k256_keccak(pub_key: ecdsa_k256_keccak::PublicKey) -> Self {
86 Self {
87 pub_key: pub_key.into(),
88 auth_scheme: AuthScheme::EcdsaK256Keccak,
89 }
90 }
91
92 pub fn from_public_key(pub_key: PublicKey) -> Self {
96 Self {
97 auth_scheme: pub_key.auth_scheme(),
98 pub_key: pub_key.to_commitment(),
99 }
100 }
101
102 pub fn public_key_slot() -> &'static StorageSlotName {
104 &PUBKEY_SLOT_NAME
105 }
106
107 pub fn scheme_id_slot() -> &'static StorageSlotName {
109 &SCHEME_ID_SLOT_NAME
110 }
111
112 pub fn public_key_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
114 (
115 Self::public_key_slot().clone(),
116 StorageSlotSchema::value("Public key commitment", SchemaType::pub_key()),
117 )
118 }
119 pub fn auth_scheme_slot_schema() -> (StorageSlotName, StorageSlotSchema) {
121 (
122 Self::scheme_id_slot().clone(),
123 StorageSlotSchema::value("Scheme ID", SchemaType::auth_scheme()),
124 )
125 }
126
127 pub fn component_metadata() -> AccountComponentMetadata {
129 let storage_schema = StorageSchema::new(vec![
130 Self::public_key_slot_schema(),
131 Self::auth_scheme_slot_schema(),
132 ])
133 .expect("storage schema should be valid");
134
135 AccountComponentMetadata::new(Self::NAME)
136 .with_description(
137 "Authentication component using ECDSA K256 Keccak or Falcon512 Poseidon2 signature scheme",
138 )
139 .with_storage_schema(storage_schema)
140 }
141}
142
143impl From<AuthSingleSig> for AccountComponent {
144 fn from(basic_signature: AuthSingleSig) -> Self {
145 let metadata = AuthSingleSig::component_metadata();
146
147 let storage_slots = vec![
148 StorageSlot::with_value(
149 AuthSingleSig::public_key_slot().clone(),
150 basic_signature.pub_key.into(),
151 ),
152 StorageSlot::with_value(
153 AuthSingleSig::scheme_id_slot().clone(),
154 Word::from([basic_signature.auth_scheme.as_u8(), 0, 0, 0]),
155 ),
156 ];
157
158 AccountComponent::new(AuthSingleSig::code().clone(), storage_slots, metadata).expect(
159 "singlesig component should satisfy the requirements of a valid account component",
160 )
161 }
162}