Skip to main content

ferveo_nucypher_common/
serialization.rs

1//! This adds a few utility functions for serializing and deserializing
2//! [arkworks](http://arkworks.rs/) types that implement [CanonicalSerialize] and [CanonicalDeserialize].
3//! Adapted from [o1-labs/proof-systems](https://raw.githubusercontent.com/o1-labs/proof-systems/31c76ceae3122f0ce09cded8260960ed5cbbe3d8/utils/src/serialization.rs).
4
5use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
6use serde::{self, Deserialize, Serialize};
7use serde_with::Bytes;
8
9//
10// Serialization with serde
11//
12
13pub mod ser {
14    //! You can use this module for serialization and deserializing arkworks types with [serde].
15    //! Simply use the following attribute on your field:
16    //! `#[serde(with = "serialization::ser") attribute"]`
17
18    use serde_with::{DeserializeAs, SerializeAs};
19
20    use super::*;
21
22    /// You can use this to serialize an arkworks type with serde and the "serialize_with" attribute.
23    /// See <https://serde.rs/field-attrs.html>
24    pub fn serialize<S>(
25        val: impl CanonicalSerialize,
26        serializer: S,
27    ) -> Result<S::Ok, S::Error>
28    where
29        S: serde::Serializer,
30    {
31        let mut bytes = vec![];
32        val.serialize_compressed(&mut bytes)
33            .map_err(serde::ser::Error::custom)?;
34
35        Bytes::serialize_as(&bytes, serializer)
36    }
37
38    /// You can use this to deserialize an arkworks type with serde and the "deserialize_with" attribute.
39    /// See <https://serde.rs/field-attrs.html>
40    pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
41    where
42        T: CanonicalDeserialize,
43        D: serde::Deserializer<'de>,
44    {
45        let bytes: Vec<u8> = Bytes::deserialize_as(deserializer)?;
46        T::deserialize_compressed(&mut &bytes[..])
47            .map_err(serde::de::Error::custom)
48    }
49}
50
51//
52// Serialization with [serde_with]
53//
54
55/// You can use [SerdeAs] with [serde_with] in order to serialize and deserialize types that implement [CanonicalSerialize] and [CanonicalDeserialize],
56/// or containers of types that implement these traits (Vec, arrays, etc.)
57/// Simply add annotations like `#[serde_as(as = "serialization::SerdeAs")]`
58/// See <https://docs.rs/serde_with/1.10.0/serde_with/guide/serde_as/index.html#switching-from-serdes-with-to-serde_as>
59pub struct SerdeAs;
60
61impl<T> serde_with::SerializeAs<T> for SerdeAs
62where
63    T: CanonicalSerialize,
64{
65    fn serialize_as<S>(val: &T, serializer: S) -> Result<S::Ok, S::Error>
66    where
67        S: serde::Serializer,
68    {
69        let mut bytes = vec![];
70        val.serialize_compressed(&mut bytes)
71            .map_err(serde::ser::Error::custom)?;
72
73        Bytes::serialize_as(&bytes, serializer)
74    }
75}
76
77impl<'de, T> serde_with::DeserializeAs<'de, T> for SerdeAs
78where
79    T: CanonicalDeserialize,
80{
81    fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
82    where
83        D: serde::Deserializer<'de>,
84    {
85        let bytes: Vec<u8> = Bytes::deserialize_as(deserializer)?;
86        T::deserialize_compressed(&mut &bytes[..])
87            .map_err(serde::de::Error::custom)
88    }
89}
90
91// TODO: Trait aliases are experimental
92// trait ByteSerializable = ToBytes + FromBytes;
93
94pub trait ToBytes {
95    fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error>;
96}
97
98pub trait FromBytes: Sized {
99    fn from_bytes(bytes: &[u8]) -> Result<Self, bincode::Error>;
100}
101
102impl<T: Serialize> ToBytes for T {
103    fn to_bytes(&self) -> Result<Vec<u8>, bincode::Error> {
104        bincode::serialize(self)
105    }
106}
107
108impl<T: for<'de> Deserialize<'de>> FromBytes for T {
109    fn from_bytes(bytes: &[u8]) -> Result<Self, bincode::Error> {
110        bincode::deserialize(bytes)
111    }
112}
113
114#[cfg(test)]
115mod test {
116    use super::*;
117
118    #[derive(Serialize, Deserialize, Debug, PartialEq)]
119    struct Test {
120        a: u32,
121        b: u32,
122    }
123
124    #[test]
125    fn test_serde() {
126        let test = Test { a: 1, b: 2 };
127        let bytes = test.to_bytes().unwrap();
128        let test2 = Test::from_bytes(&bytes).unwrap();
129        assert_eq!(test, test2);
130    }
131}