Skip to content

Commit 720ee09

Browse files
committed
[third_party] Pull-in embedpqc MLDSA library
Import `embedpqc` library containing embedded friendly implementations of ML-DSA-44, ML-DSA-65, and ML-DSA-87 signatures derived from BoringSSL. This commit pulls in both the standard variants and the stack usage optimized "tiny" variants of ML-DSA, integrated with OpenTitan's hardware KMAC block for SHAKE acceleration. The change also introduces smoke tests for each variant targeting the Earlgrey chip. Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com> Change-Id: Ide996b205dcd4cf41425571315cd0b496a6a6964
1 parent b7e35d2 commit 720ee09

39 files changed

Lines changed: 9605 additions & 0 deletions

sw/device/tests/embedpqc/BUILD

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright lowRISC contributors (OpenTitan project).
2+
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
load(
6+
"//rules/opentitan:defs.bzl",
7+
"EARLGREY_TEST_ENVS",
8+
"opentitan_test",
9+
)
10+
11+
package(default_visibility = ["//visibility:public"])
12+
13+
cc_library(
14+
name = "mldsa_test_utils",
15+
srcs = [
16+
"mldsa_test_utils.c",
17+
],
18+
hdrs = [
19+
"mldsa_test_utils.h",
20+
],
21+
deps = [
22+
"//sw/device/lib/runtime:log",
23+
],
24+
)
25+
26+
cc_library(
27+
name = "mldsa_testvectors",
28+
srcs = ["mldsa_testvectors.c"],
29+
hdrs = ["mldsa_testvectors.h"],
30+
deps = [
31+
"//third_party/embedpqc:mldsa44",
32+
"//third_party/embedpqc:mldsa65",
33+
"//third_party/embedpqc:mldsa87",
34+
],
35+
)
36+
37+
opentitan_test(
38+
name = "mldsa44_test",
39+
srcs = ["mldsa44_test.c"],
40+
exec_env = EARLGREY_TEST_ENVS,
41+
deps = [
42+
":mldsa_test_utils",
43+
":mldsa_testvectors",
44+
"//sw/device/lib/runtime:log",
45+
"//sw/device/lib/testing/test_framework:ottf_main",
46+
"//third_party/embedpqc/ports:mldsa44_caller",
47+
],
48+
)
49+
50+
opentitan_test(
51+
name = "mldsa65_test",
52+
srcs = ["mldsa65_test.c"],
53+
exec_env = EARLGREY_TEST_ENVS,
54+
deps = [
55+
":mldsa_test_utils",
56+
":mldsa_testvectors",
57+
"//sw/device/lib/runtime:log",
58+
"//sw/device/lib/testing/test_framework:ottf_main",
59+
"//third_party/embedpqc/ports:mldsa65_caller",
60+
],
61+
)
62+
63+
opentitan_test(
64+
name = "mldsa87_test",
65+
srcs = ["mldsa87_test.c"],
66+
exec_env = EARLGREY_TEST_ENVS,
67+
deps = [
68+
":mldsa_test_utils",
69+
":mldsa_testvectors",
70+
"//sw/device/lib/runtime:log",
71+
"//sw/device/lib/testing/test_framework:ottf_main",
72+
"//third_party/embedpqc/ports:mldsa87_caller",
73+
],
74+
)
75+
76+
opentitan_test(
77+
name = "mldsa44_tiny_test",
78+
srcs = ["mldsa44_tiny_test.c"],
79+
exec_env = EARLGREY_TEST_ENVS,
80+
deps = [
81+
":mldsa_test_utils",
82+
":mldsa_testvectors",
83+
"//sw/device/lib/runtime:log",
84+
"//sw/device/lib/testing/test_framework:ottf_main",
85+
"//third_party/embedpqc/ports:mldsa44_tiny_caller",
86+
],
87+
)
88+
89+
opentitan_test(
90+
name = "mldsa65_tiny_test",
91+
srcs = ["mldsa65_tiny_test.c"],
92+
exec_env = EARLGREY_TEST_ENVS,
93+
deps = [
94+
":mldsa_test_utils",
95+
":mldsa_testvectors",
96+
"//sw/device/lib/runtime:log",
97+
"//sw/device/lib/testing/test_framework:ottf_main",
98+
"//third_party/embedpqc/ports:mldsa65_tiny_caller",
99+
],
100+
)
101+
102+
opentitan_test(
103+
name = "mldsa87_tiny_test",
104+
srcs = ["mldsa87_tiny_test.c"],
105+
exec_env = EARLGREY_TEST_ENVS,
106+
deps = [
107+
":mldsa_test_utils",
108+
":mldsa_testvectors",
109+
"//sw/device/lib/runtime:log",
110+
"//sw/device/lib/testing/test_framework:ottf_main",
111+
"//third_party/embedpqc/ports:mldsa87_tiny_caller",
112+
],
113+
)
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright lowRISC contributors (OpenTitan project).
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include "third_party/embedpqc/mldsa44.h"
6+
7+
#include "sw/device/lib/runtime/log.h"
8+
#include "sw/device/lib/testing/test_framework/check.h"
9+
#include "sw/device/lib/testing/test_framework/ottf_main.h"
10+
#include "sw/device/tests/embedpqc/mldsa_test_utils.h"
11+
#include "sw/device/tests/embedpqc/mldsa_testvectors.h"
12+
#include "third_party/embedpqc/ports/mldsa44_caller.h"
13+
14+
OTTF_DEFINE_TEST_CONFIG();
15+
16+
bool test_main(void) {
17+
LOG_INFO("MLDSA44 Test starting...");
18+
19+
// Allocate a single static buffer to reuse for all RAM outputs to save BSS
20+
// space.
21+
static uint8_t buf[MLDSA44_SIGNATURE_BYTES];
22+
23+
// 1. Keygen Test
24+
paint_stack();
25+
mldsa44_pub_from_seed_with_stack(buf, kMldsa44KeygenSeed,
26+
&mldsa_stack[MLDSA_STACK_SIZE]);
27+
size_t keygen_stack = get_max_stack_usage();
28+
LOG_INFO("mldsa44_pub_from_seed Max Stack Usage: %u bytes",
29+
(unsigned int)keygen_stack);
30+
31+
CHECK(check_arrays_eq_verbose(buf, kMldsa44ExpectedPublicKey,
32+
MLDSA44_PUBLIC_KEY_BYTES),
33+
"PublicKey mismatch!");
34+
LOG_INFO("Keygen Test Passed.");
35+
36+
// 2. Sign Test
37+
paint_stack();
38+
mldsa44_sign_deterministic_with_stack(buf, kMldsa44SignSeed, kMldsa44Message,
39+
sizeof(kMldsa44Message),
40+
&mldsa_stack[MLDSA_STACK_SIZE]);
41+
size_t sign_stack = get_max_stack_usage();
42+
LOG_INFO("mldsa44_sign Max Stack Usage: %u bytes", (unsigned int)sign_stack);
43+
44+
CHECK(check_arrays_eq_verbose(buf, kMldsa44ExpectedSignature,
45+
MLDSA44_SIGNATURE_BYTES),
46+
"Signature mismatch!");
47+
LOG_INFO("Sign Test Passed.");
48+
49+
// 3. Verify Test
50+
mldsa44_pub_from_seed_with_stack(buf, kMldsa44SignSeed,
51+
&mldsa_stack[MLDSA_STACK_SIZE]);
52+
paint_stack();
53+
int verify_res = mldsa44_verify_with_stack(
54+
buf, kMldsa44ExpectedSignature, kMldsa44Message, sizeof(kMldsa44Message),
55+
&mldsa_stack[MLDSA_STACK_SIZE]);
56+
size_t verify_stack = get_max_stack_usage();
57+
LOG_INFO("mldsa44_verify Max Stack Usage: %u bytes",
58+
(unsigned int)verify_stack);
59+
60+
CHECK(verify_res != 0, "mldsa44_verify failed!");
61+
LOG_INFO("Verify Test Passed.");
62+
63+
LOG_INFO("MLDSA44 Test completed successfully!");
64+
return true;
65+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright lowRISC contributors (OpenTitan project).
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include "third_party/embedpqc/mldsa44_tiny.h"
6+
7+
#include "sw/device/lib/runtime/log.h"
8+
#include "sw/device/lib/testing/test_framework/check.h"
9+
#include "sw/device/lib/testing/test_framework/ottf_main.h"
10+
#include "sw/device/tests/embedpqc/mldsa_test_utils.h"
11+
#include "sw/device/tests/embedpqc/mldsa_testvectors.h"
12+
#include "third_party/embedpqc/ports/mldsa44_tiny_caller.h"
13+
14+
OTTF_DEFINE_TEST_CONFIG();
15+
16+
bool test_main(void) {
17+
LOG_INFO("MLDSA44-TINY Test starting...");
18+
19+
// Allocate a single static buffer to reuse for all RAM outputs to save BSS
20+
// space.
21+
static uint8_t buf[MLDSA44_SIGNATURE_BYTES];
22+
23+
// 1. Keygen Test
24+
paint_stack();
25+
mldsa44_tiny_pub_from_seed_with_stack(buf, kMldsa44KeygenSeed,
26+
&mldsa_stack[MLDSA_STACK_SIZE]);
27+
size_t keygen_stack = get_max_stack_usage();
28+
LOG_INFO("mldsa44_tiny_pub_from_seed Max Stack Usage: %u bytes",
29+
(unsigned int)keygen_stack);
30+
31+
CHECK(check_arrays_eq_verbose(buf, kMldsa44ExpectedPublicKey,
32+
MLDSA44_PUBLIC_KEY_BYTES),
33+
"PublicKey mismatch!");
34+
LOG_INFO("Keygen Test Passed.");
35+
36+
// 2. Sign Test
37+
paint_stack();
38+
mldsa44_tiny_sign_deterministic_with_stack(
39+
buf, kMldsa44SignSeed, kMldsa44Message, sizeof(kMldsa44Message),
40+
&mldsa_stack[MLDSA_STACK_SIZE]);
41+
size_t sign_stack = get_max_stack_usage();
42+
LOG_INFO("mldsa44_tiny_sign Max Stack Usage: %u bytes",
43+
(unsigned int)sign_stack);
44+
45+
CHECK(check_arrays_eq_verbose(buf, kMldsa44ExpectedSignature,
46+
MLDSA44_SIGNATURE_BYTES),
47+
"Signature mismatch!");
48+
LOG_INFO("Sign Test Passed.");
49+
50+
// 3. Verify Test
51+
mldsa44_tiny_pub_from_seed_with_stack(buf, kMldsa44SignSeed,
52+
&mldsa_stack[MLDSA_STACK_SIZE]);
53+
paint_stack();
54+
int verify_res = mldsa44_tiny_verify_with_stack(
55+
buf, kMldsa44ExpectedSignature, kMldsa44Message, sizeof(kMldsa44Message),
56+
&mldsa_stack[MLDSA_STACK_SIZE]);
57+
size_t verify_stack = get_max_stack_usage();
58+
LOG_INFO("mldsa44_tiny_verify Max Stack Usage: %u bytes",
59+
(unsigned int)verify_stack);
60+
61+
CHECK(verify_res != 0, "mldsa44_tiny_verify failed!");
62+
LOG_INFO("Verify Test Passed.");
63+
64+
LOG_INFO("MLDSA44-TINY Test completed successfully!");
65+
return true;
66+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright lowRISC contributors (OpenTitan project).
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include "third_party/embedpqc/mldsa65.h"
6+
7+
#include "sw/device/lib/runtime/log.h"
8+
#include "sw/device/lib/testing/test_framework/check.h"
9+
#include "sw/device/lib/testing/test_framework/ottf_main.h"
10+
#include "sw/device/tests/embedpqc/mldsa_test_utils.h"
11+
#include "sw/device/tests/embedpqc/mldsa_testvectors.h"
12+
#include "third_party/embedpqc/ports/mldsa65_caller.h"
13+
14+
OTTF_DEFINE_TEST_CONFIG();
15+
16+
bool test_main(void) {
17+
LOG_INFO("MLDSA65 Test starting...");
18+
19+
// Allocate a single static buffer to reuse for all RAM outputs to save BSS
20+
// space.
21+
static uint8_t buf[MLDSA65_SIGNATURE_BYTES];
22+
23+
// 1. Keygen Test
24+
paint_stack();
25+
mldsa65_pub_from_seed_with_stack(buf, kMldsa65KeygenSeed,
26+
&mldsa_stack[MLDSA_STACK_SIZE]);
27+
size_t keygen_stack = get_max_stack_usage();
28+
LOG_INFO("mldsa65_pub_from_seed Max Stack Usage: %u bytes",
29+
(unsigned int)keygen_stack);
30+
31+
CHECK(check_arrays_eq_verbose(buf, kMldsa65ExpectedPublicKey,
32+
MLDSA65_PUBLIC_KEY_BYTES),
33+
"PublicKey mismatch!");
34+
LOG_INFO("Keygen Test Passed.");
35+
36+
// 2. Sign Test
37+
paint_stack();
38+
mldsa65_sign_deterministic_with_stack(buf, kMldsa65SignSeed, kMldsa65Message,
39+
sizeof(kMldsa65Message),
40+
&mldsa_stack[MLDSA_STACK_SIZE]);
41+
size_t sign_stack = get_max_stack_usage();
42+
LOG_INFO("mldsa65_sign Max Stack Usage: %u bytes", (unsigned int)sign_stack);
43+
44+
CHECK(check_arrays_eq_verbose(buf, kMldsa65ExpectedSignature,
45+
MLDSA65_SIGNATURE_BYTES),
46+
"Signature mismatch!");
47+
LOG_INFO("Sign Test Passed.");
48+
49+
// 3. Verify Test
50+
mldsa65_pub_from_seed_with_stack(buf, kMldsa65SignSeed,
51+
&mldsa_stack[MLDSA_STACK_SIZE]);
52+
paint_stack();
53+
int verify_res = mldsa65_verify_with_stack(
54+
buf, kMldsa65ExpectedSignature, kMldsa65Message, sizeof(kMldsa65Message),
55+
&mldsa_stack[MLDSA_STACK_SIZE]);
56+
size_t verify_stack = get_max_stack_usage();
57+
LOG_INFO("mldsa65_verify Max Stack Usage: %u bytes",
58+
(unsigned int)verify_stack);
59+
60+
CHECK(verify_res != 0, "mldsa65_verify failed!");
61+
LOG_INFO("Verify Test Passed.");
62+
63+
LOG_INFO("MLDSA65 Test completed successfully!");
64+
return true;
65+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright lowRISC contributors (OpenTitan project).
2+
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include "third_party/embedpqc/mldsa65_tiny.h"
6+
7+
#include "sw/device/lib/runtime/log.h"
8+
#include "sw/device/lib/testing/test_framework/check.h"
9+
#include "sw/device/lib/testing/test_framework/ottf_main.h"
10+
#include "sw/device/tests/embedpqc/mldsa_test_utils.h"
11+
#include "sw/device/tests/embedpqc/mldsa_testvectors.h"
12+
#include "third_party/embedpqc/ports/mldsa65_tiny_caller.h"
13+
14+
OTTF_DEFINE_TEST_CONFIG();
15+
16+
bool test_main(void) {
17+
LOG_INFO("MLDSA65-TINY Test starting...");
18+
19+
// Allocate a single static buffer to reuse for all RAM outputs to save BSS
20+
// space.
21+
static uint8_t buf[MLDSA65_SIGNATURE_BYTES];
22+
23+
// 1. Keygen Test
24+
paint_stack();
25+
mldsa65_tiny_pub_from_seed_with_stack(buf, kMldsa65KeygenSeed,
26+
&mldsa_stack[MLDSA_STACK_SIZE]);
27+
size_t keygen_stack = get_max_stack_usage();
28+
LOG_INFO("mldsa65_tiny_pub_from_seed Max Stack Usage: %u bytes",
29+
(unsigned int)keygen_stack);
30+
31+
CHECK(check_arrays_eq_verbose(buf, kMldsa65ExpectedPublicKey,
32+
MLDSA65_PUBLIC_KEY_BYTES),
33+
"PublicKey mismatch!");
34+
LOG_INFO("Keygen Test Passed.");
35+
36+
// 2. Sign Test
37+
paint_stack();
38+
mldsa65_tiny_sign_deterministic_with_stack(
39+
buf, kMldsa65SignSeed, kMldsa65Message, sizeof(kMldsa65Message),
40+
&mldsa_stack[MLDSA_STACK_SIZE]);
41+
size_t sign_stack = get_max_stack_usage();
42+
LOG_INFO("mldsa65_tiny_sign Max Stack Usage: %u bytes",
43+
(unsigned int)sign_stack);
44+
45+
CHECK(check_arrays_eq_verbose(buf, kMldsa65ExpectedSignature,
46+
MLDSA65_SIGNATURE_BYTES),
47+
"Signature mismatch!");
48+
LOG_INFO("Sign Test Passed.");
49+
50+
// 3. Verify Test
51+
mldsa65_tiny_pub_from_seed_with_stack(buf, kMldsa65SignSeed,
52+
&mldsa_stack[MLDSA_STACK_SIZE]);
53+
paint_stack();
54+
int verify_res = mldsa65_tiny_verify_with_stack(
55+
buf, kMldsa65ExpectedSignature, kMldsa65Message, sizeof(kMldsa65Message),
56+
&mldsa_stack[MLDSA_STACK_SIZE]);
57+
size_t verify_stack = get_max_stack_usage();
58+
LOG_INFO("mldsa65_tiny_verify Max Stack Usage: %u bytes",
59+
(unsigned int)verify_stack);
60+
61+
CHECK(verify_res != 0, "mldsa65_tiny_verify failed!");
62+
LOG_INFO("Verify Test Passed.");
63+
64+
LOG_INFO("MLDSA65-TINY Test completed successfully!");
65+
return true;
66+
}

0 commit comments

Comments
 (0)