Skip to main content

securedrop_protocol_minimal/client/
challenge.rs

1use crate::challenge::{decrypt_message_id, derive_challenge_key};
2use crate::keys::NR_ID;
3use crate::primitives::ristretto255::dh_shared_secret;
4use crate::{FetchResponse, UserSecret};
5use alloc::vec::Vec;
6use uuid::Uuid;
7
8/// Solve fetch challenges (encrypted message IDs) and return array of valid message_ids.
9/// TODO: For simplicity, serialize/deserialize is skipped
10#[cfg_attr(hax, hax_lib::fstar::verification_status(lax))]
11pub fn solve_fetch_challenges<S: UserSecret>(
12    recipient: &S,
13    challenges: &[FetchResponse],
14) -> Vec<Uuid> {
15    let mut message_ids: Vec<Uuid> = Vec::new();
16
17    for chall in challenges.iter() {
18        // Compute 3-party DH on the pmgdh
19        let maybe_kmid_secret = dh_shared_secret(&chall.pmgdh, recipient.fetch_keypair().0);
20        let challenge_key = derive_challenge_key(&maybe_kmid_secret, NR_ID).unwrap();
21
22        // Try decrypting the encrypted message id
23        // Convert to UUID (v4) format and add to message ID list on success
24        match decrypt_message_id(&challenge_key, &chall.enc_id) {
25            Ok(message_id_bytes) => {
26                let uuid = crate::primitives::provider::uuid_parse::from_slice(&message_id_bytes);
27
28                message_ids.push(uuid);
29            }
30            Err(_) => {
31                // An error in decryption is fine (may not be a valid message_id), but
32                // an error in uuid parsing isn't.
33            }
34        }
35    }
36    message_ids
37}