Skip to content

feat(sig): add derandomized keypair generation for ML-DSA (OQS_SIG_keypair_derand)#2476

Open
systemslibrarian wants to merge 2 commits into
open-quantum-safe:mainfrom
systemslibrarian:feature/sig-keypair-derand
Open

feat(sig): add derandomized keypair generation for ML-DSA (OQS_SIG_keypair_derand)#2476
systemslibrarian wants to merge 2 commits into
open-quantum-safe:mainfrom
systemslibrarian:feature/sig-keypair-derand

Conversation

@systemslibrarian

Copy link
Copy Markdown

Closes #2475.

Summary

Exposes deterministic / derandomized keypair generation for the OQS_SIG family, mirroring the existing OQS_KEM derand API:

  • Adds a keypair_derand(pk, sk, seed) function pointer and a length_keypair_seed field to OQS_SIG, plus a top-level OQS_SIG_keypair_derand(...) wrapper — the same shape OQS_KEM already has.
  • Implements OQS_SIG_ml_dsa_{44,65,87}_keypair_derand over FIPS-204's seed-based keygen (ML-DSA.KeyGen_internal(ξ), a 32-byte seed). For schemes without seed-based keygen, keypair_derand is NULL, length_keypair_seed is 0, and the wrapper returns OQS_ERROR.
  • Propagates a family-level derandomized_keypair flag through copy_from_upstream so the per-scheme symbol and the decl/def guards are generated, and regenerates the SIG docs (adds the "Keypair seed size (bytes)" column already present on the KEM docs).

This unblocks seed/passphrase-recoverable post-quantum signing keys (e.g. deriving an ML-DSA signing key from a BIP-39 mnemonic), which the KEM side already supports via keypair_derand.

Testing (all in CI)

  • tests/test_sig.c — verifies determinism (same seed → identical pk/sk) and that the derived keypair is functional (sign/verify), plus the NULL-contract for schemes without derand.
  • tests/vectors_sig.c — the ACVP keyGen vector's seed is exactly FIPS-204's ξ, so this now also feeds it to OQS_SIG_keypair_derand and requires the result to match NIST's known-answer pk/sk — proving the public API really computes KeyGen_internal(ξ). Runs under tests/test_acvp_vectors.py.
  • tests/fuzz_test_sig.c — exercises OQS_SIG_keypair_derand under libFuzzer/ASAN where supported.

Locally: ACVP keyGen KAT green for ML-DSA-44/65/87 (with a negative control), libFuzzer/ASAN clean, astyle clean on changed files, and test_code_conventions.py passes (265).

Version / API checklist

  • Does this PR change the input/output behaviour of a cryptographic algorithm (i.e., does it change known answer test values)? — No. Existing keygen output is unchanged; this only adds a new way to supply the seed. The derand path reproduces the same FIPS-204 ACVP known answers.
  • Does this PR change the list of algorithms available / otherwise change an API? — Yes, additively. It adds (does not remove/rename) a function pointer + a field at the end of OQS_SIG and a new OQS_SIG_keypair_derand symbol, mirroring OQS_KEM. No algorithms are added/removed/renamed. Flagging for maintainer judgment on whether oqs-provider / benchmarking-list updates are wanted, given the change is purely additive.

Generative AI disclosure

Portions of the test scaffolding and this description were drafted with the help of generative AI (Claude). The contributor has reviewed and verified the changes — including running the ACVP KAT, fuzzer, and convention checks — and affirms them.

systemslibrarian and others added 2 commits June 26, 2026 02:18
Add OQS_SIG_keypair_derand, mirroring the existing OQS_KEM derand API: a
keypair_derand function pointer and length_keypair_seed field on OQS_SIG,
a top-level OQS_SIG_keypair_derand wrapper, and per-scheme
OQS_SIG_ml_dsa_{44,65,87}_keypair_derand backed by FIPS-204
ML-DSA.KeyGen_internal over a 32-byte seed.

- copy_from_upstream: propagate the family-level derandomized_keypair flag
  into SIG scheme scope and derive the per-impl derand symbol as
  <signature_keypair>_internal (upstream mldsa-native META exposes no
  separate derand symbol); guard the whole keypair_derand definition on
  derandomized_keypair so non-derand schemes emit neither decl nor def.
- docs: add "Keypair seed size (bytes)" to the SIG parameter-set tables.
- tests: sig_test_derand verifies determinism (same seed -> identical
  pk/sk), seed-dependence (different seed -> different keypair), a
  sign/verify round-trip on the derived key, and the NULL/unsupported
  contract for schemes without derandomized keygen.

Implements open-quantum-safe#2475

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Paul Clark <paul@systemslibrarian.dev>
- fuzz_test_sig: exercise OQS_SIG_keypair_derand under libFuzzer/ASAN
- vectors_sig: cross-check derand keygen against FIPS-204 ACVP keyGen
  known answers (the ACVP seed is xi), proving KeyGen_internal(xi)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Paul Clark <paul@systemslibrarian.dev>
@systemslibrarian systemslibrarian force-pushed the feature/sig-keypair-derand branch from 9fe9fe9 to c729851 Compare June 26, 2026 02:18
@systemslibrarian systemslibrarian marked this pull request as ready for review June 26, 2026 02:21
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.

Feature request: expose deterministic/derandomized keygen for the SIG family (OQS_SIG_*_keypair_derand) — mirroring the existing OQS_KEM derand API

1 participant