Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions crates/algorithms/curve25519/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,15 @@ trait Curve25519 {
pub struct X25519;

impl libcrux_traits::kem::arrayref::Kem<DK_LEN, EK_LEN, EK_LEN, SS_LEN, DK_LEN, DK_LEN> for X25519 {
type KeyGenError = libcrux_traits::kem::arrayref::KeyGenError;
type EncapsError = libcrux_traits::kem::arrayref::EncapsError;
type DecapsError = libcrux_traits::kem::arrayref::DecapsError;

fn keygen(
ek: &mut [u8; DK_LEN],
dk: &mut [U8; EK_LEN],
rand: &[U8; DK_LEN],
) -> Result<(), libcrux_traits::kem::arrayref::KeyGenError> {
) -> Result<(), Self::KeyGenError> {
dk.copy_from_slice(rand);
clamp(dk.declassify_ref_mut());
secret_to_public(ek, dk.declassify_ref());
Expand All @@ -52,7 +56,7 @@ impl libcrux_traits::kem::arrayref::Kem<DK_LEN, EK_LEN, EK_LEN, SS_LEN, DK_LEN,
ss: &mut [U8; SS_LEN],
ek: &[u8; EK_LEN],
rand: &[U8; DK_LEN],
) -> Result<(), libcrux_traits::kem::arrayref::EncapsError> {
) -> Result<(), Self::EncapsError> {
let mut eph_dk = *rand;
clamp(eph_dk.declassify_ref_mut());
secret_to_public(ct, eph_dk.declassify_ref());
Expand All @@ -65,7 +69,7 @@ impl libcrux_traits::kem::arrayref::Kem<DK_LEN, EK_LEN, EK_LEN, SS_LEN, DK_LEN,
ss: &mut [U8; SS_LEN],
ct: &[u8; DK_LEN],
dk: &[U8; EK_LEN],
) -> Result<(), libcrux_traits::kem::arrayref::DecapsError> {
) -> Result<(), Self::DecapsError> {
ecdh(ss.declassify_ref_mut(), ct, dk.declassify_ref())
.map_err(|_| libcrux_traits::kem::arrayref::DecapsError::Unknown)
}
Expand Down
10 changes: 7 additions & 3 deletions crates/algorithms/p256/src/impl_kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ const RAND_KEYGEN_LEN: usize = SCALAR_LEN;
const RAND_ENCAPS_LEN: usize = SCALAR_LEN;

impl Kem<EK_LEN, DK_LEN, CT_LEN, SS_LEN, RAND_KEYGEN_LEN, RAND_ENCAPS_LEN> for super::P256 {
type KeyGenError = KeyGenError;
type EncapsError = EncapsError;
type DecapsError = DecapsError;

fn keygen(
ek: &mut [u8; EK_LEN],
dk: &mut [U8; DK_LEN],
rand: &[U8; RAND_KEYGEN_LEN],
) -> Result<(), KeyGenError> {
) -> Result<(), Self::KeyGenError> {
if !super::p256::validate_private_key(rand.as_slice().declassify_ref()) {
return Err(KeyGenError::InvalidRandomness);
}
Expand All @@ -35,7 +39,7 @@ impl Kem<EK_LEN, DK_LEN, CT_LEN, SS_LEN, RAND_KEYGEN_LEN, RAND_ENCAPS_LEN> for s
ss: &mut [U8; SS_LEN],
ek: &[u8; EK_LEN],
rand: &[U8; RAND_ENCAPS_LEN],
) -> Result<(), EncapsError> {
) -> Result<(), Self::EncapsError> {
if !super::p256::validate_public_key(ek) {
return Err(EncapsError::InvalidEncapsKey);
}
Expand All @@ -59,7 +63,7 @@ impl Kem<EK_LEN, DK_LEN, CT_LEN, SS_LEN, RAND_KEYGEN_LEN, RAND_ENCAPS_LEN> for s
ss: &mut [U8; SS_LEN],
ct: &[u8; CT_LEN],
dk: &[U8; DK_LEN],
) -> Result<(), DecapsError> {
) -> Result<(), Self::DecapsError> {
if !super::p256::validate_public_key(ct) {
return Err(DecapsError::InvalidCiphertext);
}
Expand Down
10 changes: 7 additions & 3 deletions libcrux-kem/src/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,10 @@ mod xwing {
RAND_ENCAPS_LEN,
> for XWing
{
type KeyGenError = libcrux_traits::kem::owned::KeyGenError;
type EncapsError = libcrux_traits::kem::owned::EncapsError;
type DecapsError = libcrux_traits::kem::owned::DecapsError;

fn keygen(
ek: &mut [u8; EK_LEN],
dk: &mut [u8; DK_LEN],
Expand All @@ -957,7 +961,7 @@ mod xwing {
let dk_m: &mut [u8; MLKEM768_DK_LEN] = dk_m.try_into().unwrap();
let dk_x: &mut [u8; X25519_DK_LEN] = dk_x.try_into().unwrap();

MlKem768::keygen(ek_m, dk_m, rand_m)?;
MlKem768::keygen(ek_m, dk_m, rand_m).unwrap();
X25519::keygen(ek_x, dk_x, rand_x)?;

Ok(())
Expand Down Expand Up @@ -986,7 +990,7 @@ mod xwing {
hash_buffer[128..134].copy_from_slice(&[0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c]);

let ss_m: &mut [u8; 32] = (&mut hash_buffer[0..32]).try_into().unwrap();
MlKem768::encaps(ct_m, ss_m, ek_m, rand_m)?;
MlKem768::encaps(ct_m, ss_m, ek_m, rand_m).unwrap();

let ss_x: &mut [u8; 32] = (&mut hash_buffer[32..64]).try_into().unwrap();
X25519::encaps(ct_x, ss_x, ek_x, rand_x)?;
Expand Down Expand Up @@ -1018,7 +1022,7 @@ mod xwing {
hash_buffer[128..134].copy_from_slice(&[0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c]);

let ss_m: &mut [u8; 32] = (&mut hash_buffer[0..32]).try_into().unwrap();
MlKem768::decaps(ss_m, ct_m, dk_m)?;
MlKem768::decaps(ss_m, ct_m, dk_m).unwrap();

let ss_x: &mut [u8; 32] = (&mut hash_buffer[32..64]).try_into().unwrap();
X25519::decaps(ss_x, ct_x, dk_x)?;
Expand Down
10 changes: 7 additions & 3 deletions libcrux-ml-kem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,15 @@ macro_rules! impl_kem_trait {
SHARED_SECRET_SIZE,
> for $variant
{
type KeyGenError = core::convert::Infallible;
type EncapsError = core::convert::Infallible;
type DecapsError = core::convert::Infallible;

fn keygen(
ek: &mut [u8; CPA_PKE_PUBLIC_KEY_SIZE],
dk: &mut [u8; SECRET_KEY_SIZE],
rand: &[u8; KEY_GENERATION_SEED_SIZE],
) -> Result<(), libcrux_traits::kem::owned::KeyGenError> {
) -> Result<(), Self::KeyGenError> {
let key_pair = generate_key_pair(*rand);
ek.copy_from_slice(key_pair.pk());
dk.copy_from_slice(key_pair.sk());
Expand All @@ -144,7 +148,7 @@ macro_rules! impl_kem_trait {
ss: &mut [u8; SHARED_SECRET_SIZE],
ek: &[u8; CPA_PKE_PUBLIC_KEY_SIZE],
rand: &[u8; SHARED_SECRET_SIZE],
) -> Result<(), libcrux_traits::kem::owned::EncapsError> {
) -> Result<(), Self::EncapsError> {
let public_key: $pk = ek.into();

let (ct_, ss_) = encapsulate(&public_key, *rand);
Expand All @@ -158,7 +162,7 @@ macro_rules! impl_kem_trait {
ss: &mut [u8; SHARED_SECRET_SIZE],
ct: &[u8; CPA_PKE_CIPHERTEXT_SIZE],
dk: &[u8; SECRET_KEY_SIZE],
) -> Result<(), libcrux_traits::kem::owned::DecapsError> {
) -> Result<(), Self::DecapsError> {
let secret_key: $sk = dk.into();
let ciphertext: $ct = ct.into();

Expand Down
13 changes: 10 additions & 3 deletions traits/src/kem/arrayref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,21 @@ pub trait Kem<
const RAND_ENCAPS_LEN: usize,
>
{
/// Error type for key generation
type KeyGenError: core::fmt::Debug;
/// Error type for encapsulation
type EncapsError: core::fmt::Debug;
/// Error type for decapsulation
type DecapsError: core::fmt::Debug;

/// Generate a pair of encapsulation and decapsulation keys.
/// It is the responsibility of the caller to ensure that the `rand` argument is actually
/// random.
fn keygen(
ek: &mut [u8; EK_LEN],
dk: &mut [U8; DK_LEN],
rand: &[U8; RAND_KEYGEN_LEN],
) -> Result<(), KeyGenError>;
) -> Result<(), Self::KeyGenError>;

/// Encapsulate a shared secret towards a given encapsulation key.
/// It is the responsibility of the caller to ensure that the `rand` argument is actually
Expand All @@ -31,14 +38,14 @@ pub trait Kem<
ss: &mut [U8; SS_LEN],
ek: &[u8; EK_LEN],
rand: &[U8; RAND_ENCAPS_LEN],
) -> Result<(), EncapsError>;
) -> Result<(), Self::EncapsError>;

/// Decapsulate a shared secret.
fn decaps(
ss: &mut [U8; SS_LEN],
ct: &[u8; CT_LEN],
dk: &[U8; DK_LEN],
) -> Result<(), DecapsError>;
) -> Result<(), Self::DecapsError>;
}

/// Error generating key with provided randomness
Expand Down
20 changes: 14 additions & 6 deletions traits/src/kem/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,25 @@ pub trait Kem<
const RAND_ENCAPS_LEN: usize,
>
{
type KeyGenError: core::fmt::Debug;
type EncapsError: core::fmt::Debug;
type DecapsError: core::fmt::Debug;

/// Generate a pair of encapsulation and decapsulation keys.
/// It is the responsibility of the caller to ensure that the `rand` argument is actually
/// random.
fn keygen(rand: &[U8; RAND_KEYGEN_LEN]) -> Result<([U8; DK_LEN], [u8; EK_LEN]), KeyGenError>;
fn keygen(rand: &[U8; RAND_KEYGEN_LEN]) -> Result<([U8; DK_LEN], [u8; EK_LEN]), Self::KeyGenError>;

/// Encapsulate a shared secret towards a given encapsulation key.
/// It is the responsibility of the caller to ensure that the `rand` argument is actually
/// random.
fn encaps(
ek: &[u8; EK_LEN],
rand: &[U8; RAND_ENCAPS_LEN],
) -> Result<([U8; SS_LEN], [u8; CT_LEN]), EncapsError>;
) -> Result<([U8; SS_LEN], [u8; CT_LEN]), Self::EncapsError>;

/// Decapsulate a shared secret.
fn decaps(ct: &[u8; CT_LEN], dk: &[U8; DK_LEN]) -> Result<[U8; SS_LEN], DecapsError>;
fn decaps(ct: &[u8; CT_LEN], dk: &[U8; DK_LEN]) -> Result<[U8; SS_LEN], Self::DecapsError>;
}

impl<
Expand All @@ -45,7 +49,11 @@ impl<
T: arrayref::Kem<EK_LEN, DK_LEN, CT_LEN, SS_LEN, RAND_KEYGEN_LEN, RAND_ENCAPS_LEN>,
> Kem<EK_LEN, DK_LEN, CT_LEN, SS_LEN, RAND_KEYGEN_LEN, RAND_ENCAPS_LEN> for T
{
fn keygen(rand: &[U8; RAND_KEYGEN_LEN]) -> Result<([U8; DK_LEN], [u8; EK_LEN]), KeyGenError> {
type KeyGenError = T::KeyGenError;
type EncapsError = T::EncapsError;
type DecapsError = T::DecapsError;

fn keygen(rand: &[U8; RAND_KEYGEN_LEN]) -> Result<([U8; DK_LEN], [u8; EK_LEN]), Self::KeyGenError> {
let mut dk = [0u8.classify(); DK_LEN];
let mut ek = [0u8; EK_LEN];

Expand All @@ -64,7 +72,7 @@ impl<
fn encaps(
ek: &[u8; EK_LEN],
rand: &[U8; RAND_ENCAPS_LEN],
) -> Result<([U8; SS_LEN], [u8; CT_LEN]), EncapsError> {
) -> Result<([U8; SS_LEN], [u8; CT_LEN]), Self::EncapsError> {
let mut ss = [0u8.classify(); SS_LEN];
let mut ct = [0u8; CT_LEN];

Expand All @@ -80,7 +88,7 @@ impl<
Ok((ss, ct))
}

fn decaps(ct: &[u8; CT_LEN], dk: &[U8; DK_LEN]) -> Result<[U8; SS_LEN], DecapsError> {
fn decaps(ct: &[u8; CT_LEN], dk: &[U8; DK_LEN]) -> Result<[U8; SS_LEN], Self::DecapsError> {
let mut ss = [0u8.classify(); SS_LEN];

<Self as arrayref::Kem<
Expand Down
32 changes: 23 additions & 9 deletions traits/src/kem/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,25 @@ use super::arrayref;

/// A Key Encapsulation Mechanismd (KEM). This trait takes slices as arguments.
pub trait Kem {
/// Error type for key generation
type KeyGenError: core::fmt::Debug;
/// Error type for encapsulation
type EncapsError: core::fmt::Debug;
/// Error type for decapsulation
type DecapsError: core::fmt::Debug;

/// Generate a pair of encapsulation and decapsulation keys.
/// It is the responsibility of the caller to ensure that the `rand` argument is actually
/// random.
fn keygen(ek: &mut [u8], dk: &mut [U8], rand: &[U8]) -> Result<(), KeyGenError>;
fn keygen(ek: &mut [u8], dk: &mut [U8], rand: &[U8]) -> Result<(), Self::KeyGenError>;

/// Encapsulate a shared secret towards a given encapsulation key.
/// It is the responsibility of the caller to ensure that the `rand` argument is actually
/// random.
fn encaps(ct: &mut [u8], ss: &mut [U8], ek: &[u8], rand: &[U8]) -> Result<(), EncapsError>;
fn encaps(ct: &mut [u8], ss: &mut [U8], ek: &[u8], rand: &[U8]) -> Result<(), Self::EncapsError>;

/// Decapsulate a shared secret.
fn decaps(ss: &mut [U8], ct: &[u8], dk: &[U8]) -> Result<(), DecapsError>;
fn decaps(ss: &mut [U8], ct: &[u8], dk: &[U8]) -> Result<(), Self::DecapsError>;
}

/// Error generating key with provided randomness
Expand Down Expand Up @@ -106,7 +113,11 @@ impl From<arrayref::DecapsError> for DecapsError {
macro_rules! impl_trait {
($type:ty => $ek:expr, $dk:expr, $ct:expr, $ss:expr, $rand_kg:expr, $rand_encaps:expr) => {
impl $crate::kem::slice::Kem for $type {
fn keygen(ek: &mut [u8], dk: &mut [$crate::libcrux_secrets::U8], rand: &[$crate::libcrux_secrets::U8]) -> Result<(), $crate::kem::slice::KeyGenError> {
type KeyGenError = $crate::kem::slice::KeyGenError;
type EncapsError = $crate::kem::slice::EncapsError;
type DecapsError = $crate::kem::slice::DecapsError;

fn keygen(ek: &mut [u8], dk: &mut [$crate::libcrux_secrets::U8], rand: &[$crate::libcrux_secrets::U8]) -> Result<(), Self::KeyGenError> {
let ek : &mut [u8; $ek] = ek
.try_into()
.map_err(|_| $crate::kem::slice::KeyGenError::InvalidEncapsKeyLength)?;
Expand All @@ -117,10 +128,11 @@ macro_rules! impl_trait {
.try_into()
.map_err(|_| $crate::kem::slice::KeyGenError::InvalidRandomnessLength)?;

<$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::keygen(ek, dk, rand).map_err($crate::kem::slice::KeyGenError::from)
<$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::keygen(ek, dk, rand)
.map_err(|_| $crate::kem::slice::KeyGenError::Unknown)
}

fn encaps(ct: &mut [u8], ss: &mut [$crate::libcrux_secrets::U8], ek: &[u8], rand: &[$crate::libcrux_secrets::U8]) -> Result<(), $crate::kem::slice::EncapsError>{
fn encaps(ct: &mut [u8], ss: &mut [$crate::libcrux_secrets::U8], ek: &[u8], rand: &[$crate::libcrux_secrets::U8]) -> Result<(), Self::EncapsError>{
let ct : &mut [u8; $ct] = ct
.try_into()
.map_err(|_| $crate::kem::slice::EncapsError::InvalidCiphertextLength)?;
Expand All @@ -135,10 +147,11 @@ macro_rules! impl_trait {
.map_err(|_| $crate::kem::slice::EncapsError::InvalidRandomnessLength)?;


<$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::encaps(ct, ss, ek,rand).map_err($crate::kem::slice::EncapsError::from)
<$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::encaps(ct, ss, ek,rand)
.map_err(|_| $crate::kem::slice::EncapsError::Unknown)
}

fn decaps(ss: &mut [$crate::libcrux_secrets::U8], ct: &[u8], dk: &[$crate::libcrux_secrets::U8]) -> Result<(), $crate::kem::slice::DecapsError> {
fn decaps(ss: &mut [$crate::libcrux_secrets::U8], ct: &[u8], dk: &[$crate::libcrux_secrets::U8]) -> Result<(), Self::DecapsError> {
let ss : &mut [$crate::libcrux_secrets::U8; $ss] = ss
.try_into()
.map_err(|_| $crate::kem::slice::DecapsError::InvalidSharedSecretLength)?;
Expand All @@ -149,7 +162,8 @@ macro_rules! impl_trait {
.try_into()
.map_err(|_| $crate::kem::slice::DecapsError::InvalidDecapsKeyLength)?;

<$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::decaps(ss, ct, dk).map_err($crate::kem::slice::DecapsError::from)
<$type as $crate::kem::arrayref::Kem<$ek, $dk, $ct, $ss, $rand_kg, $rand_encaps>>::decaps(ss, ct, dk)
.map_err(|_| $crate::kem::slice::DecapsError::Unknown)
}

}
Expand Down