Skip to content

Implementation of XMSS^MT#5358

Open
TJ-91 wants to merge 5 commits intorandombit:masterfrom
TJ-91:xmssmt-dev
Open

Implementation of XMSS^MT#5358
TJ-91 wants to merge 5 commits intorandombit:masterfrom
TJ-91:xmssmt-dev

Conversation

@TJ-91
Copy link
Copy Markdown
Contributor

@TJ-91 TJ-91 commented Feb 18, 2026

This implements XMSS^MT as a separate module which re-uses internal XMSS functionality.

I refactored and extended XMSS as far as is needed to not re-implement any XMSS functionality. I moved some core XMSS algorithms like tree_hash to xmss_core_ops.cpp and made it independent of XMSS keys and instead pass the required data.

Some noteworthy changes:

  • I changed the XMSS Index Registry to use uint64_t as leaf index since XMSS^MT has larger trees (up to a total height of 60). XMSS^MT simply uses the same registry and that should be no problem: The seed and the prf are equally used in XMSS^MT and the keys can be uniquely identified by it. (outdated)
  • in test_pubkey.cpp I changed
    -        result.test_sz_lt("Key has reasonable estimated strength (upper)", key.estimated_strength(), 512);
    +        result.test_sz_lte("Key has reasonable estimated strength (upper)", key.estimated_strength(), 512);
    It seems like I added the first test where an algorithm of strength 512 is actually used and using "lt" seems to be a typo.

Further notes:

  • The X.509-related stuff is not complete. PQC certificate formats will be implemented in future PRs (as part of the project P663 for the German BSI).
  • Are there any opinions on the speed and number of XMSS^MT tests? I added the tests from test_xmssmt.cpp to slow tests (ci) and generally left out the parameter sets that have large XMSS subtrees (height 20).
  • For the original XMSS code, size_t is used for the leaf index which can be more than 16 bits. Is there any particular reason why one wouldn't simply use uint32_t or similar?

Todo:

closes #5256

@TJ-91 TJ-91 force-pushed the xmssmt-dev branch 11 times, most recently from 46d0701 to 4cbc0b8 Compare February 19, 2026 15:30
@coveralls
Copy link
Copy Markdown

coveralls commented Feb 19, 2026

Coverage Status

coverage: 90.241% (-0.09%) from 90.33%
when pulling f2bba6c on TJ-91:xmssmt-dev
into 2cf293e on randombit:master.

@randombit randombit added this to the Botan 3.12 milestone Feb 20, 2026
@TJ-91 TJ-91 force-pushed the xmssmt-dev branch 2 times, most recently from 8769160 to f2bba6c Compare February 20, 2026 09:16
@TJ-91 TJ-91 marked this pull request as ready for review February 20, 2026 12:57
@TJ-91
Copy link
Copy Markdown
Contributor Author

TJ-91 commented Feb 20, 2026

@randombit @reneme I removed the draft status and welcome any feedback

@randombit
Copy link
Copy Markdown
Owner

For the original XMSS code, size_t is used for the leaf index which can be more than 16 bits. Is there any particular reason why one wouldn't simply use uint32_t or similar?

No I think this should be a specific length, probably uint64_t since that's what is used in the new state index (#5382) currently XMSS just casts those values down to size_t.

@randombit
Copy link
Copy Markdown
Owner

Sorry about all the merge conflicts btw, this recent work was unplanned, the issue of errors on concurrent usage was only recently brought to my attention and that's what is driving the XMSS patches.

@randombit randombit self-requested a review February 23, 2026 13:30
Comment thread src/lib/pubkey/xmssmt/xmssmt_privatekey.cpp Outdated
Comment thread src/lib/pubkey/xmssmt/xmssmt_publickey.cpp Outdated
Comment thread src/lib/pubkey/xmssmt/xmssmt_signature_operation.cpp Outdated
Comment thread src/lib/pubkey/xmssmt/xmssmt_signature_operation.cpp Outdated
Comment thread src/lib/pubkey/xmssmt/xmssmt_verification_operation.cpp
Comment thread src/lib/pubkey/xmssmt/xmssmt_parameters.h Outdated
@TJ-91 TJ-91 force-pushed the xmssmt-dev branch 2 times, most recently from 6b52f9c to 3cd9263 Compare February 25, 2026 15:42
@TJ-91
Copy link
Copy Markdown
Contributor Author

TJ-91 commented Feb 26, 2026

I squashed before rebasing to make my life (a lot) easier and now switched to only allowing the ASN.1 OCTET STRING encoding

@TJ-91 TJ-91 force-pushed the xmssmt-dev branch 2 times, most recently from 95d8525 to ed2ed6f Compare February 26, 2026 16:30
Comment thread src/lib/pubkey/xmssmt/xmssmt.h Outdated
TJ-91 added 4 commits March 31, 2026 09:29
XMSS^MT: implement pubkey and verify

XMSS^MT: implement keygen and sign

XMSS^MT: refactor common XMSS and XMSS^MT code
adjust for leaf idx >32 bit in the index registry
add test vector files to git

clang tidy

XMSS^MT: add some tests and documentation
various small fixes

Remove XMSS^MT private key shared mutable state (see randombit#5366), disabled for now (see randombit#5369)
@TJ-91
Copy link
Copy Markdown
Contributor Author

TJ-91 commented Apr 17, 2026

I now added CT::poison to the private seed/prf values for XMSS and XMSS^MT.
I unpoison when the values become public: WOTS+ Signature and WOTS+ Public Key components, as well as signature randomness.

In my understanding this should cover all cases but if a more sophisticated approach is required please let me know.

As expected, no leaks are found (I tested the example programs since they only execute one relatively fast parameter set)

@randombit randombit modified the milestones: Botan 3.12, Botan 3.13 Apr 27, 2026
@randombit
Copy link
Copy Markdown
Owner

@TJ-91 sorry have not and will not have time to review this in time for 3.12 (being released next Tuesday), bumped to 3.13

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.

Implementation of XMSS^MT

4 participants