Professional Documents
Culture Documents
RFC 8391
RFC 8391
Huelsing
Request for Comments: 8391 TU Eindhoven
Category: Informational D. Butin
ISSN: 2070-1721 TU Darmstadt
S. Gazdag
genua GmbH
J. Rijneveld
Radboud University
A. Mohaisen
University of Central Florida
May 2018
Abstract
Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the
document authors. All rights reserved.
Table of Contents
1. Introduction ....................................................5
1.1. CFRG Note on Post-Quantum Cryptography .....................6
1.2. Conventions Used in This Document ..........................7
2. Notation ........................................................7
2.1. Data Types .................................................7
2.2. Functions ..................................................7
2.3. Operators ..................................................8
2.4. Integer-to-Byte Conversion .................................9
2.5. Hash Function Address Scheme ...............................9
2.6. Strings of Base w Numbers .................................12
2.7. Member Functions ..........................................13
3. Primitives .....................................................14
3.1. WOTS+: One-Time Signatures ................................14
3.1.1. WOTS+ Parameters ...................................14
3.1.1.1. WOTS+ Functions ...........................15
3.1.2. WOTS+ Chaining Function ............................15
3.1.3. WOTS+ Private Key ..................................16
3.1.4. WOTS+ Public Key ...................................17
3.1.5. WOTS+ Signature Generation .........................17
3.1.6. WOTS+ Signature Verification .......................19
3.1.7. Pseudorandom Key Generation ........................20
4. Schemes ........................................................20
4.1. XMSS: eXtended Merkle Signature Scheme ....................20
4.1.1. XMSS Parameters ....................................21
4.1.2. XMSS Hash Functions ................................22
4.1.3. XMSS Private Key ...................................22
4.1.4. Randomized Tree Hashing ............................23
4.1.5. L-Trees ............................................23
4.1.6. TreeHash ...........................................24
4.1.7. XMSS Key Generation ................................25
4.1.8. XMSS Signature .....................................27
4.1.9. XMSS Signature Generation ..........................28
4.1.10. XMSS Signature Verification .......................30
4.1.11. Pseudorandom Key Generation .......................32
4.1.12. Free Index Handling and Partial Private Keys ......33
4.2. XMSS^MT: Multi-Tree XMSS ..................................33
4.2.1. XMSS^MT Parameters .................................33
4.2.2. XMSS^MT Key Generation .............................33
4.2.3. XMSS^MT Signature ..................................36
4.2.4. XMSS^MT Signature Generation .......................37
4.2.5. XMSS^MT Signature Verification .....................39
4.2.6. Pseudorandom Key Generation ........................40
4.2.7. Free Index Handling and Partial Private Keys .......40
1. Introduction
OTS schemes, and MTS schemes composed from them, were proposed by
Merkle in 1979 [Merkle83]. They were well-studied in the 1990s and
have regained interest from the mid 2000s onwards because of their
resistance against quantum-computer-aided attacks. These kinds of
signature schemes are called hash-based signature schemes as they are
built out of a cryptographic hash function. Hash-based signature
schemes generally feature small private and public keys as well as
fast signature generation and verification; however, they also
feature large signatures and relatively slow key generation. In
addition, they are suitable for compact implementations that benefit
various applications and are naturally resistant to most kinds of
side-channel attacks.
Note that the fact that the schemes described in this document are
stateful also implies that classical APIs for digital signatures
cannot be used without modification. The API MUST be able to handle
a secret key state; in particular, this means that the API MUST allow
to return an updated secret key state.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
2. Notation
Bytes and byte strings are the fundamental data types. A byte is a
sequence of eight bits. A single byte is denoted as a pair of
hexadecimal digits with a leading "0x". A byte string is an ordered
sequence of zero or more bytes and is denoted as an ordered sequence
of hexadecimal characters with a leading "0x". For example, 0xe534f0
is a byte string of length 3. An array of byte strings is an
ordered, indexed set starting with index 0 in which all byte strings
have identical length. We assume big-endian representation for any
data types or structures.
2.2. Functions
2.3. Operators
Arrays are used in the common way, where the i^th element of an array
A is denoted A[i]. Byte strings are treated as arrays of bytes where
necessary: if X is a byte string, then X[i] denotes its i^th byte,
where X[0] is the leftmost byte.
The schemes in the next two sections use two kinds of hash functions
parameterized by security parameter n. For the hash tree
constructions, a hash function that maps an n-byte key and 2n-byte
inputs to n-byte outputs is used. To randomize this function, 3n
bytes are needed -- n bytes for the key and 2n bytes for a bitmask.
For the OTS scheme constructions, a hash function that maps n-byte
keys and n-byte inputs to n-byte outputs is used. To randomize this
function, 2n bytes are needed -- n bytes for the key and n bytes for
a bitmask. Consequently, three addresses are needed for the first
function and two addresses for the second one.
There are three different types of addresses for the different use
cases. One type is used for the hashes in OTS schemes, one is used
for hashes within the main Merkle tree construction, and one is used
for hashes in the L-trees. The latter is used to compress one-time
public keys. All these types share as much format as possible. In
the remainder of this section, we describe these types in detail.
We first describe the OTS address case. In this case, the type word
is followed by an OTS address word that encodes the index of the OTS
key pair within the tree. The next word encodes the chain address
followed by a word that encodes the address of the hash function call
within the chain. The last word, called keyAndMask, is used to
generate two different addresses for one hash function call. The
word is set to zero to generate the key. To generate the n-byte
bitmask, the word is set to one.
+-------------------------+
| layer address (32 bits)|
+-------------------------+
| tree address (64 bits)|
+-------------------------+
| type = 0 (32 bits)|
+-------------------------+
| OTS address (32 bits)|
+-------------------------+
| chain address (32 bits)|
+-------------------------+
| hash address (32 bits)|
+-------------------------+
| keyAndMask (32 bits)|
+-------------------------+
We now discuss the L-tree case, which means that the type word is set
to one. In that case, the type word is followed by an L-tree address
word that encodes the index of the leaf computed with this L-tree.
The next word encodes the height of the node being input for the next
computation inside the L-tree. The following word encodes the index
of the node at that height, inside the L-tree. This time, the last
word, keyAndMask, is used to generate three different addresses for
one function call. The word is set to zero to generate the key. To
generate the most significant n bytes of the 2n-byte bitmask, the
word is set to one. The least significant bytes are generated using
the address with the word set to two.
+-------------------------+
| layer address (32 bits)|
+-------------------------+
| tree address (64 bits)|
+-------------------------+
| type = 1 (32 bits)|
+-------------------------+
| L-tree address (32 bits)|
+-------------------------+
| tree height (32 bits)|
+-------------------------+
| tree index (32 bits)|
+-------------------------+
| keyAndMask (32 bits)|
+-------------------------+
An L-tree Address
We now describe the remaining type for the main tree hash addresses.
In this case, the type word is set to two, followed by a zero padding
of one word. The next word encodes the height of the tree node being
input for the next computation, followed by a word that encodes the
index of this node at that height. As for the L-tree addresses, the
last word, keyAndMask, is used to generate three different addresses
for one function call. The word is set to zero to generate the key.
To generate the most significant n bytes of the 2n-byte bitmask, the
word is set to one. The least significant bytes are generated using
the address with the word set to two.
+-------------------------+
| layer address (32 bits)|
+-------------------------+
| tree address (64 bits)|
+-------------------------+
| type = 2 (32 bits)|
+-------------------------+
| Padding = 0 (32 bits)|
+-------------------------+
| tree height (32 bits)|
+-------------------------+
| tree index (32 bits)|
+-------------------------+
| keyAndMask (32 bits)|
+-------------------------+
Algorithm 1: base_w
int in = 0;
int out = 0;
unsigned int total = 0;
int bits = 0;
int consumed;
X (represented as bits)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 0| 0| 0| 1| 0| 0| 1| 0| 0| 0| 1| 1| 0| 1| 0| 0|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
X[0] | X[1]
base_w(X, 16, 4)
+-----------+-----------+-----------+-----------+
| 1 | 2 | 3 | 4 |
+-----------+-----------+-----------+-----------+
a[0] a[1] a[2] a[3]
base_w(X, 16, 3)
+-----------+-----------+-----------+
| 1 | 2 | 3 |
+-----------+-----------+-----------+
a[0] a[1] a[2]
base_w(X, 16, 2)
+-----------+-----------+
| 1 | 2 |
+-----------+-----------+
a[0] a[1]
Example
3. Primitives
WOTS+ uses the parameters n and w; they both take positive integer
values. These parameters are summarized as follows:
The parameters are used to compute values len, len_1, and len_2:
if ( s == 0 ) {
return X;
}
if ( (i + s) > (w - 1) ) {
return NULL;
}
byte[n] tmp = chain(X, i, s - 1, SEED, ADRS);
ADRS.setHashAddress(i + s - 1);
ADRS.setKeyAndMask(0);
KEY = PRF(SEED, ADRS);
ADRS.setKeyAndMask(1);
BM = PRF(SEED, ADRS);
Input: No input
Output: WOTS+ private key sk
ADRS except for the last three 32-bit words. Please note that the
SEED used here is public information also available to a verifier.
The pseudocode for signature generation is shown below (Algorithm 5),
where M is the message and sig is the resulting signature.
Input: Message M, WOTS+ private key sk, address ADRS, seed SEED
Output: WOTS+ signature sig
csum = 0;
// Compute checksum
for ( i = 0; i < len_1; i++ ) {
csum = csum + w - 1 - msg[i];
}
+---------------------------------+
| |
| sig_ots[0] | n bytes
| |
+---------------------------------+
| |
˜ .... ˜
| |
+---------------------------------+
| |
| sig_ots[len - 1] | n bytes
| |
+---------------------------------+
WOTS+ Signature
csum = 0;
// Compute checksum
for ( i = 0; i < len_1; i++ ) {
csum = csum + w - 1 - msg[i];
}
4. Schemes
(public) seed that is part of the public key using the pseudorandom
function PRF. The value corresponding to the root of the XMSS tree
forms the XMSS public key together with the seed.
To generate a key pair that can be used to sign 2^h messages, a tree
of height h is used. XMSS is a stateful signature scheme, meaning
that the private key changes with every signature generation. To
prevent one-time private keys from being used twice, the WOTS+ key
pairs are numbered from 0 to (2^h) - 1 according to the related leaf,
starting from index 0 for the leftmost leaf. The private key
contains an index that is updated with every signature generation,
such that it contains the index of the next unused WOTS+ key pair.
A signature consists of the index of the used WOTS+ key pair, the
WOTS+ signature on the message, and the so-called authentication
path. The latter is a vector of tree nodes that allow a verifier to
compute a value for the root of the tree starting from a WOTS+
signature. A verifier computes the root value and compares it to the
respective value in the XMSS public key. If they match, the
signature is declared valid. The XMSS private key consists of all
WOTS+ private keys and the current index. To reduce storage, a
pseudorandom key generation procedure, as described in [BDH11], MAY
be used. The security of the used method MUST at least match the
security of the XMSS instance.
For XMSS and XMSS^MT, private and public keys are denoted by SK (S
for secret) and PK, respectively. For WOTS+, private and public keys
are denoted by sk (s for secret) and pk, respectively. XMSS and
XMSS^MT signatures are denoted by Sig. WOTS+ signatures are denoted
by sig.
An XMSS private key SK contains 2^h WOTS+ private keys, the leaf
index idx of the next WOTS+ private key that has not yet been used,
SK_PRF (an n-byte key to generate pseudorandom values for randomized
message hashing), the n-byte value root (which is the root node of
the tree and SEED), and the n-byte public seed used to pseudorandomly
generate bitmasks and hash function keys. Although root and SEED
formally would be considered only part of the public key, they are
needed (e.g., for signature generation) and hence are also required
for functions that do not take the public key as input.
The leaf index idx is initialized to zero when the XMSS private key
is created. The key SK_PRF MUST be sampled from a secure source of
randomness that follows the uniform distribution. The WOTS+ private
keys MUST be generated as described in Section 3.1, or, to reduce the
private key size, a cryptographic pseudorandom method MUST be used as
discussed in Section 4.1.11. SEED is generated as a uniformly random
n-byte string. Although SEED is public, it is critical for security
that it is generated using a good entropy source. The root node is
generated as described below in the section on key generation
(Section 4.1.7). That section also contains an example algorithm for
combined private and public key generation.
Algorithm 7: RAND_HASH
ADRS.setKeyAndMask(0);
KEY = PRF(SEED, ADRS);
ADRS.setKeyAndMask(1);
BM_0 = PRF(SEED, ADRS);
ADRS.setKeyAndMask(2);
BM_1 = PRF(SEED, ADRS);
4.1.5. L-Trees
Algorithm 8: ltree
4.1.6. TreeHash
Algorithm 9: treeHash
Input: XMSS private key SK, start index s, target node height t,
address ADRS
Output: n-byte root node - top node on Stack
Input: No input
Output: XMSS private key SK, XMSS public key PK
+---------------------------------+
| algorithm OID |
+---------------------------------+
| |
| root node | n bytes
| |
+---------------------------------+
| |
| SEED | n bytes
| |
+---------------------------------+
+---------------------------------+
| |
| index idx_sig | 4 bytes
| |
+---------------------------------+
| |
| randomness r | n bytes
| |
+---------------------------------+
| |
| WOTS+ signature sig_ots | len * n bytes
| |
+---------------------------------+
| |
| auth[0] | n bytes
| |
+---------------------------------+
| |
˜ .... ˜
| |
+---------------------------------+
| |
| auth[h - 1] | n bytes
| |
+---------------------------------+
XMSS Signature
Given an XMSS private key SK, all nodes in a tree are determined.
Their values are defined in terms of treeHash (Algorithm 9). Hence,
one can compute the authentication path as follows:
Input: XMSS private key SK, WOTS+ key pair index i, ADRS
Output: Authentication path auth
idx_sig = getIdx(SK);
setIdx(SK, idx_sig + 1);
ADRS = toByte(0, 32);
byte[n] r = PRF(getSK_PRF(SK), toByte(idx_sig, 32));
byte[n] M’ = H_msg(r || getRoot(SK) || (toByte(idx_sig, n)), M);
Sig = idx_sig || r || treeSig(M’, SK, idx_sig, ADRS);
return (SK || Sig);
For XMSS, a method similar to that for WOTS+ can be used. The
suggested method from [BDH11] can be described using PRF. During key
generation, a uniformly random n-byte string S is sampled from a
secure source of randomness. This seed S MUST NOT be confused with
the public seed SEED. The seed S MUST be independent of SEED, and
because it is the main secret, it MUST be kept secret. This seed S
is used to generate an n-byte value S_ots for each WOTS+ key pair.
The n-byte value S_ots can then be used to compute the respective
WOTS+ private key using the method described in Section 3.1.7. The
seeds for the WOTS+ key pairs are computed as S_ots[i] = PRF(S,
toByte(i, 32)) where i is the index of the WOTS+ key pair. An
advantage of this method is that a WOTS+ key can be computed using
only len + 1 evaluations of PRF when S is given.
All the trees on higher layers sign root nodes of other trees, with
the root nodes being n-byte strings. Hence, no message compression
is needed, and WOTS+ is used to sign the root nodes themselves
instead of their hash values.
(which is the root of the single tree on the top layer). The index
is a global index over all WOTS+ key pairs of all XMSS trees on layer
0. It is initialized with 0. It stores the index of the last used
WOTS+ key pair on the bottom layer, i.e., a number between 0 and 2^h
- 1.
This document does not define any specific format for the XMSS^MT
private key SK_MT as it is not required for interoperability.
Algorithms 15 and 16 use a function getXMSS_SK(SK, x, y) that outputs
the reduced private key of the x^th XMSS tree on the y^th layer.
The XMSS^MT public key PK_MT contains the root of the single XMSS
tree on layer d - 1 and the seed SEED. These are the same values as
in the private key SK_MT. The pseudorandom function PRF keyed with
SEED is used to generate the bitmasks and keys for all XMSS trees.
XMSSMT_keyGen (Algorithm 15) shows example pseudocode to generate
SK_MT and PK_MT. The n-byte root node of the top-layer tree is
computed using treeHash. The algorithm XMSSMT_keyGen outputs an
XMSS^MT private key SK_MT and an XMSS^MT public key PK_MT. The
algorithm below gives an example of how the reduced XMSS private keys
can be generated. However, any of the above mentioned ways is
acceptable as long as the cryptographic strength of the used method
matches or supersedes that of the used XMSS^MT parameter set.
Input: No input
Output: XMSS^MT private key SK_MT, XMSS^MT public key PK_MT
// Example initialization
idx_MT = 0;
setIdx(SK_MT, idx_MT);
initialize SK_PRF with a uniformly random n-byte string;
setSK_PRF(SK_MT, SK_PRF);
initialize SEED with a uniformly random n-byte string;
setSEED(SK_MT, SEED);
SK = getXMSS_SK(SK_MT, 0, d - 1);
setSEED(SK, SEED);
root = treeHash(SK, 0, h / d, ADRS);
setRoot(SK_MT, root);
+---------------------------------+
| algorithm OID |
+---------------------------------+
| |
| root node | n bytes
| |
+---------------------------------+
| |
| SEED | n bytes
| |
+---------------------------------+
o the index idx_sig of the used WOTS+ key pair on the bottom layer
(ceil(h / 8) bytes),
+---------------------------------+
| |
| index idx_sig | ceil(h / 8) bytes
| |
+---------------------------------+
| |
| randomness r | n bytes
| |
+---------------------------------+
| |
| (reduced) XMSS signature Sig | (h / d + len) * n bytes
| (bottom layer 0) |
| |
+---------------------------------+
| |
| (reduced) XMSS signature Sig | (h / d + len) * n bytes
| (layer 1) |
| |
+---------------------------------+
| |
˜ .... ˜
| |
+---------------------------------+
| |
| (reduced) XMSS signature Sig | (h / d + len) * n bytes
| (layer d - 1) |
| |
+---------------------------------+
XMSS^MT Signature
// Init
ADRS = toByte(0, 32);
SEED = getSEED(SK_MT);
SK_PRF = getSK_PRF(SK_MT);
idx_sig = getIdx(SK_MT);
// Update SK_MT
setIdx(SK_MT, idx_sig + 1);
// Message compression
byte[n] r = PRF(SK_PRF, toByte(idx_sig, 32));
byte[n] M’ = H_msg(r || getRoot(SK_MT) || (toByte(idx_sig, n)), M);
// Sign
Sig_MT = idx_sig;
unsigned int idx_tree
= (h - h / d) most significant bits of idx_sig;
unsigned int idx_leaf = (h / d) least significant bits of idx_sig;
SK = idx_leaf || getXMSS_SK(SK_MT, idx_tree, 0) || SK_PRF
|| toByte(0, n) || SEED;
ADRS.setLayerAddress(0);
ADRS.setTreeAddress(idx_tree);
Sig_tmp = treeSig(M’, SK, idx_leaf, ADRS);
Sig_MT = Sig_MT || r || Sig_tmp;
for ( j = 1; j < d; j++ ) {
root = treeHash(SK, 0, h / d, ADRS);
idx_leaf = (h / d) least significant bits of idx_tree;
idx_tree = (h - j * (h / d)) most significant bits of idx_tree;
SK = idx_leaf || getXMSS_SK(SK_MT, idx_tree, j) || SK_PRF
|| toByte(0, n) || SEED;
ADRS.setLayerAddress(j);
ADRS.setTreeAddress(idx_tree);
Sig_tmp = treeSig(root, SK, idx_leaf, ADRS);
Sig_MT = Sig_MT || Sig_tmp;
}
return SK_MT || Sig_MT;
idx_sig = getIdx(Sig_MT);
SEED = getSEED(PK_MT);
ADRS = toByte(0, 32);
For XMSS^MT, a method similar to that for XMSS and WOTS+ can be used.
The method uses PRF. During key generation, a uniformly random
n-byte string S_MT is sampled from a secure source of randomness.
This seed S_MT is used to generate one n-byte value S for each XMSS
key pair. This n-byte value can be used to compute the respective
XMSS private key using the method described in Section 4.1.11. Let
S[x][y] be the seed for the x^th XMSS private key on layer y. The
seeds are computed as S[x][y] = PRF(PRF(S, toByte(y, 32)), toByte(x,
32)).
5. Parameter Sets
This section provides basic parameter sets that are assumed to cover
most relevant applications. Parameter sets for two classical
security levels are defined. Parameters with n = 32 provide a
classical security level of 256 bits. Parameters with n = 64 provide
a classical security level of 512 bits. Considering quantum-
computer-aided attacks, these output sizes yield post-quantum
security of 128 and 256 bits, respectively.
+-----------------+----------+----+----+-----+
| Name | F / PRF | n | w | len |
+-----------------+----------+----+----+-----+
| REQUIRED: | | | | |
| | | | | |
| WOTSP-SHA2_256 | SHA2-256 | 32 | 16 | 67 |
| | | | | |
| OPTIONAL: | | | | |
| | | | | |
| WOTSP-SHA2_512 | SHA2-512 | 64 | 16 | 131 |
| | | | | |
| WOTSP-SHAKE_256 | SHAKE128 | 32 | 16 | 67 |
| | | | | |
| WOTSP-SHAKE_512 | SHAKE256 | 64 | 16 | 131 |
+-----------------+----------+----+----+-----+
Table 1
+-------------------+-----------+----+----+-----+----+
| Name | Functions | n | w | len | h |
+-------------------+-----------+----+----+-----+----+
| REQUIRED: | | | | | |
| | | | | | |
| XMSS-SHA2_10_256 | SHA2-256 | 32 | 16 | 67 | 10 |
| | | | | | |
| XMSS-SHA2_16_256 | SHA2-256 | 32 | 16 | 67 | 16 |
| | | | | | |
| XMSS-SHA2_20_256 | SHA2-256 | 32 | 16 | 67 | 20 |
| | | | | | |
| OPTIONAL: | | | | | |
| | | | | | |
| XMSS-SHA2_10_512 | SHA2-512 | 64 | 16 | 131 | 10 |
| | | | | | |
| XMSS-SHA2_16_512 | SHA2-512 | 64 | 16 | 131 | 16 |
| | | | | | |
| XMSS-SHA2_20_512 | SHA2-512 | 64 | 16 | 131 | 20 |
| | | | | | |
| XMSS-SHAKE_10_256 | SHAKE128 | 32 | 16 | 67 | 10 |
| | | | | | |
| XMSS-SHAKE_16_256 | SHAKE128 | 32 | 16 | 67 | 16 |
| | | | | | |
| XMSS-SHAKE_20_256 | SHAKE128 | 32 | 16 | 67 | 20 |
| | | | | | |
| XMSS-SHAKE_10_512 | SHAKE256 | 64 | 16 | 131 | 10 |
| | | | | | |
| XMSS-SHAKE_16_512 | SHAKE256 | 64 | 16 | 131 | 16 |
| | | | | | |
| XMSS-SHAKE_20_512 | SHAKE256 | 64 | 16 | 131 | 20 |
+-------------------+-----------+----+----+-----+----+
Table 2
the worst case. The last column shows the number of messages that
can be signed with one key pair. The numbers are the same for the
XMSS-SHAKE instances with same parameters h and n.
+------------------+-------+------------+--------+--------+-------+
| Name | |Sig| | KeyGen | Sign | Verify | #Sigs |
+------------------+-------+------------+--------+--------+-------+
| REQUIRED: | | | | | |
| | | | | | |
| XMSS-SHA2_10_256 | 2,500 | 1,238,016 | 5,725 | 1,149 | 2^10 |
| | | | | | |
| XMSS-SHA2_16_256 | 2,692 | 79*10^6 | 9,163 | 1,155 | 2^16 |
| | | | | | |
| XMSS-SHA2_20_256 | 2,820 | 1,268*10^6 | 11,455 | 1,159 | 2^20 |
| | | | | | |
| OPTIONAL: | | | | | |
| | | | | | |
| XMSS-SHA2_10_512 | 9,092 | 2,417,664 | 11,165 | 2,237 | 2^10 |
| | | | | | |
| XMSS-SHA2_16_512 | 9,476 | 155*10^6 | 17,867 | 2,243 | 2^16 |
| | | | | | |
| XMSS-SHA2_20_512 | 9,732 | 2,476*10^6 | 22,335 | 2,247 | 2^20 |
+------------------+-------+------------+--------+--------+-------+
Table 3
+------------------------+-----------+----+----+-----+----+----+
| Name | Functions | n | w | len | h | d |
+------------------------+-----------+----+----+-----+----+----+
| REQUIRED: | | | | | | |
| | | | | | | |
| XMSSMT-SHA2_20/2_256 | SHA2-256 | 32 | 16 | 67 | 20 | 2 |
| | | | | | | |
| XMSSMT-SHA2_20/4_256 | SHA2-256 | 32 | 16 | 67 | 20 | 4 |
| | | | | | | |
| XMSSMT-SHA2_40/2_256 | SHA2-256 | 32 | 16 | 67 | 40 | 2 |
| | | | | | | |
| XMSSMT-SHA2_40/4_256 | SHA2-256 | 32 | 16 | 67 | 40 | 4 |
| | | | | | | |
| XMSSMT-SHA2_40/8_256 | SHA2-256 | 32 | 16 | 67 | 40 | 8 |
| | | | | | | |
| XMSSMT-SHA2_60/3_256 | SHA2-256 | 32 | 16 | 67 | 60 | 3 |
| | | | | | | |
| XMSSMT-SHA2_60/6_256 | SHA2-256 | 32 | 16 | 67 | 60 | 6 |
| | | | | | | |
| XMSSMT-SHA2_60/12_256 | SHA2-256 | 32 | 16 | 67 | 60 | 12 |
| | | | | | | |
| OPTIONAL: | | | | | | |
| | | | | | | |
| XMSSMT-SHA2_20/2_512 | SHA2-512 | 64 | 16 | 131 | 20 | 2 |
| | | | | | | |
| XMSSMT-SHA2_20/4_512 | SHA2-512 | 64 | 16 | 131 | 20 | 4 |
| | | | | | | |
| XMSSMT-SHA2_40/2_512 | SHA2-512 | 64 | 16 | 131 | 40 | 2 |
| | | | | | | |
| XMSSMT-SHA2_40/4_512 | SHA2-512 | 64 | 16 | 131 | 40 | 4 |
| | | | | | | |
| XMSSMT-SHA2_40/8_512 | SHA2-512 | 64 | 16 | 131 | 40 | 8 |
| | | | | | | |
| XMSSMT-SHA2_60/3_512 | SHA2-512 | 64 | 16 | 131 | 60 | 3 |
| | | | | | | |
| XMSSMT-SHA2_60/6_512 | SHA2-512 | 64 | 16 | 131 | 60 | 6 |
| | | | | | | |
| XMSSMT-SHA2_60/12_512 | SHA2-512 | 64 | 16 | 131 | 60 | 12 |
| | | | | | | |
| XMSSMT-SHAKE_20/2_256 | SHAKE128 | 32 | 16 | 67 | 20 | 2 |
| | | | | | | |
| XMSSMT-SHAKE_20/4_256 | SHAKE128 | 32 | 16 | 67 | 20 | 4 |
| | | | | | | |
| XMSSMT-SHAKE_40/2_256 | SHAKE128 | 32 | 16 | 67 | 40 | 2 |
| | | | | | | |
| XMSSMT-SHAKE_40/4_256 | SHAKE128 | 32 | 16 | 67 | 40 | 4 |
| | | | | | | |
| XMSSMT-SHAKE_40/8_256 | SHAKE128 | 32 | 16 | 67 | 40 | 8 |
| | | | | | | |
| XMSSMT-SHAKE_60/3_256 | SHAKE128 | 32 | 16 | 67 | 60 | 3 |
| | | | | | | |
| XMSSMT-SHAKE_60/6_256 | SHAKE128 | 32 | 16 | 67 | 60 | 6 |
| | | | | | | |
| XMSSMT-SHAKE_60/12_256 | SHAKE128 | 32 | 16 | 67 | 60 | 12 |
| | | | | | | |
| XMSSMT-SHAKE_20/2_512 | SHAKE256 | 64 | 16 | 131 | 20 | 2 |
| | | | | | | |
| XMSSMT-SHAKE_20/4_512 | SHAKE256 | 64 | 16 | 131 | 20 | 4 |
| | | | | | | |
| XMSSMT-SHAKE_40/2_512 | SHAKE256 | 64 | 16 | 131 | 40 | 2 |
| | | | | | | |
| XMSSMT-SHAKE_40/4_512 | SHAKE256 | 64 | 16 | 131 | 40 | 4 |
| | | | | | | |
| XMSSMT-SHAKE_40/8_512 | SHAKE256 | 64 | 16 | 131 | 40 | 8 |
| | | | | | | |
| XMSSMT-SHAKE_60/3_512 | SHAKE256 | 64 | 16 | 131 | 60 | 3 |
| | | | | | | |
| XMSSMT-SHAKE_60/6_512 | SHAKE256 | 64 | 16 | 131 | 60 | 6 |
| | | | | | | |
| XMSSMT-SHAKE_60/12_512 | SHAKE256 | 64 | 16 | 131 | 60 | 12 |
+------------------------+-----------+----+----+-----+----+----+
Table 4
+----------------+---------+------------+--------+--------+-------+
| Name | |Sig| | KeyGen | Sign | Verify | #Sigs |
+----------------+---------+------------+--------+--------+-------+
| REQUIRED: | | | | | |
| | | | | | |
| SHA2_20/2_256 | 4,963 | 2,476,032 | 7,227 | 2,298 | 2^20 |
| | | | | | |
| SHA2_20/4_256 | 9,251 | 154,752 | 4,170 | 4,576 | 2^20 |
| | | | | | |
| SHA2_40/2_256 | 5,605 | 2,535*10^6 | 13,417 | 2,318 | 2^40 |
| | | | | | |
| SHA2_40/4_256 | 9,893 | 4,952,064 | 7,227 | 4,596 | 2^40 |
| | | | | | |
| SHA2_40/8_256 | 18,469 | 309,504 | 4,170 | 9,152 | 2^40 |
| | | | | | |
| SHA2_60/3_256 | 8,392 | 3,803*10^6 | 13,417 | 3,477 | 2^60 |
| | | | | | |
| SHA2_60/6_256 | 14,824 | 7,428,096 | 7,227 | 6,894 | 2^60 |
| | | | | | |
| SHA2_60/12_256 | 27,688 | 464,256 | 4,170 | 13,728 | 2^60 |
| | | | | | |
| OPTIONAL: | | | | | |
| | | | | | |
| SHA2_20/2_512 | 18,115 | 4,835,328 | 14,075 | 4,474 | 2^20 |
| | | | | | |
| SHA2_20/4_512 | 34,883 | 302,208 | 8,138 | 8,928 | 2^20 |
| | | | | | |
| SHA2_40/2_512 | 19,397 | 4,951*10^6 | 26,025 | 4,494 | 2^40 |
| | | | | | |
| SHA2_40/4_512 | 36,165 | 9,670,656 | 14,075 | 8,948 | 2^40 |
| | | | | | |
| SHA2_40/8_512 | 69,701 | 604,416 | 8,138 | 17,856 | 2^40 |
| | | | | | |
| SHA2_60/3_512 | 29,064 | 7,427*10^6 | 26,025 | 6,741 | 2^60 |
| | | | | | |
| SHA2_60/6_512 | 54,216 | 14,505,984 | 14,075 | 13,422 | 2^60 |
| | | | | | |
| SHA2_60/12_512 | 104,520 | 906,624 | 8,138 | 26,784 | 2^60 |
+----------------+---------+------------+--------+--------+-------+
Table 5
6. Rationale
The goal of this note is to describe the WOTS+, XMSS, and XMSS^MT
algorithms based on the scientific literature. The description is
done in a modular way that allows basing a description of stateless
hash-based signature algorithms like SPHINCS [BHH15] on it.
The signature and public key formats are designed so that they are
easy to parse. Each format starts with a 32-bit enumeration value
that indicates all of the details of the signature algorithm and
hence defines all of the information that is needed in order to parse
the format.
7. Reference Code
8. IANA Considerations
+--------------------+-----------------+-------------+
| Numeric Identifier | Name | Reference |
+--------------------+-----------------+-------------+
| 0x00000000 | Reserved | this RFC |
| | | |
| 0x00000001 | WOTSP-SHA2_256 | Section 5.2 |
| | | |
| 0x00000002 | WOTSP-SHA2_512 | Section 5.2 |
| | | |
| 0x00000003 | WOTSP-SHAKE_256 | Section 5.2 |
| | | |
| 0x00000004 | WOTSP-SHAKE_512 | Section 5.2 |
+--------------------+-----------------+-------------+
Table 6
+--------------------+-------------------+-------------+
| Numeric Identifier | Name | Reference |
+--------------------+-------------------+-------------+
| 0x00000000 | Reserved | this RFC |
| | | |
| 0x00000001 | XMSS-SHA2_10_256 | Section 5.3 |
| | | |
| 0x00000002 | XMSS-SHA2_16_256 | Section 5.3 |
| | | |
| 0x00000003 | XMSS-SHA2_20_256 | Section 5.3 |
| | | |
| 0x00000004 | XMSS-SHA2_10_512 | Section 5.3 |
| | | |
| 0x00000005 | XMSS-SHA2_16_512 | Section 5.3 |
| | | |
| 0x00000006 | XMSS-SHA2_20_512 | Section 5.3 |
| | | |
| 0x00000007 | XMSS-SHAKE_10_256 | Section 5.3 |
| | | |
| 0x00000008 | XMSS-SHAKE_16_256 | Section 5.3 |
| | | |
| 0x00000009 | XMSS-SHAKE_20_256 | Section 5.3 |
| | | |
| 0x0000000A | XMSS-SHAKE_10_512 | Section 5.3 |
| | | |
| 0x0000000B | XMSS-SHAKE_16_512 | Section 5.3 |
| | | |
| 0x0000000C | XMSS-SHAKE_20_512 | Section 5.3 |
+--------------------+-------------------+-------------+
Table 7
+--------------------+------------------------+-------------+
| Numeric Identifier | Name | Reference |
+--------------------+------------------------+-------------+
| 0x00000000 | Reserved | this RFC |
| | | |
| 0x00000001 | XMSSMT-SHA2_20/2_256 | Section 5.4 |
| | | |
| 0x00000002 | XMSSMT-SHA2_20/4_256 | Section 5.4 |
| | | |
| 0x00000003 | XMSSMT-SHA2_40/2_256 | Section 5.4 |
| | | |
| 0x00000004 | XMSSMT-SHA2_40/4_256 | Section 5.4 |
| | | |
| 0x00000005 | XMSSMT-SHA2_40/8_256 | Section 5.4 |
| | | |
| 0x00000006 | XMSSMT-SHA2_60/3_256 | Section 5.4 |
| | | |
| 0x00000007 | XMSSMT-SHA2_60/6_256 | Section 5.4 |
| | | |
| 0x00000008 | XMSSMT-SHA2_60/12_256 | Section 5.4 |
| | | |
| 0x00000009 | XMSSMT-SHA2_20/2_512 | Section 5.4 |
| | | |
| 0x0000000A | XMSSMT-SHA2_20/4_512 | Section 5.4 |
| | | |
| 0x0000000B | XMSSMT-SHA2_40/2_512 | Section 5.4 |
| | | |
| 0x0000000C | XMSSMT-SHA2_40/4_512 | Section 5.4 |
| | | |
| 0x0000000D | XMSSMT-SHA2_40/8_512 | Section 5.4 |
| | | |
| 0x0000000E | XMSSMT-SHA2_60/3_512 | Section 5.4 |
| | | |
| 0x0000000F | XMSSMT-SHA2_60/6_512 | Section 5.4 |
| | | |
| 0x00000010 | XMSSMT-SHA2_60/12_512 | Section 5.4 |
| | | |
| 0x00000011 | XMSSMT-SHAKE_20/2_256 | Section 5.4 |
| | | |
| 0x00000012 | XMSSMT-SHAKE_20/4_256 | Section 5.4 |
| | | |
| 0x00000013 | XMSSMT-SHAKE_40/2_256 | Section 5.4 |
| | | |
| 0x00000014 | XMSSMT-SHAKE_40/4_256 | Section 5.4 |
| | | |
| 0x00000015 | XMSSMT-SHAKE_40/8_256 | Section 5.4 |
| | | |
| 0x00000016 | XMSSMT-SHAKE_60/3_256 | Section 5.4 |
| | | |
| 0x00000017 | XMSSMT-SHAKE_60/6_256 | Section 5.4 |
| | | |
| 0x00000018 | XMSSMT-SHAKE_60/12_256 | Section 5.4 |
| | | |
| 0x00000019 | XMSSMT-SHAKE_20/2_512 | Section 5.4 |
| | | |
| 0x0000001A | XMSSMT-SHAKE_20/4_512 | Section 5.4 |
| | | |
| 0x0000001B | XMSSMT-SHAKE_40/2_512 | Section 5.4 |
| | | |
| 0x0000001C | XMSSMT-SHAKE_40/4_512 | Section 5.4 |
| | | |
| 0x0000001D | XMSSMT-SHAKE_40/8_512 | Section 5.4 |
| | | |
| 0x0000001E | XMSSMT-SHAKE_60/3_512 | Section 5.4 |
| | | |
| 0x0000001F | XMSSMT-SHAKE_60/6_512 | Section 5.4 |
| | | |
| 0x00000020 | XMSSMT-SHAKE_60/12_512 | Section 5.4 |
+--------------------+------------------------+-------------+
Table 8
9. Security Considerations
A full security proof for all schemes described in this document can
be found in [HRS16]. This proof shows that an attacker has to break
at least one out of certain security properties of the used hash
functions and PRFs to forge a signature in any of the described
schemes. The proof in [HRS16] considers an initial message
compression different from the randomized hashing used here. We
comment on this below. For the original schemes, these proofs show
that an attacker has to break certain minimal security properties.
In particular, it is not sufficient to break the collision resistance
of the hash functions to generate a forgery.
The given bit security values were estimated based on the complexity
of the best-known generic attacks against the required security
properties of the used hash and pseudorandom functions, assuming
conventional and quantum adversaries. At the time of writing,
generic attacks are the best-known attacks for the parameters
suggested in the classical setting. Also, in the quantum setting,
there are no dedicated attacks known that perform better than generic
attacks. Nevertheless, the topic of quantum cryptanalysis of hash
functions is not as well understood as in the classical setting.
10. References
[Huelsing13]
Huelsing, A., "W-OTS+ - Shorter Signatures for Hash-Based
Signature Schemes", Lecture Notes in Computer Science,
Volume 7918, Progress in Cryptology - AFRICACRYPT,
DOI 10.1007/978-3-642-38553-7_10, 2013.
[Huelsing13a]
Huelsing, A., "Practical Forward Secure Signatures using
Minimal Security Assumptions", PhD thesis TU Darmstadt,
2013,
<http://tuprints.ulb.tu-darmstadt.de/3651/1/Thesis.pdf>.
[KMN14] Knecht, M., Meier, W., and C. Nicola, "A space- and time-
efficient Implementation of the Merkle Tree Traversal
Algorithm", Computing Research Repository
(CoRR), arXiv:1409.4081, 2014.
The WOTS+ signature and public key formats are formally defined using
XDR [RFC4506] in order to provide an unambiguous, machine readable
definition. Though XDR is used, these formats are simple and easy to
parse without any special tools. Note that this representation
includes all optional parameter sets. The same applies for the XMSS
and XMSS^MT formats below.
enum ots_algorithm_type {
wotsp_reserved = 0x00000000,
wotsp-sha2_256 = 0x00000001,
wotsp-sha2_512 = 0x00000002,
wotsp-shake_256 = 0x00000003,
wotsp-shake_512 = 0x00000004,
};
/* Byte strings */
case wotsp-sha2_512:
case wotsp-shake_512:
bytestring64 ots_sig_n64_len18[131];
default:
void; /* error condition */
};
case wotsp-sha2_512:
case wotsp-shake_512:
bytestring64 ots_pubk_n64_len18[131];
default:
void; /* error condition */
};
/* Byte strings */
enum xmss_algorithm_type {
xmss_reserved = 0x00000000,
xmss-sha2_10_256 = 0x00000001,
xmss-sha2_16_256 = 0x00000002,
xmss-sha2_20_256 = 0x00000003,
xmss-sha2_10_512 = 0x00000004,
xmss-sha2_16_512 = 0x00000005,
xmss-sha2_20_512 = 0x00000006,
xmss-shake_10_256 = 0x00000007,
xmss-shake_16_256 = 0x00000008,
xmss-shake_20_256 = 0x00000009,
xmss-shake_10_512 = 0x0000000A,
xmss-shake_16_512 = 0x0000000B,
xmss-shake_20_512 = 0x0000000C,
};
case xmss-sha2_16_256:
case xmss-shake_16_256:
bytestring32 path_n32_t16[16];
case xmss-sha2_20_256:
case xmss-shake_20_256:
bytestring32 path_n32_t20[20];
case xmss-sha2_10_512:
case xmss-shake_10_512:
bytestring64 path_n64_t10[10];
case xmss-sha2_16_512:
case xmss-shake_16_512:
bytestring64 path_n64_t16[16];
case xmss-sha2_20_512:
case xmss-shake_20_512:
bytestring64 path_n64_t20[20];
default:
void; /* error condition */
};
case xmss-sha2_10_512:
case xmss-sha2_16_512:
case xmss-sha2_20_512:
case xmss-shake_10_512:
case xmss-shake_16_512:
case xmss-shake_20_512:
bytestring64 rand_n64;
default:
void; /* error condition */
};
case xmss-sha2_10_512:
case xmss-sha2_16_512:
case xmss-sha2_20_512:
wotsp-sha2_512;
case xmss-shake_10_256:
case xmss-shake_16_256:
case xmss-shake_20_256:
wotsp-shake_256;
case xmss-shake_10_512:
case xmss-shake_16_512:
case xmss-shake_20_512:
wotsp-shake_512;
default:
void; /* error condition */
};
struct xmss_signature {
/* WOTS+ key pair index */
bytestring4 idx_sig;
/* Random string for randomized hashing */
random_string_xmss rand_string;
/* WOTS+ signature */
xmss_ots_signature sig_ots;
/* authentication path */
xmss_path nodes;
};
case xmss-sha2_10_512:
case xmss-sha2_16_512:
case xmss-sha2_20_512:
case xmss-shake_10_512:
case xmss-shake_16_512:
case xmss-shake_20_512:
bytestring64 seed_n64;
default:
void; /* error condition */
};
case xmss-sha2_10_512:
case xmss-sha2_16_512:
case xmss-sha2_20_512:
case xmss-shake_10_512:
case xmss-shake_16_512:
case xmss-shake_20_512:
bytestring64 root_n64;
default:
void; /* error condition */
};
struct xmss_public_key {
xmss_root root; /* Root node */
seed SEED; /* Seed for bitmasks */
};
/* Byte strings */
enum xmssmt_algorithm_type {
xmssmt_reserved = 0x00000000,
xmssmt-sha2_20/2_256 = 0x00000001,
xmssmt-sha2_20/4_256 = 0x00000002,
xmssmt-sha2_40/2_256 = 0x00000003,
xmssmt-sha2_40/4_256 = 0x00000004,
xmssmt-sha2_40/8_256 = 0x00000005,
xmssmt-sha2_60/3_256 = 0x00000006,
xmssmt-sha2_60/6_256 = 0x00000007,
xmssmt-sha2_60/12_256 = 0x00000008,
xmssmt-sha2_20/2_512 = 0x00000009,
xmssmt-sha2_20/4_512 = 0x0000000A,
xmssmt-sha2_40/2_512 = 0x0000000B,
xmssmt-sha2_40/4_512 = 0x0000000C,
xmssmt-sha2_40/8_512 = 0x0000000D,
xmssmt-sha2_60/3_512 = 0x0000000E,
xmssmt-sha2_60/6_512 = 0x0000000F,
xmssmt-sha2_60/12_512 = 0x00000010,
xmssmt-shake_20/2_256 = 0x00000011,
xmssmt-shake_20/4_256 = 0x00000012,
xmssmt-shake_40/2_256 = 0x00000013,
xmssmt-shake_40/4_256 = 0x00000014,
xmssmt-shake_40/8_256 = 0x00000015,
xmssmt-shake_60/3_256 = 0x00000016,
xmssmt-shake_60/6_256 = 0x00000017,
xmssmt-shake_60/12_256 = 0x00000018,
xmssmt-shake_20/2_512 = 0x00000019,
xmssmt-shake_20/4_512 = 0x0000001A,
xmssmt-shake_40/2_512 = 0x0000001B,
xmssmt-shake_40/4_512 = 0x0000001C,
xmssmt-shake_40/8_512 = 0x0000001D,
xmssmt-shake_60/3_512 = 0x0000001E,
xmssmt-shake_60/6_512 = 0x0000001F,
xmssmt-shake_60/12_512 = 0x00000020,
};
case xmssmt-sha2_40/2_256:
case xmssmt-sha2_40/4_256:
case xmssmt-sha2_40/8_256:
case xmssmt-sha2_40/2_512:
case xmssmt-sha2_40/4_512:
case xmssmt-sha2_40/8_512:
case xmssmt-shake_40/2_256:
case xmssmt-shake_40/4_256:
case xmssmt-shake_40/8_256:
case xmssmt-shake_40/2_512:
case xmssmt-shake_40/4_512:
case xmssmt-shake_40/8_512:
bytestring5 idx5;
case xmssmt-sha2_60/3_256:
case xmssmt-sha2_60/6_256:
case xmssmt-sha2_60/12_256:
case xmssmt-sha2_60/3_512:
case xmssmt-sha2_60/6_512:
case xmssmt-sha2_60/12_512:
case xmssmt-shake_60/3_256:
case xmssmt-shake_60/6_256:
case xmssmt-shake_60/12_256:
case xmssmt-shake_60/3_512:
case xmssmt-shake_60/6_512:
case xmssmt-shake_60/12_512:
bytestring8 idx8;
default:
void; /* error condition */
};
case xmssmt-sha2_20/2_512:
case xmssmt-sha2_20/4_512:
case xmssmt-sha2_40/2_512:
case xmssmt-sha2_40/4_512:
case xmssmt-sha2_40/8_512:
case xmssmt-sha2_60/3_512:
case xmssmt-sha2_60/6_512:
case xmssmt-sha2_60/12_512:
case xmssmt-shake_20/2_512:
case xmssmt-shake_20/4_512:
case xmssmt-shake_40/2_512:
case xmssmt-shake_40/4_512:
case xmssmt-shake_40/8_512:
case xmssmt-shake_60/3_512:
case xmssmt-shake_60/6_512:
case xmssmt-shake_60/12_512:
bytestring64 rand_n64;
default:
void; /* error condition */
};
case xmssmt-sha2_20/4_256:
case xmssmt-sha2_40/8_256:
case xmssmt-sha2_60/12_256:
case xmssmt-shake_20/4_256:
case xmssmt-shake_40/8_256:
case xmssmt-shake_60/12_256:
bytestring32 xmss_reduced_n32_t72[72];
case xmssmt-sha2_40/2_256:
case xmssmt-sha2_60/3_256:
case xmssmt-shake_40/2_256:
case xmssmt-shake_60/3_256:
bytestring32 xmss_reduced_n32_t87[87];
case xmssmt-sha2_20/2_512:
case xmssmt-sha2_40/4_512:
case xmssmt-sha2_60/6_512:
case xmssmt-shake_20/2_512:
case xmssmt-shake_40/4_512:
case xmssmt-shake_60/6_512:
bytestring64 xmss_reduced_n32_t141[141];
case xmssmt-sha2_20/4_512:
case xmssmt-sha2_40/8_512:
case xmssmt-sha2_60/12_512:
case xmssmt-shake_20/4_512:
case xmssmt-shake_40/8_512:
case xmssmt-shake_60/12_512:
bytestring64 xmss_reduced_n32_t136[136];
case xmssmt-sha2_40/2_512:
case xmssmt-sha2_60/3_512:
case xmssmt-shake_40/2_512:
case xmssmt-shake_60/3_512:
bytestring64 xmss_reduced_n32_t151[151];
default:
void; /* error condition */
};
/* xmss_reduced_array depends on d */
case xmssmt-sha2_60/3_256:
case xmssmt-sha2_60/3_512:
case xmssmt-shake_60/3_256:
case xmssmt-shake_60/3_512:
xmss_reduced xmss_red_arr_d3[3];
case xmssmt-sha2_20/4_256:
case xmssmt-sha2_20/4_512:
case xmssmt-sha2_40/4_256:
case xmssmt-sha2_40/4_512:
case xmssmt-shake_20/4_256:
case xmssmt-shake_20/4_512:
case xmssmt-shake_40/4_256:
case xmssmt-shake_40/4_512:
xmss_reduced xmss_red_arr_d4[4];
case xmssmt-sha2_60/6_256:
case xmssmt-sha2_60/6_512:
case xmssmt-shake_60/6_256:
case xmssmt-shake_60/6_512:
xmss_reduced xmss_red_arr_d6[6];
case xmssmt-sha2_40/8_256:
case xmssmt-sha2_40/8_512:
case xmssmt-shake_40/8_256:
case xmssmt-shake_40/8_512:
xmss_reduced xmss_red_arr_d8[8];
case xmssmt-sha2_60/12_256:
case xmssmt-sha2_60/12_512:
case xmssmt-shake_60/12_256:
case xmssmt-shake_60/12_512:
xmss_reduced xmss_red_arr_d12[12];
default:
void; /* error condition */
};
struct xmssmt_signature {
/* WOTS+ key pair index */
idx_sig_xmssmt idx_sig;
/* Random string for randomized hashing */
random_string_xmssmt randomness;
/* Array of d reduced XMSS signatures */
xmss_reduced_array;
};
case xmssmt-sha2_20/2_512:
case xmssmt-sha2_40/4_512:
case xmssmt-sha2_60/6_512:
case xmssmt-sha2_20/4_512:
case xmssmt-sha2_40/8_512:
case xmssmt-sha2_60/12_512:
case xmssmt-sha2_40/2_512:
case xmssmt-sha2_60/3_512:
case xmssmt-shake_20/2_512:
case xmssmt-shake_40/4_512:
case xmssmt-shake_60/6_512:
case xmssmt-shake_20/4_512:
case xmssmt-shake_40/8_512:
case xmssmt-shake_60/12_512:
case xmssmt-shake_40/2_512:
case xmssmt-shake_60/3_512:
bytestring64 seed_n64;
default:
void; /* error condition */
};
case xmssmt-sha2_20/2_512:
case xmssmt-sha2_20/4_512:
case xmssmt-sha2_40/2_512:
case xmssmt-sha2_40/4_512:
case xmssmt-sha2_40/8_512:
case xmssmt-sha2_60/3_512:
case xmssmt-sha2_60/6_512:
case xmssmt-sha2_60/12_512:
case xmssmt-shake_20/2_512:
case xmssmt-shake_20/4_512:
case xmssmt-shake_40/2_512:
case xmssmt-shake_40/4_512:
case xmssmt-shake_40/8_512:
case xmssmt-shake_60/3_512:
case xmssmt-shake_60/6_512:
case xmssmt-shake_60/12_512:
bytestring64 root_n64;
default:
void; /* error condition */
};
struct xmssmt_public_key {
xmssmt_root root; /* Root node */
seed SEED; /* Seed for bitmasks */
};
Acknowledgements
Authors’ Addresses
Andreas Huelsing
TU Eindhoven
P.O. Box 513
Eindhoven 5600 MB
The Netherlands
Email: ietf@huelsing.net
Denis Butin
TU Darmstadt
Hochschulstrasse 10
Darmstadt 64289
Germany
Email: dbutin@cdc.informatik.tu-darmstadt.de
Stefan-Lukas Gazdag
genua GmbH
Domagkstrasse 7
Kirchheim bei Muenchen 85551
Germany
Email: ietf@gazdag.de
Joost Rijneveld
Radboud University
Toernooiveld 212
Nijmegen 6525 EC
The Netherlands
Email: ietf@joostrijneveld.nl
Aziz Mohaisen
University of Central Florida
4000 Central Florida Blvd
Orlando, FL 32816
United States of America