-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
175 additions
and
74 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,105 +1,153 @@ | ||
//! Implements the core functionalities of `Covercrypt`. | ||
use std::{ | ||
cell::RefCell, | ||
collections::{HashMap, HashSet}, | ||
hash::Hash, | ||
ops::Deref, | ||
}; | ||
|
||
use cosmian_crypto_core::{R25519PrivateKey, R25519PublicKey, SymmetricKey}; | ||
use pqc_kyber::{KYBER_INDCPA_BYTES, KYBER_INDCPA_PUBLICKEYBYTES, KYBER_INDCPA_SECRETKEYBYTES}; | ||
use zeroize::ZeroizeOnDrop; | ||
use cosmian_crypto_core::{R25519PrivateKey as Scalar, R25519PublicKey as EcPoint, SymmetricKey}; | ||
|
||
use crate::{ | ||
abe_policy::Partition, | ||
data_struct::{RevisionMap, RevisionVec}, | ||
}; | ||
|
||
use self::pq_kem::kyber::{KyberPublicKey, KyberSecretKey, KYBER_INDCPA_BYTES}; | ||
|
||
#[macro_use] | ||
pub mod macros; | ||
|
||
pub mod api; | ||
pub mod pq_kem; | ||
pub mod primitives; | ||
pub mod serialization; | ||
|
||
/// The symmetric key is 32 bytes long to provide 128 bits of post-quantum | ||
/// security. | ||
/// The length of the keys encapsulated by Covercrypt. | ||
/// | ||
/// They are 32 bytes long to enable reaching 128 bits of post-quantum security | ||
/// when using it with a sensible DEM. | ||
pub const SYM_KEY_LENGTH: usize = 32; | ||
|
||
/// The length of the KMAC key. | ||
/// The length of the KMAC key used to sign user secret keys. | ||
/// | ||
/// It is only 16-byte long because no post-quantum security is needed for | ||
/// now. An upgraded signature scheme can still be added later when quantum | ||
/// computers become available. | ||
pub const KMAC_KEY_LENGTH: usize = 16; | ||
|
||
/// The length of the KMAC output. | ||
/// The length of the KMAC signature. | ||
const KMAC_LENGTH: usize = 32; | ||
|
||
/// KMAC signature is used to guarantee the integrity of the user secret keys. | ||
type KmacSignature = [u8; KMAC_LENGTH]; | ||
|
||
/// Length of the `Covercrypt` tag | ||
/// Length of the Covercrypt early abort tag | ||
const TAG_LENGTH: usize = 16; | ||
type Tag = [u8; TAG_LENGTH]; | ||
|
||
/// Kyber public key length | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
pub struct KyberPublicKey([u8; KYBER_INDCPA_PUBLICKEYBYTES]); | ||
/// Covercrypt early abort tag is used during the decapsulation to verify the | ||
/// integrity of the result. | ||
type Tag = [u8; TAG_LENGTH]; | ||
|
||
impl Deref for KyberPublicKey { | ||
type Target = [u8]; | ||
/// Number of colluding users needed to escape tracing. | ||
const TRACING_LEVEL: usize = 2; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
/// The Covercrypt subkeys hold the DH secret key associated to a coordinate. | ||
/// Subkeys can be hybridized, in which case they also hold a PQ-KEM secret key. | ||
#[derive(Debug, PartialEq, Eq)] | ||
enum PublicSubkey { | ||
Hybridized { pki: KyberPublicKey, hi: EcPoint }, | ||
Classic { hi: EcPoint }, | ||
} | ||
|
||
/// Kyber secret key length | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash, ZeroizeOnDrop)] | ||
pub struct KyberSecretKey([u8; KYBER_INDCPA_SECRETKEYBYTES]); | ||
|
||
impl Deref for KyberSecretKey { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
/// The Covercrypt subkeys hold the DH secret key associated to a coordinate. | ||
/// Subkeys can be hybridized, in which case they also hold a PQ-KEM secret key. | ||
#[derive(Debug, PartialEq, Eq)] | ||
enum SecretSubkey { | ||
Hybridized { ski: KyberSecretKey, xi: Scalar }, | ||
Classic { xi: Scalar }, | ||
} | ||
|
||
pub(super) type PublicSubkey = (Option<KyberPublicKey>, R25519PublicKey); | ||
|
||
/// Covercrypt user IDs are used to make user keys unique and traceable. | ||
/// | ||
/// They are composed of a sequence of `LENGTH` scalars. | ||
#[derive(Debug, PartialEq, Eq, Hash)] | ||
struct Uid<const LENGTH: usize>([Scalar; LENGTH]); | ||
|
||
/// Covercrypt tracing secret key. | ||
/// | ||
/// It is composed of: | ||
/// - `TRACING_LEVEL + 1` scalars; | ||
/// - the user IDs. | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct MasterPublicKey { | ||
g1: R25519PublicKey, | ||
g2: R25519PublicKey, | ||
pub(crate) subkeys: HashMap<Partition, PublicSubkey>, | ||
struct TracingSecretKey<const TRACING_LEVEL: usize> { | ||
s: Scalar, | ||
scalars: [Scalar; TRACING_LEVEL], | ||
uids: HashSet<Uid<TRACING_LEVEL>>, | ||
} | ||
|
||
pub(super) type SecretSubkey = (Option<KyberSecretKey>, R25519PrivateKey); | ||
/// Covercrypt tracing public key. | ||
#[derive(Debug, PartialEq, Eq)] | ||
struct TracingPublicKey<const TRACING_LEVEL: usize>([EcPoint; TRACING_LEVEL]); | ||
|
||
/// The Covercrypt Master Secret Key (MSK). | ||
/// | ||
/// It is composed of: | ||
/// - the tracing secret key used to produce challenges to trace user keys; | ||
/// - the secret subkeys associated to each universal coordinates. | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct MasterSecretKey { | ||
s: R25519PrivateKey, | ||
s1: R25519PrivateKey, | ||
s2: R25519PrivateKey, | ||
pub(crate) subkeys: RevisionMap<Partition, SecretSubkey>, | ||
tsk: TracingSecretKey<TRACING_LEVEL>, | ||
subkeys: RevisionMap<Partition, SecretSubkey>, | ||
kmac_key: Option<SymmetricKey<KMAC_KEY_LENGTH>>, | ||
} | ||
|
||
/// Covercrypt Public Key (PK). | ||
/// | ||
/// It is composed of: | ||
/// - the tracing public key; | ||
/// - the public subkeys associated to each universal coordinate. | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct MasterPublicKey { | ||
tpk: TracingPublicKey<TRACING_LEVEL>, | ||
subkeys: HashMap<Partition, PublicSubkey>, | ||
} | ||
|
||
/// Covercrypt User Secret Key (USK). | ||
/// | ||
/// It is composed of: | ||
/// - a user ID (pair of scalars); | ||
/// - the subkeys associated to the coordinates derived from the user | ||
/// decryption policy; | ||
/// - a signature from the MSK that guarantees its integrity. | ||
#[derive(Debug, PartialEq, Eq)] | ||
pub struct UserSecretKey { | ||
a: R25519PrivateKey, | ||
b: R25519PrivateKey, | ||
pub(crate) subkeys: RefCell<RevisionVec<Partition, SecretSubkey>>, | ||
kmac: Option<KmacSignature>, | ||
id: Uid<TRACING_LEVEL>, | ||
subkeys: RefCell<RevisionVec<Partition, SecretSubkey>>, | ||
msk_signature: Option<KmacSignature>, | ||
} | ||
|
||
/// Encapsulation of a `SYM_KEY_LENGTH`-byte key for a given coordinate. | ||
/// | ||
/// In case the security level of the associated coordinate was set to | ||
/// post-quantum secure, the key encapsulation is hybridized. This implies a | ||
/// significant size overhead. | ||
#[derive(Debug, Clone, Hash, PartialEq, Eq)] | ||
enum KeyEncapsulation { | ||
ClassicEncapsulation(Box<[u8; SYM_KEY_LENGTH]>), | ||
HybridEncapsulation(Box<[u8; KYBER_INDCPA_BYTES]>), | ||
Classic([u8; SYM_KEY_LENGTH]), | ||
Hybridized([u8; KYBER_INDCPA_BYTES]), | ||
} | ||
|
||
/// Covercrypt encapsulation. | ||
/// | ||
/// It is created for a subset of universal coordinates. One key encapsulation | ||
/// is created per associated coordinate. | ||
/// | ||
/// It is composed of: | ||
/// - the early abort tag; | ||
/// - the tracing EC points; | ||
/// - the coordinate encapsulations. | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct Encapsulation { | ||
c1: R25519PublicKey, | ||
c2: R25519PublicKey, | ||
tag: Tag, | ||
encs: HashSet<KeyEncapsulation>, | ||
tracing_points: [EcPoint; TRACING_LEVEL], | ||
coordinate_encapsulations: HashSet<KeyEncapsulation>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use pqc_kyber::{KYBER_INDCPA_PUBLICKEYBYTES, KYBER_INDCPA_SECRETKEYBYTES}; | ||
use std::ops::Deref; | ||
use zeroize::Zeroizing; | ||
|
||
pub use pqc_kyber::KYBER_INDCPA_BYTES; | ||
|
||
/// Kyber public key length | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
pub struct KyberPublicKey([u8; KYBER_INDCPA_PUBLICKEYBYTES]); | ||
|
||
impl Deref for KyberPublicKey { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
/// Kyber secret key. | ||
#[derive(Debug, Clone, PartialEq, Eq)] | ||
pub struct KyberSecretKey(Zeroizing<[u8; KYBER_INDCPA_SECRETKEYBYTES]>); | ||
|
||
impl Deref for KyberSecretKey { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
self.0.as_slice() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use pqc_kyber::{KYBER_INDCPA_BYTES, KYBER_INDCPA_PUBLICKEYBYTES, KYBER_INDCPA_SECRETKEYBYTES}; | ||
|
||
/// Kyber public key length | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
pub struct KyberPublicKey([u8; KYBER_INDCPA_PUBLICKEYBYTES]); | ||
|
||
impl Deref for KyberPublicKey { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
/// Kyber secret key. | ||
#[derive(Debug, Clone, PartialEq, Eq, Hash, ZeroizeOnDrop)] | ||
pub struct KyberSecretKey([u8; KYBER_INDCPA_SECRETKEYBYTES]); | ||
|
||
impl Deref for KyberSecretKey { | ||
type Target = [u8]; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod kyber; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
mod kyber; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.