Skip to content

Commit 7ccf963

Browse files
committed
Add tests for checking encaps implementation against ACVP KATs
Signed-off-by: Anjan Roy <hello@itzmeanjan.in>
1 parent defc822 commit 7ccf963

File tree

3 files changed

+162
-0
lines changed

3 files changed

+162
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "ml_kem/ml_kem_1024.hpp"
2+
#include "test_helper.hpp"
3+
#include <fstream>
4+
#include <gtest/gtest.h>
5+
6+
// Test
7+
//
8+
// - Is ML-KEM-1024 Encapsulation implemented correctly ?
9+
// - Is it conformant with the specification https://doi.org/10.6028/NIST.FIPS.203 ?
10+
//
11+
// using ACVP Known Answer Tests, from
12+
// https://github.com/usnistgov/ACVP-Server/blob/d98cad66639bf9d0822129c4bcae7a169fcf9ca6/gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json.
13+
TEST(ML_KEM, ML_KEM_1024_Encaps_ACVP_KnownAnswerTests)
14+
{
15+
const std::string kat_file = "./kats/ml_kem_1024_encaps.acvp.kat";
16+
std::fstream file(kat_file);
17+
18+
while (true) {
19+
std::string pk_line;
20+
21+
if (!std::getline(file, pk_line).eof()) {
22+
std::string sk_line;
23+
std::string m_line;
24+
std::string ct_line;
25+
std::string ss_line;
26+
27+
std::getline(file, sk_line);
28+
std::getline(file, m_line);
29+
std::getline(file, ct_line);
30+
std::getline(file, ss_line);
31+
32+
const auto pk = extract_and_parse_hex_string<ml_kem_1024::PKEY_BYTE_LEN>(pk_line);
33+
const auto _ = extract_and_parse_hex_string<ml_kem_1024::SKEY_BYTE_LEN>(sk_line);
34+
const auto m = extract_and_parse_hex_string<ml_kem_1024::SEED_M_BYTE_LEN>(m_line);
35+
const auto ct = extract_and_parse_hex_string<ml_kem_1024::CIPHER_TEXT_BYTE_LEN>(ct_line);
36+
const auto ss = extract_and_parse_hex_string<ml_kem_1024::SHARED_SECRET_BYTE_LEN>(ss_line);
37+
38+
std::array<uint8_t, ml_kem_1024::CIPHER_TEXT_BYTE_LEN> computed_ctxt{};
39+
std::array<uint8_t, ml_kem_1024::SHARED_SECRET_BYTE_LEN> computed_shared_secret{};
40+
41+
EXPECT_TRUE(ml_kem_1024::encapsulate(m, pk, computed_ctxt, computed_shared_secret));
42+
43+
EXPECT_EQ(ct, computed_ctxt);
44+
EXPECT_EQ(ss, computed_shared_secret);
45+
46+
std::string empty_line;
47+
std::getline(file, empty_line);
48+
} else {
49+
break;
50+
}
51+
}
52+
53+
file.close();
54+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "ml_kem/ml_kem_512.hpp"
2+
#include "test_helper.hpp"
3+
#include <fstream>
4+
#include <gtest/gtest.h>
5+
6+
// Test
7+
//
8+
// - Is ML-KEM-512 Encapsulation implemented correctly ?
9+
// - Is it conformant with the specification https://doi.org/10.6028/NIST.FIPS.203 ?
10+
//
11+
// using ACVP Known Answer Tests, from
12+
// https://github.com/usnistgov/ACVP-Server/blob/d98cad66639bf9d0822129c4bcae7a169fcf9ca6/gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json.
13+
TEST(ML_KEM, ML_KEM_512_Encaps_ACVP_KnownAnswerTests)
14+
{
15+
const std::string kat_file = "./kats/ml_kem_512_encaps.acvp.kat";
16+
std::fstream file(kat_file);
17+
18+
while (true) {
19+
std::string pk_line;
20+
21+
if (!std::getline(file, pk_line).eof()) {
22+
std::string sk_line;
23+
std::string m_line;
24+
std::string ct_line;
25+
std::string ss_line;
26+
27+
std::getline(file, sk_line);
28+
std::getline(file, m_line);
29+
std::getline(file, ct_line);
30+
std::getline(file, ss_line);
31+
32+
const auto pk = extract_and_parse_hex_string<ml_kem_512::PKEY_BYTE_LEN>(pk_line);
33+
const auto _ = extract_and_parse_hex_string<ml_kem_512::SKEY_BYTE_LEN>(sk_line);
34+
const auto m = extract_and_parse_hex_string<ml_kem_512::SEED_M_BYTE_LEN>(m_line);
35+
const auto ct = extract_and_parse_hex_string<ml_kem_512::CIPHER_TEXT_BYTE_LEN>(ct_line);
36+
const auto ss = extract_and_parse_hex_string<ml_kem_512::SHARED_SECRET_BYTE_LEN>(ss_line);
37+
38+
std::array<uint8_t, ml_kem_512::CIPHER_TEXT_BYTE_LEN> computed_ctxt{};
39+
std::array<uint8_t, ml_kem_512::SHARED_SECRET_BYTE_LEN> computed_shared_secret{};
40+
41+
EXPECT_TRUE(ml_kem_512::encapsulate(m, pk, computed_ctxt, computed_shared_secret));
42+
43+
EXPECT_EQ(ct, computed_ctxt);
44+
EXPECT_EQ(ss, computed_shared_secret);
45+
46+
std::string empty_line;
47+
std::getline(file, empty_line);
48+
} else {
49+
break;
50+
}
51+
}
52+
53+
file.close();
54+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "ml_kem/ml_kem_768.hpp"
2+
#include "test_helper.hpp"
3+
#include <fstream>
4+
#include <gtest/gtest.h>
5+
6+
// Test
7+
//
8+
// - Is ML-KEM-768 Encapsulation implemented correctly ?
9+
// - Is it conformant with the specification https://doi.org/10.6028/NIST.FIPS.203 ?
10+
//
11+
// using ACVP Known Answer Tests, from
12+
// https://github.com/usnistgov/ACVP-Server/blob/d98cad66639bf9d0822129c4bcae7a169fcf9ca6/gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json.
13+
TEST(ML_KEM, ML_KEM_768_Encaps_ACVP_KnownAnswerTests)
14+
{
15+
const std::string kat_file = "./kats/ml_kem_768_encaps.acvp.kat";
16+
std::fstream file(kat_file);
17+
18+
while (true) {
19+
std::string pk_line;
20+
21+
if (!std::getline(file, pk_line).eof()) {
22+
std::string sk_line;
23+
std::string m_line;
24+
std::string ct_line;
25+
std::string ss_line;
26+
27+
std::getline(file, sk_line);
28+
std::getline(file, m_line);
29+
std::getline(file, ct_line);
30+
std::getline(file, ss_line);
31+
32+
const auto pk = extract_and_parse_hex_string<ml_kem_768::PKEY_BYTE_LEN>(pk_line);
33+
const auto _ = extract_and_parse_hex_string<ml_kem_768::SKEY_BYTE_LEN>(sk_line);
34+
const auto m = extract_and_parse_hex_string<ml_kem_768::SEED_M_BYTE_LEN>(m_line);
35+
const auto ct = extract_and_parse_hex_string<ml_kem_768::CIPHER_TEXT_BYTE_LEN>(ct_line);
36+
const auto ss = extract_and_parse_hex_string<ml_kem_768::SHARED_SECRET_BYTE_LEN>(ss_line);
37+
38+
std::array<uint8_t, ml_kem_768::CIPHER_TEXT_BYTE_LEN> computed_ctxt{};
39+
std::array<uint8_t, ml_kem_768::SHARED_SECRET_BYTE_LEN> computed_shared_secret{};
40+
41+
EXPECT_TRUE(ml_kem_768::encapsulate(m, pk, computed_ctxt, computed_shared_secret));
42+
43+
EXPECT_EQ(ct, computed_ctxt);
44+
EXPECT_EQ(ss, computed_shared_secret);
45+
46+
std::string empty_line;
47+
std::getline(file, empty_line);
48+
} else {
49+
break;
50+
}
51+
}
52+
53+
file.close();
54+
}

0 commit comments

Comments
 (0)