zkgroup/api/call_links/
params.rs

1//
2// Copyright 2023 Signal Messenger, LLC.
3// SPDX-License-Identifier: AGPL-3.0-only
4//
5
6use partial_default::PartialDefault;
7use serde::{Deserialize, Serialize};
8
9use crate::common::errors::*;
10use crate::common::serialization::ReservedByte;
11use crate::common::sho::*;
12use crate::crypto::uid_encryption;
13use crate::{api, crypto};
14
15#[derive(Copy, Clone, Serialize, Deserialize, PartialDefault)]
16pub struct CallLinkSecretParams {
17    reserved: ReservedByte,
18    pub(crate) uid_enc_key_pair:
19        zkcredential::attributes::KeyPair<crypto::uid_encryption::UidEncryptionDomain>,
20}
21
22impl AsRef<uid_encryption::KeyPair> for CallLinkSecretParams {
23    fn as_ref(&self) -> &uid_encryption::KeyPair {
24        &self.uid_enc_key_pair
25    }
26}
27
28#[derive(Copy, Clone, Serialize, Deserialize, PartialDefault)]
29pub struct CallLinkPublicParams {
30    reserved: ReservedByte,
31    pub(crate) uid_enc_public_key:
32        zkcredential::attributes::PublicKey<crypto::uid_encryption::UidEncryptionDomain>,
33}
34
35impl CallLinkSecretParams {
36    pub fn derive_from_root_key(root_key: &[u8]) -> Self {
37        let mut sho = Sho::new(
38            b"Signal_ZKGroup_20230419_CallLinkSecretParams_DeriveFromRootKey",
39            root_key,
40        );
41        let uid_enc_key_pair = zkcredential::attributes::KeyPair::derive_from(sho.as_mut());
42
43        Self {
44            reserved: Default::default(),
45            uid_enc_key_pair,
46        }
47    }
48
49    pub fn get_public_params(&self) -> CallLinkPublicParams {
50        CallLinkPublicParams {
51            reserved: Default::default(),
52            uid_enc_public_key: self.uid_enc_key_pair.public_key,
53        }
54    }
55
56    pub fn encrypt_uid(&self, user_id: libsignal_core::Aci) -> api::groups::UuidCiphertext {
57        let uid = crypto::uid_struct::UidStruct::from_service_id(user_id.into());
58        self.encrypt_uid_struct(uid)
59    }
60
61    fn encrypt_uid_struct(
62        &self,
63        uid: crypto::uid_struct::UidStruct,
64    ) -> api::groups::UuidCiphertext {
65        let ciphertext = self.uid_enc_key_pair.encrypt(&uid);
66        api::groups::UuidCiphertext {
67            reserved: Default::default(),
68            ciphertext,
69        }
70    }
71
72    pub fn decrypt_uid(
73        &self,
74        ciphertext: api::groups::UuidCiphertext,
75    ) -> Result<libsignal_core::Aci, ZkGroupVerificationFailure> {
76        let uid = crypto::uid_encryption::UidEncryptionDomain::decrypt(
77            &self.uid_enc_key_pair,
78            &ciphertext.ciphertext,
79        )?;
80        uid.try_into().map_err(|_| ZkGroupVerificationFailure)
81    }
82}