libsignal_protocol/state/
kyber_prekey.rs1use std::fmt;
7
8use rand::TryRngCore as _;
9
10use crate::proto::storage::SignedPreKeyRecordStructure;
11use crate::state::GenericSignedPreKey;
12use crate::{kem, PrivateKey, Result, Timestamp};
13
14#[derive(
16 Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd, derive_more::From, derive_more::Into,
17)]
18pub struct KyberPreKeyId(u32);
19
20impl fmt::Display for KyberPreKeyId {
21 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
22 write!(f, "{}", self.0)
23 }
24}
25
26#[derive(Debug, Clone)]
27pub struct KyberPreKeyRecord {
28 signed_pre_key: SignedPreKeyRecordStructure,
29}
30
31impl GenericSignedPreKey for KyberPreKeyRecord {
32 type KeyPair = kem::KeyPair;
33 type Id = KyberPreKeyId;
34
35 fn get_storage(&self) -> &SignedPreKeyRecordStructure {
36 &self.signed_pre_key
37 }
38
39 fn from_storage(storage: SignedPreKeyRecordStructure) -> Self {
40 Self {
41 signed_pre_key: storage,
42 }
43 }
44}
45
46impl KyberPreKeyRecord {
47 pub fn secret_key(&self) -> Result<kem::SecretKey> {
48 kem::SecretKey::deserialize(&self.signed_pre_key.private_key)
49 }
50}
51
52impl KyberPreKeyRecord {
53 pub fn generate(
54 kyber_key_type: kem::KeyType,
55 id: KyberPreKeyId,
56 signing_key: &PrivateKey,
57 ) -> Result<KyberPreKeyRecord> {
58 let mut rng = rand::rngs::OsRng.unwrap_err();
59 let key_pair = kem::KeyPair::generate(kyber_key_type, &mut rng);
60 let signature = signing_key
61 .calculate_signature(&key_pair.public_key.serialize(), &mut rng)?
62 .into_vec();
63 let timestamp = std::time::SystemTime::now()
64 .duration_since(std::time::SystemTime::UNIX_EPOCH)
65 .expect("Time should move forward")
66 .as_millis();
67 Ok(KyberPreKeyRecord::new(
68 id,
69 Timestamp::from_epoch_millis(timestamp.try_into().expect("Timestamp too large")),
70 &key_pair,
71 &signature,
72 ))
73 }
74}