1use crate::artifacts::{deserialize_bin_or_b64, serialize_bin_or_b64};
4use crate::artifacts::{MultiRecipientCiphertext, PublicKey, UserSecretKey};
5use crate::consts::*;
6use crate::error::Error;
7use crate::identity::{EncryptionPolicy, HiddenPolicy, Policy};
8
9use ibe::kem::cgw_kv::CGWKV;
10use ibe::kem::mkem::MultiRecipient;
11use ibe::kem::{SharedSecret, IBKEM};
12
13use ibs::gg::Signature;
14
15use alloc::collections::BTreeMap;
16use alloc::fmt::Debug;
17use alloc::string::String;
18use alloc::vec::Vec;
19
20use rand::{CryptoRng, RngCore};
21use serde::{Deserialize, Serialize};
22
23#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone, Copy)]
25pub enum Mode {
26 Streaming {
28 segment_size: u32,
30
31 size_hint: (u64, Option<u64>),
35 },
36
37 InMemory {
39 size: u32,
41 },
42}
43
44impl Default for Mode {
45 fn default() -> Self {
46 Mode::Streaming {
47 segment_size: SYMMETRIC_CRYPTO_DEFAULT_CHUNK,
48 size_hint: (0, None),
49 }
50 }
51}
52
53#[derive(Debug, Eq, PartialEq, Clone, Copy)]
55pub struct Iv<const N: usize>(pub [u8; N]);
56
57impl<const N: usize> Iv<N> {
58 fn random<R: RngCore + CryptoRng>(r: &mut R) -> Self {
59 let mut buf = [0u8; N];
60 r.fill_bytes(&mut buf);
61 Self(buf)
62 }
63}
64
65impl<const N: usize> Serialize for Iv<N> {
67 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
68 where
69 S: serde::Serializer,
70 {
71 serialize_bin_or_b64(&self.0, serializer)
72 }
73}
74
75impl<'de, const N: usize> Deserialize<'de> for Iv<N> {
76 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
77 where
78 D: serde::Deserializer<'de>,
79 {
80 let mut buf = [0u8; N];
81 deserialize_bin_or_b64(&mut buf, deserializer)?;
82
83 Ok(Self(buf))
84 }
85}
86
87#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone, Copy)]
90pub enum Algorithm {
91 Aes128Gcm(Iv<12>),
94}
95
96impl Algorithm {
97 fn new_aes128_gcm<R: RngCore + CryptoRng>(r: &mut R) -> Self {
98 Self::Aes128Gcm(Iv::random(r))
99 }
100}
101
102#[derive(Debug, Serialize, Deserialize, Clone)]
104pub struct Header {
105 pub recipients: BTreeMap<String, RecipientHeader>,
107
108 pub algo: Algorithm,
110
111 #[serde(default)]
113 pub mode: Mode,
114}
115
116#[derive(Serialize, Deserialize, Clone, Debug)]
118pub struct RecipientHeader {
119 pub policy: HiddenPolicy,
121
122 pub ct: MultiRecipientCiphertext<CGWKV>,
124}
125
126impl RecipientHeader {
127 pub fn decaps(&self, usk: &UserSecretKey<CGWKV>) -> Result<SharedSecret, Error> {
131 CGWKV::multi_decaps(None, &usk.0, &self.ct.0).map_err(|_e| Error::KEM)
132 }
133}
134
135impl Header {
136 pub fn new<R: RngCore + CryptoRng>(
138 pk: &PublicKey<CGWKV>,
139 policies: &EncryptionPolicy,
140 rng: &mut R,
141 ) -> Result<(Self, SharedSecret), Error> {
142 let policies: EncryptionPolicy = policies
157 .iter()
158 .map(|(rid, policy)| (rid.clone(), policy.canonical()))
159 .collect();
160
161 let ids = policies
163 .values()
164 .map(Policy::derive_kem::<CGWKV>)
165 .collect::<Result<Vec<<CGWKV as IBKEM>::Id>, _>>()?;
166
167 let (cts, ss) = CGWKV::multi_encaps(&pk.0, &ids[..], rng);
169
170 let recipient_info: BTreeMap<String, RecipientHeader> = policies
172 .iter()
173 .zip(cts)
174 .map(|((rid, policy), ct)| {
175 (
176 rid.clone(),
177 RecipientHeader {
178 policy: policy.to_hidden(),
179 ct: MultiRecipientCiphertext(ct),
180 },
181 )
182 })
183 .collect();
184
185 Ok((
186 Header {
187 recipients: recipient_info,
188 algo: Algorithm::new_aes128_gcm(rng),
189 mode: Mode::default(),
190 },
191 ss,
192 ))
193 }
194
195 pub fn with_mode(mut self, mode: Mode) -> Self {
197 self.mode = mode;
198 self
199 }
200
201 pub fn with_algo(mut self, algo: Algorithm) -> Self {
203 self.algo = algo;
204 self
205 }
206}
207
208#[derive(Debug, Clone, Serialize, Deserialize)]
210pub struct SignatureExt {
211 pub sig: Signature,
213
214 pub pol: Policy,
216}
217
218#[cfg(test)]
219mod tests {
220 use super::*;
221 use crate::test::TestSetup;
222
223 #[test]
224 fn test_enc_dec_json() {
225 let mut rng = rand::thread_rng();
226 let setup = TestSetup::new(&mut rng);
227
228 let (header, _ss) = Header::new(&setup.ibe_pk, &setup.policy, &mut rng).unwrap();
229 let header2 = header.clone();
230
231 let s = serde_json::to_string(&header).unwrap();
232 let decoded: Header = serde_json::from_str(&s).unwrap();
233
234 assert_eq!(decoded.recipients.len(), 2);
235
236 assert_eq!(
237 &decoded.recipients.get("Bob").unwrap().policy,
238 &setup.policy.get("Bob").unwrap().to_hidden()
239 );
240
241 assert_eq!(&decoded.algo, &header2.algo);
242 assert_eq!(&decoded.mode, &header2.mode);
243 }
244
245 #[test]
246 fn test_enc_dec_binary() {
247 let mut rng = rand::thread_rng();
248 let setup = TestSetup::new(&mut rng);
249
250 let (header, _ss) = Header::new(&setup.ibe_pk, &setup.policy, &mut rng).unwrap();
251 let header2 = header.clone();
252
253 let v = crate::bincode_compat::serialize(&header).unwrap();
254 let decoded: Header = crate::bincode_compat::deserialize(&v).unwrap();
255
256 assert_eq!(decoded.recipients.len(), 2);
257 assert_eq!(
258 &decoded.recipients.get("Charlie").unwrap().policy,
259 &setup.policy.get("Charlie").unwrap().to_hidden()
260 );
261 assert_eq!(&decoded.algo, &header2.algo);
262 assert_eq!(&decoded.mode, &header2.mode);
263 }
264
265 #[test]
266 fn test_round() {
267 let mut rng = rand::thread_rng();
270 let setup = TestSetup::new(&mut rng);
271
272 let test_usk = &setup.usks[2];
274
275 let (header, ss1) = Header::new(&setup.ibe_pk, &setup.policy, &mut rng).unwrap();
276 let header2 = header.clone();
277 let header3 = header.clone();
278
279 let bytes = crate::bincode_compat::serialize(&header).unwrap();
281
282 let json = serde_json::to_string(&header2).unwrap();
284
285 let decoded1: Header = crate::bincode_compat::deserialize(&bytes).unwrap();
286 let ss2 = decoded1
287 .recipients
288 .get("Bob")
289 .unwrap()
290 .decaps(test_usk)
291 .unwrap();
292
293 let decoded2: Header = serde_json::from_str(&json).unwrap();
294 let ss3 = decoded2
295 .recipients
296 .get("Bob")
297 .unwrap()
298 .decaps(test_usk)
299 .unwrap();
300
301 assert_eq!(&decoded1.recipients.len(), &header3.recipients.len());
302 assert_eq!(&decoded1.algo, &header3.algo);
303 assert_eq!(&decoded1.mode, &header3.mode);
304
305 assert_eq!(&ss1, &ss2);
307 assert_eq!(&ss1, &ss3);
308 }
309}