Skip to content

Commit

Permalink
feat: add macro to serialize/deserialize options
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugo Rosenkranz-Costa committed Nov 22, 2023
1 parent 4935d72 commit 3ecaa3c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 44 deletions.
76 changes: 39 additions & 37 deletions src/core/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@ use crate::{
CleartextHeader, EncryptedHeader, Error,
};

/// Serialize an optional value as a LEB128-encoded unsigned integer followed by
/// the serialization of the contained value if any.
macro_rules! serialize_option {
($serializer:expr, $n:expr, $option:expr, $value:ident, $method:expr) => {{
if let Some($value) = &$option {
$n += $serializer.write_leb128_u64(1)?;
$n += $method?;
} else {
$n += $serializer.write_leb128_u64(0)?;
}
}};
}

/// Deserialize an optional value from a LEB128-encoded unsigned integer
/// followed by the deserialization of the contained value if any.
macro_rules! deserialize_option {
($deserializer:expr, $method:expr) => {{
let is_some = $deserializer.read_leb128_u64()?;
if is_some == 1 {
Some($method)
} else {
None
}
}};
}

impl Serializable for MasterPublicKey {
type Error = Error;

Expand All @@ -42,12 +68,7 @@ impl Serializable for MasterPublicKey {
n += ser.write_leb128_u64(self.subkeys.len() as u64)?;
for (partition, (pk_i, h_i)) in &self.subkeys {
n += ser.write_vec(partition)?;
if let Some(pk_i) = pk_i {
n += ser.write_leb128_u64(1)?;
n += ser.write_array(pk_i)?;
} else {
n += ser.write_leb128_u64(0)?;
}
serialize_option!(ser, n, pk_i, value, ser.write_array(value));
n += ser.write_array(&h_i.to_bytes())?;
}
Ok(n)
Expand All @@ -60,12 +81,7 @@ impl Serializable for MasterPublicKey {
let mut subkeys = HashMap::with_capacity(n_partitions);
for _ in 0..n_partitions {
let partition = de.read_vec()?;
let is_hybridized = de.read_leb128_u64()?;
let pk_i = if is_hybridized == 1 {
Some(KyberPublicKey(de.read_array()?))
} else {
None
};
let pk_i = deserialize_option!(de, KyberPublicKey(de.read_array()?));
let h_i = de.read_array::<{ R25519PublicKey::LENGTH }>()?;
subkeys.insert(
Partition::from(partition),
Expand Down Expand Up @@ -99,14 +115,15 @@ impl Serializable for MasterSecretKey {
n += ser.write_array(&self.s2.to_bytes())?;
n += ser.write_array(&self.s.to_bytes())?;
n += ser.write_leb128_u64(self.subkeys.len() as u64)?;
for (partition, (sk_i, x_i)) in self.subkeys.iter() {
for (partition, entry) in &self.subkeys.map {
// serialize partition, next and prev
n += ser.write_vec(partition)?;
if let Some(sk_i) = sk_i {
n += ser.write_leb128_u64(1)?;
n += ser.write_array(sk_i)?;
} else {
n += ser.write_leb128_u64(0)?;
}
serialize_option!(ser, n, entry.next_key, value, ser.write_vec(value));
serialize_option!(ser, n, entry.prev_key, value, ser.write_vec(value));

// serialize key values
let (sk_i, x_i) = &entry.value;
serialize_option!(ser, n, sk_i, value, ser.write_array(value));
n += ser.write_array(&x_i.to_bytes())?;
}
if let Some(kmac_key) = &self.kmac_key {
Expand All @@ -127,12 +144,7 @@ impl Serializable for MasterSecretKey {
let mut subkeys = HashMap::with_capacity(n_partitions);
for _ in 0..n_partitions {
let partition = de.read_vec()?;
let is_hybridized = de.read_leb128_u64()?;
let sk_i = if is_hybridized == 1 {
Some(KyberSecretKey(de.read_array()?))
} else {
None
};
let sk_i = deserialize_option!(de, KyberSecretKey(de.read_array()?));
let x_i = de.read_array::<{ R25519PrivateKey::LENGTH }>()?;
subkeys.insert(
Partition::from(partition),
Expand Down Expand Up @@ -179,12 +191,7 @@ impl Serializable for UserSecretKey {
n += ser.write_leb128_u64(self.subkeys.len() as u64)?;
for (partition, (sk_i, x_i)) in self.subkeys.iter() {
n += ser.write_vec(partition)?;
if let Some(sk_i) = sk_i {
n += ser.write_leb128_u64(1)?;
n += ser.write_array(sk_i)?;
} else {
n += ser.write_leb128_u64(0)?;
}
serialize_option!(ser, n, sk_i, value, ser.write_array(value));
n += ser.write_array(&x_i.to_bytes())?;
}
if let Some(kmac) = &self.kmac {
Expand All @@ -200,12 +207,7 @@ impl Serializable for UserSecretKey {
let mut subkeys = Vec::with_capacity(n_partitions);
for _ in 0..n_partitions {
let partition = de.read_vec()?;
let is_hybridized = de.read_leb128_u64()?;
let sk_i = if is_hybridized == 1 {
Some(KyberSecretKey(de.read_array()?))
} else {
None
};
let sk_i = deserialize_option!(de, KyberSecretKey(de.read_array()?));
let x_i = de.read_array::<{ R25519PrivateKey::LENGTH }>()?;
subkeys.push((
Partition::from(partition),
Expand Down
15 changes: 8 additions & 7 deletions src/data_struct/versioned_hashmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@ where
K: Debug + PartialEq + Eq + Hash,
V: Debug + PartialEq + Eq,
{
map: HashMap<K, VersionedEntry<K, V>>,
pub(crate) map: HashMap<K, VersionedEntry<K, V>>,
}

/// a `VersionedEntry` stores a value and an optional key of the next entry
/// version in the hash map.
#[derive(Debug, PartialEq, Eq, Clone)]
struct VersionedEntry<K, V> {
value: V,
prev_key: Option<K>,
next_key: Option<K>,
pub struct VersionedEntry<K, V> {
pub(crate) value: V,
pub(crate) prev_key: Option<K>,
pub(crate) next_key: Option<K>,
}

impl<K, V> VersionedEntry<K, V>
Expand Down Expand Up @@ -72,7 +72,7 @@ where
impl<'a, K, V> Iterator for VersionedHashMapIterator<'a, K, V>
where
V: Clone + Debug + Eq + PartialEq,
K: Hash + Eq + PartialEq + Clone + PartialOrd + Ord + Debug,
K: Hash + Eq + PartialEq + Clone + Debug,
{
type Item = (&'a K, &'a V);

Expand All @@ -88,7 +88,7 @@ where

impl<K, V> VersionedHashMap<K, V>
where
K: Hash + PartialEq + Eq + Clone + PartialOrd + Ord + Debug,
K: Hash + PartialEq + Eq + Clone + Debug,
V: Clone + Debug + PartialEq + Eq,
{
pub fn new() -> Self {
Expand Down Expand Up @@ -173,6 +173,7 @@ where
self.map.keys()
}

/// Iterates through all values in arbitrary order.
pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
self.map.iter().map(|(k, entry)| (k, &entry.value))
}
Expand Down

0 comments on commit 3ecaa3c

Please sign in to comment.