Skip to content

Comments

Implementation of XMSS^MT#5358

Open
TJ-91 wants to merge 1 commit intorandombit:masterfrom
TJ-91:xmssmt-dev
Open

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

Conversation

@TJ-91
Copy link
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.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.
  • 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

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
Contributor Author

TJ-91 commented Feb 20, 2026

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

@randombit
Copy link
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
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

// The public part of the input key bits was already parsed, so we can
// decide depending on the buffer length whether this must be BER decoded.
if(key_bits.size() == xmssmt_params.raw_private_key_size()) {
Copy link
Collaborator

@falko-strenzke falko-strenzke Feb 24, 2026

Choose a reason for hiding this comment

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

The fallback decoding is not needed, since there are no previous XMSS^MT private keys.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

true, it's the same for the public keys but I will then need to encode the test vectors accordingly.

}

// fall back to raw decoding
// TODO: in contrast to XMSS there are no old versions to support, however, the test vectors are decoded as raw keys (no octet string)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, there should be no fallback decoding for XMSS^MT in my view.


#include <botan/internal/xmss_core.h>
#include <botan/internal/xmss_tools.h>
#include <array>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not needed acc. to clang-tidy.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this refer to #include <array>? I think without it some Windows CI fails

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)
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