Skip to content

[crypto] Add pure Ed25519 signing and verification#233

Draft
mkannwischer wants to merge 3 commits intomasterfrom
mjk/pure-ed25519
Draft

[crypto] Add pure Ed25519 signing and verification#233
mkannwischer wants to merge 3 commits intomasterfrom
mjk/pure-ed25519

Conversation

@mkannwischer
Copy link
Copy Markdown
Contributor

@mkannwischer mkannwischer commented Apr 1, 2026

This PR adds pure Ed25519 signature generation and verification as described in RFC 8032.

Verification is a straightforward extension only touching the C-side as the hash is computed using HMAC prior to invoking ACC - this is fine as all processed data is public.

Signing is more involved as both required hashes are computed in ACC. To be able to support arbitrary message lengths, we have to stream in the message twice resulting in a 5-step API: INIT/UPDATE/MID/UPDATE/FINAL. I tried to share as much code as possible with the pre-hash mode.

This allows us to cover more ACVP test vectors and also support the Wycheproof testvectors.

I have also extended the functest accordingly and cleaned up a few typos on the way.

See the individual commit messages for details.

Add support for pure Ed25519 (RFC 8032 5.1.7) signature
verification alongside the existing HashEd25519 mode.

Pure Ed25519 computes k = SHA-512(R || A || M) without a domain
separator, while HashEd25519 computes k = SHA-512(dom2(1,ctx) ||
R || A || PH(M)). The hash k is computed on Ibex using the SHA-2
HW block, so the ACC program does not need changes.

Also removes unused message and context parameters from
ed25519_verify_start since the ACC verify program only uses
the precomputed hash_k.

Signed-off-by: Matthias J. Kannwischer <matthias@zerorisc.com>
Wire up the existing Wycheproof Ed25519 parser (150 pure Ed25519
verify vectors, 9 skipped due to non-word-aligned signature
lengths).

Signed-off-by: Matthias J. Kannwischer <matthias@zerorisc.com>
Add support for pure Ed25519 signing (RFC 8032 5.1.6) where the raw
message is signed directly without pre-hashing. The message is
streamed into ACC incrementally via a multi-phase API
(INIT/UPDATE/MID/UPDATE/FINAL), allowing arbitrarily large messages.

The message appears in both the nonce hash r = SHA-512(prefix || M)
and the challenge hash k = SHA-512(R_ || A_ || M), so it must be
streamed twice. The message chunk size has been picked as the
maximum that still fits in 3 KiB of Ibex-accessible DMEM to make
sure this code also works with the smallest configurations.

The signing logic is refactored into shared subroutines
(_ed25519_sign_compute_r_a, _ed25519_sign_compute_s) used by both the
HashEd25519 one-shot path and the pure incremental phases.

The functest is extended to a wide range of message lengths for the
pure mode, and also some additional context lengths for the
pre-hash mode.

Signed-off-by: Matthias J. Kannwischer <matthias@zerorisc.com>
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.

1 participant