use crate::Error;
use abe_policy::{AccessPolicy, Policy};
#[cfg(feature = "interface")]
use cosmian_crypto_core::bytes_ser_de::Serializable;
use cosmian_crypto_core::{
asymmetric_crypto::DhKeyPair,
symmetric_crypto::{Dem, SymKey},
};
use std::{
fmt::Debug,
ops::{Add, Div, Mul, Sub},
};
pub trait CoverCrypt<
const TAG_LENGTH: usize,
const SYM_KEY_LENGTH: usize,
const PK_LENGTH: usize,
const SK_LENGTH: usize,
KeyPair,
DEM,
>: Default + Debug + PartialEq where
KeyPair: DhKeyPair<PK_LENGTH, SK_LENGTH>,
DEM: Dem<SYM_KEY_LENGTH>,
KeyPair::PublicKey: From<KeyPair::PrivateKey>,
for<'a, 'b> &'a KeyPair::PublicKey: Add<&'b KeyPair::PublicKey, Output = KeyPair::PublicKey>
+ Mul<&'b KeyPair::PrivateKey, Output = KeyPair::PublicKey>,
for<'a, 'b> &'a KeyPair::PrivateKey: Add<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Sub<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Mul<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Div<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>,
{
const SYM_KEY_LENGTH: usize = SYM_KEY_LENGTH;
const PUBLIC_KEY_LENGTH: usize = PK_LENGTH;
const PRIVATE_KEY_LENGTH: usize = SK_LENGTH;
#[cfg(not(feature = "interface"))]
type MasterSecretKey: PartialEq + Eq;
#[cfg(feature = "interface")]
type MasterSecretKey: PartialEq + Eq + Serializable<Error = Error>;
#[cfg(not(feature = "interface"))]
type UserSecretKey: PartialEq + Eq;
#[cfg(feature = "interface")]
type UserSecretKey: PartialEq + Eq + Serializable<Error = Error>;
#[cfg(not(feature = "interface"))]
type PublicKey: PartialEq + Eq;
#[cfg(feature = "interface")]
type PublicKey: PartialEq + Eq + Serializable<Error = Error>;
#[cfg(not(feature = "interface"))]
type Encapsulation: PartialEq + Eq;
#[cfg(feature = "interface")]
type Encapsulation: PartialEq + Eq + Serializable<Error = Error>;
type SymmetricKey: SymKey<SYM_KEY_LENGTH>;
fn generate_master_keys(
&self,
policy: &Policy,
) -> Result<(Self::MasterSecretKey, Self::PublicKey), Error>;
fn update_master_keys(
&self,
policy: &Policy,
msk: &mut Self::MasterSecretKey,
mpk: &mut Self::PublicKey,
) -> Result<(), Error>;
fn generate_user_secret_key(
&self,
msk: &Self::MasterSecretKey,
user_policy: &AccessPolicy,
policy: &Policy,
) -> Result<Self::UserSecretKey, Error>;
fn refresh_user_secret_key(
&self,
usk: &mut Self::UserSecretKey,
user_policy: &AccessPolicy,
msk: &Self::MasterSecretKey,
policy: &Policy,
keep_old_accesses: bool,
) -> Result<(), Error>;
fn encaps(
&self,
policy: &Policy,
pk: &Self::PublicKey,
encryption_policy: &AccessPolicy,
) -> Result<(DEM::Key, Self::Encapsulation), Error>;
fn decaps(
&self,
sk_u: &Self::UserSecretKey,
encapsulation: &Self::Encapsulation,
) -> Result<DEM::Key, Error>;
fn encrypt(
&self,
symmetric_key: &DEM::Key,
plaintext: &[u8],
authentication_data: Option<&[u8]>,
) -> Result<Vec<u8>, Error>;
fn decrypt(
&self,
key: &DEM::Key,
ciphertext: &[u8],
authentication_data: Option<&[u8]>,
) -> Result<Vec<u8>, Error>;
}
#[derive(Debug, PartialEq, Eq)]
pub struct EncryptedHeader<
const TAG_LENGTH: usize,
const SYM_KEY_LENGTH: usize,
const PK_LENGTH: usize,
const SK_LENGTH: usize,
KeyPair,
DEM,
CoverCryptScheme,
> where
KeyPair: DhKeyPair<PK_LENGTH, SK_LENGTH>,
DEM: Dem<SYM_KEY_LENGTH>,
KeyPair::PublicKey: From<KeyPair::PrivateKey>,
for<'a, 'b> &'a KeyPair::PublicKey: Add<&'b KeyPair::PublicKey, Output = KeyPair::PublicKey>
+ Mul<&'b KeyPair::PrivateKey, Output = KeyPair::PublicKey>,
for<'a, 'b> &'a KeyPair::PrivateKey: Add<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Sub<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Mul<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Div<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>,
CoverCryptScheme: CoverCrypt<TAG_LENGTH, SYM_KEY_LENGTH, PK_LENGTH, SK_LENGTH, KeyPair, DEM>,
{
pub encapsulation: CoverCryptScheme::Encapsulation,
pub ciphertext: Vec<u8>,
}
impl<
const TAG_LENGTH: usize,
const SYM_KEY_LENGTH: usize,
const PK_LENGTH: usize,
const SK_LENGTH: usize,
KeyPair,
DEM,
CoverCryptScheme,
>
EncryptedHeader<
TAG_LENGTH,
SYM_KEY_LENGTH,
PK_LENGTH,
SK_LENGTH,
KeyPair,
DEM,
CoverCryptScheme,
>
where
KeyPair: DhKeyPair<PK_LENGTH, SK_LENGTH>,
DEM: Dem<SYM_KEY_LENGTH>,
KeyPair::PublicKey: From<KeyPair::PrivateKey>,
for<'a, 'b> &'a KeyPair::PublicKey: Add<&'b KeyPair::PublicKey, Output = KeyPair::PublicKey>
+ Mul<&'b KeyPair::PrivateKey, Output = KeyPair::PublicKey>,
for<'a, 'b> &'a KeyPair::PrivateKey: Add<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Sub<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Mul<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>
+ Div<&'b KeyPair::PrivateKey, Output = KeyPair::PrivateKey>,
CoverCryptScheme: CoverCrypt<TAG_LENGTH, SYM_KEY_LENGTH, PK_LENGTH, SK_LENGTH, KeyPair, DEM>,
{
pub fn generate(
cover_crypt: &CoverCryptScheme,
policy: &Policy,
public_key: &CoverCryptScheme::PublicKey,
encryption_policy: &AccessPolicy,
header_metadata: Option<&[u8]>,
authentication_data: Option<&[u8]>,
) -> Result<(DEM::Key, Self), Error> {
let (symmetric_key, encapsulation) =
cover_crypt.encaps(policy, public_key, encryption_policy)?;
let ciphertext = match header_metadata {
Some(d) => cover_crypt.encrypt(&symmetric_key, d, authentication_data)?,
None => vec![],
};
Ok((
symmetric_key,
Self {
encapsulation,
ciphertext,
},
))
}
pub fn decrypt(
&self,
cover_crypt: &CoverCryptScheme,
usk: &CoverCryptScheme::UserSecretKey,
authentication_data: Option<&[u8]>,
) -> Result<CleartextHeader<SYM_KEY_LENGTH, DEM>, Error> {
let symmetric_key = cover_crypt.decaps(usk, &self.encapsulation)?;
let header_metadata = if self.ciphertext.is_empty() {
vec![]
} else {
cover_crypt.decrypt(&symmetric_key, &self.ciphertext, authentication_data)?
};
Ok(CleartextHeader {
symmetric_key,
metadata: header_metadata,
})
}
}
#[derive(Debug, PartialEq, Eq)]
pub struct CleartextHeader<const KEY_LENGTH: usize, DEM>
where
DEM: Dem<KEY_LENGTH>,
{
pub symmetric_key: DEM::Key,
pub metadata: Vec<u8>,
}