Skip to content

Commit

Permalink
put the ml-kem unpacked API behind a feature
Browse files Browse the repository at this point in the history
  • Loading branch information
franziskuskiefer committed Aug 21, 2024
1 parent 5ca2e45 commit 72ab012
Show file tree
Hide file tree
Showing 16 changed files with 139 additions and 48 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/mlkem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,11 @@ jobs:
rustc --print=cfg
cargo build --verbose $RUST_TARGET_FLAG --features pre-verification
- name: 🔨 Build unpacked
run: |
rustc --print=cfg
cargo build --verbose $RUST_TARGET_FLAG --features pre-verification,unpacked
- name: 🔨 Build Release
run: cargo build --verbose --release $RUST_TARGET_FLAG --features pre-verification

Expand Down
7 changes: 5 additions & 2 deletions libcrux-ml-kem/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,17 @@ default = ["std", "mlkem512", "mlkem768", "mlkem1024"]
# Hardware features can be force enabled.
# It is not recommended to use these. This crate performs CPU feature detection
# and enables the features when they are available.
simd128 = ["libcrux-sha3/simd128","libcrux-intrinsics/simd128"]
simd256 = ["libcrux-sha3/simd256","libcrux-intrinsics/simd256"]
simd128 = ["libcrux-sha3/simd128", "libcrux-intrinsics/simd128"]
simd256 = ["libcrux-sha3/simd256", "libcrux-intrinsics/simd256"]

# Features for the different key sizes of ML-KEM
mlkem512 = []
mlkem768 = []
mlkem1024 = []

# Enable the unpacked API
unpacked = []

# Enable Round 3 Kyber in addition to ML-KEM
kyber = []

Expand Down
21 changes: 21 additions & 0 deletions libcrux-ml-kem/c-nss.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env bash

set -e
set -o pipefail

./c.sh --mlkem768

if [[ -n "$NSS_HOME" ]]; then
files=(libcrux_core.c libcrux_core.h libcrux_mlkem768.h libcrux_mlkem768_portable.c libcrux_mlkem768_portable.h libcrux_mlkem_portable.c libcrux_mlkem_portable.h libcrux_sha3.h libcrux_sha3_internal.h)
echo "copying ..."
for file in "${files[@]}"; do
echo " c/$file"
cp c/$file $NSS_HOME/lib/freebl/verified/
done

internal_files=(libcrux_core.h libcrux_mlkem_portable.h libcrux_sha3_internal.h)
for file in "${internal_files[@]}"; do
echo " c/internal/$file"
cp c/internal/$file $NSS_HOME/lib/freebl/verified/internal/
done
fi
1 change: 1 addition & 0 deletions libcrux-ml-kem/c.sh
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ while [ $# -gt 0 ]; do
--glue) glue="$2"; shift ;;
--mlkem768) features="${features} --cargo-arg=--no-default-features --cargo-arg=--features=mlkem768" ;;
--kyber768) features="${features} --cargo-arg=--features=kyber" ;;
--unpacked) features="${features} --cargo-arg=--features=unpacked" ;;
--no-glue) eurydice_glue=0 ;;
--no-karamel_include) karamel_include=0 ;;
--no-unrolling) unrolling=0 ;;
Expand Down
2 changes: 2 additions & 0 deletions libcrux-ml-kem/src/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ macro_rules! cfg_pre_verification {
($($item:item)*) => {
$(
#[cfg(feature = "pre-verification")]
#[cfg_attr(docsrs, doc(cfg(feature = "pre-verification")))]
$item
)*
}
Expand All @@ -26,6 +27,7 @@ macro_rules! cfg_kyber {
($($item:item)*) => {
$(
#[cfg(feature = "kyber")]
#[cfg_attr(docsrs, doc(cfg(feature = "kyber")))]
$item
)*
}
Expand Down
1 change: 1 addition & 0 deletions libcrux-ml-kem/src/hash_functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ pub(crate) mod avx2 {
}

/// A SIMD128 implementation of [`Hash`] for NEON
#[cfg(feature = "simd128")]
pub(crate) mod neon {
use super::*;
use libcrux_sha3::neon::x2::{self, incremental::KeccakState};
Expand Down
19 changes: 13 additions & 6 deletions libcrux-ml-kem/src/ind_cca.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
use crate::{
constant_time_ops::{
compare_ciphertexts_in_constant_time,
compare_ciphertexts_select_shared_secret_in_constant_time,
select_shared_secret_in_constant_time,
},
constant_time_ops::compare_ciphertexts_select_shared_secret_in_constant_time,
constants::{CPA_PKE_KEY_GENERATION_SEED_SIZE, H_DIGEST_SIZE, SHARED_SECRET_SIZE},
hash_functions::Hash,
ind_cpa::serialize_public_key,
polynomial::PolynomialRingElement,
serialize::deserialize_ring_elements_reduced,
types::*,
utils::into_padded_array,
variant::*,
vector::Operations,
};
#[cfg(feature = "unpacked")]
use crate::{
constant_time_ops::{
compare_ciphertexts_in_constant_time, select_shared_secret_in_constant_time,
},
polynomial::PolynomialRingElement,
};

/// Types for the unpacked API.
#[cfg(feature = "unpacked")]
pub mod unpacked {
use crate::{ind_cpa::unpacked::*, vector::traits::Operations};

Expand All @@ -37,6 +40,7 @@ pub mod unpacked {
pub public_key: MlKemPublicKeyUnpacked<K, Vector>,
}
}
#[cfg(feature = "unpacked")]
use unpacked::*;

/// Seed size for key generation
Expand Down Expand Up @@ -279,6 +283,7 @@ pub(crate) fn decapsulate<

// Unpacked API
// Generate Unpacked Keys
#[cfg(feature = "unpacked")]
pub(crate) fn generate_keypair_unpacked<
const K: usize,
const CPA_PRIVATE_KEY_SIZE: usize,
Expand Down Expand Up @@ -338,6 +343,7 @@ pub(crate) fn generate_keypair_unpacked<
}

// Encapsulate with Unpacked Public Key
#[cfg(feature = "unpacked")]
pub(crate) fn encapsulate_unpacked<
const K: usize,
const CIPHERTEXT_SIZE: usize,
Expand Down Expand Up @@ -386,6 +392,7 @@ pub(crate) fn encapsulate_unpacked<
}

// Decapsulate with Unpacked Private Key
#[cfg(feature = "unpacked")]
pub(crate) fn decapsulate_unpacked<
const K: usize,
const SECRET_KEY_SIZE: usize,
Expand Down
7 changes: 6 additions & 1 deletion libcrux-ml-kem/src/ind_cca/instantiations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ macro_rules! instantiate {
KEY_GENERATION_SEED_SIZE, SHARED_SECRET_SIZE,
};

#[cfg(feature = "unpacked")]
pub(crate) type MlKemKeyPairUnpacked<const K: usize> =
crate::ind_cca::unpacked::MlKemKeyPairUnpacked<K, $vector>;
#[cfg(feature = "unpacked")]
pub(crate) type MlKemPublicKeyUnpacked<const K: usize> =
crate::ind_cca::unpacked::MlKemPublicKeyUnpacked<K, $vector>;

Expand Down Expand Up @@ -249,6 +251,7 @@ macro_rules! instantiate {
}

/// Unpacked API
#[cfg(feature = "unpacked")]
pub(crate) fn generate_keypair_unpacked<
const K: usize,
const CPA_PRIVATE_KEY_SIZE: usize,
Expand All @@ -274,6 +277,7 @@ macro_rules! instantiate {
}

/// Portable encapsualte
#[cfg(feature = "unpacked")]
pub(crate) fn encapsulate_unpacked<
const K: usize,
const CIPHERTEXT_SIZE: usize,
Expand Down Expand Up @@ -312,7 +316,8 @@ macro_rules! instantiate {
}

/// Portable decapsulate
pub fn decapsulate_unpacked<
#[cfg(feature = "unpacked")]
pub(crate) fn decapsulate_unpacked<
const K: usize,
const SECRET_KEY_SIZE: usize,
const CPA_SECRET_KEY_SIZE: usize,
Expand Down
10 changes: 7 additions & 3 deletions libcrux-ml-kem/src/ind_cpa.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#[cfg(feature = "unpacked")]
use crate::variant::MlKem;
use crate::{
constants::{BYTES_PER_RING_ELEMENT, COEFFICIENTS_IN_RING_ELEMENT, SHARED_SECRET_SIZE},
hash_functions::Hash,
Expand All @@ -14,12 +16,12 @@ use crate::{
serialize_uncompressed_ring_element,
},
utils::into_padded_array,
variant::{MlKem, Variant},
variant::Variant,
vector::Operations,
};

#[allow(non_snake_case)]
/// Types for the unpacked API.
#[allow(non_snake_case)]
pub mod unpacked {
use crate::{polynomial::PolynomialRingElement, vector::traits::Operations};

Expand All @@ -29,13 +31,13 @@ pub mod unpacked {
}

/// An unpacked ML-KEM IND-CPA Private Key
#[cfg(feature = "unpacked")]
pub(crate) struct IndCpaPublicKeyUnpacked<const K: usize, Vector: Operations> {
pub(crate) t_as_ntt: [PolynomialRingElement<Vector>; K],
pub(crate) seed_for_A: [u8; 32],
pub(crate) A: [[PolynomialRingElement<Vector>; K]; K],
}
}

use unpacked::*;

/// Concatenate `t` and `ρ` into the public key.
Expand Down Expand Up @@ -165,6 +167,7 @@ fn sample_vector_cbd_then_ntt<
/// The NIST FIPS 203 standard can be found at
/// <https://csrc.nist.gov/pubs/fips/203/ipd>.
#[allow(non_snake_case)]
#[cfg(feature = "unpacked")]
pub(crate) fn generate_keypair_unpacked<
const K: usize,
const ETA1: usize,
Expand Down Expand Up @@ -321,6 +324,7 @@ fn compress_then_serialize_u<
/// The NIST FIPS 203 standard can be found at
/// <https://csrc.nist.gov/pubs/fips/203/ipd>.
#[allow(non_snake_case)]
#[cfg(feature = "unpacked")]
pub(crate) fn encrypt_unpacked<
const K: usize,
const CIPHERTEXT_SIZE: usize,
Expand Down
22 changes: 14 additions & 8 deletions libcrux-ml-kem/src/mlkem1024.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
//! ML-KEM 1024

use super::{
constants::*,
ind_cca::{unpacked::*, *},
types::*,
vector::traits::VectorType,
*,
};
use super::{constants::*, ind_cca::*, types::*, *};
#[cfg(feature = "unpacked")]
use super::{ind_cca::unpacked::*, vector::traits::VectorType};

// Kyber 1024 parameters
const RANK_1024: usize = 4;
Expand Down Expand Up @@ -53,9 +48,11 @@ pub type MlKem1024KeyPair = MlKemKeyPair<SECRET_KEY_SIZE_1024, CPA_PKE_PUBLIC_KE

/// An Unpacked ML-KEM 1024 Public key
#[allow(type_alias_bounds)]
#[cfg(feature = "unpacked")]
pub type MlKem1024PublicKeyUnpacked<Vector: VectorType> = MlKemPublicKeyUnpacked<RANK_1024, Vector>;
/// Am Unpacked ML-KEM 1024 Key pair
#[allow(type_alias_bounds)]
#[cfg(feature = "unpacked")]
pub type MlKem1024KeyPairUnpacked<Vector: VectorType> = MlKemKeyPairUnpacked<RANK_1024, Vector>;

// Instantiate the different functions.
Expand Down Expand Up @@ -86,6 +83,7 @@ macro_rules! instantiate {

/// Generate Kyber 1024 Key Pair
#[cfg(feature = "kyber")]
#[cfg_attr(docsrs, doc(cfg(feature = "kyber")))]
pub fn kyber_generate_key_pair(
randomness: [u8; KEY_GENERATION_SEED_SIZE],
) -> MlKem1024KeyPair {
Expand Down Expand Up @@ -147,6 +145,7 @@ macro_rules! instantiate {
/// The input is a reference to an [`MlKem1024PublicKey`] and [`SHARED_SECRET_SIZE`]
/// bytes of `randomness`.
#[cfg(feature = "kyber")]
#[cfg_attr(docsrs, doc(cfg(feature = "kyber")))]
pub fn kyber_encapsulate(
public_key: &MlKem1024PublicKey,
randomness: [u8; SHARED_SECRET_SIZE],
Expand Down Expand Up @@ -201,6 +200,7 @@ macro_rules! instantiate {
/// Generates an [`MlKemSharedSecret`].
/// The input is a reference to an [`MlKem1024PrivateKey`] and an [`MlKem1024Ciphertext`].
#[cfg(feature = "kyber")]
#[cfg_attr(docsrs, doc(cfg(feature = "kyber")))]
pub fn kyber_decapsulate(
private_key: &MlKem1024PrivateKey,
ciphertext: &MlKem1024Ciphertext,
Expand All @@ -226,6 +226,8 @@ macro_rules! instantiate {
}

/// Generate ML-KEM 1024 Key Pair in "unpacked" form
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub fn generate_key_pair_unpacked(
randomness: [u8; KEY_GENERATION_SEED_SIZE],
) -> MlKem1024KeyPairUnpacked<$vec> {
Expand Down Expand Up @@ -260,6 +262,8 @@ let _ =
()"
)
)]
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub fn encapsulate_unpacked(
public_key: &MlKem1024PublicKeyUnpacked<$vec>,
randomness: [u8; SHARED_SECRET_SIZE],
Expand All @@ -286,6 +290,8 @@ let _ =
/// Generates an [`MlKemSharedSecret`].
/// The input is a reference to an unpacked key pair of type [`MlKem1024KeyPairUnpacked`]
/// and an [`MlKem1024Ciphertext`].
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub fn decapsulate_unpacked(
private_key: &MlKem1024KeyPairUnpacked<$vec>,
ciphertext: &MlKem1024Ciphertext,
Expand Down
23 changes: 16 additions & 7 deletions libcrux-ml-kem/src/mlkem512.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
//! ML-KEM 512
use super::{
constants::*,
ind_cca::{unpacked::*, *},
types::*,
vector::traits::VectorType,
*,
};
use super::{constants::*, ind_cca::*, types::*, *};
#[cfg(feature = "unpacked")]
use super::{ind_cca::unpacked::*, vector::traits::VectorType};

// Kyber 512 parameters
const RANK_512: usize = 2;
Expand Down Expand Up @@ -50,9 +46,13 @@ pub type MlKem512KeyPair = MlKemKeyPair<SECRET_KEY_SIZE_512, CPA_PKE_PUBLIC_KEY_

/// An Unpacked ML-KEM 512 Public key
#[allow(type_alias_bounds)]
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub type MlKem512PublicKeyUnpacked<Vector: VectorType> = MlKemPublicKeyUnpacked<RANK_512, Vector>;
/// Am Unpacked ML-KEM 512 Key pair
#[allow(type_alias_bounds)]
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub type MlKem512KeyPairUnpacked<Vector: VectorType> = MlKemKeyPairUnpacked<RANK_512, Vector>;

// Instantiate the different functions.
Expand Down Expand Up @@ -96,6 +96,7 @@ macro_rules! instantiate {

/// Generate Kyber 512 Key Pair
#[cfg(feature = "kyber")]
#[cfg_attr(docsrs, doc(cfg(feature = "kyber")))]
pub fn kyber_generate_key_pair(
randomness: [u8; KEY_GENERATION_SEED_SIZE],
) -> MlKem512KeyPair {
Expand Down Expand Up @@ -141,6 +142,7 @@ macro_rules! instantiate {
/// The input is a reference to an [`MlKem512PublicKey`] and [`SHARED_SECRET_SIZE`]
/// bytes of `randomness`.
#[cfg(feature = "kyber")]
#[cfg_attr(docsrs, doc(cfg(feature = "kyber")))]
pub fn kyber_encapsulate(
public_key: &MlKem512PublicKey,
randomness: [u8; SHARED_SECRET_SIZE],
Expand Down Expand Up @@ -195,6 +197,7 @@ macro_rules! instantiate {
/// Generates an [`MlKemSharedSecret`].
/// The input is a reference to an [`MlKem512PrivateKey`] and an [`MlKem512Ciphertext`].
#[cfg(feature = "kyber")]
#[cfg_attr(docsrs, doc(cfg(feature = "kyber")))]
pub fn kyber_decapsulate(
private_key: &MlKem512PrivateKey,
ciphertext: &MlKem512Ciphertext,
Expand All @@ -220,6 +223,8 @@ macro_rules! instantiate {
}

/// Generate ML-KEM 512 Key Pair in "unpacked" form
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub fn generate_key_pair_unpacked(
randomness: [u8; KEY_GENERATION_SEED_SIZE],
) -> MlKem512KeyPairUnpacked<$vec> {
Expand Down Expand Up @@ -252,6 +257,8 @@ let _ =
()"
)
)]
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub fn encapsulate_unpacked(
public_key: &MlKem512PublicKeyUnpacked<$vec>,
randomness: [u8; SHARED_SECRET_SIZE],
Expand All @@ -278,6 +285,8 @@ let _ =
/// Generates an [`MlKemSharedSecret`].
/// The input is a reference to an unpacked key pair of type [`MlKem512KeyPairUnpacked`]
/// and an [`MlKem512Ciphertext`].
#[cfg(feature = "unpacked")]
#[cfg_attr(docsrs, doc(cfg(feature = "unpacked")))]
pub fn decapsulate_unpacked(
private_key: &MlKem512KeyPairUnpacked<$vec>,
ciphertext: &MlKem512Ciphertext,
Expand Down
Loading

0 comments on commit 72ab012

Please sign in to comment.