KAT for FIPS-203
Compliant with FIPS-203, published on August 13, 2024.
File format:
| Field | Meaning |
|---|---|
count |
Test number |
z |
Random 32-bytes z (Algorithm 15) |
d |
Random 32-bytes d (Algorithm 12) |
msg |
Random 32-bytes m (Algorithm 16) |
seed |
AES-CTR-drbg seed |
pk |
Resulting public key |
sk |
Resulting secret key |
ct |
Resulting KEM ciphertext |
ss |
Resulting KEM shared secret |
ct_n |
Invalid KEM ciphertext |
ss_n |
Shared secret resulting from decapsulation of ct_n |
Differences with the FIPS-203
- No tests for key validation
How it was generated
We use DRBG based on based on AES-CTR (see SP800-90A) for generating random bytes. For each KAT vector, the DRBG is seeded with the seed value (personalisation string is not used). The test first generates a secret and public key. Then it encapsulates and decapsulates the shared secret.
The pseudocode below may make it clearer
use aes_ctr_drbg::DrbgCtx; // aes_ctr_drbg = "0.0.2" crate
fn main() {
// Initialize DRBG with the magic value
let Ok(mut entropy) = hex::decode("60496cd0a12512800a79161189b055ac3996ad24e578d3c5fc57c1e60fa2eb4e550d08e51e9db7b67f1a616681d9182d") else {
... blah ...
}
let mut drbg: DrbgCtx = DrbgCtx::new();
drbg.init(&entropy, Vec::new());
for i in 0..100 {
drbg.get_random(&mut entropy);
kem::kem(i, &entropy);
}
}
pub fn kem(count: usize, entropy: &[u8]) {
let mut buf = Vec::new();
let mut drbg: DrbgCtx = DrbgCtx::new();
drbg.init(&entropy.clone(), Vec::new());
println!("count = {}", count);
// The code generates random strings in the following order: z,d,msg
// z
buf.resize(32, 0);
drbg.get_random(&mut buf);
println!("z = {}", hex::encode(&buf));
// d
drbg.get_random(&mut buf);
println!("d = {}", hex::encode(&buf));
// msg
drbg.get_random(&mut buf);
println!("msg = {}", hex::encode(&buf));
// Re-init
drbg.init(&entropy.clone(), Vec::new());
// Generate keys
kyber_keygen(&mut pk, &mut sk);
// Encapsulate
kyber_encaps(&pk, &mut ct, &mut ss);
// Decapsulate
kyber_decaps(&sk, &ct, &mut ss);
println!("seed = {}", hex::encode(&entropy));
println!("pk = {}", hex::encode(&pk));
println!("sk = {}", hex::encode(&sk));
println!("ct = {}", hex::encode(&ct));
println!("ss = {}", hex::encode(&ss1));