pg_core/
artifacts.rs

1//! Artifacts of the PostGuard protocol.
2//!
3//! This module implements constant-time serde serialization and deserialization for artifacts.
4//!
5//! # Notes
6//!
7//! Some artifacts do no require serialization to be constant-time, but we want to limit the
8//! dependency graph.
9
10use crate::identity::Policy;
11use crate::util::open_ct;
12use base64ct::{Base64, Encoding};
13use core::fmt;
14use ibe::{
15    kem::{cgw_kv::CGWKV, mkem::Ciphertext as MkemCt, IBKEM},
16    Compress,
17};
18use serde::de::{Error, SeqAccess, Visitor};
19use serde::{ser::SerializeTuple, Deserialize, Deserializer, Serialize, Serializer};
20
21// Computes the byte length of raw bytes encoded in (padded) b64.
22// We use this to preallocate a buffer to encode into.
23const fn b64len(raw_len: usize) -> usize {
24    // use next line when unwrap() becomes stable as a const fn:
25    // .checked_mul(4).unwrap()
26    // this will cause a compiler error when the multiplication overflows,
27    // making this function "safe" for all input.
28    (((raw_len - 1) / 3) + 1) * 4
29}
30
31pub(crate) fn serialize_bin_or_b64<S, T>(val: &T, serializer: S) -> Result<S::Ok, S::Error>
32where
33    S: Serializer,
34    T: AsRef<[u8]>,
35{
36    if serializer.is_human_readable() {
37        let mut enc_buf = vec![0u8; b64len(val.as_ref().len())];
38        let encoded = Base64::encode(val.as_ref(), &mut enc_buf)
39            .map_err(|e| serde::ser::Error::custom(format!("base64ct serialization error: {e}")))?;
40        serializer.serialize_str(encoded)
41    } else {
42        let mut seq = serializer.serialize_tuple(val.as_ref().len())?;
43        for b in val.as_ref() {
44            seq.serialize_element(b)?;
45        }
46        seq.end()
47    }
48}
49
50pub(crate) fn deserialize_bin_or_b64<'de, D: Deserializer<'de>>(
51    buf: &mut [u8],
52    deserializer: D,
53) -> Result<(), D::Error> {
54    if deserializer.is_human_readable() {
55        struct StrVisitor<'b>(&'b mut [u8]);
56
57        impl<'de> Visitor<'de> for StrVisitor<'_> {
58            type Value = ();
59
60            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
61                write!(formatter, "a string of length {}", b64len(self.0.len()))
62            }
63
64            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
65            where
66                E: Error,
67            {
68                if v.len() != b64len(self.0.len()) {
69                    return Err(Error::invalid_length(v.len(), &self));
70                }
71
72                Base64::decode(v, self.0).map_err(|e| {
73                    serde::de::Error::custom(format!("base64ct decoding error: {e}"))
74                })?;
75
76                Ok(())
77            }
78        }
79
80        deserializer.deserialize_str(StrVisitor(buf))
81    } else {
82        struct ArrayVisitor<'b>(&'b mut [u8]);
83
84        impl<'de> Visitor<'de> for ArrayVisitor<'_> {
85            type Value = ();
86
87            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
88                write!(formatter, "an array of length {}", self.0.len())
89            }
90
91            fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
92            where
93                A: SeqAccess<'de>,
94            {
95                for (index, byte) in self.0.iter_mut().enumerate() {
96                    *byte = match seq.next_element()? {
97                        Some(byte) => byte,
98                        None => return Err(Error::invalid_length(index, &self)),
99                    };
100                }
101
102                Ok(())
103            }
104        }
105
106        deserializer.deserialize_tuple(buf.len(), ArrayVisitor(buf))
107    }
108}
109
110/// Master public keys.
111#[derive(Debug, Clone, Copy)]
112pub struct PublicKey<K: IBKEM>(pub K::Pk);
113
114/// Secret keys.
115#[derive(Debug, Clone, Copy)]
116pub struct SecretKey<K: IBKEM>(pub K::Sk);
117
118/// User secret keys.
119#[derive(Debug, Clone)]
120pub struct UserSecretKey<K: IBKEM>(pub K::Usk);
121
122/// Ciphertexts.
123#[derive(Debug, Clone)]
124pub struct Ciphertext<K: IBKEM>(pub K::Ct);
125
126/// Multi-recipient ciphertexts.
127#[derive(Debug, Clone)]
128pub struct MultiRecipientCiphertext<K: IBKEM>(pub MkemCt<K>);
129
130// Note:
131// We cannot make these implementations generic over the scheme parameter because of a constant
132// expression depending on a generic parameter, see https://github.com/rust-lang/rust/issues/68436.
133// For now, the solutions are these deserialize impl macros, creating encoding/decoding buffer for
134// each scheme specifically.
135
136/// Implements [`serde::ser::Serialize`] and [`serde::de::Deserialize`] for encapsulation wrapper types.
137macro_rules! impl_serialize {
138    ($type: ty, $inner: ty) => {
139        impl Serialize for $type {
140            fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
141                serialize_bin_or_b64(&self.0.to_bytes(), serializer)
142            }
143        }
144
145        impl<'de> Deserialize<'de> for $type {
146            fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
147                let mut buf = [0u8; <$inner as Compress>::OUTPUT_SIZE];
148                deserialize_bin_or_b64(&mut buf, deserializer)?;
149
150                let artifact = open_ct(<$inner as Compress>::from_bytes(&buf)).ok_or(
151                    serde::de::Error::custom(format!("not a valid {}", stringify!($type))),
152                )?;
153
154                Ok(Self(artifact))
155            }
156        }
157    };
158}
159
160impl_serialize!(PublicKey<CGWKV>, <CGWKV as IBKEM>::Pk);
161impl_serialize!(SecretKey<CGWKV>, <CGWKV as IBKEM>::Sk);
162impl_serialize!(UserSecretKey<CGWKV>, <CGWKV as IBKEM>::Usk);
163impl_serialize!(Ciphertext<CGWKV>, <CGWKV as IBKEM>::Ct);
164impl_serialize!(MultiRecipientCiphertext<CGWKV>, MkemCt<CGWKV>);
165
166/// Identity-based signing key including its claims.
167#[derive(Debug, Clone, Serialize, Deserialize)]
168pub struct SigningKeyExt {
169    /// The signing key.
170    pub key: SigningKey,
171
172    /// The [`Policy`] associated with this signing key.
173    ///
174    /// The timestamp represents the issuing time by the PKG.
175    /// The identity is the identity for whom the key is issued.
176    pub policy: Policy,
177}
178
179/// Identity-based signing keys.
180#[derive(Debug, Clone)]
181pub struct SigningKey(pub ibs::gg::UserSecretKey);
182
183impl Serialize for SigningKey {
184    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
185    where
186        S: Serializer,
187    {
188        let bytes = bincode::serialize(&self.0).map_err(|e| {
189            serde::ser::Error::custom(format!("could not serialize signing key: {e}"))
190        })?;
191
192        debug_assert_eq!(bytes.len(), ibs::gg::USK_BYTES);
193
194        serialize_bin_or_b64(&bytes, serializer)
195    }
196}
197
198impl<'de> Deserialize<'de> for SigningKey {
199    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
200        let mut buf = [0u8; ibs::gg::USK_BYTES];
201        deserialize_bin_or_b64(&mut buf, deserializer)?;
202
203        let usk = bincode::deserialize(&buf).map_err(|e| {
204            serde::de::Error::custom(format!("could not deserialize signing key: {e}"))
205        })?;
206
207        Ok(SigningKey(usk))
208    }
209}
210
211/// Identity-based public master key (signing).
212#[doc(hidden)]
213#[derive(Debug, Clone)]
214pub struct VerifyingKey(pub ibs::gg::PublicKey);
215
216impl Serialize for VerifyingKey {
217    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
218    where
219        S: Serializer,
220    {
221        let bytes = bincode::serialize(&self.0).map_err(|e| {
222            serde::ser::Error::custom(format!("could not serialize public key: {e}"))
223        })?;
224
225        debug_assert_eq!(bytes.len(), ibs::gg::PK_BYTES);
226
227        serialize_bin_or_b64(&bytes, serializer)
228    }
229}
230
231impl<'de> Deserialize<'de> for VerifyingKey {
232    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
233        let mut buf = [0u8; ibs::gg::PK_BYTES];
234        deserialize_bin_or_b64(&mut buf, deserializer)?;
235
236        let pk: ibs::gg::PublicKey = bincode::deserialize(&buf).map_err(|e| {
237            serde::de::Error::custom(format!("could not deserialize public key: {e}"))
238        })?;
239
240        Ok(VerifyingKey(pk))
241    }
242}
243
244#[cfg(test)]
245mod tests {
246    mod kem {
247        use super::super::*;
248        use alloc::vec::Vec;
249        use ibe::kem::mkem::MultiRecipient;
250        use ibe::Derive;
251
252        struct KEMSetup<K: IBKEM> {
253            pk: K::Pk,
254            sk: K::Sk,
255            ct: K::Ct,
256            usk: K::Usk,
257            mct: MkemCt<K>,
258        }
259
260        fn default_encryption_setup<K>() -> KEMSetup<K>
261        where
262            K: IBKEM,
263            K: MultiRecipient,
264        {
265            let mut rng = rand::thread_rng();
266            let (pk, sk) = K::setup(&mut rng);
267            let id1 = <K as IBKEM>::Id::derive_str("test1");
268            let id2 = <K as IBKEM>::Id::derive_str("test2");
269            let usk = K::extract_usk(Some(&pk), &sk, &id1, &mut rng);
270            let (ct, _) = K::encaps(&pk, &id1, &mut rng);
271            let ids = [id1, id2];
272            let (cts, _) = K::multi_encaps(&pk, &ids, &mut rng);
273            let mcts: Vec<MkemCt<K>> = cts.collect();
274            let mct = mcts[0].clone();
275
276            KEMSetup {
277                pk,
278                sk,
279                ct,
280                usk,
281                mct,
282            }
283        }
284
285        #[test]
286        fn test_serialize_pk_json() {
287            let KEMSetup { pk, .. } = default_encryption_setup::<CGWKV>();
288
289            let wrapped_pk = PublicKey::<CGWKV>(pk);
290            let pk_encoded = serde_json::to_string(&wrapped_pk).unwrap();
291            let pk_decoded: PublicKey<CGWKV> = serde_json::from_str(&pk_encoded).unwrap();
292
293            assert_eq!(&wrapped_pk.0, &pk_decoded.0);
294        }
295
296        #[test]
297        fn test_serialize_sk_json() {
298            let KEMSetup { sk, .. } = default_encryption_setup::<CGWKV>();
299
300            let wrapped_sk = SecretKey::<CGWKV>(sk);
301            let sk_encoded = serde_json::to_string(&wrapped_sk).unwrap();
302            let sk_decoded: SecretKey<CGWKV> = serde_json::from_str(&sk_encoded).unwrap();
303
304            assert_eq!(&wrapped_sk.0, &sk_decoded.0);
305        }
306
307        #[test]
308        fn test_serialize_usk_json() {
309            let KEMSetup { usk, .. } = default_encryption_setup::<CGWKV>();
310
311            let wrapped_usk = UserSecretKey::<CGWKV>(usk);
312            let usk_encoded = serde_json::to_string(&wrapped_usk).unwrap();
313            let usk_decoded: UserSecretKey<CGWKV> = serde_json::from_str(&usk_encoded).unwrap();
314
315            assert_eq!(&wrapped_usk.0, &usk_decoded.0);
316        }
317
318        #[test]
319        fn test_serialize_ct_json() {
320            let KEMSetup { ct, .. } = default_encryption_setup::<CGWKV>();
321
322            let wrapped_ct = Ciphertext::<CGWKV>(ct);
323            let ct_encoded = serde_json::to_string(&wrapped_ct).unwrap();
324            let ct_decoded: Ciphertext<CGWKV> = serde_json::from_str(&ct_encoded).unwrap();
325
326            assert_eq!(&wrapped_ct.0, &ct_decoded.0);
327        }
328
329        #[test]
330        fn test_serialize_mkemct_json() {
331            let KEMSetup { mct, .. } = default_encryption_setup::<CGWKV>();
332
333            let wrapped_mct = MultiRecipientCiphertext::<CGWKV>(mct);
334            let mct_encoded = serde_json::to_string(&wrapped_mct).unwrap();
335            let mct_decoded: MultiRecipientCiphertext<CGWKV> =
336                serde_json::from_str(&mct_encoded).unwrap();
337
338            assert_eq!(&wrapped_mct.0.to_bytes(), &mct_decoded.0.to_bytes());
339        }
340
341        #[test]
342        fn test_serialize_pk_bin() {
343            let KEMSetup { pk, .. } = default_encryption_setup::<CGWKV>();
344
345            let wrapped_pk = PublicKey::<CGWKV>(pk);
346            let pk_encoded = bincode::serialize(&wrapped_pk).unwrap();
347            let pk_decoded: PublicKey<CGWKV> = bincode::deserialize(&pk_encoded[..]).unwrap();
348
349            assert_eq!(&wrapped_pk.0, &pk_decoded.0);
350        }
351
352        #[test]
353        fn test_serialize_sk_bin() {
354            let KEMSetup { sk, .. } = default_encryption_setup::<CGWKV>();
355
356            let wrapped_sk = SecretKey::<CGWKV>(sk);
357            let sk_encoded = bincode::serialize(&wrapped_sk).unwrap();
358            let sk_decoded: SecretKey<CGWKV> = bincode::deserialize(&sk_encoded[..]).unwrap();
359
360            assert_eq!(&wrapped_sk.0, &sk_decoded.0);
361        }
362
363        #[test]
364        fn test_serialize_usk_bin() {
365            let KEMSetup { usk, .. } = default_encryption_setup::<CGWKV>();
366
367            let wrapped_usk = UserSecretKey::<CGWKV>(usk);
368            let usk_encoded = bincode::serialize(&wrapped_usk).unwrap();
369            let usk_decoded: UserSecretKey<CGWKV> = bincode::deserialize(&usk_encoded[..]).unwrap();
370
371            assert_eq!(&wrapped_usk.0, &usk_decoded.0);
372        }
373
374        #[test]
375        fn test_serialize_ct_bin() {
376            let KEMSetup { ct, .. } = default_encryption_setup::<CGWKV>();
377
378            let wrapped_ct = Ciphertext::<CGWKV>(ct);
379            let ct_encoded = bincode::serialize(&wrapped_ct).unwrap();
380            let ct_decoded: Ciphertext<CGWKV> = bincode::deserialize(&ct_encoded[..]).unwrap();
381
382            assert_eq!(&wrapped_ct.0, &ct_decoded.0);
383        }
384
385        #[test]
386        fn test_serialize_mkemct_bin() {
387            let KEMSetup { mct, .. } = default_encryption_setup::<CGWKV>();
388
389            let wrapped_mct = MultiRecipientCiphertext::<CGWKV>(mct);
390            let mct_encoded = bincode::serialize(&wrapped_mct).unwrap();
391            let mct_decoded: MultiRecipientCiphertext<CGWKV> =
392                bincode::deserialize(&mct_encoded).unwrap();
393
394            assert_eq!(&wrapped_mct.0.to_bytes(), &mct_decoded.0.to_bytes());
395        }
396
397        #[test]
398        fn test_kem_regression_json() {
399            let pk ="\"g2sPj5dg1SH15TwQ9k0YsFrpUJbLgxK67mGezYZeB6Zl22AnTnkmHVXv06E44Ev1qd4nsj6SK3l6O21N/J/0/zM36vZhEF56/Kyt2qd93ovZJHqPqCMmYY3pi2d2DP9vt9w/Y0T7LXOKJZLzFzyoXR+ca/quRbQrJRrvz1YZdz36ehJ1CFO63HbqZhUIE21XjL9KKdx3S91cclj337f/FXNF5uPb+6E/6oKh0VniGPArspFhQ5ca/h+k6DsVgpYXgRohU5jqT3FYtx82OewAMo+GGUEmejGgnJwF/V69y6tH16ohZ24RVetn8F8qKkeYhLfMmnWIsjAoD/TIkznRyuQOBhR6bQhNdFP3WM2Z6a6bt/y8NVqDgGhr+hBrD8los9RZAlMlNYLHQgxiSuj3k84FHdX22QpEiUpXWJttwmzLKJyP1lhhmO98+T5Em347hsvLellKAEUABl3lr+Z5Pu6/RKz0ZOsD3fxeGzbPDtxuzqc3uXbrMe0jpG5kwR8B1lLaSs/aychKaSJ5znt9zllzzXjPIuE/+UTXcjmYmO837UVMajj5pZrPOcuf9mLEBoq82irr21UBzHJawgNAStpdWVz5Ie22dDKytdeJv1S1Se4tiZfbJTpRM0FmIX8ZEyfXwehUWFS5GCnwkwkhWyzWMGeDXb2AT+OLDSH7MqWneh2KqjtW6bBEs0XcyvSLEtApi/NDfJk3OZ0/SAJb3tH2c7HN1X0l+HJxuHtT1sDzg3JVizwJwd53mKwgFAnWDkYRScKdAEv+EM0upC5YVhnUYYLfJ8YhC8RTU4W5cvg7Q9rfKonDmZLnJTr2aRo3D9CpfjUffuxBUoARSwJlH14KlI0Id91I8z/Fy1jo22x1dP7gHSl/fto+tGnbpYvj\"";
400            let sk = "\"im1K0e1zoEmOoBtWEhMEFbK7BiQrGYh37ua2FX/bCg+cNyUEsE0ObpqZQG5t4ZAFFMsOR/f2HgLGZRbhHdXLCSIxJ5NzjtVUT5KQrbu81D9n/jUOWF47Mp5Sp+b9WzJiVWaakn7j7HuRH4uRJJTg69W+fhBj8eJFoFJL0FEGLgpyiLR1OTLSN6hrxJxQhfGkOvSAPocMw5SNGdtDS+8MDbnuK5+P/bKlTNgg0Tn5sw0wnQ5hluc4flkrcWv+E0wR98sPiRbpLK5qFYmcttzrafpbacj4RwolTrkr0fgdVzBpVhODC0WmFV07ml8t+Q8l3TBmXuZQNF2hF51d1+LabvEToP+g7NHdYoqw4cqw/7hziz52k3HYQ/oICYL/7mAs1kZxbbxtLRK3/FqleG9RrjFkerfV0P47MKNuOlX5Fl97+3/vu47MKVBGJIDUPeh/jKEczw3Pc2CZN8O6XOmRIsj626Hh3nSZ+W0fmhPTjY8gf4nHpOylHvZIMoAe/REv+KMHOMAFwc19fMGUZN/iXqKRp6Tgvao7/o6w1DJsQigDDnyQPhsWqgGIrV2OCTpKRuIOa16EYafbJFPDMlmRLgdIjw4sWXvnFjI45Oqem02RmhBSArR7HxEb0g1QUkEA/XNZI/l/8R241k4BRWZKebfqhqx5JxIe55F6JsqhvRQ=\"";
401            let usk = "\"mXLtWwa0YF2+nhiYn7AvG+Fkf4ih6orDMCnDeXxit4ejBLUkyAY0PowIF/UigkU9CygnZEmw09oFM5DxHjeYXB79ck3V8slKANxwXqxmrShf8YGR6BqpLugZW/jWATKZslKVFeDPs8gh0xCbejdBlX2lJLgNB9M5t/NxSuqnNUyCb/zYPGC1ElE3mcUWu8fsDFfIBFveQ/7b5Y8HQOyEUBwYlAbJmQs9XPSJ19WIWoqZNulhkFlcsjW8cj5cquNvpz4NEXKlkz46YMto+wyafbrcBfDbhDHPDFYEVRzGx1JrQ+tVGlJYskCtHMCzdPYfGROot2NcPcP18WB4oIppe1RBglgkM6uZx2kRYsOmJteHfYhjy5rAUTqG52BXqH24o64RNMWKDlL+/hkkqsMCT6UEvdS18xaQBc5mcQ5Hxcwl+sYuZvyy+3ZyE08zVjjrCvy+qa8DViT4ThAvM0phg6EngAhzZVONEPRuglKsd4LlDtk/Qx+pkjvAdMJvkP2qkqhmyZarWAQWHY5jOEl5t7WQNhKSRJkj4NQLMAZ+cxhQxpNy63+p1ejGsWlcjIejCPTeHjP/IJdtdaIYXjBFqsRUpi1Cd27XapHq3fntAYab+jG0TagGdHJbIMkdR6K+sRgA8QjiQsSEElzhZ/hIEDqxq1QkFllltFNodx+zTO7IowNRgJxUtkUUDRvUmNpRA+L2Wl2/Nv2CW+KNiuizwPDzsGs46c29DR5AYHVPEJOsvkzdHEa/IMxXnuqdSTsl\"";
402            let ct = "\"pjhu9vnHq7VoT+O0jftONe+9U7NhJ+jqHxV0KQczBgBQ/gaUO30kaYbSlc4IEQHeqOeUitp1I3JAD+juoprsiau6kKWw6gu0mJp/YsTF3b6SQ0q2Mhl3RxzCuWfWVZR8hR7DcQHlyoG1FMbj8tTE2Hsv8BBb0JghwedYmWXhe/7U+DkEEYQKcHPaq5pVfF1HkKnMdwA935uIULIFXGcC3Z3q56PwDCAjjv+lzkpRAlx8kPgyv9IKdhNHhLfJNuAUkzFzYSy08udRKvq0eCl/VH4mWvmWcbQOMn/BguwdGok=\"";
403            let mrct = "\"kDxkcKzqw67KhSGYkN6Lbc3PaZmyZZACvHpk5nnC17hneJUi6rDzmbvi21YJ1nrQuQMA4nIb1uuw2akHVajdv/V56G5fpyYUAzrb6IvltPxQbo/7dBsteYyD+OGwVKEho0zPr3yWVhNt9BGwGJvwXClVmmX2MRYVmQ1Gq55TON91VK/upr8Hr3XWRGwR8lhQjy0etI/v7K7UKp90nhQY4JcXlwk666YoDjhLs+gFCOxUpY1bIswJpDVr9mCXMXujdPqiRpoltYYEhdBInhID0WjA5zxvr4zobNxMSZWfk5eAcCHYxItjHX4FCYqrGcPFc5uOUhWOZmay7iNwjczcmMAlMYbSx3ppfDjGfQd06lSygsATkQmTgCMZrwM=\"";
404
405            let _pk_decoded: PublicKey<CGWKV> = serde_json::from_str(pk).unwrap();
406            let _sk_decoded: SecretKey<CGWKV> = serde_json::from_str(sk).unwrap();
407            let _ct_decoded: Ciphertext<CGWKV> = serde_json::from_str(ct).unwrap();
408            let _usk_decoded: UserSecretKey<CGWKV> = serde_json::from_str(usk).unwrap();
409            let _mct_decoded: MultiRecipientCiphertext<CGWKV> = serde_json::from_str(mrct).unwrap();
410        }
411    }
412
413    mod sign {
414        use super::super::{SigningKey, VerifyingKey};
415        use ibs::gg::*;
416        use rand::Rng;
417
418        struct SignSetup {
419            pk: PublicKey,
420            usk: UserSecretKey,
421        }
422
423        fn default_signing_setup() -> SignSetup {
424            let mut rng = rand::thread_rng();
425            let (pk, sk) = ibs::gg::setup(&mut rng);
426
427            let id = Identity::from(rng.gen::<[u8; IDENTITY_BYTES]>());
428            let usk = ibs::gg::keygen(&sk, &id, &mut rng);
429
430            SignSetup { pk, usk }
431        }
432
433        #[test]
434        fn test_signing_regression() {
435            let pk = "\"XMTJUg+94jtBhy/z655djL97gFLeDfANA9mhnQ+2tzE=\"";
436            let usk = "\"K3Ijgx5lgGA/wD+/rzVVQ6l4xF4N/zxMQPTbsP4c0wJkf/Q1Q3z8STL0Qg1E+b3upqRKNivYKzPZ0246z09bLst0nqGC69fa6PRpG2kEOAXS8B/h6fI/B/I0D9BfQmbU\"";
437            let sk = [
438                3, 156, 140, 183, 148, 171, 164, 239, 191, 152, 103, 133, 137, 241, 96, 169, 157,
439                199, 137, 169, 187, 204, 85, 118, 79, 35, 52, 83, 37, 217, 230, 13,
440            ];
441
442            let _pk: VerifyingKey = serde_json::from_str(&pk).unwrap();
443            let _usk: SigningKey = serde_json::from_str(&usk).unwrap();
444            let _sk: SecretKey = bincode::deserialize(&sk).unwrap();
445        }
446
447        macro_rules! test_serialize {
448            ($name: ident, $setup: ident, $type: tt, $ser: path, $de: path, $member: tt) => {
449                #[test]
450                fn $name() {
451                    let setup = $setup();
452
453                    let wrapped = $type(setup.$member.clone());
454                    let serialized = $ser(&wrapped).unwrap();
455                    let deserialized: $type = $de(&serialized).unwrap();
456
457                    assert_eq!(&setup.$member, &deserialized.0);
458                }
459            };
460        }
461
462        test_serialize!(
463            test_serialize_verifying_key_bin,
464            default_signing_setup,
465            VerifyingKey,
466            bincode::serialize,
467            bincode::deserialize,
468            pk
469        );
470
471        test_serialize!(
472            test_serialize_signing_key_bin,
473            default_signing_setup,
474            SigningKey,
475            bincode::serialize,
476            bincode::deserialize,
477            usk
478        );
479
480        test_serialize!(
481            test_serialize_verifying_key_json,
482            default_signing_setup,
483            VerifyingKey,
484            serde_json::to_string,
485            serde_json::from_str,
486            pk
487        );
488
489        test_serialize!(
490            test_serialize_signing_key_json,
491            default_signing_setup,
492            SigningKey,
493            serde_json::to_string,
494            serde_json::from_str,
495            usk
496        );
497    }
498}