From 32a371ec6e79d7822780752eb9d1452ec412fed9 Mon Sep 17 00:00:00 2001 From: Hugo Rosenkranz-Costa Date: Tue, 28 Nov 2023 15:31:59 +0100 Subject: [PATCH] feat: replace `VersionedVec` with `RevisionVec` in USK implementation --- src/core/mod.rs | 4 +- src/core/primitives.rs | 60 +++---- src/core/serialization.rs | 53 +++--- src/data_struct/mod.rs | 4 +- src/data_struct/revision_vec.rs | 143 ++++++++------- src/data_struct/versioned_vec.rs | 294 ------------------------------- src/test_utils/mod.rs | 110 +++++++----- 7 files changed, 199 insertions(+), 469 deletions(-) delete mode 100644 src/data_struct/versioned_vec.rs diff --git a/src/core/mod.rs b/src/core/mod.rs index d9982619..2e705cea 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -8,7 +8,7 @@ use zeroize::ZeroizeOnDrop; use crate::{ abe_policy::Partition, - data_struct::{RevisionMap, VersionedVec}, + data_struct::{RevisionMap, RevisionVec}, }; #[macro_use] @@ -80,7 +80,7 @@ pub struct MasterSecretKey { pub struct UserSecretKey { a: R25519PrivateKey, b: R25519PrivateKey, - pub(crate) subkeys: VersionedVec<(Partition, Subkey)>, + pub(crate) subkeys: RevisionVec, kmac: Option, } diff --git a/src/core/primitives.rs b/src/core/primitives.rs index 166dcb7d..1a92b916 100644 --- a/src/core/primitives.rs +++ b/src/core/primitives.rs @@ -21,7 +21,7 @@ use super::{ use crate::{ abe_policy::{AttributeStatus, EncryptionHint, Partition}, core::{Encapsulation, KeyEncapsulation, MasterPublicKey, MasterSecretKey, UserSecretKey}, - data_struct::{RevisionMap, VersionedVec}, + data_struct::{RevisionMap, RevisionVec}, Error, }; @@ -42,7 +42,7 @@ fn compute_user_key_kmac(msk: &MasterSecretKey, usk: &UserSecretKey) -> Option = decryption_set + let subkeys: RevisionVec<_, _> = decryption_set .iter() .filter_map(|partition| { msk.subkeys @@ -245,7 +245,7 @@ pub fn decaps( for encapsulation_i in &encapsulation.encs { // BFS search user subkeys to first try the most recent rotations of each // partitions. - for (_, (sk_j, x_j)) in usk.subkeys.bfs() { + for (sk_j, x_j) in usk.subkeys.bfs() { let e_j = match encapsulation_i { KeyEncapsulation::HybridEncapsulation(epq_i) => { if let Some(sk_j) = sk_j { @@ -674,42 +674,28 @@ mod tests { &msk, &mut usk, //&HashSet::from([partition_2.clone(), partition_4.clone()]), )?; - assert!(!usk.subkeys.iter().any(|x| { - x == &( - partition_1.clone(), - old_msk - .subkeys - .get_current_revision(&partition_1) - .unwrap() - .clone(), + assert!(!usk.subkeys.flat_iter().any(|x| { + x == ( + &partition_1, + old_msk.subkeys.get_current_revision(&partition_1).unwrap(), ) })); - assert!(usk.subkeys.iter().any(|x| { - x == &( - partition_2.clone(), - msk.subkeys - .get_current_revision(&partition_2) - .unwrap() - .clone(), + assert!(usk.subkeys.flat_iter().any(|x| { + x == ( + &partition_2, + msk.subkeys.get_current_revision(&partition_2).unwrap(), ) })); - assert!(!usk.subkeys.iter().any(|x| { - x == &( - partition_3.clone(), - old_msk - .subkeys - .get_current_revision(&partition_3) - .unwrap() - .clone(), + assert!(!usk.subkeys.flat_iter().any(|x| { + x == ( + &partition_3, + old_msk.subkeys.get_current_revision(&partition_3).unwrap(), ) })); - assert!(usk.subkeys.iter().any(|x| { - x == &( - partition_4.clone(), - msk.subkeys - .get_current_revision(&partition_4) - .unwrap() - .clone(), + assert!(usk.subkeys.flat_iter().any(|x| { + x == ( + &partition_4, + msk.subkeys.get_current_revision(&partition_4).unwrap(), ) })); Ok(()) @@ -742,10 +728,10 @@ mod tests { let usk_ = UserSecretKey::deserialize(&bytes)?; assert!(verify_user_key_kmac(&msk, &usk_).is_ok()); - usk.subkeys.insert_new_chain(iter::once(( + usk.subkeys.insert_new_chain( Partition(b"3".to_vec()), - (None, R25519PrivateKey::new(&mut rng)), - ))); + iter::once((None, R25519PrivateKey::new(&mut rng))), + ); // KMAC verify will fail after modifying the user key assert!(verify_user_key_kmac(&msk, &usk).is_err()); diff --git a/src/core/serialization.rs b/src/core/serialization.rs index 640475f7..9f8595c7 100644 --- a/src/core/serialization.rs +++ b/src/core/serialization.rs @@ -15,7 +15,7 @@ use crate::{ Encapsulation, KeyEncapsulation, MasterPublicKey, MasterSecretKey, UserSecretKey, SYM_KEY_LENGTH, }, - data_struct::{RevisionMap, VersionedVec}, + data_struct::{RevisionList, RevisionMap, RevisionVec}, CleartextHeader, EncryptedHeader, Error, }; @@ -47,11 +47,7 @@ macro_rules! serialize_option { macro_rules! deserialize_option { ($deserializer:expr, $method:expr) => {{ let is_some = $deserializer.read_leb128_u64()?; - if is_some == 1 { - Some($method) - } else { - None - } + if is_some == 1 { Some($method) } else { None } }}; } @@ -192,12 +188,18 @@ impl Serializable for UserSecretKey { + self.kmac.as_ref().map_or_else(|| 0, |kmac| kmac.len()) // subkeys serialization + to_leb128_len(self.subkeys.nb_chains()) - // upper bound on chains leb128 length - + self.subkeys.nb_chains() * to_leb128_len(self.subkeys.len()) + self.subkeys.len() * R25519PrivateKey::LENGTH; - for (partition, (sk_i, _)) in self.subkeys.iter() { + /*for (partition, (sk_i, _)) in self.subkeys.iter() { length += (to_leb128_len(partition.len()) + partition.len()) + serialize_len_option!(sk_i, _value, KYBER_INDCPA_SECRETKEYBYTES); + }*/ + for chain in &self.subkeys.chains { + let partition = chain.get_key(); + length += to_leb128_len(partition.len()) + partition.len(); + length += to_leb128_len(chain.len()); + for (_, (sk_i, _)) in chain.iter() { + length += serialize_len_option!(sk_i, _value, KYBER_INDCPA_SECRETKEYBYTES); + } } length } @@ -206,12 +208,12 @@ impl Serializable for UserSecretKey { let mut n = ser.write_array(&self.a.to_bytes())?; n += ser.write_array(&self.b.to_bytes())?; n += ser.write_leb128_u64(self.subkeys.nb_chains() as u64)?; - for chain_index in 0..self.subkeys.nb_chains() { - n += ser.write_leb128_u64(self.subkeys.chain_length(chain_index) as u64)?; - // Iterate through all partitions in the chain (stored in ante-chronological - // order) so we reverse it to write the older partition first. - for (partition, (sk_i, x_i)) in self.subkeys.iter_chain(chain_index).rev() { - n += ser.write_vec(partition)?; + for chain in &self.subkeys.chains { + // write chain partition + n += ser.write_vec(chain.get_key())?; + // iterate through all subkeys in the chain + n += ser.write_leb128_u64(chain.len() as u64)?; + for (_, (sk_i, x_i)) in chain.iter() { serialize_option!(ser, n, sk_i, value, ser.write_array(value)); n += ser.write_array(&x_i.to_bytes())?; } @@ -225,23 +227,20 @@ impl Serializable for UserSecretKey { fn read(de: &mut Deserializer) -> Result { let a = R25519PrivateKey::try_from_bytes(de.read_array::<{ R25519PrivateKey::LENGTH }>()?)?; let b = R25519PrivateKey::try_from_bytes(de.read_array::<{ R25519PrivateKey::LENGTH }>()?)?; - let n_partitions_chains = ::try_from(de.read_leb128_u64()?)?; - let mut subkeys = VersionedVec::with_capacity(n_partitions_chains); - for _ in 0..n_partitions_chains { - // Read all partitions forming a chain and inserting them all at one. - let n_partitions = ::try_from(de.read_leb128_u64()?)?; - let it = (0..n_partitions) + let n_partitions = ::try_from(de.read_leb128_u64()?)?; + let mut subkeys = RevisionVec::with_capacity(n_partitions); + for _ in 0..n_partitions { + let partition = Partition::from(de.read_vec()?); + // read all keys forming a chain and inserting them all at once. + let n_keys = ::try_from(de.read_leb128_u64()?)?; + let it = (0..n_keys) .map(|_| { - let partition = de.read_vec()?; let sk_i = deserialize_option!(de, KyberSecretKey(de.read_array()?)); let x_i = de.read_array::<{ R25519PrivateKey::LENGTH }>()?; - Ok::<_, Self::Error>(( - Partition::from(partition), - (sk_i, R25519PrivateKey::try_from_bytes(x_i)?), - )) + Ok::<_, Self::Error>((sk_i, R25519PrivateKey::try_from_bytes(x_i)?)) }) .filter_map(Result::ok); - subkeys.insert_new_chain(it); + subkeys.chains.push(RevisionList::from_iter(partition, it)) } let kmac = de.read_array::<{ KMAC_LENGTH }>().ok(); diff --git a/src/data_struct/mod.rs b/src/data_struct/mod.rs index 9a401251..208e8691 100644 --- a/src/data_struct/mod.rs +++ b/src/data_struct/mod.rs @@ -2,9 +2,7 @@ mod dictionary; pub mod error; mod revision_map; mod revision_vec; -mod versioned_vec; pub use dictionary::Dict; pub use revision_map::RevisionMap; -pub use revision_vec::RevisionVec; -pub use versioned_vec::VersionedVec; +pub use revision_vec::{RevisionList, RevisionVec}; diff --git a/src/data_struct/revision_vec.rs b/src/data_struct/revision_vec.rs index ce74ebb7..42de9eaf 100644 --- a/src/data_struct/revision_vec.rs +++ b/src/data_struct/revision_vec.rs @@ -1,4 +1,4 @@ -use std::collections::VecDeque; +use std::{collections::VecDeque, iter}; use super::error::Error; @@ -19,21 +19,21 @@ use super::error::Error; // TODO: check Serialize/Deserialize #[derive(Default, Debug, PartialEq, Eq)] pub struct RevisionVec { - data: Vec>, + pub(crate) chains: Vec>, length: usize, } impl RevisionVec { pub fn new() -> Self { Self { - data: Vec::new(), + chains: Vec::new(), length: 0, } } pub fn with_capacity(capacity: usize) -> Self { Self { - data: Vec::with_capacity(capacity), + chains: Vec::with_capacity(capacity), length: 0, } } @@ -47,16 +47,16 @@ impl RevisionVec { } pub fn nb_chains(&self) -> usize { - self.data.len() + self.chains.len() } pub fn chain_length(&self, chain_index: usize) -> usize { - self.data[chain_index].len() + self.chains[chain_index].len() } pub fn push_front(&mut self, chain_index: usize, item: T) -> Result<(), Error> { let chain = self - .data + .chains .get_mut(chain_index) .ok_or(Error::missing_entry(&chain_index))?; @@ -68,57 +68,37 @@ impl RevisionVec { /// Inserts entry versions in reverse chronological order /// The iterator must be in chronological order as the items are inserted /// backward. - pub fn insert_new_chain(&mut self, _iterator: impl Iterator) { - /*let mut new_list = LinkedList::new(); + pub fn insert_new_chain(&mut self, key: K, iterator: impl Iterator) { + let mut new_list = RevisionList::new(key); for item in iterator { new_list.push_front(item); } if !new_list.is_empty() { self.length += new_list.len(); - self.data.push(new_list); - }*/ - todo!() - } - - /// Removes old entry version. - pub fn pop_back(&mut self, _chain_index: usize) -> Result { - /*let chain = self - .data - .get_mut(chain_index) - .ok_or(Error::missing_entry(&chain_index))?; - - let removed_item = chain.pop_back().expect("chains should not be empty"); - self.length -= 1; - - if chain.is_empty() { - self.data.swap_remove(chain_index); + self.chains.push(new_list); } - - Ok(removed_item)*/ - todo!() } pub fn clear(&mut self) { - self.data.clear(); - self.length = self.data.len(); + self.chains.clear(); + self.length = self.chains.len(); } /// Provides reference to the current entry version. pub fn front(&self, chain_index: usize) -> Option<&T> { - self.data.get(chain_index)?.front() + self.chains.get(chain_index)?.front() } /// Iterates through all versions of an entry starting from the most recent /// one. pub fn iter_chain(&self, chain_index: usize) -> impl Iterator { - self.data[chain_index].iter().map(|(_, v)| v) + self.chains[chain_index].iter().map(|(_, v)| v) } /// Iterates through all versions of all entries - pub fn iter(&self) -> impl Iterator { - self.data - .iter() - .flat_map(|chain| chain.iter().map(|(_, v)| v)) + /// Returns the key and value for each entry. + pub fn flat_iter(&self) -> impl Iterator { + self.chains.iter().flat_map(|chain| chain.iter()) } pub fn bfs(&self) -> BfsIterator { @@ -127,12 +107,19 @@ impl RevisionVec { } pub struct BfsIterator<'a, T> { - chains: VecDeque<&'a Element>, + queue: VecDeque<&'a Element>, } impl<'a, T> BfsIterator<'a, T> { - pub fn new(_versioned_vec: &'a RevisionVec) -> Self { - todo!() + pub fn new(revision_vec: &'a RevisionVec) -> Self { + // add all chain heads to the iterator queue + Self { + queue: revision_vec + .chains + .iter() + .filter_map(|chain| Some(chain.head.as_ref()?.as_ref())) + .collect(), + } } } @@ -140,36 +127,27 @@ impl<'a, T> Iterator for BfsIterator<'a, T> { type Item = &'a T; fn next(&mut self) -> Option { - /*loop { - if self.chains.is_empty() { - return None; - } - self.index %= self.chains.len(); - let chain = &mut self.chains[self.index]; - - if let Some(next_entry) = chain.next() { - self.index += 1; - break Some(next_entry); - } else { - let _ = self.chains.remove(self.index); - } - }*/ - todo!() + // get first element in the iterator queue + let current_element = self.queue.pop_front()?; + if let Some(next_element) = current_element.next.as_ref() { + // add next element of this chain at the back of the queue + self.queue.push_back(next_element); + } + Some(¤t_element.data) } } -/// Create VersionedVec from an iterator, each element will be inserted in a +/// Create `RevisionVec`` from an iterator, each element will be inserted in a /// different chain. Use `insert_new_chain` to collect an iterator inside the /// same chain. -impl FromIterator for RevisionVec { - fn from_iter>(_iter: I) -> Self { - /*let iterator = iter.into_iter(); +impl FromIterator<(K, T)> for RevisionVec { + fn from_iter>(iter: I) -> Self { + let iterator = iter.into_iter(); let mut vec = Self::with_capacity(iterator.size_hint().0); - for item in iterator { - vec.insert_new_chain(iter::once(item)) + for (key, item) in iterator { + vec.insert_new_chain(key, iter::once(item)) } - vec*/ - todo!() + vec } } @@ -179,6 +157,15 @@ struct Element { next: Option>>, } +impl Element { + pub fn new(item: T) -> Self { + Self { + data: item, + next: None, + } + } +} + #[derive(Default, Debug, PartialEq, Eq)] pub struct RevisionList { key: K, @@ -203,6 +190,10 @@ impl RevisionList { self.head.is_none() } + pub fn get_key(&self) -> &K { + &self.key + } + pub fn push_front(&mut self, val: T) { let new_element = Element { data: val, @@ -220,6 +211,32 @@ impl RevisionList { pub fn iter(&self) -> impl Iterator { RevisionListIter::new(self) } + + /// Creates a `RevisionList` from an iterator by inserting elements in the + /// order of arrival: first item in the iterator will end up at the front. + pub fn from_iter(key: K, mut iter: impl Iterator) -> Self { + if let Some(first_element) = iter.next() { + let mut length = 1; + let mut head = Some(Box::new(Element::new(first_element))); + let mut current_element = head.as_mut().expect("next element was inserted above"); + for next_item in iter { + current_element.next = Some(Box::new(Element::new(next_item))); + current_element = current_element + .next + .as_mut() + .expect("next element was inserted above"); + length += 1; + } + + Self { key, length, head } + } else { + Self { + key, + length: 0, + head: None, + } + } + } } pub struct RevisionListIter<'a, K, T> { diff --git a/src/data_struct/versioned_vec.rs b/src/data_struct/versioned_vec.rs deleted file mode 100644 index 303547d9..00000000 --- a/src/data_struct/versioned_vec.rs +++ /dev/null @@ -1,294 +0,0 @@ -use std::{ - collections::{linked_list, LinkedList}, - iter, -}; - -use super::error::Error; - -/// a `VersionedVec` stores for each entry a linked list of versions. -/// The entry versions are stored in reverse chronological order: -/// -/// Vec [ -/// 0: a" -> a' -> a -/// 1: b -/// 2: c' -> c -/// ] -/// -/// Insertions are only allowed at the front of the linked list. -/// Deletions can only happen at the end of the linked list. -/// -/// This guarantees that the entry versions are always ordered. -// TODO: does index matter for Eq compare? -// TODO: check Serialize/Deserialize -#[derive(Default, Debug, PartialEq, Eq)] -pub struct VersionedVec { - data: Vec>, - length: usize, -} - -impl VersionedVec { - pub fn new() -> Self { - Self { - data: Vec::new(), - length: 0, - } - } - - pub fn with_capacity(capacity: usize) -> Self { - Self { - data: Vec::with_capacity(capacity), - length: 0, - } - } - - pub fn len(&self) -> usize { - self.length - } - - pub fn is_empty(&self) -> bool { - self.len() == 0 - } - - pub fn nb_chains(&self) -> usize { - self.data.len() - } - - pub fn chain_length(&self, chain_index: usize) -> usize { - self.data[chain_index].len() - } - - pub fn push_front(&mut self, chain_index: usize, item: T) -> Result<(), Error> { - let chain = self - .data - .get_mut(chain_index) - .ok_or(Error::missing_entry(&chain_index))?; - - self.length += 1; - chain.push_front(item); - Ok(()) - } - - /// Inserts entry versions in reverse chronological order - /// The iterator must be in chronological order as the items are inserted - /// backward. - pub fn insert_new_chain(&mut self, iterator: impl Iterator) { - let mut new_list = LinkedList::new(); - for item in iterator { - new_list.push_front(item); - } - if !new_list.is_empty() { - self.length += new_list.len(); - self.data.push(new_list); - } - } - - /// Removes old entry versions. - /*pub fn pop_chain(&mut self, chain_index: usize, stop_key: &K) -> Result<(), Error> { - let list = &mut self.data[chain_index]; - - while let Some((key, _)) = list.back() { - if key == stop_key { - return Ok(()); - } - list.pop_back(); - } - Err(Error::KeyError("Stop key was not found".to_string())) - }*/ - - /// Removes old entry version. - pub fn pop_back(&mut self, chain_index: usize) -> Result { - let chain = self - .data - .get_mut(chain_index) - .ok_or(Error::missing_entry(&chain_index))?; - - let removed_item = chain.pop_back().expect("chains should not be empty"); - self.length -= 1; - - if chain.is_empty() { - self.data.swap_remove(chain_index); - } - - Ok(removed_item) - } - - pub fn clear(&mut self) { - self.data.clear(); - self.length = self.data.len(); - } - - /// Provides reference to the oldest entry version. - pub fn back(&self, chain_index: usize) -> Option<&T> { - self.data.get(chain_index)?.back() - } - - /// Provides reference to the current entry version. - pub fn front(&self, chain_index: usize) -> Option<&T> { - self.data.get(chain_index)?.front() - } - - /// Iterates through all versions of an entry starting from the most recent - /// one. - pub fn iter_chain(&self, chain_index: usize) -> impl DoubleEndedIterator { - self.data[chain_index].iter() - } - - /// Iterates through all versions of all entries - pub fn iter(&self) -> impl Iterator { - self.data.iter().flat_map(|chain| chain.iter()) - } - - pub fn bfs(&self) -> BfsIterator { - BfsIterator::new(self) - } -} - -pub struct BfsIterator<'a, T> { - chains: Vec>, - index: usize, -} - -impl<'a, T> BfsIterator<'a, T> { - pub fn new(versioned_vec: &'a VersionedVec) -> Self { - Self { - chains: versioned_vec.data.iter().map(LinkedList::iter).collect(), - index: 0, - } - } -} - -impl<'a, T> Iterator for BfsIterator<'a, T> { - type Item = &'a T; - - fn next(&mut self) -> Option { - loop { - if self.chains.is_empty() { - return None; - } - self.index %= self.chains.len(); - let chain = &mut self.chains[self.index]; - - if let Some(next_entry) = chain.next() { - self.index += 1; - break Some(next_entry); - } else { - let _ = self.chains.remove(self.index); - } - } - } -} - -/// Create VersionedVec from an iterator, each element will be inserted in a -/// different chain. Use `insert_new_chain` to collect an iterator inside the -/// same chain. -impl FromIterator for VersionedVec { - fn from_iter>(iter: I) -> Self { - let iterator = iter.into_iter(); - let mut vec = Self::with_capacity(iterator.size_hint().0); - for item in iterator { - vec.insert_new_chain(iter::once(item)) - } - vec - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_versioned_vec() -> Result<(), Error> { - let mut versioned_vec: VersionedVec<(u32, String)> = VersionedVec::new(); - assert!(versioned_vec.is_empty()); - - // Inserting new chains - let first_chain_index = 0; - versioned_vec.insert_new_chain( - vec![ - (1, "key1".to_string()), - (11, "key11".to_string()), - (111, "key111".to_string()), - ] - .into_iter(), - ); - let second_chain_index = 1; - versioned_vec - .insert_new_chain(vec![(2, "key2".to_string()), (22, "key22".to_string())].into_iter()); - let third_chain_index = 2; - versioned_vec.insert_new_chain(vec![(3, "key3".to_string())].into_iter()); - - assert_eq!(versioned_vec.data.len(), 3); - assert_eq!(versioned_vec.nb_chains(), 3); - assert_eq!(versioned_vec.len(), 6); - assert_eq!(versioned_vec.chain_length(first_chain_index), 3); - assert_eq!(versioned_vec.chain_length(second_chain_index), 2); - assert_eq!(versioned_vec.chain_length(third_chain_index), 1); - - // Get front - assert_eq!( - versioned_vec.front(second_chain_index), - Some(&(22, "key22".to_string())) - ); - - // Push back - let new_entry_version = (222, "key222".to_string()); - versioned_vec.push_front(second_chain_index, new_entry_version.clone())?; - - assert_eq!( - versioned_vec.front(second_chain_index), - Some(&new_entry_version) - ); - - // Remove elements - versioned_vec.pop_back(first_chain_index)?; - assert_eq!(versioned_vec.len(), 6); - - versioned_vec.pop_back(second_chain_index)?; - assert_eq!(versioned_vec.len(), 5); - // Front element should be the same - assert_eq!( - versioned_vec.front(second_chain_index), - Some(&new_entry_version) - ); - - versioned_vec.pop_back(third_chain_index)?; - assert_eq!(versioned_vec.len(), 4); - // the chain 3 was completely removed - assert!(versioned_vec.pop_back(third_chain_index).is_err()); - - // Iterate - assert_eq!(versioned_vec.iter_chain(first_chain_index).count(), 2); - assert_eq!(versioned_vec.iter().count(), versioned_vec.len()); - - versioned_vec.clear(); - assert!(versioned_vec.is_empty()); - - Ok(()) - } - - #[test] - fn test_versioned_vec_iterator() { - let mut versioned_vec: VersionedVec = VersionedVec::new(); - - // Inserting new chains - versioned_vec.insert_new_chain(vec![1, 11, 111].into_iter()); - versioned_vec.insert_new_chain(vec![2, 22].into_iter()); - versioned_vec.insert_new_chain(vec![3].into_iter()); - - // Depth iter - let depth_iter: Vec<_> = versioned_vec.iter().copied().collect(); - assert_eq!(depth_iter, vec![111, 11, 1, 22, 2, 3]); - - // Breadth iter - let bfs: Vec<_> = versioned_vec.bfs().copied().collect(); - assert_eq!(bfs, vec![111, 22, 3, 11, 2, 1]); - - // Iter chain by chain <=> depth iter - assert_eq!( - versioned_vec.iter().collect::>(), - (0..versioned_vec.nb_chains()) - .flat_map(|index| versioned_vec.iter_chain(index)) - .collect::>() - ); - } -} diff --git a/src/test_utils/mod.rs b/src/test_utils/mod.rs index 1ef852bb..4504441f 100644 --- a/src/test_utils/mod.rs +++ b/src/test_utils/mod.rs @@ -175,26 +175,28 @@ mod tests { // 4 partitions accessed by the user were rotated (MKG Protected, Low Secret, // Medium Secret and High Secret) assert_eq!(usk.subkeys.len(), original_usk.subkeys.len() + 4); - for x_i in original_usk.subkeys.iter() { - assert!(usk.subkeys.iter().any(|x| x == x_i)); + for x_i in original_usk.subkeys.flat_iter() { + assert!(usk.subkeys.flat_iter().any(|x| x == x_i)); } // refresh the user key but do NOT preserve access to old partitions cover_crypt.refresh_user_secret_key(&mut usk, &decryption_policy, &msk, &policy, false)?; // the user should still have access to the same number of partitions assert_eq!(usk.subkeys.len(), original_usk.subkeys.len()); - for x_i in original_usk.subkeys.iter() { - assert!(!usk.subkeys.iter().any(|x| x == x_i)); + for x_i in original_usk.subkeys.flat_iter() { + assert!(!usk.subkeys.flat_iter().any(|x| x == x_i)); } // try to modify the user key and refresh let part = Partition::from(vec![1, 6]); - usk.subkeys.insert_new_chain(iter::once(( + usk.subkeys.insert_new_chain( part.clone(), - msk.subkeys.get_current_revision(&part).unwrap().clone(), - ))); - assert!(cover_crypt - .refresh_user_secret_key(&mut usk, &decryption_policy, &msk, &policy, false) - .is_err()); + iter::once(msk.subkeys.get_current_revision(&part).unwrap().clone()), + ); + assert!( + cover_crypt + .refresh_user_secret_key(&mut usk, &decryption_policy, &msk, &policy, false) + .is_err() + ); Ok(()) } @@ -244,9 +246,11 @@ mod tests { EncryptedHeader::generate(&cover_crypt, &policy, &mpk, &secret_sales_ap, None, None)?; // User cannot decrypt new message without refreshing its key - assert!(encrypted_header - .decrypt(&cover_crypt, &low_secret_usk, None) - .is_err()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &low_secret_usk, None) + .is_err() + ); cover_crypt.refresh_user_secret_key( &mut low_secret_usk, @@ -256,9 +260,11 @@ mod tests { false, )?; - assert!(encrypted_header - .decrypt(&cover_crypt, &low_secret_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &low_secret_usk, None) + .is_ok() + ); Ok(()) } @@ -305,9 +311,11 @@ mod tests { // 5 is the size of the security level dimension assert_eq!(new_partitions_msk.len(), partitions_msk.len() - 5); - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_ok() + ); // refresh the user key and preserve access to old partitions let new_decryption_policy = @@ -322,9 +330,11 @@ mod tests { &policy, true, )?; - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_err()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_err() + ); Ok(()) } @@ -369,9 +379,11 @@ mod tests { // msk hasn't changed assert_eq!(new_partitions_msk.len(), partitions_msk.len()); - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_ok() + ); // Can not encrypt using deactivated attribute let top_secret_ap = @@ -392,9 +404,11 @@ mod tests { &policy, true, )?; - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_ok() + ); // refresh the user key and remove access to old partitions cover_crypt.refresh_user_secret_key( @@ -404,9 +418,11 @@ mod tests { &policy, false, )?; - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_ok() + ); // // Rotating the disabled attribute should only change the msk @@ -447,9 +463,11 @@ mod tests { // update the master keys cover_crypt.update_master_keys(&policy, &mut msk, &mut mpk)?; - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_ok() + ); // refresh the user key and preserve access to old partitions let new_decryption_policy = AccessPolicy::from_boolean_expression( @@ -462,9 +480,11 @@ mod tests { &policy, false, )?; - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_ok() + ); Ok(()) } @@ -566,9 +586,11 @@ mod tests { )?; // Decryption fails without refreshing the user key - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_err()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_err() + ); cover_crypt.refresh_user_secret_key( &mut top_secret_fin_usk, @@ -581,9 +603,11 @@ mod tests { )?; // The refreshed key can decrypt the header - assert!(encrypted_header - .decrypt(&cover_crypt, &top_secret_fin_usk, None) - .is_ok()); + assert!( + encrypted_header + .decrypt(&cover_crypt, &top_secret_fin_usk, None) + .is_ok() + ); Ok(()) }