Skip to content

Commit

Permalink
fix: rename ElGamal encryption to masking primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
tbrezot committed Feb 5, 2024
1 parent 8af8e50 commit e1e482d
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 55 deletions.
37 changes: 13 additions & 24 deletions src/core/pke/elgamal/mod.rs → src/core/elgamal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Exposes an ElGamal PKE based on an ElGamal KEM.
//! Exposes masking and unmasking primitives based on an ElGamal KEM.
//!
//! Current implementation only uses Ristretto on Curve25519 but plans to add
//! more curves is on the TODO list.
Expand Down Expand Up @@ -144,16 +144,13 @@ fn otp_decrypt<const LENGTH: usize>(
Ok(ptx)
}

/// Encrypts the given secret using a classic KEM.
/// Masks the given bytes using the key derived from the ElGamal shared secret.
///
/// # Security
///
/// This is a KEM-DEM PKE implementation using an ElGammal KEM and the one-time
/// pad as DEM. Security therefore relies on the fact that different secrets are
/// never encrypted using the same ElGammal keypair.
///
/// Provides 128-bit of classical security.
pub fn encrypt<const LENGTH: usize>(
/// The security relies on the fact that the same ElGammal keypair is never used
/// on different input bytes.
pub fn mask<const LENGTH: usize>(
ephemeral_sk: &Scalar,
recipient_pk: &EcPoint,
ptx: &Secret<LENGTH>,
Expand All @@ -165,21 +162,13 @@ pub fn encrypt<const LENGTH: usize>(
otp_encrypt(&key, ptx)
}

/// Decrypts the given secret using a classic KEM.
///
/// # Security
///
/// This is a KEM-DEM PKE implementation using an ElGammal KEM and the one-time
/// pad as DEM. Security therefore relies on the fact that different secrets are
/// never encrypted using the same ElGammal keypair.
///
/// Provides 128-bit of classical security.
pub fn decrypt<const LENGTH: usize>(
sk: &Scalar,
pk: &EcPoint,
/// Unmasks the given bytes using the key derived from the ElGamal shared secret.
pub fn unmask<const LENGTH: usize>(
recipient_sk: &Scalar,
ephemeral_pk: &EcPoint,
ctx: &[u8],
) -> Result<Secret<LENGTH>, Error> {
let mut shared_secret = pk * sk;
let mut shared_secret = ephemeral_pk * recipient_sk;
let mut key = SymmetricKey::<LENGTH>::default();
kdf256!(&mut *key, &shared_secret.to_bytes());
shared_secret.zeroize();
Expand All @@ -194,7 +183,7 @@ mod tests {
CsRng, Secret,
};

use super::{decrypt, encrypt, EcPoint, Keypair, Scalar};
use super::{mask, unmask, EcPoint, Keypair, Scalar};

/// Arbitrary plaintext length.
const PTX_LENGTH: usize = 108;
Expand All @@ -212,12 +201,12 @@ mod tests {
let ptx = Secret::<PTX_LENGTH>::random(&mut rng);
let ephemeral_keypair = keygen(&mut rng);
let recipient_keypair = keygen(&mut rng);
let ctx = encrypt(
let ctx = mask(
ephemeral_keypair.sk(),
recipient_keypair.pk().unwrap(),
&ptx,
);
let res = decrypt(
let res = unmask(
recipient_keypair.sk(),
ephemeral_keypair.pk().unwrap(),
&ctx,
Expand Down
File renamed without changes.
8 changes: 3 additions & 5 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ pub mod primitives;
#[cfg(feature = "serialization")]
pub mod serialization;

mod pke;
mod elgamal;
mod postquantum;
#[cfg(test)]
mod tests;

use pke::{
elgamal::{self, EcPoint, Scalar},
postquantum,
};
use elgamal::{EcPoint, Scalar};

/// The length of the keys encapsulated by Covercrypt.
///
Expand Down
2 changes: 0 additions & 2 deletions src/core/pke/mod.rs

This file was deleted.

File renamed without changes.
File renamed without changes.
37 changes: 19 additions & 18 deletions src/core/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ use tiny_keccak::{Hasher, IntoXof, Kmac, Xof};
use zeroize::Zeroize;

use super::{
pke, CoordinateKeypair, CoordinatePublicKey, CoordinateSecretKey, KmacSignature,
TracingSecretKey, KMAC_KEY_LENGTH, KMAC_SIG_LENGTH, MIN_TRACING_LEVEL, SEED_LENGTH, TAG_LENGTH,
elgamal, postquantum, CoordinateKeypair, CoordinatePublicKey, CoordinateSecretKey,
KmacSignature, TracingSecretKey, KMAC_KEY_LENGTH, KMAC_SIG_LENGTH, MIN_TRACING_LEVEL,
SEED_LENGTH, TAG_LENGTH,
};
use crate::{
abe_policy::{AttributeStatus, Coordinate, EncryptionHint},
Expand Down Expand Up @@ -78,7 +79,7 @@ pub fn setup(rng: &mut impl CryptoRngCore, tracing_level: usize) -> Result<Maste
"tracing level cannot be lower than {MIN_TRACING_LEVEL}"
)));
}
let s = pke::elgamal::Scalar::new(rng);
let s = elgamal::Scalar::new(rng);

let mut tsk = TracingSecretKey::default();
(0..=tracing_level).for_each(|_| tsk.increase_tracing(rng));
Expand Down Expand Up @@ -140,8 +141,8 @@ pub fn encaps(
mpk: &MasterPublicKey,
encryption_set: &HashSet<Coordinate>,
) -> Result<(SymmetricKey<SEED_LENGTH>, Encapsulation), Error> {
let ephemeral_sk = pke::elgamal::Scalar::new(rng);
let seed = Secret::<SEED_LENGTH>::random(rng);
let ephemeral_random = elgamal::Scalar::new(rng);
let session_key = Secret::<SEED_LENGTH>::random(rng);
let mut coordinate_encapsulations = HashSet::with_capacity(encryption_set.len());
for coordinate in encryption_set {
match mpk.coordinate_keys.get(coordinate) {
Expand All @@ -150,8 +151,8 @@ pub fn encaps(
elgamal_pk,
}) => {
let mut elgamal_ctx =
pke::elgamal::encrypt::<SEED_LENGTH>(&ephemeral_sk, elgamal_pk, &seed);
let postquantum_ctx = pke::postquantum::encrypt(rng, postquantum_pk, &elgamal_ctx)?;
elgamal::mask::<SEED_LENGTH>(&ephemeral_random, elgamal_pk, &session_key);
let postquantum_ctx = postquantum::encrypt(rng, postquantum_pk, &elgamal_ctx)?;
// Zeroize the ElGamal ciphertext as it may not be secure in the
// post-quantum world.
//
Expand All @@ -160,7 +161,7 @@ pub fn encaps(
coordinate_encapsulations.insert(SeedEncapsulation::Hybridized(postquantum_ctx));
}
Some(CoordinatePublicKey::Classic { elgamal_pk }) => {
let ctx = pke::elgamal::encrypt(&ephemeral_sk, elgamal_pk, &seed);
let ctx = elgamal::mask(&ephemeral_random, elgamal_pk, &session_key);
coordinate_encapsulations.insert(SeedEncapsulation::Classic(ctx));
}

Expand All @@ -172,8 +173,8 @@ pub fn encaps(
};
}

let traps = mpk.set_traps(&ephemeral_sk);
let (tag, key) = eakem_hash!(TAG_LENGTH, SEED_LENGTH, &*seed, KEY_GEN_INFO)
let traps = mpk.set_traps(&ephemeral_random);
let (tag, key) = eakem_hash!(TAG_LENGTH, SEED_LENGTH, &*session_key, KEY_GEN_INFO)
.map_err(Error::CryptoCoreError)?;

Ok((
Expand All @@ -192,12 +193,12 @@ pub fn decaps(
usk: &UserSecretKey,
encapsulation: &Encapsulation,
) -> Result<Option<SymmetricKey<SEED_LENGTH>>, Error> {
let precomp = usk
let ephemeral_point = usk
.id
.iter()
.zip(encapsulation.traps.iter())
.map(|(marker, trap)| trap * marker)
.fold(pke::elgamal::EcPoint::identity(), |mut acc, elt| {
.fold(elgamal::EcPoint::identity(), |mut acc, elt| {
acc = &acc + &elt;
acc
});
Expand All @@ -215,11 +216,11 @@ pub fn decaps(
},
SeedEncapsulation::Hybridized(ctx),
) => {
let elgammal_ctx = pke::postquantum::decrypt(postquantum_sk, ctx);
pke::elgamal::decrypt(elgamal_sk, &precomp, &elgammal_ctx)?
let elgammal_ctx = postquantum::decrypt(postquantum_sk, ctx);
elgamal::unmask(elgamal_sk, &ephemeral_point, &elgammal_ctx)?
}
(CoordinateSecretKey::Classic { elgamal_sk }, SeedEncapsulation::Classic(enc)) => {
pke::elgamal::decrypt(elgamal_sk, &precomp, enc)?
elgamal::unmask(elgamal_sk, &ephemeral_point, enc)?
}
(CoordinateSecretKey::Classic { .. }, SeedEncapsulation::Hybridized(_))
| (CoordinateSecretKey::Hybridized { .. }, SeedEncapsulation::Classic(_)) => {
Expand Down Expand Up @@ -273,12 +274,12 @@ pub fn update_coordinate_keys(
));
}

let elgamal_sk = pke::elgamal::Scalar::new(rng);
let elgamal_sk = elgamal::Scalar::new(rng);
let elgamal_pk = &h * &elgamal_sk;
let elgamal_keypair = pke::elgamal::Keypair::new(elgamal_sk, elgamal_pk);
let elgamal_keypair = elgamal::Keypair::new(elgamal_sk, elgamal_pk);

let postquantum_keypair = if EncryptionHint::Hybridized == hint {
Some(pke::postquantum::Keypair::random(rng))
Some(postquantum::Keypair::random(rng))
} else {
None
};
Expand Down
9 changes: 3 additions & 6 deletions src/core/serialization/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@ use cosmian_crypto_core::{
};

use super::{
pke::{
self,
elgamal::{EcPoint, Scalar},
postquantum::{self, PublicKey},
},
elgamal::{EcPoint, Scalar},
postquantum::{self, PublicKey},
CoordinateKeypair, CoordinatePublicKey, CoordinateSecretKey, TracingPublicKey,
TracingSecretKey, UserId, KMAC_KEY_LENGTH, KMAC_SIG_LENGTH, TAG_LENGTH,
};
Expand Down Expand Up @@ -58,7 +55,7 @@ impl Serializable for CoordinatePublicKey {
fn length(&self) -> usize {
match self {
CoordinatePublicKey::Hybridized { .. } => {
1 + SEED_LENGTH + pke::postquantum::PublicKey::LENGTH
1 + SEED_LENGTH + postquantum::PublicKey::LENGTH
}
CoordinatePublicKey::Classic { .. } => 1 + SEED_LENGTH,
}
Expand Down

0 comments on commit e1e482d

Please sign in to comment.