Skip to content

Commit

Permalink
wip: feat: merge msk/mpk
Browse files Browse the repository at this point in the history
  • Loading branch information
tbrezot committed Jan 26, 2024
1 parent 1320757 commit 70e2281
Show file tree
Hide file tree
Showing 30 changed files with 2,136 additions and 1,462 deletions.
1 change: 0 additions & 1 deletion benches/benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ use cosmian_cover_crypt::{
};
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};

// Policy settings
fn policy() -> Result<Policy, Error> {
#[cfg(not(feature = "hybridized_bench"))]
let (security_level, department) = {
Expand Down
13 changes: 6 additions & 7 deletions examples/runme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ fn main() {

// Setup Covercrypt and generate master keys
let cover_crypt = Covercrypt::default();
let (mut msk, mut mpk) = cover_crypt.generate_master_keys(&policy).unwrap();
let (mut msk, _) = cover_crypt.setup().unwrap();
let mpk = cover_crypt.update_master_keys(&policy, &mut msk).unwrap();

// The user has a security clearance `Security Level::Top Secret`,
// and belongs to the finance department (`Department::FIN`).
let access_policy =
AccessPolicy::parse("Security Level::Top Secret && Department::FIN").unwrap();
let mut usk = cover_crypt
.generate_user_secret_key(&msk, &access_policy, &policy)
.generate_user_secret_key(&mut msk, &access_policy, &policy)
.unwrap();

// Encrypt
Expand All @@ -62,8 +63,8 @@ fn main() {
//
// Rekey all keys using the `Security Level::Top Secret` attribute
let rekey_access_policy = AccessPolicy::Attr(Attribute::from(("Security Level", "Top Secret")));
cover_crypt
.rekey_master_keys(&rekey_access_policy, &policy, &mut msk, &mut mpk)
let mpk = cover_crypt
.rekey(&rekey_access_policy, &policy, &mut msk)
.unwrap();

// Encrypt with rotated attribute
Expand All @@ -76,9 +77,7 @@ fn main() {
.is_err());

// refresh user secret key, do not grant old encryption access
cover_crypt
.refresh_user_secret_key(&mut usk, &msk, false)
.unwrap();
cover_crypt.refresh_usk(&mut usk, &mut msk, false).unwrap();

// The user with refreshed key is able to decrypt the newly encrypted header.
assert!(new_encrypted_header
Expand Down
2 changes: 1 addition & 1 deletion src/abe_policy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub use policy_versions::{LegacyPolicy, PolicyV1, PolicyV2 as Policy};
use serde::{Deserialize, Serialize};

#[cfg(test)]
mod tests;
pub(crate) mod tests;

#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum PolicyVersion {
Expand Down
59 changes: 54 additions & 5 deletions src/abe_policy/partitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,54 @@ use cosmian_crypto_core::bytes_ser_de::Serializer;

use crate::Error;

/// Partition associated to a subset. It corresponds to a combination
/// of attributes across all dimensions.
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Clone, Hash)]
/// Space coordinate.
///
/// It is a representation of a given combination of one component per
/// dimension.
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct Coordinate(Vec<u8>);

impl Coordinate {
/// Creates a `Partition` from the given list of values.
/// Computes the coordinate associated to the given list of IDs of dimension
/// component.
///
/// Coordinates are defined using one component per dimension. But in
/// practice, neutral elements may be omitted: no component from a given
/// dimension means a neutral component.
///
/// The current implementation simply uses a sorted sequence of `u32` IDs.
///
/// This is bad because:
/// - it creates *coupling* between the internal coordinate representation
/// (ID serialization) and the way dimension coordinates are represented
/// in the policy object (needs to provide the unique ID).
/// - this means coordinates are variable-length variables, and thus heap
/// allocated.
///
/// This is good because:
/// - it minimizes coordinate size (e.g. hashing would creates 16-byte long
/// coordinates) ...
/// ... *only* when components IDs and the number of non-neutral
/// components are kept small (btw, the number of such components is
/// limited to 200; this is OK since the dimensionality is an upper
/// bound).
///
/// => good for small dimensionality and young policies (not many
/// deletions/creations) but do not scale well.
///
/// Alternative implementation could simply use hashing. This allows using
/// arbitrary representations for dimension components (strings? ->
/// attribute names). This releases the constraint that policy need to
/// produce (thus store) unique IDs for dimension components. Coordinates
/// would then be fixed size 16-byte long values.
///
/// However:
/// - this means that hash need to be *commutative* and *associative* or
/// that sorting is used before hashing (and sorting arbitrary types may
/// be less efficient than sorting `u32`, even though it may be negligible
/// compared to the crypto operation times)
/// - recreating a deleted components will result in the same coordinate.
/// This is
pub fn from_attribute_ids(mut attribute_ids: Vec<u32>) -> Result<Self, Error> {
// guard against overflow of the 1024 bytes buffer below
if attribute_ids.len() > 200 {
Expand Down Expand Up @@ -56,10 +97,18 @@ impl From<&[u8]> for Coordinate {

#[cfg(test)]
mod tests {
use cosmian_crypto_core::bytes_ser_de::Deserializer;
use cosmian_crypto_core::{bytes_ser_de::Deserializer, reexport::rand_core::CryptoRngCore};

use super::*;

impl Coordinate {
pub fn random(rng: &mut impl CryptoRngCore) -> Self {
let mut coordinate = Self(vec![0; 16]);
rng.fill_bytes(&mut coordinate.0);
coordinate
}
}

#[test]
fn test_partitions() -> Result<(), Error> {
let mut values: Vec<u32> = vec![12, 0, u32::MAX, 1];
Expand Down
3 changes: 2 additions & 1 deletion src/abe_policy/policy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,10 @@ pub fn combine(

#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::policy;

use super::*;

#[test]
fn test_combine() {
let mut policy = policy().unwrap();
Expand Down
Loading

0 comments on commit 70e2281

Please sign in to comment.