Skip to main content

securedrop_protocol_minimal/
traits.rs

1use crate::VerifyingKey;
2use crate::message::MessageKeyPair;
3use crate::message::MessagePublicKey;
4use crate::metadata::MetadataPublicKey;
5use crate::primitives::ristretto255::DHPrivateKey;
6use crate::primitives::ristretto255::DHPublicKey;
7use crate::sign::{JournalistEphemeralKey, JournalistLongTermKey, Signature};
8use alloc::vec::Vec;
9
10use crate::ciphertext::Plaintext;
11use crate::keys::{
12    Enrollment, KeyBundlePublic, MessageKeyBundle, SignedKeyBundlePublic, SignedLongtermPubKeyBytes,
13};
14
15// Sealed traits that downstream crates should not implement.
16// Do not re-export!
17use crate::sealed;
18
19////////////////////////
20///
21/// Users have the following (public traits) in common:
22/// They expose a fetch pubkey, a message auth pubkey
23/// (implicit authentication),
24/// and a collection of KeyBundles (tuples of keys - a keybundle contains
25/// all the key material required to send a message to a given user).
26/// A Source has a KeyBundle collection of size 1.
27/// A Journalist has KeyBundle collection of size > 1.
28/// Some users (Sources) use a key from their message bundle as
29/// their message auth key.
30pub trait UserPublic {
31    fn fetch_pk(&self) -> &DHPublicKey;
32    /// The long-term SD-APKE public key `pk^APKE`.
33    fn message_auth_pk(&self) -> &MessagePublicKey;
34    fn message_metadata_pk(&self) -> &MetadataPublicKey;
35    /// The ephemeral SD-APKE public key `pk^{APKE_E}` from a key bundle.
36    fn message_enc_pk(&self) -> &MessagePublicKey;
37}
38
39pub trait JournalistPublic: UserPublic {
40    fn verifying_key(&self) -> &VerifyingKey;
41    fn self_signature(&self) -> &Signature<JournalistLongTermKey>;
42    fn signed_keybytes(&self) -> &SignedLongtermPubKeyBytes;
43    fn ephemeral_bundle(&self) -> &KeyBundlePublic;
44    fn ephemeral_signature(&self) -> &Signature<JournalistEphemeralKey>;
45}
46
47#[cfg(not(hax))]
48pub trait Enrollable: sealed::Sealed {
49    // sealed traits don't play nice with hax right now, so this is a workaround
50    fn signing_key(&self) -> &VerifyingKey;
51    fn enroll(&self) -> Enrollment;
52    /// Each item is a [`SignedKeyBundlePublic`]: the public keys together with the
53    /// journalist's self-signature over them.
54    fn signed_keybundles(&self) -> Vec<SignedKeyBundlePublic>;
55}
56
57#[cfg(hax)]
58pub trait Enrollable {
59    fn signing_key(&self) -> &VerifyingKey;
60    fn enroll(&self) -> Enrollment;
61    /// Each item is a [`SignedKeyBundlePublic`]: the public keys together with the
62    /// journalist's self-signature over them.
63    fn signed_keybundles(&self) -> Vec<SignedKeyBundlePublic>;
64}
65
66/// Users have the following (secret traits) in common:
67/// They have a fetching keypair used to retrieve messages;
68/// They have a message authentication keypair used to implicitly
69/// authenticate their messages (via DH-AKEM);
70/// They can index a KeyBundle (tuple) and use it to attempt to
71/// decrypt a message.
72#[cfg(not(hax))]
73pub trait UserSecret: sealed::Sealed {
74    fn num_bundles(&self) -> usize;
75    fn fetch_keypair(&self) -> (&DHPrivateKey, &DHPublicKey);
76    /// The long-term SD-APKE keypair (`sk^APKE`, `pk^APKE`)
77    fn message_auth_keypair(&self) -> &MessageKeyPair;
78    fn build_message(&self, message: Vec<u8>) -> Plaintext;
79    fn keybundles(&self) -> Vec<&MessageKeyBundle>;
80}
81
82#[cfg(hax)]
83pub trait UserSecret {
84    fn num_bundles(&self) -> usize;
85    fn fetch_keypair(&self) -> (&DHPrivateKey, &DHPublicKey);
86    /// The long-term SD-APKE keypair (`sk^APKE`, `pk^APKE`).
87    fn message_auth_keypair(&self) -> &MessageKeyPair;
88    fn build_message(&self, message: Vec<u8>) -> Plaintext;
89    fn keybundles(&self) -> Vec<&MessageKeyBundle>;
90}
91
92// hax doesn't work well with sealed trait pattern right now
93#[cfg(not(hax))]
94pub trait RestrictedApi: sealed::Sealed {}
95
96#[cfg(hax)]
97pub trait RestrictedApi {}