1use ml_kem::EncodedSizeUser;
5#[cfg(any(debug_assertions, feature = "server"))]
6use rand_core::CryptoRngCore;
7
8#[cfg(debug_assertions)]
9use ecdh_omr::Decoy;
10use reach_aliases::*;
11#[cfg(any(feature = "reaching", feature = "reachable"))]
12use reach_proc_macros::ParticipantPublicKeys;
13use reach_proc_macros::{Verifier, communicable, prosted};
14#[cfg(debug_assertions)]
15use reach_signatures::FN_DSA_SIGNATURE_EMPTY;
16use reach_signatures::{Signatures, Verifiable, Verifies};
17
18#[cfg(any(feature = "reaching", feature = "reachable"))]
19use crate::error::WireError;
20use crate::macros::*;
21#[cfg(any(feature = "reachable", feature = "attestant"))]
22use crate::storage::Storable;
23#[cfg(any(feature = "reachable", feature = "server", debug_assertions))]
24use crate::traits::*;
25use crate::wire::{Response, proto};
26#[cfg(any(feature = "reachable", feature = "server", feature = "attestant"))]
27use crate::{
28 communication::MatchResponse,
29 wire::{ReachOk, Request},
30};
31
32#[cfg(any(feature = "reachable", feature = "server"))]
33mod reachable_server {
34 use super::*;
35
36 #[communicable(Request::RemoveReachablePublicKeys)]
37 #[prosted(proto::RemoveReachablePublicKeys, Decode, Encode, ProstTraits)]
38 pub struct RemoveReachablePublicKeys {
39 pub ec_public_key: X25519Public,
40 pub pq_public_key: MlKemPublic,
41 }
42}
43
44#[cfg(any(feature = "reachable", feature = "server"))]
45pub use reachable_server::*;
46
47#[prosted(proto::AttestantVerifyingKeys, Decode, Encode, ProstTraits)]
48#[derive(Verifier, Debug, Clone, Copy)]
49pub struct AttestantVerifyingKeys {
50 pub ec_verifying_key: Ed25519Verifying,
51 pub pq_verifying_key: FnDsaVerifying,
52}
53
54#[cfg(feature = "server")]
55impl AuditAuthenticationAssurance for AttestantVerifyingKeys {}
56
57#[cfg(any(feature = "reachable", feature = "attestant"))]
58impl Storable for AttestantVerifyingKeys {}
59
60digestible!(AttestantVerifyingKeys, verifying_keys);
61
62#[cfg(any(feature = "reaching", feature = "reachable"))]
63pub fn verify_signature_chains(
64 attestant_verifying_keys: &AttestantVerifyingKeys,
65 reachable_signed_keys: &[ReachableSignedKeys],
66) -> Result<(), WireError> {
67 for item in reachable_signed_keys {
68 if !item.verifying_keys.verify(attestant_verifying_keys) {
69 return Err(WireError::Verification);
70 }
71 if !item.public_keys.verify(&item.verifying_keys) {
72 return Err(WireError::Verification);
73 }
74 }
75
76 Ok(())
77}
78
79impl Verifies<ReachableVerifyingKeys> for AttestantVerifyingKeys {}
80
81#[cfg(any(feature = "attestant", feature = "reachable", feature = "server"))]
82mod attestant_reachable_server {
83 use super::*;
84
85 #[derive(Clone, Copy)]
86 #[communicable(Response::AuthenticationChallenge)]
87 #[prosted(proto::AuthenticationChallenge, Decode, Encode, ProstTraits)]
88 pub struct AuthenticationChallenge {
89 pub authentication_challenge: ThreeTwo,
90 }
91
92 #[cfg(feature = "server")]
93 impl RandomFromRng for AuthenticationChallenge {
94 fn random_from_rng(csprng: &mut impl CryptoRngCore) -> Self {
95 Self {
96 authentication_challenge: ThreeTwo::random_from_rng(csprng),
97 }
98 }
99 }
100
101 #[communicable(Request::AuthenticationAssurance)]
102 #[prosted(proto::AuthenticationAssurance, Decode, Encode, ProstTraits)]
103 pub struct AuthenticationAssurance {
104 pub authenticator_id: SixFour,
105 pub ec_signature: Ed25519Signature,
106 pub pq_signature: FnDsaSignature,
107 }
108
109 impl Signatures for AuthenticationAssurance {
110 fn ec_signature(&self) -> &Ed25519Signature {
111 &self.ec_signature
112 }
113
114 fn pq_signature(&self) -> &FnDsaSignature {
115 &self.pq_signature
116 }
117 }
118
119 impl MatchResponse<Request> for AuthenticationAssurance {
120 type Resp = ReachOk;
121 }
122}
123
124#[cfg(any(feature = "attestant", feature = "reachable", feature = "server"))]
125pub use attestant_reachable_server::*;
126
127#[cfg(any(feature = "reaching", feature = "reachable", feature = "server"))]
128mod reaching_reachable_server {
129 #[cfg(any(feature = "reaching", feature = "reachable"))]
130 use reach_proc_macros::prosted;
131
132 use super::*;
133
134 use crate::ParticipantType;
135
136 #[prosted(proto::ReachableSignedKeys, Decode, Encode, EncodeOwned)]
137 pub struct ReachableSignedKeys {
138 pub verifying_keys: ReachableVerifyingKeys,
139 pub public_keys: ReachablePublicKeys,
140 }
141
142 nested_participant_keys!(ReachableSignedKeys);
143
144 #[communicable(Response::Reach, owned)]
145 #[prosted(proto::Reach, Decode, EncodeOwned, ProstTraitsOwned)]
146 pub struct Reach {
147 pub reachable_signed_keys: Vec<ReachableSignedKeys>,
148 pub envelope_id_hints: EnvelopeIdHints,
149 }
150}
151
152#[cfg(any(feature = "reaching", feature = "reachable", feature = "server"))]
153pub use reaching_reachable_server::*;
154
155#[derive(Debug, Clone)]
156#[prosted(proto::ReachablePublicKeys, Decode, Encode, EncodeOwned, ProstTraits)]
157#[cfg_attr(
158 any(feature = "reaching", feature = "reachable"),
159 derive(ParticipantPublicKeys)
160)]
161pub struct ReachablePublicKeys {
162 pub ec_public_key: X25519Public,
163 pub pq_public_key: MlKemPublic,
164 pub ec_signature: Ed25519Signature,
165 pub pq_signature: FnDsaSignature,
166}
167
168digestible!(ReachablePublicKeys, public_keys);
169
170impl Signatures for ReachablePublicKeys {
171 fn ec_signature(&self) -> &Ed25519Signature {
172 &self.ec_signature
173 }
174
175 fn pq_signature(&self) -> &FnDsaSignature {
176 &self.pq_signature
177 }
178}
179
180impl Verifies<ReachablePublicKeys> for ReachableVerifyingKeys {}
181
182impl Verifiable for ReachablePublicKeys {}
183
184#[cfg(any(feature = "reachable", feature = "server"))]
185impl AuditAuthenticationAssurance for ReachableVerifyingKeys {}
186
187#[prosted(proto::SharedVerifyingKeys, Decode, Encode, ProstTraits)]
188#[cfg_attr(
189 any(feature = "reaching", feature = "reachable", feature = "attestant"),
190 derive(Verifier, Clone)
191)]
192pub struct SharedVerifyingKeys {
193 pub ec_verifying_key: Ed25519Verifying,
194 pub pq_verifying_key: FnDsaVerifying,
195 pub attestant_ec_signature: Ed25519Signature,
196 pub attestant_pq_signature: FnDsaSignature,
197}
198
199impl Signatures for SharedVerifyingKeys {
200 fn ec_signature(&self) -> &Ed25519Signature {
201 &self.attestant_ec_signature
202 }
203
204 fn pq_signature(&self) -> &FnDsaSignature {
205 &self.attestant_pq_signature
206 }
207}
208
209impl Verifies<SharedVerifyingKeys> for AttestantVerifyingKeys {}
210
211digestible!(SharedVerifyingKeys, verifying_keys);
212
213impl Verifiable for SharedVerifyingKeys {}
214
215#[cfg(debug_assertions)]
216impl Decoy for SharedVerifyingKeys {
217 fn random_decoy(csprng: &mut impl CryptoRngCore) -> Self {
218 let mut attestant_pq_signature = FN_DSA_SIGNATURE_EMPTY;
219 csprng.fill_bytes(&mut attestant_pq_signature);
220 let mut pq_verifying_key = FN_DSA_VERIFYING_EMPTY;
221 csprng.fill_bytes(&mut pq_verifying_key);
222
223 Self {
224 ec_verifying_key: Ed25519Verifying::from(&Ed25519Signing::generate(csprng)),
225 pq_verifying_key,
226 attestant_ec_signature: Ed25519Signature::from_bytes(&SixFour::random_from_rng(csprng)),
227 attestant_pq_signature,
228 }
229 }
230}
231
232#[cfg(any(feature = "reachable", feature = "attestant"))]
233impl Storable for SharedVerifyingKeys {}
234
235#[prosted(proto::SharedPublicKeys, Decode, Encode, ProstTraits)]
236#[derive(Debug)]
237pub struct SharedPublicKeys {
238 pub ec_public_key: X25519Public,
239 pub pq_public_key: MlKemPublic,
240 pub attestant_ec_signature: Ed25519Signature,
241 pub attestant_pq_signature: FnDsaSignature,
242}
243
244impl Signatures for SharedPublicKeys {
245 fn ec_signature(&self) -> &Ed25519Signature {
246 &self.attestant_ec_signature
247 }
248
249 fn pq_signature(&self) -> &FnDsaSignature {
250 &self.attestant_pq_signature
251 }
252}
253
254impl Verifies<SharedPublicKeys> for AttestantVerifyingKeys {}
255
256#[cfg(any(feature = "reachable", feature = "attestant"))]
257impl Storable for SharedPublicKeys {}
258
259#[cfg_attr(
260 any(feature = "reachable", feature = "server", feature = "attestant"),
261 communicable(Request::ReachableVerifyingKeys)
262)]
263#[prosted(
264 proto::ReachableVerifyingKeys,
265 Decode,
266 EncodeOwned,
267 Encode,
268 ProstTraits
269)]
270#[derive(Debug, Verifier, Clone)]
271pub struct ReachableVerifyingKeys {
272 pub ec_verifying_key: Ed25519Verifying,
273 pub pq_verifying_key: FnDsaVerifying,
274 pub attestant_ec_signature: Ed25519Signature,
275 pub attestant_pq_signature: FnDsaSignature,
276}
277
278impl Signatures for ReachableVerifyingKeys {
279 fn ec_signature(&self) -> &Ed25519Signature {
280 &self.attestant_ec_signature
281 }
282
283 fn pq_signature(&self) -> &FnDsaSignature {
284 &self.attestant_pq_signature
285 }
286}
287
288digestible!(ReachableVerifyingKeys, verifying_keys);
289
290impl Verifiable for ReachableVerifyingKeys {}
291
292#[cfg(any(feature = "reachable", feature = "attestant"))]
293impl Storable for ReachableVerifyingKeys {}
294
295#[cfg(any(feature = "attestant", feature = "server"))]
296mod attestant_server {
297 use super::*;
298
299 #[prosted(proto::RemoveReachableVerifyingKeys, Decode, Encode)]
300 pub struct RemoveReachableVerifyingKeys {
301 pub reachable_id: ThreeTwo,
302 pub attestant_timed_ec_signature: Ed25519Signature,
303 pub attestant_timed_pq_signature: FnDsaSignature,
304 }
305
306 impl MatchResponse<Request> for RemoveReachableVerifyingKeys {
307 type Resp = ReachOk;
308 }
309}
310
311#[cfg(any(feature = "attestant", feature = "server"))]
312pub use attestant_server::*;
313
314#[cfg(any(feature = "attestant", feature = "server", feature = "reachable"))]
315impl MatchResponse<Request> for ReachableVerifyingKeys {
316 type Resp = ReachOk;
317}