diff --git a/README.md b/README.md index 7826a24c..28fea610 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ policies over these attributes. - [Building and testing](#building-and-testing) - [Features](#features) * [Key generation](#key-generation) - * [Policies and partitions](#policies-and-partitions) + * [Policies and coordinates](#policies-and-coordinates) * [Serialization](#serialization) * [Symmetric key encapsulation](#symmetric-key-encapsulation) * [Secret key decapsulation](#secret-key-decapsulation) @@ -103,7 +103,7 @@ The key generations may be long if the policy contains many rights or if there are many users. But this is usually run once at setup. Key update and refresh stay fast if the changes are small. -### Policies and partitions +### Policies and coordinates CoverCrypt is an attribute-based encryption algorithm. This means that an encrypted header produced for the attributes `France` and `Top Secret` can only @@ -118,20 +118,20 @@ objects are defined: policy is expressed as a boolean expression of attributes. - **user policy**: subset of the policy for which a user key enables decryption; a user policy is expressed as a boolean expression of attributes. -- **partition**: combination of one attribute from each policy axis. +- **coordinate**: combination of one attribute from each policy axis. When generating the master keys, the global policy is converted into the set of -all possible partitions and a keypair is generated for each one of these -partitions. The master public key holds all the public key of all these +all possible coordinates and a keypair is generated for each one of these +coordinates. The master public key holds all the public key of all these keypairs and the master secret key holds the secret key of all these keypairs. When encrypting for a given encryption policy, this policy is converted into a -set of partitions. Then, one key encapsulation is generated per partition using +set of coordinates. Then, one key encapsulation is generated per coordinate using the corresponding public sub-key in the master public key. Similarly, when generating a user secret key for a given user policy, this -policy is converted into the set of corresponding partitions and the user -receives the secret sub-key associated to each partitions. +policy is converted into the set of corresponding coordinates and the user +receives the secret sub-key associated to each coordinates. **Example**: the following policy is composed of two axes. The `Security` axis composed of three attributes and the `Country` axis composed of 4 attributes. @@ -153,9 +153,9 @@ Policy: { ``` The encryption policy `Security::Medium && ( Country::France || -Country::Spain)` would be converted into two partitions. The encryption policy +Country::Spain)` would be converted into two coordinates. The encryption policy `Security::High` would be expanded into `Security::High && (Country::France || -... || Country::Spain)` then converted into 4 partitions. +... || Country::Spain)` then converted into 4 coordinates. ### Serialization @@ -166,17 +166,17 @@ $$3 \cdot L_{sk} + \texttt{LEB128sizeof}(|\mathcal{P}|) + \sum\limits_{p~\in~\ma - public key: $$2 \cdot L_{pk} + \texttt{LEB128sizeof}(|\mathcal{P}|) + \sum\limits_{p~\in~\mathcal{P}} \left( \texttt{LEB128sizeof}(\texttt{sizeof}(p)) + \texttt{sizeof}(p) + 1 + L_{pk} + \delta_{p,~h} \cdot L_{pk}^{pq}\right)$$ - user secret key: -$$2 \cdot L_{sk} + \texttt{LEB128sizeof}(n_{p}) + \sum\limits_{p~\in~partitions} \left( 1 + L_{sk} + \delta_{p,~h} \cdot L_{sk}^{pq}\right)$$ +$$2 \cdot L_{sk} + \texttt{LEB128sizeof}(n_{p}) + \sum\limits_{p~\in~coordinates} \left( 1 + L_{sk} + \delta_{p,~h} \cdot L_{sk}^{pq}\right)$$ - encapsulation: -$$2 \cdot L_{pk} + T + \texttt{LEB128sizeof}(n_{p}) + \sum\limits_{p~\in~partitions} \left(1 + \delta_{p,~c} \cdot L_{pk} + \delta_{p,~h} \cdot L_c^{pq}\right)$$ +$$2 \cdot L_{pk} + T + \texttt{LEB128sizeof}(n_{p}) + \sum\limits_{p~\in~coordinates} \left(1 + \delta_{p,~c} \cdot L_{pk} + \delta_{p,~h} \cdot L_c^{pq}\right)$$ - encrypted header (encapsulation and symmetrically encrypted metadata): $$\texttt{sizeof}(encapsulation) + \texttt{LEB128sizeof} \left(C_{overhead} + \texttt{sizeof}(metadata)\right) + C_{overhead} + \texttt{sizeof}(metadata)$$ where: -- $|\mathcal{P}|$ is the number of partitions related to the encryption policy -- $\delta_{p,~c} = 1$ if $p$ is a classic partition, 0 otherwise -- $\delta_{p,~h} = 1 - \delta_{p,~c}$ (i.e. 1 if $p$ is a hybridized partition, +- $|\mathcal{P}|$ is the number of coordinates related to the encryption policy +- $\delta_{p,~c} = 1$ if $p$ is a classic coordinate, 0 otherwise +- $\delta_{p,~h} = 1 - \delta_{p,~c}$ (i.e. 1 if $p$ is a hybridized coordinate, 0 otherwise) - $\texttt{sizeof}: n \rightarrow$ size of $n$ in bytes - $\texttt{LEB128sizeof}: n \rightarrow \left\lceil \frac{8 \cdot \texttt{sizeof}(n)}{7}\right\rceil$ @@ -204,7 +204,7 @@ to store metadata. Classic implementation sizes: -| Nb. of partitions | Encapsulation size (in bytes) | User decryption key size (in bytes) | +| Nb. of coordinates | Encapsulation size (in bytes) | User decryption key size (in bytes) | |-------------------|-------------------------------|-------------------------------------| | 1 | 130 | 98 | | 2 | 163 | 131 | @@ -214,7 +214,7 @@ Classic implementation sizes: Post-quantum implementation sizes: -| Nb. of partitions | Encapsulation size (in bytes) | User decryption key size (in bytes) | +| Nb. of coordinates | Encapsulation size (in bytes) | User decryption key size (in bytes) | |-------------------|-------------------------------|-------------------------------------| | 1 | 1186 | 1250 | | 2 | 2275 | 2435 | diff --git a/src/abe_policy/partitions.rs b/src/abe_policy/coordinates.rs similarity index 72% rename from src/abe_policy/partitions.rs rename to src/abe_policy/coordinates.rs index dd94d09a..92e39075 100644 --- a/src/abe_policy/partitions.rs +++ b/src/abe_policy/coordinates.rs @@ -4,23 +4,23 @@ use cosmian_crypto_core::bytes_ser_de::Serializer; use crate::Error; -/// Partition associated to a subset. It corresponds to a combination +/// Coordinate associated to a subset. It corresponds to a combination /// of attributes across all dimensions. #[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Hash)] -pub struct Partition(pub(crate) Vec); +pub struct Coordinate(pub(crate) Vec); -impl Partition { - /// Creates a `Partition` from the given list of values. +impl Coordinate { + /// Creates a `Coordinate` from the given list of values. pub fn from_attribute_ids(mut attribute_ids: Vec) -> Result { // guard against overflow of the 1024 bytes buffer below if attribute_ids.len() > 200 { return Err(Error::InvalidAttribute( "The current implementation does not currently support more than 200 attributes \ - for a partition" + for a coordinate" .to_string(), )); } - // the sort operation allows to get the same `Partition` for : + // the sort operation allows to get the same `Coordinate` for : // `Department::HR && Level::Secret` // and // `Level::Secret && Department::HR` @@ -34,7 +34,7 @@ impl Partition { } } -impl Deref for Partition { +impl Deref for Coordinate { type Target = [u8]; fn deref(&self) -> &Self::Target { @@ -42,13 +42,13 @@ impl Deref for Partition { } } -impl From> for Partition { +impl From> for Coordinate { fn from(value: Vec) -> Self { Self(value) } } -impl From<&[u8]> for Partition { +impl From<&[u8]> for Coordinate { fn from(value: &[u8]) -> Self { Self(value.to_vec()) } @@ -61,12 +61,12 @@ mod tests { use super::*; #[test] - fn test_partitions() -> Result<(), Error> { + fn test_coordinates() -> Result<(), Error> { let mut values: Vec = vec![12, 0, u32::MAX, 1]; - let partition = Partition::from_attribute_ids(values.clone())?; - // values are sorted n Partition + let coordinate = Coordinate::from_attribute_ids(values.clone())?; + // values are sorted n Coordinate values.sort_unstable(); - let mut de = Deserializer::new(&partition); + let mut de = Deserializer::new(&coordinate); for v in values { let val = de.read_leb128_u64().unwrap() as u32; assert_eq!(v, val); diff --git a/src/abe_policy/mod.rs b/src/abe_policy/mod.rs index 275ab4f5..4aefaffb 100644 --- a/src/abe_policy/mod.rs +++ b/src/abe_policy/mod.rs @@ -9,15 +9,15 @@ mod access_policy; mod attribute; +mod coordinates; mod dimension; -mod partitions; mod policy; mod policy_versions; pub use access_policy::AccessPolicy; pub use attribute::{Attribute, AttributeStatus, Attributes, EncryptionHint}; +pub use coordinates::Coordinate; pub use dimension::{AttributeParameters, Dimension, DimensionBuilder}; -pub use partitions::Partition; pub use policy_versions::{LegacyPolicy, PolicyV1, PolicyV2 as Policy}; use serde::{Deserialize, Serialize}; diff --git a/src/abe_policy/policy.rs b/src/abe_policy/policy.rs index 99253203..389fe511 100644 --- a/src/abe_policy/policy.rs +++ b/src/abe_policy/policy.rs @@ -7,8 +7,8 @@ use std::{ use serde_json::Value; use super::{ - AccessPolicy, Attribute, AttributeParameters, AttributeStatus, Dimension, DimensionBuilder, - EncryptionHint, LegacyPolicy, Partition, Policy, PolicyV1, PolicyVersion, + AccessPolicy, Attribute, AttributeParameters, AttributeStatus, Coordinate, Dimension, + DimensionBuilder, EncryptionHint, LegacyPolicy, Policy, PolicyV1, PolicyVersion, }; use crate::Error; @@ -177,12 +177,12 @@ impl Policy { /// activation status. pub fn generate_universal_coordinates( &self, - ) -> Result, Error> { + ) -> Result, Error> { let universe = self.dimensions.iter().collect::>(); combine(universe.as_slice()) .into_iter() .map(|(combination, is_hybridized, is_readonly)| { - Partition::from_attribute_ids(combination) + Coordinate::from_attribute_ids(combination) .map(|coordinate| (coordinate, (is_hybridized, is_readonly))) }) .collect() @@ -200,7 +200,7 @@ impl Policy { pub fn generate_semantic_space_coordinates( &self, ap: AccessPolicy, - ) -> Result, Error> { + ) -> Result, Error> { let dnf = ap.to_dnf(); let mut coordinates = HashSet::new(); for conjunction in dnf { @@ -216,7 +216,7 @@ impl Policy { .collect::, Error>>()?; // TODO: Some coordinates may be computed twice (the lower dimensions). for (ids, _, _) in combine(&semantic_space.iter().collect::>()) { - coordinates.insert(Partition::from_attribute_ids(ids)?); + coordinates.insert(Coordinate::from_attribute_ids(ids)?); } } Ok(coordinates) @@ -232,11 +232,11 @@ impl Policy { pub fn generate_point_coordinates( &self, ap: AccessPolicy, - ) -> Result, Error> { + ) -> Result, Error> { let dnf = ap.to_dnf(); let mut coordinates = HashSet::with_capacity(dnf.len()); for conjunction in dnf { - let coo = Partition::from_attribute_ids( + let coo = Coordinate::from_attribute_ids( conjunction .into_iter() .map(|attr| self.get_attribute(&attr).map(|params| params.id)) @@ -367,33 +367,33 @@ mod tests { { let mut coordinates = HashSet::new(); - coordinates.insert(Partition::from_attribute_ids(vec![])?); + coordinates.insert(Coordinate::from_attribute_ids(vec![])?); - coordinates.insert(Partition::from_attribute_ids(vec![policy + coordinates.insert(Coordinate::from_attribute_ids(vec![policy .get_attribute_id(&Attribute { dimension: "Department".to_string(), name: "HR".to_string(), })?])?); - coordinates.insert(Partition::from_attribute_ids(vec![policy + coordinates.insert(Coordinate::from_attribute_ids(vec![policy .get_attribute_id(&Attribute { dimension: "Department".to_string(), name: "FIN".to_string(), })?])?); - coordinates.insert(Partition::from_attribute_ids(vec![policy + coordinates.insert(Coordinate::from_attribute_ids(vec![policy .get_attribute_id(&Attribute { dimension: "Security Level".to_string(), name: "Protected".to_string(), })?])?); - coordinates.insert(Partition::from_attribute_ids(vec![policy + coordinates.insert(Coordinate::from_attribute_ids(vec![policy .get_attribute_id(&Attribute { dimension: "Security Level".to_string(), name: "Low Secret".to_string(), })?])?); - coordinates.insert(Partition::from_attribute_ids(vec![ + coordinates.insert(Coordinate::from_attribute_ids(vec![ policy.get_attribute_id(&Attribute { dimension: "Department".to_string(), name: "HR".to_string(), @@ -404,7 +404,7 @@ mod tests { })?, ])?); - coordinates.insert(Partition::from_attribute_ids(vec![ + coordinates.insert(Coordinate::from_attribute_ids(vec![ policy.get_attribute_id(&Attribute { dimension: "Department".to_string(), name: "HR".to_string(), @@ -415,7 +415,7 @@ mod tests { })?, ])?); - coordinates.insert(Partition::from_attribute_ids(vec![ + coordinates.insert(Coordinate::from_attribute_ids(vec![ policy.get_attribute_id(&Attribute { dimension: "Department".to_string(), name: "FIN".to_string(), @@ -426,7 +426,7 @@ mod tests { })?, ])?); - coordinates.insert(Partition::from_attribute_ids(vec![ + coordinates.insert(Coordinate::from_attribute_ids(vec![ policy.get_attribute_id(&Attribute { dimension: "Department".to_string(), name: "FIN".to_string(), diff --git a/src/abe_policy/policy_versions.rs b/src/abe_policy/policy_versions.rs index 5084aecd..67a062a7 100644 --- a/src/abe_policy/policy_versions.rs +++ b/src/abe_policy/policy_versions.rs @@ -16,7 +16,7 @@ pub struct PolicyV2 { pub(crate) version: PolicyVersion, /// Last value taken by the attribute. /// TODO: after some mutations, this counter will become very high, which implies the size of - /// the partitions will become huge (d * log_2(id) * 8/7). + /// the coordinate will become huge (d * log_2(id) * 8/7). pub(crate) last_attribute_value: u32, /// Policy axes: maps axes name to the list of associated attribute names diff --git a/src/core/api.rs b/src/core/api.rs index d5b211ff..6e38e1ba 100644 --- a/src/core/api.rs +++ b/src/core/api.rs @@ -53,9 +53,9 @@ impl Covercrypt { /// Updates the master keys according to this new policy. /// - /// When a partition exists in the new policy but not in the master keys, - /// a new key pair is added to the master keys for that partition. - /// When a partition exists on the master keys, but not in the new policy, + /// When a coordinate exists in the new policy but not in the master keys, + /// a new key pair is added to the master keys for that coordinate. + /// When a coordinate exists on the master keys, but not in the new policy, /// it is removed from the master keys. /// /// - `policy` : Policy to use to generate the keys @@ -143,8 +143,8 @@ impl Covercrypt { /// Refreshes the user key according to the given master key and user /// policy. /// - /// The user key will be granted access to the current partitions, as - /// determined by its access policy. If `preserve_old_partitions_access` + /// The user key will be granted access to the current coordinates, as + /// determined by its access policy. If `preserve_old_coordinates_access` /// is set, the old user access will be preserved. /// /// - `usk` : the user key to refresh diff --git a/src/core/mod.rs b/src/core/mod.rs index 8648b952..aa11c7d1 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -11,7 +11,7 @@ use pqc_kyber::{KYBER_INDCPA_BYTES, KYBER_INDCPA_PUBLICKEYBYTES, KYBER_INDCPA_SE use zeroize::ZeroizeOnDrop; use crate::{ - abe_policy::Partition, + abe_policy::Coordinate, data_struct::{RevisionMap, RevisionVec}, }; @@ -67,7 +67,7 @@ pub(super) type PublicSubkey = (Option, R25519PublicKey); pub struct MasterPublicKey { g1: R25519PublicKey, g2: R25519PublicKey, - pub(crate) subkeys: HashMap, + pub(crate) subkeys: HashMap, } pub(super) type SecretSubkey = (Option, R25519PrivateKey); @@ -77,7 +77,7 @@ pub struct MasterSecretKey { s: R25519PrivateKey, s1: R25519PrivateKey, s2: R25519PrivateKey, - pub(crate) subkeys: RevisionMap, + pub(crate) subkeys: RevisionMap, kmac_key: Option>, } @@ -85,7 +85,7 @@ pub struct MasterSecretKey { pub struct UserSecretKey { a: R25519PrivateKey, b: R25519PrivateKey, - pub(crate) subkeys: RevisionVec, + pub(crate) subkeys: RevisionVec, kmac: Option, } diff --git a/src/core/primitives.rs b/src/core/primitives.rs index e8b45ba5..9bb3eb51 100644 --- a/src/core/primitives.rs +++ b/src/core/primitives.rs @@ -25,7 +25,7 @@ use crate::{ abe_policy::{ AttributeStatus, AttributeStatus::{DecryptOnly, EncryptDecrypt}, - EncryptionHint, Partition, + Coordinate, EncryptionHint, }, core::{Encapsulation, KeyEncapsulation, MasterPublicKey, MasterSecretKey, UserSecretKey}, data_struct::{RevisionMap, RevisionVec}, @@ -49,8 +49,8 @@ fn compute_user_key_kmac(msk: &MasterSecretKey, usk: &UserSecretKey) -> Option, + coordinates: HashMap, ) -> (MasterSecretKey, MasterPublicKey) { let s = R25519PrivateKey::new(rng); let s1 = R25519PrivateKey::new(rng); @@ -172,14 +172,14 @@ pub fn setup( let g1 = R25519PublicKey::from(&s1); let g2 = R25519PublicKey::from(&s2); - let mut sub_sk = RevisionMap::with_capacity(partitions.len()); - let mut sub_pk = HashMap::with_capacity(partitions.len()); + let mut sub_sk = RevisionMap::with_capacity(coordinates.len()); + let mut sub_pk = HashMap::with_capacity(coordinates.len()); - for (partition, (is_hybridized, write_status)) in partitions { + for (coordinate, (is_hybridized, write_status)) in coordinates { let (public_subkey, secret_subkey) = create_subkey_pair(rng, &h, is_hybridized); - sub_sk.insert(partition.clone(), secret_subkey); + sub_sk.insert(coordinate.clone(), secret_subkey); if write_status == EncryptDecrypt { - sub_pk.insert(partition, public_subkey); + sub_pk.insert(coordinate, public_subkey); } } @@ -214,17 +214,17 @@ pub fn setup( pub fn keygen( rng: &mut impl CryptoRngCore, msk: &MasterSecretKey, - decryption_set: &HashSet, + decryption_set: &HashSet, ) -> Result { let a = R25519PrivateKey::new(rng); let b = &(&msk.s - &(&a * &msk.s1)) / &msk.s2; - // Use the last key for each partitions in the decryption set + // Use the last key for each coordinates in the decryption set let mut subkeys = RevisionVec::with_capacity(decryption_set.len()); - decryption_set.iter().try_for_each(|partition| { - let subkey = msk.subkeys.get_latest(partition).ok_or(Error::KeyError( + decryption_set.iter().try_for_each(|coordinate| { + let subkey = msk.subkeys.get_latest(coordinate).ok_or(Error::KeyError( "Master secret key and Policy are not in sync.".to_string(), ))?; - subkeys.create_chain_with_single_value(partition.clone(), subkey.clone()); + subkeys.create_chain_with_single_value(coordinate.clone(), subkey.clone()); Ok::<_, Error>(()) })?; @@ -249,7 +249,7 @@ pub fn keygen( pub fn encaps( rng: &mut impl CryptoRngCore, mpk: &MasterPublicKey, - encryption_set: &HashSet, + encryption_set: &HashSet, ) -> Result<(SymmetricKey, Encapsulation), Error> { let mut seed = Zeroizing::new([0; SYM_KEY_LENGTH]); rng.fill_bytes(&mut *seed); @@ -258,8 +258,8 @@ pub fn encaps( let c1 = &mpk.g1 * &r; let c2 = &mpk.g2 * &r; let mut encs = HashSet::with_capacity(encryption_set.len()); - for partition in encryption_set { - if let Some((pk_i, h_i)) = mpk.subkeys.get(partition) { + for coordinate in encryption_set { + if let Some((pk_i, h_i)) = mpk.subkeys.get(coordinate) { let mut e_i = [0; SYM_KEY_LENGTH]; kdf256!(&mut e_i, &(h_i * &r).to_bytes()); xor_in_place(&mut e_i, &seed); @@ -273,7 +273,7 @@ pub fn encaps( encs.insert(KeyEncapsulation::ClassicEncapsulation(Box::new(e_i))); } } - // else unknown target partition + // else unknown target coordinate else { return Err(Error::KeyError( "Missing public key for this attribute, it appears that you are trying to encrypt \ @@ -306,7 +306,7 @@ pub fn decaps( let precomp = &(&encapsulation.c1 * &usk.a) + &(&encapsulation.c2 * &usk.b); for encapsulation_i in &encapsulation.encs { // BFS search user subkeys to first try the most recent rotations of each - // partitions. + // coordinates. for (sk_j, x_j) in usk.subkeys.bfs() { let e_j = match encapsulation_i { KeyEncapsulation::HybridEncapsulation(epq_i) => { @@ -334,19 +334,19 @@ pub fn decaps( Err(Error::InsufficientAccessPolicy) } -/// Update the given master keys for the given list of partitions. +/// Update the given master keys for the given list of coordinates. /// -/// If a partition exists in the keys but not in the list, it will be removed +/// If a coordinate exists in the keys but not in the list, it will be removed /// from the keys. /// -/// If a partition exists in the list, but not in the keys, it will be "added" -/// to the keys, by adding a new partition key pair as performed in the setup +/// If a coordinate exists in the list, but not in the keys, it will be "added" +/// to the keys, by adding a new coordinate key pair as performed in the setup /// procedure above. /// -/// If a partition exists in the list and in the keys, hybridization property +/// If a coordinate exists in the list and in the keys, hybridization property /// will be set as given. /// -/// If a partition exists in the list and in the master secret key a new public +/// If a coordinate exists in the list and in the master secret key a new public /// sub-key is derived. /// /// # Error @@ -360,40 +360,41 @@ pub fn decaps( /// - `rng` : random number generator /// - `msk` : master secret key /// - `mpk` : master public key -/// - `partition_set` : new set of partitions to use after the update +/// - `coordinate_set` : new set of coordinates to use after the update pub fn update( rng: &mut impl CryptoRngCore, msk: &mut MasterSecretKey, mpk: &mut MasterPublicKey, - partitions_set: HashMap, + coordinates_set: HashMap, ) -> Result<(), Error> { - // Remove keys from partitions deleted from Policy - msk.subkeys.retain(|part| partitions_set.contains_key(part)); + // Remove keys from coordinates deleted from Policy + msk.subkeys + .retain(|part| coordinates_set.contains_key(part)); mpk.subkeys - .retain(|part, _| partitions_set.contains_key(part)); + .retain(|part, _| coordinates_set.contains_key(part)); let h = R25519PublicKey::from(&msk.s); - for (partition, (is_hybridized, write_status)) in partitions_set { - // check if secret key exist for this partition - if let Some(secret_subkey) = msk.subkeys.get_latest_mut(&partition) { + for (coordinate, (is_hybridized, write_status)) in coordinates_set { + // check if secret key exist for this coordinate + if let Some(secret_subkey) = msk.subkeys.get_latest_mut(&coordinate) { // update the master secret and public subkey if needed - match (write_status, mpk.subkeys.get_mut(&partition)) { + match (write_status, mpk.subkeys.get_mut(&coordinate)) { (EncryptDecrypt, None) => unreachable!(), (EncryptDecrypt, Some(public_subkey)) => { update_subkey_pair(rng, &h, public_subkey, secret_subkey, is_hybridized)?; } (DecryptOnly, None) => update_master_subkey(rng, &h, secret_subkey, is_hybridized), (DecryptOnly, Some(_)) => { - mpk.subkeys.remove(&partition); + mpk.subkeys.remove(&coordinate); update_master_subkey(rng, &h, secret_subkey, is_hybridized); } } } else { // generate new keys let (public_subkey, secret_subkey) = create_subkey_pair(rng, &h, is_hybridized); - msk.subkeys.insert(partition.clone(), secret_subkey); + msk.subkeys.insert(coordinate.clone(), secret_subkey); if write_status == EncryptDecrypt { - mpk.subkeys.insert(partition, public_subkey); + mpk.subkeys.insert(coordinate, public_subkey); } } } @@ -413,7 +414,7 @@ pub fn rekey( rng: &mut impl CryptoRngCore, msk: &mut MasterSecretKey, mpk: &mut MasterPublicKey, - coordinates: HashSet, + coordinates: HashSet, ) -> Result<(), Error> { let h = R25519PublicKey::from(&msk.s); for coordinate in coordinates { @@ -426,7 +427,7 @@ pub fn rekey( let (public_subkey, secret_subkey) = create_subkey_pair(rng, &h, is_hybridized); msk.subkeys.insert(coordinate.clone(), secret_subkey); - // update public subkey if partition is not read only + // update public subkey if coordinate is not read only if mpk.subkeys.contains_key(&coordinate) { mpk.subkeys.insert(coordinate, public_subkey); } @@ -440,7 +441,7 @@ pub fn rekey( /// /// - `msk` : master secret key /// - `coordinates` : set of subkeys coordinate to prune -pub fn prune(msk: &mut MasterSecretKey, coordinates: &HashSet) -> Result<(), Error> { +pub fn prune(msk: &mut MasterSecretKey, coordinates: &HashSet) -> Result<(), Error> { for coordinate in coordinates { msk.subkeys.keep(coordinate, 1); } @@ -451,7 +452,7 @@ pub fn prune(msk: &mut MasterSecretKey, coordinates: &HashSet) -> Res /// /// If `keep_old_rights` is set to false, old sub-keys are removed. /// -/// If a partition exists in the list and in the master secret key, the +/// If a coordinate exists in the list and in the master secret key, the /// associated sub-key is added to the user key. /// /// # Parameters @@ -527,38 +528,38 @@ mod tests { #[test] fn test_cover_crypt() -> Result<(), Error> { - let admin_partition = Partition(b"admin".to_vec()); - let dev_partition = Partition(b"dev".to_vec()); - // partition list - let partitions_set = HashMap::from([ + let admin_coordinate = Coordinate(b"admin".to_vec()); + let dev_coordinate = Coordinate(b"dev".to_vec()); + // coordinate list + let coordinates_set = HashMap::from([ ( - admin_partition.clone(), + admin_coordinate.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - dev_partition.clone(), + dev_coordinate.clone(), (EncryptionHint::Classic, AttributeStatus::EncryptDecrypt), ), ]); // user list let users_set = vec![ - HashSet::from([dev_partition.clone()]), - HashSet::from([admin_partition.clone(), dev_partition.clone()]), + HashSet::from([dev_coordinate.clone()]), + HashSet::from([admin_coordinate.clone(), dev_coordinate.clone()]), ]; // target set - let admin_target_set = HashSet::from([admin_partition.clone()]); + let admin_target_set = HashSet::from([admin_coordinate.clone()]); // secure random number generator let mut rng = CsRng::from_entropy(); // setup scheme - let (mut msk, mut mpk) = setup(&mut rng, partitions_set); + let (mut msk, mut mpk) = setup(&mut rng, coordinates_set); - // The admin partition matches a hybridized sub-key. - let admin_secret_subkeys = msk.subkeys.get_latest(&admin_partition); + // The admin coordinate matches a hybridized sub-key. + let admin_secret_subkeys = msk.subkeys.get_latest(&admin_coordinate); assert!(admin_secret_subkeys.is_some()); assert!(admin_secret_subkeys.unwrap().0.is_some()); - // The developer partition matches a classic sub-key. - let dev_secret_subkeys = msk.subkeys.get_latest(&dev_partition); + // The developer coordinate matches a classic sub-key. + let dev_secret_subkeys = msk.subkeys.get_latest(&dev_coordinate); assert!(dev_secret_subkeys.is_some()); assert!(dev_secret_subkeys.unwrap().0.is_none()); @@ -585,30 +586,30 @@ mod tests { let res1 = decaps(&admin_usk, &encapsulation)?; assert_eq!(sym_key, res1, "Wrong decapsulation for user 1!"); - // Change partitions - let client_partition = Partition(b"client".to_vec()); - let new_partitions_set = HashMap::from([ + // Change coordinates + let client_coordinate = Coordinate(b"client".to_vec()); + let new_coordinates_set = HashMap::from([ ( - dev_partition.clone(), + dev_coordinate.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - client_partition.clone(), + client_coordinate.clone(), (EncryptionHint::Classic, AttributeStatus::EncryptDecrypt), ), ]); - let client_target_set = HashSet::from([client_partition.clone()]); + let client_target_set = HashSet::from([client_coordinate.clone()]); - update(&mut rng, &mut msk, &mut mpk, new_partitions_set)?; + update(&mut rng, &mut msk, &mut mpk, new_coordinates_set)?; refresh(&msk, &mut dev_usk, true)?; - // The dev partition matches a hybridized sub-key. - let dev_secret_subkeys = msk.subkeys.get_latest(&dev_partition); + // The dev coordinate matches a hybridized sub-key. + let dev_secret_subkeys = msk.subkeys.get_latest(&dev_coordinate); assert!(dev_secret_subkeys.is_some()); assert!(dev_secret_subkeys.unwrap().0.is_some()); - // The client partition matches a classic sub-key. - let client_secret_subkeys = msk.subkeys.get_latest(&client_partition); + // The client coordinate matches a classic sub-key. + let client_secret_subkeys = msk.subkeys.get_latest(&client_coordinate); assert!(client_secret_subkeys.is_some()); assert!(client_secret_subkeys.unwrap().0.is_none()); @@ -645,7 +646,7 @@ mod tests { ); // Client is able to decapsulate. - let client_usk = keygen(&mut rng, &msk, &HashSet::from([client_partition]))?; + let client_usk = keygen(&mut rng, &msk, &HashSet::from([client_coordinate]))?; let res0 = decaps(&client_usk, &new_encapsulation); match res0 { Err(err) => panic!("Client should be able to decapsulate: {err:?}"), @@ -657,129 +658,131 @@ mod tests { #[test] fn test_master_keys_update() -> Result<(), Error> { - let partition_1 = Partition(b"1".to_vec()); - let partition_2 = Partition(b"2".to_vec()); - // partition list - let partitions_set = HashMap::from([ + let coordinate_1 = Coordinate(b"1".to_vec()); + let coordinate_2 = Coordinate(b"2".to_vec()); + // coordinate list + let coordinates_set = HashMap::from([ ( - partition_1.clone(), + coordinate_1.clone(), (EncryptionHint::Classic, AttributeStatus::EncryptDecrypt), ), ( - partition_2.clone(), + coordinate_2.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ]); // secure random number generator let mut rng = CsRng::from_entropy(); // setup scheme - let (mut msk, mut mpk) = setup(&mut rng, partitions_set); + let (mut msk, mut mpk) = setup(&mut rng, coordinates_set); - // now remove partition 1 and add partition 3 - let partition_3 = Partition(b"3".to_vec()); - let new_partitions_set = HashMap::from([ + // now remove coordinate 1 and add coordinate 3 + let coordinate_3 = Coordinate(b"3".to_vec()); + let new_coordinates_set = HashMap::from([ ( - partition_2.clone(), + coordinate_2.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - partition_3.clone(), + coordinate_3.clone(), (EncryptionHint::Classic, AttributeStatus::EncryptDecrypt), ), ]); - update(&mut rng, &mut msk, &mut mpk, new_partitions_set)?; - assert!(!msk.subkeys.contains_key(&partition_1)); - assert!(msk.subkeys.contains_key(&partition_2)); - assert!(msk.subkeys.contains_key(&partition_3)); - assert!(!mpk.subkeys.contains_key(&partition_1)); - assert!(mpk.subkeys.contains_key(&partition_2)); - assert!(mpk.subkeys.contains_key(&partition_3)); + update(&mut rng, &mut msk, &mut mpk, new_coordinates_set)?; + assert!(!msk.subkeys.contains_key(&coordinate_1)); + assert!(msk.subkeys.contains_key(&coordinate_2)); + assert!(msk.subkeys.contains_key(&coordinate_3)); + assert!(!mpk.subkeys.contains_key(&coordinate_1)); + assert!(mpk.subkeys.contains_key(&coordinate_2)); + assert!(mpk.subkeys.contains_key(&coordinate_3)); Ok(()) } #[test] fn test_user_key_refresh() -> Result<(), Error> { - let partition_1 = Partition(b"1".to_vec()); - let partition_2 = Partition(b"2".to_vec()); - let partition_3 = Partition(b"3".to_vec()); - // partition list - let partitions_set = HashMap::from([ + let coordinate_1 = Coordinate(b"1".to_vec()); + let coordinate_2 = Coordinate(b"2".to_vec()); + let coordinate_3 = Coordinate(b"3".to_vec()); + // coordinate list + let coordinates_set = HashMap::from([ ( - partition_1.clone(), + coordinate_1.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - partition_2.clone(), + coordinate_2.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - partition_3.clone(), + coordinate_3.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ]); // secure random number generator let mut rng = CsRng::from_entropy(); // setup scheme - let (mut msk, mut mpk) = setup(&mut rng, partitions_set); - // create a user key with access to partition 1 and 2 + let (mut msk, mut mpk) = setup(&mut rng, coordinates_set); + // create a user key with access to coordinate 1 and 2 let mut usk = keygen( &mut rng, &msk, - &HashSet::from([partition_1.clone(), partition_2.clone()]), + &HashSet::from([coordinate_1.clone(), coordinate_2.clone()]), )?; - // now remove partition 1 and remove hybrid key from partition 3 - let new_partition_set = HashMap::from([ + // now remove coordinate 1 and remove hybrid key from coordinate 3 + let new_coordinate_set = HashMap::from([ ( - partition_2.clone(), + coordinate_2.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - partition_3.clone(), + coordinate_3.clone(), (EncryptionHint::Classic, AttributeStatus::EncryptDecrypt), ), ]); //Covercrypt the master keys let old_msk = MasterSecretKey::deserialize(msk.serialize()?.as_slice())?; - update(&mut rng, &mut msk, &mut mpk, new_partition_set)?; + update(&mut rng, &mut msk, &mut mpk, new_coordinate_set)?; // refresh the user key refresh(&msk, &mut usk, true)?; - // user key kept old access to partition 1 + // user key kept old access to coordinate 1 assert!(!usk.subkeys.flat_iter().any(|x| { x == ( - &partition_1, - old_msk.subkeys.get_latest(&partition_1).unwrap(), + &coordinate_1, + old_msk.subkeys.get_latest(&coordinate_1).unwrap(), ) })); - assert!(usk - .subkeys - .flat_iter() - .any(|x| { x == (&partition_2, msk.subkeys.get_latest(&partition_2).unwrap(),) })); - // user key kept the old hybrid key for partition 3 + assert!(usk.subkeys.flat_iter().any(|x| { + x == ( + &coordinate_2, + msk.subkeys.get_latest(&coordinate_2).unwrap(), + ) + })); + // user key kept the old hybrid key for coordinate 3 assert!(!usk.subkeys.flat_iter().any(|x| { x == ( - &partition_3, - old_msk.subkeys.get_latest(&partition_3).unwrap(), + &coordinate_3, + old_msk.subkeys.get_latest(&coordinate_3).unwrap(), ) })); - // add new key for partition 2 + // add new key for coordinate 2 rekey( &mut rng, &mut msk, &mut mpk, - HashSet::from([partition_2.clone()]), + HashSet::from([coordinate_2.clone()]), )?; // refresh the user key refresh(&msk, &mut usk, true)?; let usk_subkeys: Vec<_> = usk .subkeys .flat_iter() - .filter(|(part, _)| *part == &partition_2) + .filter(|(part, _)| *part == &coordinate_2) .map(|(_, subkey)| subkey) .collect(); - let msk_subkeys: Vec<_> = msk.subkeys.get(&partition_2).unwrap().iter().collect(); + let msk_subkeys: Vec<_> = msk.subkeys.get(&coordinate_2).unwrap().iter().collect(); assert_eq!(usk_subkeys.len(), 2); assert_eq!(usk_subkeys, msk_subkeys); @@ -788,25 +791,25 @@ mod tests { #[test] fn test_user_key_kmac() -> Result<(), Error> { - let partition_1 = Partition(b"1".to_vec()); - let partition_2 = Partition(b"2".to_vec()); - // partition list - let partitions_set = HashMap::from([ + let coordinate_1 = Coordinate(b"1".to_vec()); + let coordinate_2 = Coordinate(b"2".to_vec()); + // coordinate list + let coordinates_set = HashMap::from([ ( - partition_1.clone(), + coordinate_1.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - partition_2.clone(), + coordinate_2.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ]); // secure random number generator let mut rng = CsRng::from_entropy(); // setup scheme - let (msk, _) = setup(&mut rng, partitions_set); - // create a user key with access to partition 1 and 2 - let mut usk = keygen(&mut rng, &msk, &HashSet::from([partition_1, partition_2]))?; + let (msk, _) = setup(&mut rng, coordinates_set); + // create a user key with access to coordinate 1 and 2 + let mut usk = keygen(&mut rng, &msk, &HashSet::from([coordinate_1, coordinate_2]))?; assert!(verify_user_key_kmac(&msk, &usk).is_ok()); let bytes = usk.serialize()?; @@ -814,7 +817,7 @@ mod tests { assert!(verify_user_key_kmac(&msk, &usk_).is_ok()); usk.subkeys.create_chain_with_single_value( - Partition(b"3".to_vec()), + Coordinate(b"3".to_vec()), (None, R25519PrivateKey::new(&mut rng)), ); // KMAC verify will fail after modifying the user key diff --git a/src/core/serialization.rs b/src/core/serialization.rs index 0839fd06..4ee31baa 100644 --- a/src/core/serialization.rs +++ b/src/core/serialization.rs @@ -10,7 +10,7 @@ use pqc_kyber::{KYBER_INDCPA_PUBLICKEYBYTES, KYBER_INDCPA_SECRETKEYBYTES}; use super::{KyberPublicKey, KyberSecretKey, KMAC_KEY_LENGTH, KMAC_LENGTH, TAG_LENGTH}; use crate::{ - abe_policy::Partition, + abe_policy::Coordinate, core::{ Encapsulation, KeyEncapsulation, MasterPublicKey, MasterSecretKey, UserSecretKey, SYM_KEY_LENGTH, @@ -64,8 +64,8 @@ impl Serializable for MasterPublicKey { // subkeys serialization + to_leb128_len(self.subkeys.len()) + self.subkeys.len() * R25519PublicKey::LENGTH; - for (partition, (pk_i, _)) in &self.subkeys { - length += to_leb128_len(partition.len()) + partition.len(); + for (coordinate, (pk_i, _)) in &self.subkeys { + length += to_leb128_len(coordinate.len()) + coordinate.len(); length += serialize_len_option!(pk_i, _value, KYBER_INDCPA_PUBLICKEYBYTES); } length @@ -75,8 +75,8 @@ impl Serializable for MasterPublicKey { let mut n = ser.write_array(&self.g1.to_bytes())?; n += ser.write_array(&self.g2.to_bytes())?; n += ser.write_leb128_u64(self.subkeys.len() as u64)?; - for (partition, (pk_i, h_i)) in &self.subkeys { - n += ser.write_vec(partition)?; + for (coordinate, (pk_i, h_i)) in &self.subkeys { + n += ser.write_vec(coordinate)?; serialize_option!(ser, n, pk_i, value, ser.write_array(value)); n += ser.write_array(&h_i.to_bytes())?; } @@ -86,14 +86,14 @@ impl Serializable for MasterPublicKey { fn read(de: &mut Deserializer) -> Result { let g1 = R25519PublicKey::try_from_bytes(de.read_array::<{ R25519PublicKey::LENGTH }>()?)?; let g2 = R25519PublicKey::try_from_bytes(de.read_array::<{ R25519PublicKey::LENGTH }>()?)?; - let n_partitions = ::try_from(de.read_leb128_u64()?)?; - let mut subkeys = HashMap::with_capacity(n_partitions); - for _ in 0..n_partitions { - let partition = Partition::from(de.read_vec()?); + let n_coordinates = ::try_from(de.read_leb128_u64()?)?; + let mut subkeys = HashMap::with_capacity(n_coordinates); + for _ in 0..n_coordinates { + let coordinate = Coordinate::from(de.read_vec()?); let pk_i = deserialize_option!(de, KyberPublicKey(de.read_array()?)); let h_i = R25519PublicKey::try_from_bytes(de.read_array::<{ R25519PublicKey::LENGTH }>()?)?; - subkeys.insert(partition, (pk_i, h_i)); + subkeys.insert(coordinate, (pk_i, h_i)); } Ok(Self { g1, g2, subkeys }) } @@ -108,8 +108,8 @@ impl Serializable for MasterSecretKey { // subkeys serialization + to_leb128_len(self.subkeys.len()) + self.subkeys.count_elements() * R25519PrivateKey::LENGTH; - for (partition, chain) in &self.subkeys.map { - length += to_leb128_len(partition.len()) + partition.len(); + for (coordinate, chain) in &self.subkeys.map { + length += to_leb128_len(coordinate.len()) + coordinate.len(); length += to_leb128_len(chain.len()); for (sk_i, _) in chain { let x = serialize_len_option!(sk_i, _value, KYBER_INDCPA_SECRETKEYBYTES); @@ -124,8 +124,8 @@ 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, chain) in &self.subkeys.map { - n += ser.write_vec(partition)?; + for (coordinate, chain) in &self.subkeys.map { + n += ser.write_vec(coordinate)?; n += ser.write_leb128_u64(chain.len() as u64)?; for (sk_i, x_i) in chain { serialize_option!(ser, n, sk_i, value, ser.write_array(value)); @@ -146,10 +146,10 @@ impl Serializable for MasterSecretKey { R25519PrivateKey::try_from_bytes(de.read_array::<{ R25519PrivateKey::LENGTH }>()?)?; let s = R25519PrivateKey::try_from_bytes(de.read_array::<{ R25519PrivateKey::LENGTH }>()?)?; - let n_partitions = ::try_from(de.read_leb128_u64()?)?; - let mut subkeys = RevisionMap::with_capacity(n_partitions); - for _ in 0..n_partitions { - let partition = Partition::from(de.read_vec()?); + let n_coordinates = ::try_from(de.read_leb128_u64()?)?; + let mut subkeys = RevisionMap::with_capacity(n_coordinates); + for _ in 0..n_coordinates { + let coordinate = Coordinate::from(de.read_vec()?); let n_keys = ::try_from(de.read_leb128_u64()?)?; let chain: Result, Self::Error> = (0..n_keys) .map(|_| { @@ -158,7 +158,7 @@ impl Serializable for MasterSecretKey { Ok((sk_i, R25519PrivateKey::try_from_bytes(x_i)?)) }) .collect(); - subkeys.map.insert(partition, chain?); + subkeys.map.insert(coordinate, chain?); } let kmac_key = match de.read_array::<{ KMAC_KEY_LENGTH }>() { @@ -185,8 +185,8 @@ impl Serializable for UserSecretKey { // subkeys serialization + to_leb128_len(self.subkeys.len()) + self.subkeys.count_elements() * R25519PrivateKey::LENGTH; - for (partition, chain) in self.subkeys.iter() { - length += to_leb128_len(partition.len()) + partition.len(); + for (coordinate, chain) in self.subkeys.iter() { + length += to_leb128_len(coordinate.len()) + coordinate.len(); length += to_leb128_len(chain.len()); for (sk_i, _) in chain { length += serialize_len_option!(sk_i, _value, KYBER_INDCPA_SECRETKEYBYTES); @@ -199,9 +199,9 @@ 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.len() as u64)?; - for (partition, chain) in self.subkeys.iter() { - // write chain partition - n += ser.write_vec(partition)?; + for (coordinate, chain) in self.subkeys.iter() { + // write chain coordinate + n += ser.write_vec(coordinate)?; // iterate through all subkeys in the chain n += ser.write_leb128_u64(chain.len() as u64)?; for (sk_i, x_i) in chain { @@ -218,10 +218,10 @@ 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 = ::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()?); + let n_coordinates = ::try_from(de.read_leb128_u64()?)?; + let mut subkeys = RevisionVec::with_capacity(n_coordinates); + for _ in 0..n_coordinates { + let coordinate = Coordinate::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 new_chain: Result, _> = (0..n_keys) @@ -231,7 +231,7 @@ impl Serializable for UserSecretKey { Ok::<_, Self::Error>((sk_i, R25519PrivateKey::try_from_bytes(x_i)?)) }) .collect(); - subkeys.insert_new_chain(partition, new_chain?); + subkeys.insert_new_chain(coordinate, new_chain?); } let kmac = de.read_array::<{ KMAC_LENGTH }>().ok(); @@ -305,9 +305,9 @@ impl Serializable for Encapsulation { let c1 = R25519PublicKey::try_from_bytes(de.read_array::<{ R25519PublicKey::LENGTH }>()?)?; let c2 = R25519PublicKey::try_from_bytes(de.read_array::<{ R25519PublicKey::LENGTH }>()?)?; let tag = de.read_array()?; - let n_partitions = ::try_from(de.read_leb128_u64()?)?; - let mut encs = HashSet::with_capacity(n_partitions); - for _ in 0..n_partitions { + let n_coordinates = ::try_from(de.read_leb128_u64()?)?; + let mut encs = HashSet::with_capacity(n_coordinates); + for _ in 0..n_coordinates { let key_encapsulation = de.read()?; encs.insert(key_encapsulation); } @@ -418,23 +418,23 @@ mod tests { #[test] fn test_serialization() -> Result<(), Error> { // Setup - let admin_partition = Partition(b"admin".to_vec()); - let dev_partition = Partition(b"dev".to_vec()); - let partitions_set = HashMap::from([ + let admin_coordinate = Coordinate(b"admin".to_vec()); + let dev_coordinate = Coordinate(b"dev".to_vec()); + let coordinates_set = HashMap::from([ ( - admin_partition.clone(), + admin_coordinate.clone(), (EncryptionHint::Hybridized, AttributeStatus::EncryptDecrypt), ), ( - dev_partition.clone(), + dev_coordinate.clone(), (EncryptionHint::Classic, AttributeStatus::EncryptDecrypt), ), ]); - let user_set = HashSet::from([admin_partition.clone(), dev_partition.clone()]); - let target_set = HashSet::from([admin_partition, dev_partition]); + let user_set = HashSet::from([admin_coordinate.clone(), dev_coordinate.clone()]); + let target_set = HashSet::from([admin_coordinate, dev_coordinate]); let mut rng = CsRng::from_entropy(); - let (msk, mpk) = setup(&mut rng, partitions_set); + let (msk, mpk) = setup(&mut rng, coordinates_set); // Check Covercrypt `MasterSecretKey` serialization. let bytes = msk.serialize()?; diff --git a/src/test_utils/mod.rs b/src/test_utils/mod.rs index 28d36d7a..5b9c2b48 100644 --- a/src/test_utils/mod.rs +++ b/src/test_utils/mod.rs @@ -39,7 +39,7 @@ mod tests { use super::*; use crate::{ - abe_policy::{AccessPolicy, Attribute, LegacyPolicy, Partition}, + abe_policy::{AccessPolicy, Attribute, Coordinate, LegacyPolicy}, Covercrypt, EncryptedHeader, }; @@ -80,7 +80,7 @@ mod tests { assert_eq!(mpk.subkeys.len(), 30); assert_eq!(msk.subkeys.count_elements(), 30); - // rekey all partitions which include `Department::FIN` + // rekey all coordinates which include `Department::FIN` let rekey_access_policy = AccessPolicy::Attr(Attribute::new("Department", "FIN")); cover_crypt.rekey_master_keys(&rekey_access_policy, &policy, &mut msk, &mut mpk)?; // public key contains only the last subkeys @@ -164,9 +164,9 @@ mod tests { 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 + // refresh the user key but do NOT preserve access to old coordinates cover_crypt.refresh_user_secret_key(&mut usk, &msk, false)?; - // the user should still have access to the same number of partitions + // the user should still have access to the same number of coordinates assert_eq!( usk.subkeys.count_elements(), original_usk.subkeys.count_elements() @@ -176,7 +176,7 @@ mod tests { } // try to modify the user key and refresh - let part = Partition::from(vec![1, 6]); + let part = Coordinate::from(vec![1, 6]); usk.subkeys.create_chain_with_single_value( part.clone(), msk.subkeys.get_latest(&part).unwrap().clone(), @@ -194,11 +194,11 @@ mod tests { let cover_crypt = Covercrypt::default(); let (mut msk, mut mpk) = cover_crypt.generate_master_keys(&policy)?; - let partitions_msk: Vec = msk.subkeys.keys().cloned().collect(); - let partitions_mpk: Vec = mpk.subkeys.keys().cloned().collect(); - assert_eq!(partitions_msk.len(), partitions_mpk.len()); - for p in &partitions_msk { - assert!(partitions_mpk.contains(p)); + let coordinates_msk: Vec = msk.subkeys.keys().cloned().collect(); + let coordinates_mpk: Vec = mpk.subkeys.keys().cloned().collect(); + assert_eq!(coordinates_msk.len(), coordinates_mpk.len()); + for p in &coordinates_msk { + assert!(coordinates_mpk.contains(p)); } // @@ -214,13 +214,13 @@ mod tests { )?; // update the master keys cover_crypt.update_master_keys(&policy, &mut msk, &mut mpk)?; - let new_partitions_msk: Vec = msk.subkeys.keys().cloned().collect(); - let new_partitions_mpk: Vec = mpk.subkeys.keys().cloned().collect(); - assert_eq!(new_partitions_msk.len(), new_partitions_mpk.len()); - for p in &new_partitions_msk { - assert!(new_partitions_mpk.contains(p)); + let new_coordinates_msk: Vec = msk.subkeys.keys().cloned().collect(); + let new_coordinates_mpk: Vec = mpk.subkeys.keys().cloned().collect(); + assert_eq!(new_coordinates_msk.len(), new_coordinates_mpk.len()); + for p in &new_coordinates_msk { + assert!(new_coordinates_mpk.contains(p)); } - assert_eq!(new_partitions_msk.len(), partitions_msk.len() + 6); + assert_eq!(new_coordinates_msk.len(), coordinates_msk.len() + 6); // // Encrypt @@ -250,11 +250,11 @@ mod tests { let cover_crypt = Covercrypt::default(); let (mut msk, mut mpk) = cover_crypt.generate_master_keys(&policy)?; - let partitions_msk: Vec = msk.subkeys.keys().cloned().collect(); - let partitions_mpk: Vec = mpk.subkeys.keys().cloned().collect(); - assert_eq!(partitions_msk.len(), partitions_mpk.len()); - for p in &partitions_msk { - assert!(partitions_mpk.contains(p)); + let coordinates_msk: Vec = msk.subkeys.keys().cloned().collect(); + let coordinates_mpk: Vec = mpk.subkeys.keys().cloned().collect(); + assert_eq!(coordinates_msk.len(), coordinates_mpk.len()); + for p in &coordinates_msk { + assert!(coordinates_mpk.contains(p)); } // @@ -276,24 +276,24 @@ mod tests { // update the master keys cover_crypt.update_master_keys(&policy, &mut msk, &mut mpk)?; - let new_partitions_msk: Vec = msk.subkeys.keys().cloned().collect(); - let new_partitions_mpk: Vec = mpk.subkeys.keys().cloned().collect(); - assert_eq!(new_partitions_msk.len(), new_partitions_mpk.len()); - for p in &new_partitions_msk { - assert!(new_partitions_mpk.contains(p)); + let new_coordinates_msk: Vec = msk.subkeys.keys().cloned().collect(); + let new_coordinates_mpk: Vec = mpk.subkeys.keys().cloned().collect(); + assert_eq!(new_coordinates_msk.len(), new_coordinates_mpk.len()); + for p in &new_coordinates_msk { + assert!(new_coordinates_mpk.contains(p)); } // 5 is the size of the security level dimension - assert_eq!(new_partitions_msk.len(), partitions_msk.len() - 6); + assert_eq!(new_coordinates_msk.len(), coordinates_msk.len() - 6); assert!(encrypted_header .decrypt(&cover_crypt, &top_secret_fin_usk, None) .is_ok()); - // refresh the user key and preserve access to old partitions + // refresh the user key and preserve access to old coordinates let _new_decryption_policy = AccessPolicy::parse("Security Level::Top Secret && Department::HR")?; - // refreshing the user key will remove access to removed partitions even if we + // refreshing the user key will remove access to removed coordinates even if we // keep old rotations cover_crypt.refresh_user_secret_key(&mut top_secret_fin_usk, &msk, true)?; assert!(encrypted_header @@ -309,9 +309,9 @@ mod tests { let cover_crypt = Covercrypt::default(); let (mut msk, mut mpk) = cover_crypt.generate_master_keys(&policy)?; - let partitions_msk: Vec = msk.subkeys.keys().cloned().collect(); - let partitions_mpk: Vec = mpk.subkeys.keys().cloned().collect(); - assert_eq!(partitions_msk.len(), partitions_mpk.len()); + let coordinates_msk: Vec = msk.subkeys.keys().cloned().collect(); + let coordinates_mpk: Vec = mpk.subkeys.keys().cloned().collect(); + assert_eq!(coordinates_msk.len(), coordinates_mpk.len()); // // New user secret key @@ -332,12 +332,12 @@ mod tests { // update the master keys cover_crypt.update_master_keys(&policy, &mut msk, &mut mpk)?; - let new_partitions_msk: Vec = msk.subkeys.keys().cloned().collect(); - let new_partitions_mpk: Vec = mpk.subkeys.keys().cloned().collect(); - // the disabled partition have been removed from mpk - assert_eq!(new_partitions_msk.len() - 6, new_partitions_mpk.len()); + let new_coordinates_msk: Vec = msk.subkeys.keys().cloned().collect(); + let new_coordinates_mpk: Vec = mpk.subkeys.keys().cloned().collect(); + // the disabled coordinate have been removed from mpk + assert_eq!(new_coordinates_msk.len() - 6, new_coordinates_mpk.len()); // msk has not changed - assert_eq!(new_partitions_msk.len(), partitions_msk.len()); + assert_eq!(new_coordinates_msk.len(), coordinates_msk.len()); assert!(encrypted_header .decrypt(&cover_crypt, &top_secret_fin_usk, None) @@ -351,13 +351,13 @@ mod tests { .is_err() ); - // refresh the user key and preserve access to old partitions + // refresh the user key and preserve access to old coordinates cover_crypt.refresh_user_secret_key(&mut top_secret_fin_usk, &msk, true)?; assert!(encrypted_header .decrypt(&cover_crypt, &top_secret_fin_usk, None) .is_ok()); - // refresh the user key and remove access to old partitions should still work + // refresh the user key and remove access to old coordinates should still work cover_crypt.refresh_user_secret_key(&mut top_secret_fin_usk, &msk, false)?; assert!(encrypted_header .decrypt(&cover_crypt, &top_secret_fin_usk, None) @@ -401,7 +401,7 @@ mod tests { .decrypt(&cover_crypt, &top_secret_fin_usk, None) .is_ok()); - // refresh the user key and preserve access to old partitions + // refresh the user key and preserve access to old coordinates let _new_decryption_policy = AccessPolicy::parse("Security Level::Top Secret && Department::Finance")?; cover_crypt.refresh_user_secret_key(&mut top_secret_fin_usk, &msk, false)?;