Skip to content

[sw] Pull-in MLDSA software impl for eg100#30552

Open
sasdf wants to merge 3 commits into
lowRISC:earlgrey_1.0.0from
sasdf:mjTmlqqtoxz
Open

[sw] Pull-in MLDSA software impl for eg100#30552
sasdf wants to merge 3 commits into
lowRISC:earlgrey_1.0.0from
sasdf:mjTmlqqtoxz

Conversation

@sasdf

@sasdf sasdf commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

This PR integrates the embedpqc software implementation of ML-DSA (supporting 44, 65, and 87 profiles, including their tiny-stack variants) and updates the KMAC driver to support the required SHAKE operations.

Key Changes

  1. ML-DSA Software Library (third_party/embedpqc):
    • Pulled in the core embedpqc library files.
    • Added a porting layer in third_party/embedpqc/ports/ that implements the SHAKE128 and SHAKE256 interfaces by wrapping the Silicon Creator KMAC driver.
  2. KMAC Driver Enhancements (sw/device/silicon_creator/lib/drivers/):
    • Added kmac_shake128_configure() to support SHAKE-128 mode.
    • Refactored squeezing logic to expose kmac_squeeze_words() and kmac_done(), allowing arbitrary-length squeezing required by ML-DSA.
  3. Verification Tests (sw/device/tests/embedpqc/):
    • Added test suites for ML-DSA-44, -65, and -87 (both standard and tiny versions) using test vectors to verify correctness and measure stack usage.

Stack usage estimation:

Algorithm / Phase Variant KeyGen Sign Verify
ML-DSA-44 Non-Tiny 18,036 B 32,212 B 15,652 B
Tiny 9,908 B 13,492 B 11,268 B
ML-DSA-65 Non-Tiny 25,204 B 44,532 B 26,948 B
Tiny 14,004 B 16,644 B 15,316 B
ML-DSA-87 Non-Tiny 33,396 B 59,140 B 35,428 B
Tiny 18,100 B 20,820 B 19,700 B

@sasdf sasdf force-pushed the mjTmlqqtoxz branch 3 times, most recently from a394044 to 720ee09 Compare June 30, 2026 20:24
@sasdf sasdf requested review from cfrantz and siemen11 June 30, 2026 22:26
@sasdf sasdf marked this pull request as ready for review June 30, 2026 22:26
@sasdf sasdf requested a review from a team as a code owner June 30, 2026 22:26
@sasdf sasdf requested review from moidx and removed request for a team June 30, 2026 22:26
Comment on lines +16 to +28
register uint8_t *a0 asm("a0") = out_pk;
register const uint8_t *a1 asm("a1") = seed;
register void *a2 asm("a2") = stack_top;

asm volatile(
"mv s1, sp\n"
"mv sp, a2\n"
"call mldsa44_tiny_pub_from_seed\n"
"mv sp, s1\n"
: "+r"(a0), "+r"(a1), "+r"(a2)
:
: "ra", "s1", "a3", "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", "t4",
"t5", "t6", "memory");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is pretty advanced stuff :)

What does the codegen look like for this, and how does this compare with writing an actual assembly language entrypoint (e.g. mldsa44_tiny_caller.S)?

With an assembly-language entrypoint, we could simply obey the C-ABI register convention rather than having to mark it all as clobbered in the inline assembly statement. However, we'd have to appropriately manage whichever register is responsible for holding the original stack pointer so we can restore it after the call returns.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Hmm, I forgot the reason why I decided to switch from standalone asm to inline asm during prototyping...)

The PR is updated to use assembly-language entrypoint, and I also confirmed manually that unused functions will be stripped correctly.

Comment on lines +29 to +38
cc_library(
name = "mldsa44",
srcs = ["mldsa44.c"],
hdrs = ["mldsa44.h"],
deps = [
":ct",
":mldsa_mu",
"//third_party/embedpqc/ports:shake",
],
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we bringing in both the regular and tiny versions of the functions?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have the tools for measuring latency on real chips now, maybe we can keep both variants for now and decide later?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is almost certain we only need tiny, no @cfrantz ?

Comment thread third_party/embedpqc/ports/shake.c Outdated
@sasdf sasdf force-pushed the mjTmlqqtoxz branch 2 times, most recently from 5ab37dc to a586c10 Compare July 1, 2026 19:48

@siemen11 siemen11 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @sasdf, what a monster haha! I checked the assembly whether the parts that should be constant time are so, this looks to be the case

@johannheyszl

Copy link
Copy Markdown
Contributor

Can we add some cycle counts to the tiny executions maybe?

sasdf added 2 commits July 6, 2026 21:34
Using `.strip()` on the file content before splitting removes all
leading whitespaces of the entire file. By switching to `.rstrip()`,
we preserve any leading empty lines/spaces while still stripping
trailing whitespaces and ensuring the file ends with a single newline.

Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
Change-Id: Ib9954c5ed78c1610b1148ee7913f786f6a6a6964
This patch exports the `kmac_squeeze_words` and `kmac_done` functions
from the kmac driver to allow caller to squeeze an arbitrary number of
words from the Keccak state incrementally.

Also, adds `kmac_shake128_configure` to support SHAKE-128 configuration.

Signed-off-by: Yi-Hsuan Deng <yhdeng@google.com>
Change-Id: Ide996b205dcd4cf41425571315cd0b496a6a6964
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants