aws_lc_rs/unstable/
kem.rsuse 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};
const KYBER512_R3_SECRET_KEY_LENGTH: usize = 1632;
const KYBER512_R3_CIPHERTEXT_LENGTH: usize = 768;
const KYBER512_R3_PUBLIC_KEY_LENGTH: usize = 800;
const KYBER512_R3_SHARED_SECRET_LENGTH: usize = 32;
const KYBER768_R3_SECRET_KEY_LENGTH: usize = 2400;
const KYBER768_R3_CIPHERTEXT_LENGTH: usize = 1088;
const KYBER768_R3_PUBLIC_KEY_LENGTH: usize = 1184;
const KYBER768_R3_SHARED_SECRET_LENGTH: usize = 32;
const KYBER1024_R3_SECRET_KEY_LENGTH: usize = 3168;
const KYBER1024_R3_CIPHERTEXT_LENGTH: usize = 1568;
const KYBER1024_R3_PUBLIC_KEY_LENGTH: usize = 1568;
const KYBER1024_R3_SHARED_SECRET_LENGTH: usize = 32;
#[allow(deprecated)]
const KYBER512_R3: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::Kyber512_R3,
decapsulate_key_size: KYBER512_R3_SECRET_KEY_LENGTH,
encapsulate_key_size: KYBER512_R3_PUBLIC_KEY_LENGTH,
ciphertext_size: KYBER512_R3_CIPHERTEXT_LENGTH,
shared_secret_size: KYBER512_R3_SHARED_SECRET_LENGTH,
};
#[allow(deprecated)]
const KYBER768_R3: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::Kyber768_R3,
decapsulate_key_size: KYBER768_R3_SECRET_KEY_LENGTH,
encapsulate_key_size: KYBER768_R3_PUBLIC_KEY_LENGTH,
ciphertext_size: KYBER768_R3_CIPHERTEXT_LENGTH,
shared_secret_size: KYBER768_R3_SHARED_SECRET_LENGTH,
};
#[allow(deprecated)]
const KYBER1024_R3: Algorithm<AlgorithmId> = Algorithm {
id: AlgorithmId::Kyber1024_R3,
decapsulate_key_size: KYBER1024_R3_SECRET_KEY_LENGTH,
encapsulate_key_size: KYBER1024_R3_PUBLIC_KEY_LENGTH,
ciphertext_size: KYBER1024_R3_CIPHERTEXT_LENGTH,
shared_secret_size: KYBER1024_R3_SHARED_SECRET_LENGTH,
};
#[allow(non_camel_case_types)]
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum AlgorithmId {
#[deprecated]
Kyber512_R3,
#[deprecated]
Kyber768_R3,
#[deprecated]
Kyber1024_R3,
}
impl crate::kem::AlgorithmIdentifier for AlgorithmId {
#[inline]
fn nid(self) -> i32 {
#[allow(deprecated)]
match self {
AlgorithmId::Kyber512_R3 => NID_KYBER512_R3,
AlgorithmId::Kyber768_R3 => NID_KYBER768_R3,
AlgorithmId::Kyber1024_R3 => NID_KYBER1024_R3,
}
}
}
impl crate::sealed::Sealed for AlgorithmId {}
#[must_use]
pub const fn get_algorithm(id: AlgorithmId) -> Option<&'static Algorithm<AlgorithmId>> {
#[allow(deprecated)]
match id {
AlgorithmId::Kyber512_R3 => Some(&KYBER512_R3),
AlgorithmId::Kyber768_R3 => Some(&KYBER768_R3),
AlgorithmId::Kyber1024_R3 => Some(&KYBER1024_R3),
}
}
#[cfg(test)]
mod tests {
#![allow(deprecated)]
use crate::{
error::KeyRejected,
kem::{DecapsulationKey, EncapsulationKey},
};
use super::{get_algorithm, AlgorithmId, KYBER1024_R3, KYBER512_R3, KYBER768_R3};
#[test]
fn test_kem_serialize() {
for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] {
let priv_key = DecapsulationKey::generate(algorithm).unwrap();
assert_eq!(priv_key.algorithm(), algorithm);
let pub_key = priv_key.encapsulation_key().unwrap();
let pubkey_raw_bytes = pub_key.key_bytes().unwrap();
let pub_key_from_bytes =
EncapsulationKey::new(algorithm, pubkey_raw_bytes.as_ref()).unwrap();
assert_eq!(
pub_key.key_bytes().unwrap().as_ref(),
pub_key_from_bytes.key_bytes().unwrap().as_ref()
);
assert_eq!(pub_key.algorithm(), pub_key_from_bytes.algorithm());
}
}
#[test]
fn test_kem_wrong_sizes() {
for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] {
let too_long_bytes = vec![0u8; algorithm.encapsulate_key_size() + 1];
let long_pub_key_from_bytes = EncapsulationKey::new(algorithm, &too_long_bytes);
assert_eq!(
long_pub_key_from_bytes.err(),
Some(KeyRejected::too_large())
);
let too_short_bytes = vec![0u8; algorithm.encapsulate_key_size() - 1];
let short_pub_key_from_bytes = EncapsulationKey::new(algorithm, &too_short_bytes);
assert_eq!(
short_pub_key_from_bytes.err(),
Some(KeyRejected::too_small())
);
}
}
#[test]
fn test_kem_e2e() {
for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] {
let priv_key = DecapsulationKey::generate(algorithm).unwrap();
assert_eq!(priv_key.algorithm(), algorithm);
let pub_key = priv_key.encapsulation_key().unwrap();
let (alice_ciphertext, alice_secret) =
pub_key.encapsulate().expect("encapsulate successful");
let bob_secret = priv_key
.decapsulate(alice_ciphertext)
.expect("decapsulate successful");
assert_eq!(alice_secret.as_ref(), bob_secret.as_ref());
}
}
#[test]
fn test_serialized_kem_e2e() {
for algorithm in [&KYBER512_R3, &KYBER768_R3, &KYBER1024_R3] {
let priv_key = DecapsulationKey::generate(algorithm).unwrap();
assert_eq!(priv_key.algorithm(), algorithm);
let pub_key = priv_key.encapsulation_key().unwrap();
let pub_key_bytes = pub_key.key_bytes().unwrap();
drop(pub_key);
let retrieved_pub_key =
EncapsulationKey::new(algorithm, pub_key_bytes.as_ref()).unwrap();
let (ciphertext, bob_secret) = retrieved_pub_key
.encapsulate()
.expect("encapsulate successful");
let alice_secret = priv_key
.decapsulate(ciphertext)
.expect("encapsulate successful");
assert_eq!(alice_secret.as_ref(), bob_secret.as_ref());
}
}
#[test]
fn test_get_algorithm() {
for id in [
AlgorithmId::Kyber512_R3,
AlgorithmId::Kyber768_R3,
AlgorithmId::Kyber1024_R3,
] {
let alg = get_algorithm(id).expect("algorithm retrievable");
assert_eq!(alg.id(), id);
}
}
#[test]
fn test_debug_fmt() {
let alg = get_algorithm(AlgorithmId::Kyber512_R3).expect("algorithm retrievable");
let private = DecapsulationKey::generate(alg).expect("successful generation");
assert_eq!(
format!("{private:?}"),
"DecapsulationKey { algorithm: Kyber512_R3, .. }"
);
assert_eq!(
format!(
"{:?}",
private.encapsulation_key().expect("public key retrievable")
),
"EncapsulationKey { algorithm: Kyber512_R3, .. }"
);
}
}