Skip to content

Commit

Permalink
Stabilize ML-KEM; bump to v1.12.0
Browse files Browse the repository at this point in the history
  • Loading branch information
justsmth committed Dec 12, 2024
1 parent 3e83854 commit f8c16e3
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 131 deletions.
4 changes: 2 additions & 2 deletions aws-lc-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "aws-lc-rs"
authors = ["AWS-LibCrypto"]
version = "1.11.1"
version = "1.12.0"
# this crate re-exports whatever sys crate that was selected
links = "aws_lc_rs_1_11_1_sys"
links = "aws_lc_rs_1_12_0_sys"
edition = "2021"
rust-version = "1.63.0"
keywords = ["crypto", "cryptography", "security"]
Expand Down
12 changes: 5 additions & 7 deletions aws-lc-rs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ test:
cargo test --all-targets --features unstable
cargo test --release --all-targets
cargo test --release --all-targets --features bindgen,unstable
ifeq ($(UNAME_S),Linux)
cargo test --release --all-targets --features fips,unstable
cargo test --no-default-features --features fips,unstable
endif
cargo test --no-default-features --features aws-lc-sys,unstable
cargo test --no-default-features --features aws-lc-sys,ring-sig-verify,unstable
cargo test --no-default-features --features aws-lc-sys,ring-io,unstable
cargo test --no-default-features --features aws-lc-sys,alloc,unstable
cargo test --no-default-features --all-targets --features fips,unstable
cargo test --no-default-features --all-targets --features aws-lc-sys,unstable
cargo test --no-default-features --all-targets --features aws-lc-sys,ring-sig-verify,unstable
cargo test --no-default-features --all-targets --features aws-lc-sys,ring-io,unstable
cargo test --no-default-features --all-targets --features aws-lc-sys,alloc,unstable

msrv:
cargo msrv verify
Expand Down
114 changes: 42 additions & 72 deletions aws-lc-rs/src/kem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! ```ignore
//! use aws_lc_rs::{
//! kem::{Ciphertext, DecapsulationKey, EncapsulationKey},
//! unstable::kem::{ML_KEM_512}
//! kem::{ML_KEM_512}
//! };
//!
//! // Alice generates their (private) decapsulation key.
Expand Down Expand Up @@ -60,65 +60,48 @@ use aws_lc::{
use core::{cmp::Ordering, ptr::null_mut};
use zeroize::Zeroize;

#[cfg(not(feature = "fips"))]
pub(crate) mod semistable {
#![allow(unused)]

use super::{Algorithm, AlgorithmId};

const ML_KEM_512_SHARED_SECRET_LENGTH: usize = 32;
const ML_KEM_512_PUBLIC_KEY_LENGTH: usize = 800;
const ML_KEM_512_SECRET_KEY_LENGTH: usize = 1632;
const ML_KEM_512_CIPHERTEXT_LENGTH: usize = 768;

const ML_KEM_768_SHARED_SECRET_LENGTH: usize = 32;
const ML_KEM_768_PUBLIC_KEY_LENGTH: usize = 1184;
const ML_KEM_768_SECRET_KEY_LENGTH: usize = 2400;
const ML_KEM_768_CIPHERTEXT_LENGTH: usize = 1088;

const ML_KEM_1024_SHARED_SECRET_LENGTH: usize = 32;
const ML_KEM_1024_PUBLIC_KEY_LENGTH: usize = 1568;
const ML_KEM_1024_SECRET_KEY_LENGTH: usize = 3168;
const ML_KEM_1024_CIPHERTEXT_LENGTH: usize = 1568;

/// NIST FIPS 203 ML-KEM-512 algorithm.
pub const ML_KEM_512: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::MlKem512,
decapsulate_key_size: ML_KEM_512_SECRET_KEY_LENGTH,
encapsulate_key_size: ML_KEM_512_PUBLIC_KEY_LENGTH,
ciphertext_size: ML_KEM_512_CIPHERTEXT_LENGTH,
shared_secret_size: ML_KEM_512_SHARED_SECRET_LENGTH,
};

/// NIST FIPS 203 ML-KEM-768 algorithm.
pub const ML_KEM_768: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::MlKem768,
decapsulate_key_size: ML_KEM_768_SECRET_KEY_LENGTH,
encapsulate_key_size: ML_KEM_768_PUBLIC_KEY_LENGTH,
ciphertext_size: ML_KEM_768_CIPHERTEXT_LENGTH,
shared_secret_size: ML_KEM_768_SHARED_SECRET_LENGTH,
};
const ML_KEM_512_SHARED_SECRET_LENGTH: usize = 32;
const ML_KEM_512_PUBLIC_KEY_LENGTH: usize = 800;
const ML_KEM_512_SECRET_KEY_LENGTH: usize = 1632;
const ML_KEM_512_CIPHERTEXT_LENGTH: usize = 768;

const ML_KEM_768_SHARED_SECRET_LENGTH: usize = 32;
const ML_KEM_768_PUBLIC_KEY_LENGTH: usize = 1184;
const ML_KEM_768_SECRET_KEY_LENGTH: usize = 2400;
const ML_KEM_768_CIPHERTEXT_LENGTH: usize = 1088;

const ML_KEM_1024_SHARED_SECRET_LENGTH: usize = 32;
const ML_KEM_1024_PUBLIC_KEY_LENGTH: usize = 1568;
const ML_KEM_1024_SECRET_KEY_LENGTH: usize = 3168;
const ML_KEM_1024_CIPHERTEXT_LENGTH: usize = 1568;

/// NIST FIPS 203 ML-KEM-512 algorithm.
pub const ML_KEM_512: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::MlKem512,
decapsulate_key_size: ML_KEM_512_SECRET_KEY_LENGTH,
encapsulate_key_size: ML_KEM_512_PUBLIC_KEY_LENGTH,
ciphertext_size: ML_KEM_512_CIPHERTEXT_LENGTH,
shared_secret_size: ML_KEM_512_SHARED_SECRET_LENGTH,
};

/// NIST FIPS 203 ML-KEM-1024 algorithm.
pub const ML_KEM_1024: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::MlKem1024,
decapsulate_key_size: ML_KEM_1024_SECRET_KEY_LENGTH,
encapsulate_key_size: ML_KEM_1024_PUBLIC_KEY_LENGTH,
ciphertext_size: ML_KEM_1024_CIPHERTEXT_LENGTH,
shared_secret_size: ML_KEM_1024_SHARED_SECRET_LENGTH,
};
}
/// NIST FIPS 203 ML-KEM-768 algorithm.
pub const ML_KEM_768: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::MlKem768,
decapsulate_key_size: ML_KEM_768_SECRET_KEY_LENGTH,
encapsulate_key_size: ML_KEM_768_PUBLIC_KEY_LENGTH,
ciphertext_size: ML_KEM_768_CIPHERTEXT_LENGTH,
shared_secret_size: ML_KEM_768_SHARED_SECRET_LENGTH,
};

#[cfg(feature = "fips")]
mod missing_nid {
pub const NID_MLKEM512: i32 = 988;
pub const NID_MLKEM768: i32 = 989;
pub const NID_MLKEM1024: i32 = 990;
}
/// NIST FIPS 203 ML-KEM-1024 algorithm.
pub const ML_KEM_1024: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::MlKem1024,
decapsulate_key_size: ML_KEM_1024_SECRET_KEY_LENGTH,
encapsulate_key_size: ML_KEM_1024_PUBLIC_KEY_LENGTH,
ciphertext_size: ML_KEM_1024_CIPHERTEXT_LENGTH,
shared_secret_size: ML_KEM_1024_SHARED_SECRET_LENGTH,
};

#[cfg(feature = "fips")]
use self::missing_nid::{NID_MLKEM1024, NID_MLKEM512, NID_MLKEM768};
#[cfg(not(feature = "fips"))]
use aws_lc::{NID_MLKEM1024, NID_MLKEM512, NID_MLKEM768};

/// An identifier for a KEM algorithm.
Expand Down Expand Up @@ -192,9 +175,6 @@ where
}

/// Identifier for a KEM algorithm.
///
/// See [`crate::unstable::kem::AlgorithmId`] and [`crate::unstable::kem::get_algorithm`] for
/// access to algorithms not subject to semantic versioning guarantees.
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AlgorithmId {
Expand Down Expand Up @@ -529,15 +509,10 @@ fn kem_key_generate(nid: i32) -> Result<LcPtr<EVP_PKEY>, Unspecified> {
#[cfg(test)]
mod tests {
use super::{Ciphertext, SharedSecret};

#[cfg(not(feature = "fips"))]
use crate::error::KeyRejected;

#[cfg(not(feature = "fips"))]
use super::{DecapsulationKey, EncapsulationKey};
use crate::error::KeyRejected;

#[cfg(not(feature = "fips"))]
use crate::kem::semistable::{ML_KEM_1024, ML_KEM_512, ML_KEM_768};
use crate::kem::{ML_KEM_1024, ML_KEM_512, ML_KEM_768};

#[test]
fn ciphertext() {
Expand All @@ -559,7 +534,6 @@ mod tests {
}

#[test]
#[cfg(not(feature = "fips"))]
fn test_kem_serialize() {
for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] {
let priv_key = DecapsulationKey::generate(algorithm).unwrap();
Expand All @@ -579,7 +553,6 @@ mod tests {
}

#[test]
#[cfg(not(feature = "fips"))]
fn test_kem_wrong_sizes() {
for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] {
let too_long_bytes = vec![0u8; algorithm.encapsulate_key_size() + 1];
Expand All @@ -599,7 +572,6 @@ mod tests {
}

#[test]
#[cfg(not(feature = "fips"))]
fn test_kem_e2e() {
for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] {
let priv_key = DecapsulationKey::generate(algorithm).unwrap();
Expand All @@ -619,7 +591,6 @@ mod tests {
}

#[test]
#[cfg(not(feature = "fips"))]
fn test_serialized_kem_e2e() {
for algorithm in [&ML_KEM_512, &ML_KEM_768, &ML_KEM_1024] {
let priv_key = DecapsulationKey::generate(algorithm).unwrap();
Expand Down Expand Up @@ -648,7 +619,6 @@ mod tests {
}

#[test]
#[cfg(not(feature = "fips"))]
fn test_debug_fmt() {
let private = DecapsulationKey::generate(&ML_KEM_512).expect("successful generation");
assert_eq!(
Expand Down
57 changes: 7 additions & 50 deletions aws-lc-rs/src/unstable/kem.rs
Original file line number Diff line number Diff line change
@@ -1,58 +1,14 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR ISC

//! Unstable KEM Algorithms for usage with the [`crate::kem`] module.
//!
//! # ⚠️ Warning
//! Algorithms contained in this module are subject to changes, relocation,
//! or removal across minor releases, and thus are not subject to semantic versioning policies.
//!
//! # Example
//!
//! ```ignore
//! use aws_lc_rs::{
//! kem::{Ciphertext, DecapsulationKey, EncapsulationKey},
//! unstable::kem::{ML_KEM_512}
//! };
//!
//! // Alice generates their (private) decapsulation key.
//! let decapsulation_key = DecapsulationKey::generate(&ML_KEM_512)?;
//!
//! // Alices computes the (public) encapsulation key.
//! let encapsulation_key = decapsulation_key.encapsulation_key()?;
//!
//! let encapsulation_key_bytes = encapsulation_key.key_bytes()?;
//!
//! // Alice sends the encapsulation key bytes to bob through some
//! // protocol message.
//! let encapsulation_key_bytes = encapsulation_key_bytes.as_ref();
//!
//! // Bob constructs the (public) encapsulation key from the key bytes provided by Alice.
//! let retrieved_encapsulation_key = EncapsulationKey::new(&ML_KEM_512, encapsulation_key_bytes)?;
//!
//! // Bob executes the encapsulation algorithm to to produce their copy of the secret, and associated ciphertext.
//! let (ciphertext, bob_secret) = retrieved_encapsulation_key.encapsulate()?;
//!
//! // Alice receives ciphertext bytes from bob
//! let ciphertext_bytes = ciphertext.as_ref();
//!
//! // Bob sends Alice the ciphertext computed from the encapsulation algorithm, Alice runs decapsulation to derive their
//! // copy of the secret.
//! let alice_secret = decapsulation_key.decapsulate(Ciphertext::from(ciphertext_bytes))?;
//!
//! // Alice and Bob have now arrived to the same secret
//! assert_eq!(alice_secret.as_ref(), bob_secret.as_ref());
//!
//! # Ok::<(), aws_lc_rs::error::Unspecified>(())
//! ```
#![allow(deprecated)]
use core::fmt::Debug;

use crate::kem::Algorithm;
use aws_lc::{NID_KYBER1024_R3, NID_KYBER512_R3, NID_KYBER768_R3};

#[cfg(not(feature = "fips"))]
pub use crate::kem::semistable::{ML_KEM_1024, ML_KEM_512, ML_KEM_768};
#[deprecated(note = "use aws_lc_rs::kem::{ML_KEM_512, ML_KEM_768, ML_KEM_1024}")]
pub use crate::kem::{ML_KEM_1024, ML_KEM_512, ML_KEM_768};

// Key lengths defined as stated on the CRYSTALS website:
// https://pq-crystals.org/kyber/
Expand Down Expand Up @@ -108,15 +64,15 @@ const KYBER1024_R3: Algorithm<AlgorithmId> = Algorithm {
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AlgorithmId {
/// NIST Round 3 submission of the Kyber-512 algorithm.
#[deprecated]
#[deprecated(note = "use aws_lc_rs:kem::ML_KEM_512")]
Kyber512_R3,

/// NIST Round 3 submission of the Kyber-768 algorithm.
#[deprecated]
#[deprecated(note = "use aws_lc_rs:kem::ML_KEM_768")]
Kyber768_R3,

/// NIST Round 3 submission of the Kyber-1024 algorithm.
#[deprecated]
#[deprecated(note = "use aws_lc_rs:kem::ML_KEM_1024")]
Kyber1024_R3,
}

Expand Down Expand Up @@ -255,6 +211,7 @@ mod tests {
}

#[test]

fn test_debug_fmt() {
let alg = get_algorithm(AlgorithmId::Kyber512_R3).expect("algorithm retrievable");
let private = DecapsulationKey::generate(alg).expect("successful generation");
Expand Down

0 comments on commit f8c16e3

Please sign in to comment.