libsignal_protocol/state/
bundle.rs1use std::clone::Clone;
7
8use crate::state::{PreKeyId, SignedPreKeyId};
9use crate::{DeviceId, IdentityKey, KyberPreKeyId, PublicKey, Result, SignalProtocolError, kem};
10
11#[derive(Clone)]
12struct SignedPreKey {
13 id: SignedPreKeyId,
14 public_key: PublicKey,
15 signature: Vec<u8>,
16}
17
18impl SignedPreKey {
19 fn new(id: SignedPreKeyId, public_key: PublicKey, signature: Vec<u8>) -> Self {
20 Self {
21 id,
22 public_key,
23 signature,
24 }
25 }
26}
27
28#[derive(Clone)]
29struct KyberPreKey {
30 id: KyberPreKeyId,
31 public_key: kem::PublicKey,
32 signature: Vec<u8>,
33}
34
35impl KyberPreKey {
36 fn new(id: KyberPreKeyId, public_key: kem::PublicKey, signature: Vec<u8>) -> Self {
37 Self {
38 id,
39 public_key,
40 signature,
41 }
42 }
43}
44
45pub struct PreKeyBundleContent {
50 pub registration_id: Option<u32>,
51 pub device_id: Option<DeviceId>,
52 pub pre_key_id: Option<PreKeyId>,
53 pub pre_key_public: Option<PublicKey>,
54 pub signed_pre_key_id: Option<SignedPreKeyId>,
55 pub signed_pre_key_public: Option<PublicKey>,
56 pub signed_pre_key_signature: Option<Vec<u8>>,
57 pub identity_key: Option<IdentityKey>,
58 pub kyber_pre_key_id: Option<KyberPreKeyId>,
59 pub kyber_pre_key_public: Option<kem::PublicKey>,
60 pub kyber_pre_key_signature: Option<Vec<u8>>,
61}
62
63impl From<PreKeyBundle> for PreKeyBundleContent {
64 fn from(bundle: PreKeyBundle) -> Self {
65 Self {
66 registration_id: Some(bundle.registration_id),
67 device_id: Some(bundle.device_id),
68 pre_key_id: bundle.pre_key_id,
69 pre_key_public: bundle.pre_key_public,
70 signed_pre_key_id: Some(bundle.ec_signed_pre_key.id),
71 signed_pre_key_public: Some(bundle.ec_signed_pre_key.public_key),
72 signed_pre_key_signature: Some(bundle.ec_signed_pre_key.signature),
73 identity_key: Some(bundle.identity_key),
74 kyber_pre_key_id: Some(bundle.kyber_pre_key.id),
75 kyber_pre_key_public: Some(bundle.kyber_pre_key.public_key),
76 kyber_pre_key_signature: Some(bundle.kyber_pre_key.signature),
77 }
78 }
79}
80
81impl TryFrom<PreKeyBundleContent> for PreKeyBundle {
82 type Error = SignalProtocolError;
83
84 fn try_from(content: PreKeyBundleContent) -> Result<Self> {
85 PreKeyBundle::new(
86 content.registration_id.ok_or_else(|| {
87 SignalProtocolError::InvalidArgument("registration_id is required".to_string())
88 })?,
89 content.device_id.ok_or_else(|| {
90 SignalProtocolError::InvalidArgument("device_id is required".to_string())
91 })?,
92 content.pre_key_id.zip(content.pre_key_public),
93 content.signed_pre_key_id.ok_or_else(|| {
94 SignalProtocolError::InvalidArgument("signed_pre_key_id is required".to_string())
95 })?,
96 content.signed_pre_key_public.ok_or_else(|| {
97 SignalProtocolError::InvalidArgument(
98 "signed_pre_key_public is required".to_string(),
99 )
100 })?,
101 content.signed_pre_key_signature.ok_or_else(|| {
102 SignalProtocolError::InvalidArgument(
103 "signed_pre_key_signature is required".to_string(),
104 )
105 })?,
106 content.kyber_pre_key_id.ok_or_else(|| {
107 SignalProtocolError::InvalidArgument("kyber_pre_key_id is required".to_string())
108 })?,
109 content.kyber_pre_key_public.ok_or_else(|| {
110 SignalProtocolError::InvalidArgument("kyber_pre_key_public is required".to_string())
111 })?,
112 content.kyber_pre_key_signature.ok_or_else(|| {
113 SignalProtocolError::InvalidArgument(
114 "kyber_pre_key_signature is required".to_string(),
115 )
116 })?,
117 content.identity_key.ok_or_else(|| {
118 SignalProtocolError::InvalidArgument("identity_key is required".to_string())
119 })?,
120 )
121 }
122}
123
124#[derive(Clone)]
125pub struct PreKeyBundle {
126 registration_id: u32,
127 device_id: DeviceId,
128 pre_key_id: Option<PreKeyId>,
129 pre_key_public: Option<PublicKey>,
130 ec_signed_pre_key: SignedPreKey,
131 identity_key: IdentityKey,
132 kyber_pre_key: KyberPreKey,
133}
134
135impl PreKeyBundle {
136 #[expect(clippy::too_many_arguments)]
137 pub fn new(
138 registration_id: u32,
139 device_id: DeviceId,
140 pre_key: Option<(PreKeyId, PublicKey)>,
141 signed_pre_key_id: SignedPreKeyId,
142 signed_pre_key_public: PublicKey,
143 signed_pre_key_signature: Vec<u8>,
144 kyber_pre_key_id: KyberPreKeyId,
145 kyber_pre_key_public: kem::PublicKey,
146 kyber_pre_key_signature: Vec<u8>,
147 identity_key: IdentityKey,
148 ) -> Result<Self> {
149 let (pre_key_id, pre_key_public) = match pre_key {
150 None => (None, None),
151 Some((id, key)) => (Some(id), Some(key)),
152 };
153
154 let ec_signed_pre_key = SignedPreKey::new(
155 signed_pre_key_id,
156 signed_pre_key_public,
157 signed_pre_key_signature,
158 );
159
160 let kyber_pre_key = KyberPreKey::new(
161 kyber_pre_key_id,
162 kyber_pre_key_public,
163 kyber_pre_key_signature,
164 );
165
166 Ok(Self {
167 registration_id,
168 device_id,
169 pre_key_id,
170 pre_key_public,
171 ec_signed_pre_key,
172 identity_key,
173 kyber_pre_key,
174 })
175 }
176
177 pub fn registration_id(&self) -> Result<u32> {
178 Ok(self.registration_id)
179 }
180
181 pub fn device_id(&self) -> Result<DeviceId> {
182 Ok(self.device_id)
183 }
184
185 pub fn pre_key_id(&self) -> Result<Option<PreKeyId>> {
186 Ok(self.pre_key_id)
187 }
188
189 pub fn pre_key_public(&self) -> Result<Option<PublicKey>> {
190 Ok(self.pre_key_public)
191 }
192
193 pub fn signed_pre_key_id(&self) -> Result<SignedPreKeyId> {
194 Ok(self.ec_signed_pre_key.id)
195 }
196
197 pub fn signed_pre_key_public(&self) -> Result<PublicKey> {
198 Ok(self.ec_signed_pre_key.public_key)
199 }
200
201 pub fn signed_pre_key_signature(&self) -> Result<&[u8]> {
202 Ok(self.ec_signed_pre_key.signature.as_ref())
203 }
204
205 pub fn identity_key(&self) -> Result<&IdentityKey> {
206 Ok(&self.identity_key)
207 }
208
209 pub fn kyber_pre_key_id(&self) -> Result<KyberPreKeyId> {
210 Ok(self.kyber_pre_key.id)
211 }
212
213 pub fn kyber_pre_key_public(&self) -> Result<&kem::PublicKey> {
214 Ok(&self.kyber_pre_key.public_key)
215 }
216
217 pub fn kyber_pre_key_signature(&self) -> Result<&[u8]> {
218 Ok(&self.kyber_pre_key.signature)
219 }
220
221 pub fn modify<F>(self, modify: F) -> Result<Self>
222 where
223 F: FnOnce(&mut PreKeyBundleContent),
224 {
225 let mut content = self.into();
226 modify(&mut content);
227 content.try_into()
228 }
229}