open-quantum-safe / liboqs

C library for prototyping and experimenting with quantum-resistant cryptography
https://openquantumsafe.org/
Other
1.89k stars 463 forks source link

Incorrect Order of z and d in NIST tests #1853

Closed abhinav-thales closed 3 months ago

abhinav-thales commented 3 months ago

In the NIST tests for ML-KEM, the random number stream is constructed as [z || d || m] i.e. the first random byte returned by randombytes() would be z followed by d and m.

However, in the code

64 bytes random is generated together https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/ml_kem/pqcrystals-kyber-standard_ml-kem-512-ipd_ref/kem.c#L54 and then passed to derand api for keypair generation.

In the derand api, first 32 byte is used for keypair generation https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/ml_kem/pqcrystals-kyber-standard_ml-kem-512-ipd_ref/kem.c#L29 which makes the first 32 byte as 'd' as per Algo 12 of FIPS-203.

The next 32 bytes are appended to end of private key https://github.com/open-quantum-safe/liboqs/blob/main/src/kem/ml_kem/pqcrystals-kyber-standard_ml-kem-512-ipd_ref/kem.c#L33 which makes it 'z' as per Algo 15.

So, the random byte stream construction should be [d || z || m] so that randombytes are output in the order of d->z->m

Currently, it works for NIST Intermediate Vectors as the value of z and d are same for all KEM version. Incase, they are different the tests would fail.

A simple switch of z and d at https://github.com/open-quantum-safe/liboqs/blob/main/tests/test_kem_vectors.sh#L26 should solve this IMO.

bhess commented 3 months ago

Thank you @abhinav-thales for catching this! I think your analysis is correct, which would indeed lead to issues if z and d are not the same. I'll follow up with a PR.