reach_attestant/
memory.rs

1// SPDX-FileCopyrightText: 2023—2025 eaon <eaon@posteo.net>
2// SPDX-License-Identifier: EUPL-1.2
3
4use fn_dsa_kgen::KeyPairGenerator;
5use ml_kem::{EncodedSizeUser, KemCore};
6use rand_core::CryptoRngCore;
7use reach_aliases::*;
8use reach_core::{
9    error,
10    macros::digestible,
11    memory::{Key, SharedSecretKeys, SharedSigningKeys},
12    storage::*,
13    wire::{AttestantVerifyingKeys, SharedPublicKeys, SharedVerifyingKeys},
14    *,
15};
16use reach_encryption::{Decryptable, Encryptable};
17use reach_proc_macros::{PublicKeys, SecretKeysRandomFromRng, SigningKeys, VerifyingKeys, prosted};
18use reach_signatures::*;
19use wire::Salts;
20
21use crate::storage;
22
23mod v0 {
24    include!(concat!(
25        env!("OUT_DIR"),
26        "/reachable_attestant.memory_v0.rs"
27    ));
28}
29
30pub(crate) mod proto {
31    pub(crate) use super::v0::AttestantSigningKeys;
32}
33
34#[prosted(proto::AttestantSigningKeys, Decode, Encode, ProstTraits)]
35#[derive(SigningKeys, VerifyingKeys)]
36pub struct AttestantSigningKeys {
37    pub ec_signing_key: Ed25519Signing,
38    pub pq_signing_key: FnDsaSigning,
39    pub pq_verifying_key: FnDsaVerifying,
40}
41
42impl Encryptable<GenericVault> for AttestantSigningKeys {}
43impl Decryptable<GenericVault> for AttestantSigningKeys {}
44
45impl AttestantSigningKeys {
46    pub fn verifying_keys(&self) -> AttestantVerifyingKeys {
47        AttestantVerifyingKeys::from(self)
48    }
49}
50
51impl VerifyingKeys<AttestantVerifyingKeys> for AttestantSigningKeys {}
52
53pub fn load(profile_name: &str) -> Result<GenericVault, error::StorageError> {
54    GenericVault::load(&storage::file_path(profile_name, None, "lask", false)?)
55}
56
57pub fn lock_and_store(
58    signing_keys: &AttestantSigningKeys,
59    key: &Key,
60    augmentation: Vec<u8>,
61    profile_name: &str,
62    csprng: &mut impl CryptoRngCore,
63) -> Result<(), error::StorageError> {
64    let encrypted: GenericVault = signing_keys.encrypt(key, csprng)?;
65    encrypted
66        .augment(augmentation)
67        .store(&storage::file_path(profile_name, None, "lask", true)?)
68}
69
70impl AssureAuthentication for AttestantSigningKeys {}
71
72pub struct UnsignedSalts {
73    pub attestant_identity: ThreeTwo,
74    pub shared_secret: ThreeTwo,
75    pub reaching_static: ThreeTwo,
76    pub verifying_keys_mac: ThreeTwo,
77    pub reaching_current: ThreeTwo,
78    pub reaching_previous: ThreeTwo,
79}
80
81impl RandomFromRng for UnsignedSalts {
82    fn random_from_rng(csprng: &mut impl CryptoRngCore) -> Self {
83        Self {
84            attestant_identity: ThreeTwo::random_from_rng(csprng),
85            shared_secret: ThreeTwo::random_from_rng(csprng),
86            reaching_static: ThreeTwo::random_from_rng(csprng),
87            verifying_keys_mac: ThreeTwo::random_from_rng(csprng),
88            reaching_current: ThreeTwo::random_from_rng(csprng),
89            reaching_previous: ThreeTwo::random_from_rng(csprng),
90        }
91    }
92}
93
94impl Digestible for UnsignedSalts {
95    fn hashable_bytes(&self) -> Vec<Box<dyn AsRef<[u8]> + '_>> {
96        vec![
97            Box::new(&self.attestant_identity),
98            Box::new(&self.shared_secret),
99            Box::new(&self.reaching_static),
100            Box::new(&self.verifying_keys_mac),
101        ]
102    }
103}
104
105impl Signable for UnsignedSalts {
106    type SignedType = Salts;
107
108    fn with_signature(
109        self,
110        attestant_ec_signature: Ed25519Signature,
111        attestant_pq_signature: FnDsaSignature,
112    ) -> Salts {
113        Salts {
114            attestant_identity: self.attestant_identity,
115            shared_secret: self.shared_secret,
116            reaching_static: self.reaching_static,
117            verifying_keys_mac: self.verifying_keys_mac,
118            reaching_current: self.reaching_current,
119            reaching_previous: self.reaching_previous,
120            attestant_ec_signature,
121            attestant_pq_signature,
122        }
123    }
124}
125
126#[derive(SigningKeys, VerifyingKeys)]
127pub struct UnsignedSharedSigningKeys {
128    pub ec_signing_key: Ed25519Signing,
129    pub pq_signing_key: FnDsaSigning,
130    pub pq_verifying_key: FnDsaVerifying,
131}
132
133digestible!(UnsignedSharedSigningKeys, signing_keys);
134
135impl Signable for UnsignedSharedSigningKeys {
136    type SignedType = SharedSigningKeys;
137
138    fn with_signature(
139        self,
140        attestant_ec_signature: Ed25519Signature,
141        attestant_pq_signature: FnDsaSignature,
142    ) -> SharedSigningKeys {
143        SharedSigningKeys {
144            ec_signing_key: self.ec_signing_key,
145            pq_signing_key: self.pq_signing_key,
146            attestant_ec_signature,
147            attestant_pq_signature,
148        }
149    }
150}
151
152pub struct UnsignedSharedVerifyingKeys {
153    pub ec_verifying_key: Ed25519Verifying,
154    pub pq_verifying_key: FnDsaVerifying,
155}
156
157digestible!(UnsignedSharedVerifyingKeys, verifying_keys);
158
159impl Signable for UnsignedSharedVerifyingKeys {
160    type SignedType = SharedVerifyingKeys;
161
162    fn with_signature(
163        self,
164        attestant_ec_signature: Ed25519Signature,
165        attestant_pq_signature: FnDsaSignature,
166    ) -> SharedVerifyingKeys {
167        SharedVerifyingKeys {
168            ec_verifying_key: self.ec_verifying_key,
169            pq_verifying_key: self.pq_verifying_key,
170            attestant_ec_signature,
171            attestant_pq_signature,
172        }
173    }
174}
175
176#[derive(SecretKeysRandomFromRng, PublicKeys)]
177pub struct UnsignedSharedSecretKeys {
178    pub ec_secret_key: X25519Secret,
179    pub pq_secret_key: MlKemSecret,
180    pub pq_public_key: MlKemPublic,
181}
182
183digestible!(UnsignedSharedSecretKeys, secret_keys);
184
185impl Signable for UnsignedSharedSecretKeys {
186    type SignedType = SharedSecretKeys;
187
188    fn with_signature(
189        self,
190        attestant_ec_signature: Ed25519Signature,
191        attestant_pq_signature: FnDsaSignature,
192    ) -> SharedSecretKeys {
193        SharedSecretKeys {
194            ec_secret_key: self.ec_secret_key,
195            pq_secret_key: self.pq_secret_key,
196            attestant_ec_signature,
197            attestant_pq_signature,
198        }
199    }
200}
201
202pub struct UnsignedSharedPublicKeys {
203    pub ec_public_key: X25519Public,
204    pub pq_public_key: MlKemPublic,
205}
206
207digestible!(UnsignedSharedPublicKeys, public_keys);
208
209impl Signable for UnsignedSharedPublicKeys {
210    type SignedType = SharedPublicKeys;
211
212    fn with_signature(
213        self,
214        attestant_ec_signature: Ed25519Signature,
215        attestant_pq_signature: FnDsaSignature,
216    ) -> SharedPublicKeys {
217        SharedPublicKeys {
218            ec_public_key: self.ec_public_key,
219            pq_public_key: self.pq_public_key,
220            attestant_ec_signature,
221            attestant_pq_signature,
222        }
223    }
224}