FIPS 205
Federal Information Processing Standards Publication

Stateless Hash-Based Digital SignatureStandard
Category: Computer Security

Subcategory: Cryptography

Information Technology Laboratory
National Institute of Standards and Technology
Gaithersburg, MD 20899-8900
This publication is available free of charge from:https://doi.org/10.6028/NIST.FIPS.205
Published: August 13, 2024

U.S. Department of Commerce
Gina M. Raimondo, Secretary
National Institute of Standards and Technology
Laurie E. Locascio, NIST Director and Under Secretary of Commerce for Standards and Technology

Foreword
The Federal Information Processing Standards Publication (FIPS) series of the National Institute of Standards
and Technology (NIST) is the official series of publications relating to standards and guidelines developed
under 15 U.S.C. 278g-3, and issued by the Secretary of Commerce under 40 U.S.C. 11331.
Comments concerning this Federal Information Processing Standard publication are welcomed and should
be submitted using the contact information in the “Inquiries and comments” clause of the announcement
section.
Kevin M. Stine, Director
Information Technology Laboratory

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Abstract
This standard specifies the stateless hash-based digital signature algorithm (SLH-DSA). Digital
signatures are used to detect unauthorized modifications to data and to authenticate the identityof the signatory. In addition, the recipient of signed data can use a digital signature as evidence indemonstrating to a third party that the signature was, in fact, generated by the claimed signatory.
This is known as non-repudiation since the signatory cannot easily repudiate the signature at alater time. SLH-DSA is based on SPHINCS+ , which was selected for standardization as part of the
NIST Post-Quantum Cryptography Standardization process.
Keywords: computer security; cryptography; digital signatures; Federal Information Processing
Standards; hash-based signatures; post-quantum; public-key cryptography.

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Federal Information Processing Standards Publication 205
Published: August 13, 2024
Effective: August 13, 2024

Announcing theStateless Hash-Based Digital Signature Standard
Federal Information Processing Standards (FIPS) publications are developed by the National
Institute of Standards and Technology (NIST) under 15 U.S.C. 278g-3 and issued by the Secretaryof Commerce under 40 U.S.C. 11331.
1. Name of Standard. Stateless Hash-Based Digital Signature Standard (FIPS 205).
2. Category of Standard. Computer Security. Subcategory. Cryptography.
3. Explanation. This standard specifies a stateless hash-based digital signature scheme (SLHDSA) for applications that require a digital signature rather than a written signature. Additional
digital signature schemes are specified and approved in other NIST Special Publications and
FIPS publications (e.g., FIPS 186-5 [1]). A digital signature is represented in a computer as astring of bits and computed using a set of rules and parameters that allow the identity of thesignatory and the integrity of the data to be verified. Digital signatures may be generated on
both stored and transmitted data.
Signature generation uses a private key to generate a digital signature. Signature verification
uses a public key that corresponds to but is not the same as the private key. Each signatory
possesses a private and public key pair. Public keys may be known by the public, but private
keys must be kept secret. Anyone can verify the signature by employing the signatory’s public
key. Only the user who possesses the private key can perform signature generation.
The digital signature is provided to the intended verifier along with the signed data. The
verifying entity verifies the signature by using the claimed signatory’s public key. Similar
procedures may be used to generate and verify signatures for both stored and transmitted
data.
This standard specifies several parameter sets for SLH-DSA that are approved for use. Additional parameter sets may be specified and approved in future NIST Special Publications.
4. Approving Authority. Secretary of Commerce.
5. Maintenance Agency. Department of Commerce, National Institute of Standards and Technology, Information Technology Laboratory (ITL).
6. Applicability. This standard is applicable to all federal departments and agencies for theprotection of sensitive unclassified information that is not subject to section 2315 of Title 10,
United States Code, or section 3502 (2) of Title 44, United States Code. Either this standard,
FIPS 204, FIPS 186-5, or NIST Special Publication 800-208 shall be used in designing andimplementing public-key-based signature systems that federal departments and agencies operate or that are operated for them under contract. In the future, additional digital signatureiFIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

schemes may be specified and approved in FIPS publications or NIST Special Publications.
The adoption and use of this standard are available to private and commercial organizations.
7. Applications. A digital signature algorithm allows an entity to authenticate the integrity ofsigned data and the identity of the signatory. The recipient of a signed message can use adigital signature as evidence in demonstrating to a third party that the signature was, in fact,
generated by the claimed signatory. This is known as non-repudiation since the signatory
cannot easily repudiate the signature at a later time. A digital signature algorithm is intended
for use in electronic mail, electronic funds transfer, electronic data interchange, software
distribution, data storage, and other applications that require data integrity assurance anddata origin authentication.
8. Implementations. A digital signature algorithm may be implemented in software, firmware,
hardware, or any combination thereof. NIST will develop a validation program to test implementations for conformance to the algorithms in this standard. For every computational
procedure that is specified in this standard, a conforming implementation may replace thegiven set of steps with any mathematically equivalent process. In other words, different
procedures that produce the correct output for every input are permitted. Information about
validation programs is available at https://csrc.nist.gov/projects/cmvp. Examples for digital
signature algorithms are available at https://csrc.nist.gov/projects/cryptographic-standardsand-guidelines/example-values.
Agencies are advised that digital signature key pairs shall not be used for other purposes.
9. Other Approved Security Functions. Digital signature implementations that comply with thisstandard shall employ cryptographic algorithms that have been approved for protecting Federal Government-sensitive information. Approved cryptographic algorithms and techniques
include those that are either:a. Specified in a Federal Information Processing Standard (FIPS) publication,b. Adopted in a FIPS or NIST recommendation, orc. Specified in the list of approved security functions in SP 800-140C.
10. Export Control. Certain cryptographic devices and technical data regarding them are subject
to federal export controls. Exports of cryptographic modules that implement this standard
and technical data regarding them must comply with these federal regulations and be licensed
by the Bureau of Industry and Security of the U.S. Department of Commerce. Information
about export regulations is available at https://www.bis.doc.gov.
11. Patents. The algorithm in this standard may be covered by U.S. or foreign patents.
12. Implementation Schedule. This standard becomes effective immediately upon final publication.
13. Specifications. Federal Information Processing Standard (FIPS) 205, Stateless Hash-Based
Digital Signature Standard (affixed).

ii

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

14. Qualifications. The security of a digital signature system depends on the secrecy of thesignatory’s private keys. Signatories shall, therefore, guard against the disclosure of theirprivate keys. While it is the intent of this standard to specify general security requirements forgenerating digital signatures, conformance to this standard does not ensure that a particular
implementation is secure. It is the responsibility of an implementer to ensure that any modulethat implements a digital signature capability is designed and built in a secure manner.
Similarly, the use of a product containing an implementation that conforms to this standard
does not guarantee the security of the overall system in which the product is used. The responsible authority in each agency or department shall ensure that an overall implementation
provides an acceptable level of security.
Since a standard of this nature must be flexible enough to adapt to advancements andinnovations in science and technology, this standard will be reviewed every five years in order
to assess its adequacy.
15. Waiver Procedure. The Federal Information Security Management Act (FISMA) does notallow for waivers to Federal Information Processing Standards (FIPS) that are made mandatory
by the Secretary of Commerce.
16. Where to Obtain Copies of the Standard. This publication is available by accessing https://csrc.nist.gov/publications. Other computer security publications are available at the same
website.
17. How to Cite This Publication. NIST has assigned NIST FIPS 205 as the publication identifier
for this FIPS, per the NIST Technical Series Publication Identifier Syntax. NIST recommends
that it be cited as follows:
National Institute of Standards and Technology (2024) Stateless Hash-Based Digital Signature Standard. (Department of Commerce, Washington, D.C.), Federal Information Processing Standards Publication (FIPS) NIST FIPS 205. https://doi.org/10.6028/NIST.FIPS.205
18. Inquiries and Comments. Inquiries and comments about this FIPS may be submitted tofips-205-comments@nist.gov.

iii

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Federal Information Processing Standards Publication 205
Specification for theStateless Hash-Based Digital Signature Standard
Table of Contents
1 Introduction1

1.1

Purpose and Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.2

Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

2 Glossary of Terms, Acronyms, and Symbols

2

2.1 Terms and Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

2.2 Acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4

2.3

5

Mathematical Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

3 Overview of the SLH-DSA Signature Scheme

7

3.1 Additional Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

9

3.2

10

Implementation Considerations . . . . . . . . . . . . . . . . . . . . . . . . .

4 Functions and Addressing
4.1

11

Hash Functions and Pseudorandom Functions . . . . . . . . . . . . . . . . .

11

4.2 Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

11

4.3

Member Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

4.4 Arrays, Byte Strings, and Integers . . . . . . . . . . . . . . . . . . . . . . . .

15

5 Winternitz One-Time Signature Plus Scheme

17

5.1 WOTS+ Public-Key Generation . . . . . . . . . . . . . . . . . . . . . . . . . .

18

5.2 WOTS+ Signature Generation . . . . . . . . . . . . . . . . . . . . . . . . . .

19Computing a WOTS+ Public Key From a Signature . . . . . . . . . . . . . . .

21

5.3

6 eXtended Merkle Signature Scheme (XMSS)

22

6.1

Generating a Merkle Hash Tree . . . . . . . . . . . . . . . . . . . . . . . . .

22

6.2

Generating an XMSS Signature . . . . . . . . . . . . . . . . . . . . . . . . . .

23

6.3

Computing an XMSS Public Key From a Signature . . . . . . . . . . . . . . . .

25

7 The SLH-DSA Hypertree

26
iv

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

7.1

Hypertree Signature Generation . . . . . . . . . . . . . . . . . . . . . . . . .

26

7.2

Hypertree Signature Verification . . . . . . . . . . . . . . . . . . . . . . . . .

28

8 Forest of Random Subsets (FORS)

29

8.1

Generating FORS Secret Values . . . . . . . . . . . . . . . . . . . . . . . . . .

29

8.2

Generating a Merkle Hash Tree . . . . . . . . . . . . . . . . . . . . . . . . .

30

8.3

Generating a FORS Signature . . . . . . . . . . . . . . . . . . . . . . . . . . .

30

8.4

Computing a FORS Public Key From a Signature . . . . . . . . . . . . . . . . .

31

9 SLH-DSA Internal Functions

33

9.1

SLH-DSA Key Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33

9.2

SLH-DSA Signature Generation . . . . . . . . . . . . . . . . . . . . . . . . . .

34

9.3

SLH-DSA Signature Verification . . . . . . . . . . . . . . . . . . . . . . . . . .

36

10 SLH-DSA External Functions

37

10.1 SLH-DSA Key Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37

10.2 SLH-DSA Signature Generation . . . . . . . . . . . . . . . . . . . . . . . . . .
10.2.1 Pure SLH-DSA Signature Generation . . . . . . . . . . . . . . . . . . .
10.2.2 HashSLH-DSA Signature Generation . . . . . . . . . . . . . . . . . . .
10.3 SLH-DSA Signature Verification . . . . . . . . . . . . . . . . . . . . . . . . . .

37
38
39
41

11 Parameter Sets

43

11.1 SLH-DSA Using SHAKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

44

11.2 SLH-DSA Using SHA2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
11.2.1 SLH-DSA Using SHA2 for Security Category 1 . . . . . . . . . . . . . . .
11.2.2 SLH-DSA Using SHA2 for Security Categories 3 and 5 . . . . . . . . . .

44
45
46

References

47

Appendix A — Differences From the SPHINCS+ Submission

51

A.1 Changes From FIPS 205 Initial Public Draft . . . . . . . . . . . . . . . . . . . .

v

51

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

List of Tables
Table 1
Table 2
Table 3

Member functions for addresses . . . . . . . . . . . . . . . . . . . . . .
SLH-DSA parameter sets . . . . . . . . . . . . . . . . . . . . . . . . . .
Member functions for compressed addresses . . . . . . . . . . . . . . .

14
43
45

List of Figures
Figure 1
Figure 2
Figure 3
Figure 4
Figure 5
Figure 6
Figure 7
Figure 8
Figure 9
Figure 10
Figure 11
Figure 12
Figure 13
Figure 14
Figure 15
Figure 16
Figure 17
Figure 18

An SLH-DSA signature . . . . . . . . . . . . . . . . . . . . . . . . . . .
Address (ADRS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
WOTS+ hash address . . . . . . . . . . . . . . . . . . . . . . . . . . .
WOTS+ public-key compression address . . . . . . . . . . . . . . . . .
Hash tree address . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
FORS tree address . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
FORS tree roots compression address . . . . . . . . . . . . . . . . . . .
WOTS+ key generation address . . . . . . . . . . . . . . . . . . . . . .
FORS key generation address . . . . . . . . . . . . . . . . . . . . . . .
WOTS+ signature data format . . . . . . . . . . . . . . . . . . . . . . .
XMSS signature data format . . . . . . . . . . . . . . . . . . . . . . . .
Merkle hash tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
HT signature data format . . . . . . . . . . . . . . . . . . . . . . . . .
FORS signature data format . . . . . . . . . . . . . . . . . . . . . . . .
SLH-DSA private key . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SLH-DSA public key . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
SLH-DSA signature data format . . . . . . . . . . . . . . . . . . . . . .
Compressed address (ADRS𝑐 ) . . . . . . . . . . . . . . . . . . . . . .

8
12
12
12
13
13
13
14
14
19
22
24
26
29
33
33
34
45

List of Algorithms
Algorithm 1
Algorithm 2
Algorithm 3
Algorithm 4
Algorithm 5
Algorithm 6
Algorithm 7
Algorithm 8
Algorithm 9
Algorithm 10
Algorithm 11
Algorithm 12
Algorithm 13
Algorithm 14

gen_len2 (𝑛, 𝑙𝑔𝑤 ) . . . . . . . . . . . . . . . . . . . . . . . . . . . .
toInt(𝑋, 𝑛) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
toByte(𝑥, 𝑛) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
base_2b (𝑋, 𝑏, 𝑜𝑢𝑡_𝑙𝑒𝑛) . . . . . . . . . . . . . . . . . . . . . . . .
chain(𝑋, 𝑖, 𝑠, PK.seed, ADRS) . . . . . . . . . . . . . . . . . . .
wots_pkGen(SK.seed, PK.seed, ADRS) . . . . . . . . . . . . . .
wots_sign(𝑀, SK.seed, PK.seed, ADRS) . . . . . . . . . . . . .
wots_pkFromSig(𝑠𝑖𝑔, 𝑀, PK.seed, ADRS) . . . . . . . . . . . . .
xmss_node(SK.seed, 𝑖, 𝑧, PK.seed, ADRS) . . . . . . . . . . . .
xmss_sign(𝑀, SK.seed, 𝑖𝑑𝑥, PK.seed, ADRS) . . . . . . . . . . .
xmss_pkFromSig(𝑖𝑑𝑥, SIG𝑋𝑀𝑆𝑆 , 𝑀, PK.seed, ADRS) . . . . . . .
ht_sign(𝑀, SK.seed, PK.seed, 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ) . . . . . . . . . .
ht_verify(𝑀, SIG𝐻𝑇 , PK.seed, 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , PK.root) . . . . . .
fors_skGen(SK.seed, PK.seed, ADRS, 𝑖𝑑𝑥) . . . . . . . . . . . .
vi

10
15
15
16
18
18
20
21
23
24
25
27
28
29

FIPS 205

Algorithm 15
Algorithm 16
Algorithm 17
Algorithm 18
Algorithm 19
Algorithm 20
Algorithm 21
Algorithm 22
Algorithm 23
Algorithm 24
Algorithm 25

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

fors_node(SK.seed, 𝑖, 𝑧, PK.seed, ADRS) . . . . . . . . . . . . .
fors_sign(𝑚𝑑, SK.seed, PK.seed, ADRS) . . . . . . . . . . . . .
fors_pkFromSig(SIG𝐹 𝑂𝑅𝑆 , 𝑚𝑑, PK.seed, ADRS) . . . . . . . . . .
slh_keygen_internal(SK.seed, SK.prf, PK.seed) . . . . . . . . . .
slh_sign_internal(𝑀, SK, 𝑎𝑑𝑑𝑟𝑛𝑑) . . . . . . . . . . . . . . . . . . .
slh_verify_internal(𝑀, SIG, PK) . . . . . . . . . . . . . . . . . . . .
slh_keygen() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
slh_sign(𝑀, 𝑐𝑡𝑥, SK) . . . . . . . . . . . . . . . . . . . . . . . . . .
hash_slh_sign(𝑀, 𝑐𝑡𝑥, PH, SK) . . . . . . . . . . . . . . . . . . . . .
slh_verify(𝑀, SIG, 𝑐𝑡𝑥, PK) . . . . . . . . . . . . . . . . . . . . . . .
hash_slh_verify(𝑀, SIG, 𝑐𝑡𝑥, PH, PK) . . . . . . . . . . . . . . . . .

vii

30
31
32
34
35
36
37
39
40
41
42

FIPS 205

1.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Introduction

1.1 Purpose and Scope
This standard defines a method for digital signature generation that can be used for the protectionof binary data (commonly called a message) and for the verification and validation of those digital
signatures.1 The security of the stateless hash-based digital signature algorithm (SLH-DSA) relieson the presumed difficulty of finding preimages for hash functions as well as several related
properties of the same hash functions. Unlike the algorithms specified in FIPS 186-5 [1], SLH-DSA
is designed to provide resistance against attacks from a large-scale quantum computer.
This standard specifies the mathematical steps that need to be performed for key generation,
signature generation, and signature verification. Additional assurances are required for digital
signatures to be valid (e.g., the assurance of identity and private key possession). SP 800-89,
Recommendation for Obtaining Assurances for Digital Signature Applications [3], specifies therequired assurances and the methods for obtaining these assurances.

1.2 Context
Over the past several years, there has been steady progress toward building quantum computers.
The security of many commonly used public-key cryptosystems will be at risk if large-scalequantum computers are ever realized. This would include key-establishment schemes and digital
signatures that are based on integer factorization and discrete logarithms (both over finite fields
and elliptic curves). As a result, in 2016, NIST initiated a public Post-Quantum Cryptography(PQC) Standardization process to select quantum-resistant public-key cryptographic algorithms
for standardization. A total of 82 candidate algorithms were submitted to NIST for consideration.
After three rounds of evaluation and analysis, NIST selected the first four algorithms for standardization. These algorithms are intended to protect sensitive U.S. Government information
well into the foreseeable future, including after the advent of cryptographically relevant quantum computers. This standard includes the specification for one of the algorithms selected:
SPHINCS+ , a stateless hash-based digital signature scheme. This standard contains several minor
modifications compared to Version 3 [4], which was submitted at the beginning of round threeof the NIST PQC Standardization process. The changes are described in Appendix A. Throughout
this standard, SPHINCS+ will be referred to as SLH-DSA for stateless hash-based digital signaturealgorithm.

1

NIST Special Publication (SP) 800-175B [2], Guideline for Using Cryptographic Standards in the Federal Government:
Cryptographic Mechanisms, includes a general discussion of digital signatures.

1

FIPS 205

2.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Glossary of Terms, Acronyms, and Symbols

2.1 Terms and Definitions
approved

FIPS-approved and/or NIST-recommended. An algorithm or technique that is either 1) specified in a FIPS or NIST recommendation, 2)
adopted in a FIPS or NIST recommendation, or 3) specified in a list of
NIST-approved security functions. [1]big-endian

The property of a byte string having its bytes positioned in order ofdecreasing significance. In particular, the leftmost (first) byte is themost significant, and the rightmost (last) byte is the least significant.
The term “big-endian” may also be applied in the same manner to bit
strings. [5, adapted]

byte string

An array of integers in which each integer is in the set {0, … , 255}.

claimed signatory

From the verifier’s perspective, the claimed signatory is the entity that
purportedly generated a digital signature. [1]destroy

An action applied to a key or a piece of secret data. After a key or apiece of secret data is destroyed, no information about its value canbe recovered. [1]digital signature

The result of a cryptographic transformation of data that, when properly implemented, provides a mechanism for verifying origin authentication, data integrity, and signatory non-repudiation. [1]entityAn individual (person), organization, device, or process. Used interchangeably with party. [1]equivalent process

Two processes are equivalent if the same output is produced when
the same values are input to each process (either as input parameters,
as values made available during the process, or both). [1]extendable-output
functionA function on bit strings in which the output can be extended to any
desired length. Approved XOFs (such as those specified in FIPS 202 [6])are designed to satisfy the following properties as long as the specified
output length is sufficiently long to prevent trivial attacks:
1. (One-way) It is computationally infeasible to find any input thatmaps to any new pre-specified output.
2. (Collision-resistant) It is computationally infeasible to find any
two distinct inputs that map to the same output. [7, adapted]

fresh random value

A previously unused output of a random bit generator.

hash function

A function on bit strings in which the length of the output is fixed.
Approved hash functions (such as those specified in FIPS 180 [8] andFIPS 202 [6]) are designed to satisfy the following properties:

2

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

1. (One-way) It is computationally infeasible to find any input thatmaps to any new pre-specified output
2. (Collision-resistant) It is computationally infeasible to find any
two distinct inputs that map to the same output. [1]hash value

See message digest.

key

A parameter used in conjunction with a cryptographic algorithm that
determines its operation. Examples applicable to this standard include:
1. The computation of a digital signature from data, and
2. The verification of a digital signature. [1]key pair

A public key and its corresponding private key. [1]message

The data that is signed. Also known as signed data during the signature
verification and validation process. [1]message digest

The result of applying a hash function to a message. Also known as ahash value. [1]non-repudiation

A service that is used to provide assurance of the integrity and originof data in such a way that the integrity and origin can be verified andvalidated by a third party as having originated from a specific entity inpossession of the private key (i.e., the signatory). [1]owner

A key pair owner is the entity authorized to use the private key of a
key pair. [1]party

An individual (person), organization, device, or process. Used interchangeably with entity. [1]private key

A cryptographic key that is used with an asymmetric (public-key) cryptographic algorithm. The private key is uniquely associated with theowner and is not made public. The private key is used to compute a
digital signature that may be verified using the corresponding public
key. [1]pseudorandom

A process or data produced by a process is said to be pseudorandom
when the outcome is deterministic yet also effectively random as longas the internal action of the process is hidden from observation. For
cryptographic purposes, “effectively random” means “computationally indistinguishable from random within the limits of the intended
security strength.” [1]public key

A cryptographic key that is used with an asymmetric (public-key) cryptographic algorithm and is associated with a private key. The public
key is associated with an owner and may be made public. In the caseof digital signatures, the public key is used to verify a digital signaturethat was generated using the corresponding private key. [1]3

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

security category

A number associated with the security strength of a post-quantum
cryptographic algorithm, as specified by NIST (see [9, Sect. 5.6]).

security strength

A number associated with the amount of work (i.e., the number ofoperations) that is required to break a cryptographic algorithm orsystem. [1]shallUsed to indicate a requirement of this standard. [1]shouldUsed to indicate a strong recommendation but not a requirement of
this standard. Ignoring the recommendation could result in undesirable results. [1]signatory

The entity that generates a digital signature on data using a private
key. [1]signature generation The process of using a digital signature algorithm and a private key togenerate a digital signature on data. [1]signature validation

The (mathematical) verification of the digital signature and obtaining the appropriate assurances (e.g., public-key validity, private-key
possession, etc.). [1]signature verification The process of using a digital signature algorithm and a public key toverify a digital signature on data. [1]signed data

The data or message upon which a digital signature has been computed.
Also see message. [1]verifier

The entity that verifies the authenticity of a digital signature using the
public key. [1]2.2 Acronyms
ADRS

Address

ADRSc

Compressed Address

AES

Advanced Encryption Standard

DER

Distinguished Encoding Rules

FIPS

Federal Information Processing Standard

FORS

Forest of Random Subsets

ITL

Information Technology Laboratory

MGF

Mask Generation Function

NIST

National Institute of Standards and Technology

OID

Object Identifier

PQC

Post-Quantum Cryptography

PRF

Pseudorandom Function
4

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

SHA

Secure Hash Algorithm

SHAKE

Secure Hash Algorithm KECCAKSPSpecial Publication

RFC

Request for Comments

WOTS+

Winternitz One-Time Signature PlusXMSSeXtended Merkle Signature Scheme

XOF

eXtendable-Output Function

2.3 Mathematical Symbols
𝑋∥𝑌

The concatenation of two arrays 𝑋 and 𝑌. If 𝑋 is an array of length ℓ𝑥 ,and 𝑌 is an array of length ℓ𝑦 , then 𝑍 = 𝑋 ∥ 𝑌 is an array of lengthℓ𝑥 + ℓ𝑦 such that
𝑍[𝑖] = {𝑋[𝑖]if 0 ≤ 𝑖 < ℓ𝑥
𝑌 [𝑖 − ℓ𝑥 ] if ℓ𝑥 ≤ 𝑖 < ℓ𝑥 + ℓ𝑦 .

𝑋[𝑖 ∶ 𝑗]A subarray of 𝑋. If 𝑋 is an array of length ℓ𝑥 , 0 ≤ 𝑖 < 𝑗 ≤ ℓ𝑥 , and𝑌 = 𝑋[𝑖 ∶ 𝑗], then 𝑌 is an array of length 𝑗 − 𝑖 such that 𝑌 [𝑘] =𝑋[𝑖 + 𝑘] for 0 ≤ 𝑘 < 𝑗 − 𝑖.

Truncℓ (𝑋)A truncation function that outputs the leftmost ℓ bytes of the input
byte string 𝑋. If 𝑌 = Truncℓ (𝑋), then 𝑌 is a byte string (array) oflength ℓ such that 𝑌 [𝑖] = 𝑋[𝑖] for 0 ≤ 𝑖 < ℓ (i.e., 𝑌 = 𝑋[0 ∶ ℓ]).

|𝑋|

The length (in bytes) of byte string 𝑋.

⌈𝑎⌉

The ceiling of 𝑎; the smallest integer that is greater than or equal to 𝑎.
For example, ⌈5⌉ = 5, ⌈5.3⌉ = 6, and ⌈−2.1⌉ = −2. [1]⌊𝑎⌋The floor of 𝑎; the largest integer that is less than or equal to 𝑎. For
example, ⌊5⌋ = 5, ⌊5.3⌋ = 5, and ⌊−2.1⌋ = −3. [1]𝑎 mod 𝑛The unique remainder 𝑟, 0 ≤ 𝑟 ≤ (𝑛 − 1), when integer 𝑎 is divided
by the positive integer 𝑛. For example, 23 mod 7 = 2. [1]𝑎⋅𝑏The product of 𝑎 and 𝑏. For example, 3 ⋅ 5 = 15.

𝑎𝑏𝑎 raised to the power 𝑏. For example, 25 = 32.

log2 𝑥The base 2 logarithm of 𝑥. For example, log2 (16) = 4.

0bThe prefix to a number that is represented in binary.

0x

The prefix to a number that is represented in hexadecimal. [1, adapted]𝑎≫𝑏

The logical right shift of 𝑎 by 𝑏 positions (i.e., 𝑎 ≫ 𝑏 = ⌊𝑎/2𝑏 ⌋). For
example, 0x73 ≫ 4 = 7. [10, adapted]
5FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD𝑎≪𝑏

The logical left shift of 𝑎 by 𝑏 positions (i.e., 𝑎 ≪ 𝑏 = 𝑎 ⋅ 2𝑏 ). For
example, 0x73 ≪ 4 = 0x730. [10, adapted]𝑎⊕𝑏

The bitwise exclusive-or of 𝑎 and 𝑏. For example, 115 ⊕ 1 = 114(115 ⊕ 1 = 0b01110011 ⊕ 0b00000001 = 0b01110010 = 114).

𝑠←𝑥

In pseudocode, this notation means that the variable 𝑠 is set to thevalue of the expression 𝑥.

$𝑠 ←− 𝔹𝑛

In pseudocode, this notation means that the variable 𝑠 is set to abyte string of length 𝑛 chosen at random. A fresh random value isgenerated for each time this step is performed.

⊥

A symbol indicating failure or the lack of output from an algorithm.

6

FIPS 205

3.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Overview of the SLH-DSA Signature Scheme

SLH-DSA is a stateless hash-based signature scheme that is constructed using other hash-based
signature schemes as components: (1) a few-time signature scheme, forest of random subsets(FORS), and (2) a multi-time signature scheme, the eXtended Merkle Signature Scheme (XMSS).
XMSS is constructed using the hash-based one-time signature scheme Winternitz One-Time
Signature Plus (WOTS+ ) as a component.2
Conceptually, an SLH-DSA key pair consists of a very large set of FORS key pairs.3 The few-time
signature scheme FORS allows each key pair to safely sign a small number of messages. An
SLH-DSA signature is created by computing a randomized hash of the message, using part of theresulting message digest to pseudorandomly select a FORS key, and signing the remaining part ofthe message digest with that key. An SLH-DSA signature consists of the FORS signature and theinformation that authenticates the FORS public key. The authentication information is createdusing XMSS signatures.
XMSS is a multi-time signature scheme that is created using a combination of WOTS+ one-time′
signatures and Merkle hash trees [13]. An XMSS key consists of 2ℎ WOTS+ keys and can sign′
2ℎ messages. The WOTS+ public keys are formed into a Merkle hash tree, and the root of thetree is the XMSS public key. (The Merkle hash tree formed from the WOTS+ keys is also referred
to as an XMSS tree.) An XMSS signature consists of a WOTS+ signature and an authentication
path within the Merkle hash tree for the WOTS+ public key. In Figure 1, triangles represent
XMSS trees, squares represent the WOTS+ public keys, and circles represent the interior nodesof the hash tree. Within an XMSS tree, the square and circles that are filled in represent theauthentication path for the WOTS+ public key needed to verify the signature.
The authentication information for a FORS public key is a hypertree signature. A hypertree is atree of XMSS trees, as depicted in Figure 1. The tree consists of 𝑑 layers4 in which the top layer′(layer 𝑑 − 1) consists of a single XMSS tree, the next layer down (layer 𝑑 − 2) consists of 2ℎ′
XMSS trees, and the lowest layer (layer 0) consists of 2(𝑑−1)ℎ XMSS trees. The public key of each
XMSS key at layers 0 through 𝑑 − 2 is signed by an XMSS key at the next higher layer. The XMSS′
keys at layer 0 collectively have 2𝑑ℎ = 2ℎ WOTS+ keys, which are used to sign the 2ℎ FORS
public keys in the SLH-DSA key pair. The sequence of 𝑑 XMSS signatures needed to authenticate
a FORS public key when starting with the public key of the XMSS key at layer 𝑑 − 1 is a hypertree
signature. An SLH-DSA signature consists of a FORS signature along with a hypertree signature.
An SLH-DSA public key (Figure 16) contains two 𝑛-byte components: (1) PK.root, which is the
public key of the XMSS key at layer 𝑑 − 1, and (2) PK.seed, which is used to provide domain
separation between different SLH-DSA key pairs. An SLH-DSA private key (Figure 15) consists ofan 𝑛-byte seed SK.seed that is used to pseudorandomly generate all of the secret values for the
WOTS+ and FORS keys and an 𝑛-byte key SK.prf that is used in the generation of the randomized
hash of the message. An SLH-DSA private key also includes copies of PK.root and PK.seed, as
these values are needed during both signature generation and signature verification.
The WOTS+ and XMSS schemes that are used as components of SLH-DSA are not the same as the WOTS+ and
XMSS schemes in RFC 8391 [11] and SP 800-208 [12].
3
For the parameter sets in this standard, an SLH-DSA key pair contains 263 , 264 , 266 , or 268 FORS keys, which arepseudorandomly generated from a single seed.
4
For the parameter sets in this standard, 𝑑 is 7, 8, 17, or 22.
2

7

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

PK.root
layer 𝑑 − 1 = 2

WOTS+ signaturelayer 1

Merkle tree node+

WOTS signature

WOTS+ public key
FORS public key

layer 0WOTS+ signature

FORS signature
Message
Figure 1. An SLH-DSA signature
The WOTS+ one-time signature scheme is specified in Section 5, and the XMSS multi-time signature scheme is specified in Section 6. Section 7 specifies the generation and verification of
hypertree signatures. The FORS few-time signature scheme is specified in Section 8. Finally,
Section 9 specifies the SLH-DSA key generation, signature, and verification functions. As the
WOTS+ , XMSS, hypertree, and FORS schemes described in this standard are not intended foruse as stand-alone signature schemes, only the components of the schemes necessary to implement SLH-DSA are described. In particular, these sections do not include functions for key pairgeneration, and a signature verification function is only specified for hypertree signatures.
When used in this standard, WOTS+ , XMSS, and FORS signatures are implicitly verified using
functions to generate public keys from messages and signatures (see Sections 5.3, 6.3, and
8.4). When verifying an SLH-DSA signature, the randomized hash of the message and the FORS
signature are used to compute a candidate FORS public key. The candidate FORS public key andthe WOTS+ signature from the layer 0 XMSS key are used to compute a candidate WOTS+ public
key, which is then used in conjunction with the corresponding authentication path to compute a
candidate XMSS public key. The candidate layer 0 XMSS public key is used along with the layer 1
8

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARDXMSS signature to compute a candidate layer 1 XMSS public key. This process is repeated until acandidate layer 𝑑 − 1 public key has been computed. SLH-DSA signature verification succeeds if
the computed candidate layer 𝑑 − 1 XMSS public key is the same as the SLH-DSA public key root
PK.root.

3.1 Additional Requirements
This section specifies requirements for cryptographic modules that implement SLH-DSA. Section 3.2 discusses issues that implementers of cryptographic modules should take into consideration but that are not requirements. SP 800-89, Recommendation for Obtaining Assurances for
Digital Signature Applications [3], specifies requirements that apply to the use of digital signatureschemes.
Randomness generation. SLH-DSA key generation (Algorithm 21) requires the generation of threerandom 𝑛-byte values: PK.seed, SK.seed, and SK.prf, where 𝑛 is 16, 24, or 32, depending on
the parameter set. For each invocation of key generation, each of these values shall be a fresh(i.e., not previously used) random value generated using an approved random bit generator(RBG), as prescribed in SP 800-90A, SP 800-90B, and SP 800-90C [14, 15, 16]. Moreover, the RBG
used shall have a security strength of at least 8𝑛 bits. See Table 2 for the value of 𝑛 for eachparameter set.
Destruction of sensitive data. Data used internally by key generation and signing algorithms inintermediate computation steps could be used by an adversary to gain information about theprivate key and thereby compromise security. The data used internally by verification algorithms
is similarly sensitive for some applications, including the verification of signatures that are used asbearer tokens (i.e., authentication secrets) or signatures on plaintext messages that are intended
to be confidential. Intermediate values of the verification algorithm may reveal information
about its inputs (i.e., the message, signature, and public key), and in some applications, security
or privacy requires one or more of these inputs to be confidential. Therefore, implementations of
SLH-DSA shall ensure that any local copies of the inputs and any potentially sensitive intermediate
data are destroyed as soon as they are no longer needed.
Key checks. SP 800-89 imposes requirements for the assurance of public-key validity and privatekey possession. In the case of SLH-DSA, where public-key validation is required, implementations
shall verify that the public key is 2𝑛 bytes in length. When the assurance of private key possession
is obtained via regeneration, the owner of the private key shall check that the private key is 4𝑛
bytes in length and shall use SK.seed and PK.seed to recompute PK.root and compare the
newly generated value with the value in the private key currently held.
Floating-point arithmetic. Implementations of SLH-DSA shall not use floating-point arithmetic,
as rounding errors in floating point operations may lead to incorrect results in some cases. In all
pseudocode in this standard in which division is performed (e.g., 𝑥/𝑦) and 𝑦 may not divide 𝑥,
either ⌊𝑥/𝑦⌋ or ⌈𝑥/𝑦⌉ is used. Both of these can be computed without floating-point arithmetic,as ordinary integer division 𝑥/𝑦 computes ⌊𝑥/𝑦⌋, and ⌈𝑥/𝑦⌉ = ⌊(𝑥 + 𝑦 − 1)/𝑦⌋ for non-negative
integers 𝑥 and positive integers 𝑦.

9FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

While the value of 𝑙𝑒𝑛2 (see Equation 5.3) may be computed without using floating-point arithmetic (see Algorithm 1), it is recommended that this value be precomputed. For all parameter
sets in this standard, 𝑙𝑒𝑛2 is 3.
Algorithm 1 gen_len2 (𝑛, 𝑙𝑔𝑤 )Computes 𝑙𝑒𝑛2 (Equation 5.3).
Input: Security parameter 𝑛, bits per hash chain 𝑙𝑔𝑤 .
Output: 𝑙𝑒𝑛2 .
1: 𝑤 ← 2𝑙𝑔𝑤
8⋅𝑛+𝑙𝑔𝑤 −1
2: 𝑙𝑒𝑛1 ← ⌊⌋𝑙𝑔𝑤
3: 𝑚𝑎𝑥_𝑐ℎ𝑒𝑐𝑘𝑠𝑢𝑚 = 𝑙𝑒𝑛1 ⋅ (𝑤 − 1)
4: 𝑙𝑒𝑛2 ← 1
5: 𝑐𝑎𝑝𝑎𝑐𝑖𝑡𝑦 ← 𝑤
6: while 𝑐𝑎𝑝𝑎𝑐𝑖𝑡𝑦 ≤ 𝑚𝑎𝑥_𝑐ℎ𝑒𝑐𝑘𝑠𝑢𝑚 do
7:
𝑙𝑒𝑛2 ← 𝑙𝑒𝑛2 + 1
8:𝑐𝑎𝑝𝑎𝑐𝑖𝑡𝑦 ← 𝑐𝑎𝑝𝑎𝑐𝑖𝑡𝑦 ⋅ 𝑤
9: end while
10: return 𝑙𝑒𝑛2

▷ Equation 5.1▷ Equation 5.2▷ maximum possible checksum value▷ maximum value that may be signed using▷ 𝑙𝑒𝑛2 hash chains is 𝑤𝑙𝑒𝑛2 − 1 = 𝑐𝑎𝑝𝑎𝑐𝑖𝑡𝑦 − 1

3.2 Implementation Considerations
This section discusses some implementation considerations for SLH-DSA.
Do not support component use. As WOTS+ , XMSS, FORS, and hypertree signature schemes are
not approved for use as stand-alone signature schemes, cryptographic modules should not makeinterfaces to these components available to applications. SP 800-208 [12] specifies approved
stateful hash-based signature schemes.
Side-channel and fault attacks. For signature schemes, the secrecy of the private key is critical.
Care must be taken to protect implementations against attacks, such as side-channel attacks
or fault attacks [17, 18, 19, 20, 21]. A cryptographic device may leak critical information withside-channel analysis or attacks that allow internal data or keying material to be extracted without
breaking the cryptographic primitives.

10

FIPS 205

4.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Functions and Addressing

4.1 Hash Functions and Pseudorandom Functions
The specification of SLH-DSA makes use of six functions — PRF𝑚𝑠𝑔 , H𝑚𝑠𝑔 , PRF, Tℓ , H, andF — that are all implemented using hash functions or XOFs with fixed output lengths. The inputs
and output of each function are byte strings. In the following definitions, 𝔹 = {0, … , 255}
denotes the set of all bytes, 𝔹𝑛 denotes the set of byte strings of length 𝑛 bytes, and 𝔹∗ denotes
the set of all byte strings. The ADRS input is described in Section 4.2.
• PRF𝑚𝑠𝑔 (SK.prf, 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑, 𝑀 ) (𝔹𝑛 × 𝔹𝑛 × 𝔹∗ → 𝔹𝑛 ) is a pseudorandom function(PRF) that generates the randomizer (𝑅) for the randomized hashing of the message to besigned.
• H𝑚𝑠𝑔 (𝑅, PK.seed, PK.root, 𝑀 ) (𝔹𝑛 × 𝔹𝑛 × 𝔹𝑛 × 𝔹∗ → 𝔹𝑚 ) is used to generate thedigest of the message to be signed.
• PRF(PK.seed, SK.seed, ADRS) (𝔹𝑛 × 𝔹𝑛 × 𝔹32 → 𝔹𝑛 ) is a PRF that is used togenerate the secret values in WOTS+ and FORS private keys.
• Tℓ (PK.seed, ADRS, 𝑀ℓ ) (𝔹𝑛 × 𝔹32 × 𝔹ℓ𝑛 → 𝔹𝑛 ) is a hash function that maps anℓ𝑛-byte message to an 𝑛-byte message.
• H(PK.seed, ADRS, 𝑀2 ) (𝔹𝑛 × 𝔹32 × 𝔹2𝑛 → 𝔹𝑛 ) is a special case of Tℓ that takes a
2𝑛-byte message as input.
• F(PK.seed, ADRS, 𝑀1 ) (𝔹𝑛 × 𝔹32 × 𝔹𝑛 → 𝔹𝑛 ) is a hash function that takes an 𝑛-byte
message as input and produces an 𝑛-byte output.
The specific instantiations for these functions differ for different parameter sets and are specified
in Section 11.

4.2 Addresses
Four of the functions described in Section 4.1 take a 32-byte address (i.e., ADRS) as input. An
ADRS consists of public values that indicate the position of the value being computed by thefunction. A different ADRS value is used for each call to each function. In the case of PRF,
this is used to generate a large number of different secret values from a single seed. In the caseof Tℓ , H, and F, it is used to mitigate multi-target attacks. In the pseudocode, where addresses
are passed as parameters, they may be passed either by reference or by value.
The structure of an ADRS conforms to word boundaries, with each word being 4 bytes longand values encoded as unsigned integers in big-endian byte order (see Figure 2). The first wordof ADRS specifies the layer address, which is the height of an XMSS tree within the hypertree.
Trees on the bottom layer have a height of zero, and the single XMSS tree at the top has a heightof 𝑑 − 1 (see Figure 1). The next three words of ADRS specify the tree address, which is the
position of an XMSS tree within a layer of the hypertree. The leftmost XMSS tree in a layer has a′tree address of zero, and the rightmost XMSS tree in layer 𝐿 has a tree address of 2(𝑑−1−𝐿)ℎ − 1.
The next word is used to specify the type of the address, which differs depending on the use case.
11

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

There are seven different types of address used in SLH-DSA, as described below.5 The address
type determines how the final 12 bytes of the address are to be interpreted. The algorithms
in this standard are written based on the assumption that whenever the type in an ADRS ischanged, the final 12 bytes of the address are initialized to zero.

layer address

4 bytestree address

12 bytes

𝑡𝑦𝑝𝑒

4 bytes
12 bytesFigure 2. Address (ADRS)The type is set to WOTS_HASH (i.e., 𝑡𝑦𝑝𝑒 = 0) for a WOTS+ hash address (see Figure 3), which isused when computing hash chains in WOTS+ . When type is WOTS_HASH, the next word encodes
the key pair address, which is the index of the WOTS+ key pair within the XMSS tree specified
by the layer and tree addresses, with the leftmost WOTS+ key having an index of zero and the′rightmost WOTS+ key having an index of 2ℎ − 1. Next is the chain address, which encodes theindex of the chain within WOTS+ , followed by the hash address, which encodes the address ofthe hash function within the chain.
layer address

layer address

tree address

tree address

𝑡𝑦𝑝𝑒 = 0 (WOTS_HASH)key pair address
chain address
hash address

4 bytes
4 bytes
4 bytesFigure 3. WOTS+ hash address

𝑡𝑦𝑝𝑒 = 1 (WOTS_PK)
key pair address

4 bytes

𝑝𝑎𝑑𝑑𝑖𝑛𝑔 = 0

8 bytesFigure 4. WOTS+ public-key compression address

The type is set to WOTS_PK (i.e., 𝑡𝑦𝑝𝑒 = 1) when compressing WOTS+ public keys (see Figure 4).
As when the type is WOTS_HASH, the next word encodes the index of the WOTS+ key pair within
the XMSS tree specified by the layer and tree addresses. The remaining two words of ADRS
are not needed and are set to zero.
The type is set to TREE (i.e., 𝑡𝑦𝑝𝑒 = 2) when computing the hashes within the XMSS tree (seeFigure 5). For this type of address, the next word is always set to zero. The following word
5

The type word will have a value of 0, 1, 2, 3, 4, 5, or 6. In order to improve readability, these values will bereferred to in this standard by the constants WOTS_HASH, WOTS_PK, TREE, FORS_TREE, FORS_ROOTS, WOTS_PRF,
and FORS_PRF, respectively.

12

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

encodes the height of the node within the tree that is being computed, and the final word
encodes the index of the node at that height.
layer address
tree address
𝑡𝑦𝑝𝑒 = 2 (TREE)
𝑝𝑎𝑑𝑑𝑖𝑛𝑔 = 0
tree heighttree index

4 bytes
4 bytes
4 bytesFigure 5. Hash tree address
The type is set to FORS_TREE (i.e., 𝑡𝑦𝑝𝑒 = 3) when computing hashes within the FORS tree (seeFigure 6). The next word is the key pair address, which encodes the FORS key that is used. The
value is the same as the key pair address for the WOTS+ key used to sign the FORS key (seeFigure 3 and Figure 4). The next two words — the tree height and tree index — encode the node
within the FORS tree that is being computed. The tree height starts with zero for the leaf nodes.
The tree index is counted continuously across the 𝑘 different FORS trees. The leftmost node in
the leftmost tree has an index of zero, and the rightmost node in the rightmost tree at level 𝑗
has an index of 𝑘 ⋅ 2(𝑎−𝑗) − 1, where 𝑎 is the height of the tree.
layer address = 0

layer address = 0

tree address

tree address

𝑡𝑦𝑝𝑒 = 3 (FORS_TREE)
key pair address
tree heighttree index

𝑡𝑦𝑝𝑒 = 4 (FORS_ROOTS)
key pair address

4 bytes

𝑝𝑎𝑑𝑑𝑖𝑛𝑔 = 0

8 bytes

4 bytes
4 bytes
4 bytesFigure 6. FORS tree address

Figure 7. FORS tree roots compression address

The type is set to FORS_ROOTS (i.e., 𝑡𝑦𝑝𝑒 = 4) when compressing the 𝑘 FORS tree roots (seeFigure 7). The next word is the key pair address, which has the same meaning as it does in the
FORS_TREE address. The remaining two words of ADRS are not needed and are set to zero.
The type is set to WOTS_PRF (i.e., 𝑡𝑦𝑝𝑒 = 5) when generating secret values for WOTS+ keys (seeFigure 8). The values for the other words in the address are set to the same values as for the
WOTS_HASH address (Figure 3) used for the chain. The hash address is always set to zero.

13

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

layer address

layer address = 0

tree address

tree address

𝑡𝑦𝑝𝑒 = 5 (WOTS_PRF)
key pair address
chain address
hash address = 0

𝑡𝑦𝑝𝑒 = 6 (FORS_PRF)
key pair address
tree height = 0
tree index

4 bytes
4 bytes
4 bytesFigure 8. WOTS+ key generation address

4 bytes
4 bytes
4 bytesFigure 9. FORS key generation address

The type is set to FORS_PRF (i.e., 𝑡𝑦𝑝𝑒 = 6) when generating secret values for FORS keys (seeFigure 9). The values for the other words in the address are set to the same values as for the
FORS_TREE address (Figure 6) used for the same leaf node.

4.3 Member Functions
The algorithms in this standard make use of member functions. If a complex data structure(e.g., an ADRS) contains a component 𝑋, then ADRS.getX() returns the value of 𝑋, and
ADRS.setX(𝑌) sets the component 𝑋 in ADRS to the value held by 𝑌. If a data structure 𝑠
contains multiple instances of 𝑋, then 𝑠.getX(𝑖) returns the value of the 𝑖th instance of 𝑋 in 𝑠.
For example, if 𝑠 is a FORS signature (Figure 14), then 𝑠.getAUTH(𝑖) returns the authentication
path for the 𝑖th tree.
Whenever the type in an address changes, the final 12 bytes of the address are initialized to zero.
The member function ADRS.setTypeAndClear(𝑌) for addresses sets the 𝑡𝑦𝑝𝑒 of the ADRS to
𝑌 and sets the final 12 bytes of the ADRS to zero.6
Table 1 shows alternative notation for each of the member functions that operates on addresses.
Table 1. Member functions for addresses
Member function
ADRS.setLayerAddress(𝑙)ADRS.setTreeAddress(𝑡)ADRS.setTypeAndClear(𝑌)ADRS.setKeyPairAddress(𝑖)ADRS.setChainAddress(𝑖)ADRS.setTreeHeight(𝑖)ADRS.setHashAddress(𝑖)ADRS.setTreeIndex(𝑖)𝑖 ← ADRS.getKeyPairAddress()𝑖 ← ADRS.getTreeIndex()
6

Expanded notation
ADRS ← toByte(𝑙, 4) ∥ ADRS[4 ∶ 32]
ADRS ← ADRS[0 ∶ 4] ∥ toByte(𝑡, 12) ∥ ADRS[16 ∶ 32]
ADRS ← ADRS[0 ∶ 16] ∥ toByte(𝑌 , 4) ∥ toByte(0, 12)
ADRS ← ADRS[0 ∶ 20] ∥ toByte(𝑖, 4) ∥ ADRS[24 ∶ 32]
ADRS ← ADRS[0 ∶ 24] ∥ toByte(𝑖, 4) ∥ ADRS[28 ∶ 32]
ADRS ← ADRS[0 ∶ 28] ∥ toByte(𝑖, 4)
𝑖 ← toInt(ADRS[20 ∶ 24], 4)𝑖 ← toInt(ADRS[28 ∶ 32], 4)As noted in Section 4.2, the type (𝑌) is an integer. However, in the pseudocode, the constants WOTS_HASH, WOTS_PK,
TREE, FORS_TREE, FORS_ROOTS, WOTS_PRF, and FORS_PRF are used in order to improve readability.

14

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

4.4 Arrays, Byte Strings, and Integers
If 𝑋 is a byte string of length 𝑛, then 𝑋[𝑖] for 𝑖 ∈ {0, … , 𝑛 − 1} will refer to the 𝑖th element in
the string 𝑋. If 𝑋 is an array of 𝑚 𝑛-byte strings, then 𝑋[𝑖] for 𝑖 ∈ {0, … , 𝑚 − 1} will refer tothe 𝑖th 𝑛-byte string in 𝑋, and 𝑋 will refer to the 𝑚 ⋅ 𝑛-byte string 𝑋[0] ∥ 𝑋[1] ∥ … 𝑋[𝑚 − 1].
A byte string may be interpreted as the big-endian representation of an integer. In such cases, abyte string 𝑋 of length 𝑛 is converted to the integer
𝑋[0] ⋅ 256𝑛−1 + 𝑋[1] ⋅ 256𝑛−2 + … 𝑋[𝑛 − 2] ⋅ 256 + 𝑋[𝑛 − 1].
Similarly, an integer 𝑥 may be converted to a byte string of length 𝑛 by finding coefficients
𝑥0 , 𝑥1 , … 𝑥𝑛−2 , 𝑥𝑛−1 ∈ {0, … , 255} such that𝑥 = 𝑥0 ⋅ 256𝑛−1 + 𝑥1 ⋅ 256𝑛−2 + … 𝑥𝑛−2 ⋅ 256 + 𝑥𝑛−1
and then setting the byte string to be 𝑥0 𝑥1 … 𝑥𝑛−2 𝑥𝑛−1 .
Algorithm 2 is a function that converts a byte string 𝑋 of length 𝑛 to an integer, and Algorithm 3
is a function that converts an integer 𝑥 to a byte string of length 𝑛.
Algorithm 2 toInt(𝑋, 𝑛)
Converts a byte string to an integer.
Input: 𝑛-byte string 𝑋.
Output: Integer value of 𝑋.
1: 𝑡𝑜𝑡𝑎𝑙 ← 0
2: for 𝑖 from 0 to 𝑛 − 1 do
3:𝑡𝑜𝑡𝑎𝑙 ← 256 ⋅ 𝑡𝑜𝑡𝑎𝑙 + 𝑋[𝑖]4: end for5: return 𝑡𝑜𝑡𝑎𝑙

Algorithm 3 toByte(𝑥, 𝑛)
Converts an integer to a byte string.
Input: Integer 𝑥, string length 𝑛.
Output: Byte string of length 𝑛 containing binary representation of 𝑥 in big-endian byte-order.
1: 𝑡𝑜𝑡𝑎𝑙 ← 𝑥
2: for 𝑖 from 0 to 𝑛 − 1 do
3:𝑆[𝑛 − 1 − 𝑖] ← 𝑡𝑜𝑡𝑎𝑙 mod 256
𝑡𝑜𝑡𝑎𝑙 ← 𝑡𝑜𝑡𝑎𝑙 ≫ 8
4:
5: end for
6: return 𝑆▷ least significant 8 bits of 𝑡𝑜𝑡𝑎𝑙

15

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

For the WOTS+ and FORS schemes, the messages to be signed need to be split into a sequenceof 𝑏-bit strings, where each 𝑏-bit string is interpreted as an integer between 0 and 2𝑏 − 1.7 Thisis the equivalent of creating the base-2𝑏 representation of the message. The base_2b function(Algorithm 4) takes a byte string 𝑋, a bit string length 𝑏, and an output length 𝑜𝑢𝑡_𝑙𝑒𝑛 as input
and returns an array of base-2𝑏 integers that represent the first 𝑜𝑢𝑡_𝑙𝑒𝑛 ⋅ 𝑏 bits of 𝑋 if theindividual bytes in 𝑋 are encoded as 8-bit strings in big-endian bit order. 𝑋 must be at least⌈𝑜𝑢𝑡_𝑙𝑒𝑛 ⋅ 𝑏/8⌉ bytes in length. As the value of 𝑏𝑖𝑡𝑠 will never exceed 𝑏 + 7, a 𝑏 + 7-bit unsigned
integer is sufficient to store 𝑡𝑜𝑡𝑎𝑙 (i.e., 𝑡𝑜𝑡𝑎𝑙 may be stored as a 32-bit unsigned integer).
Algorithm 4 base_2b (𝑋, 𝑏, 𝑜𝑢𝑡_𝑙𝑒𝑛)
Computes the base 2𝑏 representation of 𝑋.
Input: Byte string 𝑋 of length at least ⌈ 𝑜𝑢𝑡_8𝑙𝑒𝑛⋅𝑏 ⌉, integer 𝑏, output length 𝑜𝑢𝑡_𝑙𝑒𝑛.
Output: Array of 𝑜𝑢𝑡_𝑙𝑒𝑛 integers in the range [0, … , 2𝑏 − 1].
1: 𝑖𝑛 ← 0
2: 𝑏𝑖𝑡𝑠 ← 0
3: 𝑡𝑜𝑡𝑎𝑙 ← 0
4: for 𝑜𝑢𝑡 from 0 to 𝑜𝑢𝑡_𝑙𝑒𝑛 − 1 do
5:
while 𝑏𝑖𝑡𝑠 < 𝑏 do
6:
𝑡𝑜𝑡𝑎𝑙 ← (𝑡𝑜𝑡𝑎𝑙 ≪ 8) + 𝑋[𝑖𝑛]7:𝑖𝑛 ← 𝑖𝑛 + 1
8:𝑏𝑖𝑡𝑠 ← 𝑏𝑖𝑡𝑠 + 8
9:end while
10:
𝑏𝑖𝑡𝑠 ← 𝑏𝑖𝑡𝑠 − 𝑏
11:𝑏𝑎𝑠𝑒𝑏[𝑜𝑢𝑡] ← (𝑡𝑜𝑡𝑎𝑙 ≫ 𝑏𝑖𝑡𝑠) mod 2𝑏
12: end for
13: return 𝑏𝑎𝑠𝑒𝑏

7

𝑏 will be the value of 𝑙𝑔𝑤 when the base_2b function is used in WOTS+ , and 𝑏 will be the value of 𝑎 when thebase_2b function is used in FORS. For the parameter sets in this standard, 𝑙𝑔𝑤 is 4, and 𝑎 is 6, 8, 9, 12, or 14.

16

FIPS 205

5.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Winternitz One-Time Signature Plus Scheme

This section describes the WOTS+ one-time signature scheme that is a component of SLH-DSA.
WOTS+ uses two parameters. The security parameter 𝑛 is the length in bytes of the messages
that may be signed as well as the length of the private key elements, public key elements, andsignature elements. For the parameter sets specified in this standard, 𝑛 may be 16, 24, or 32(see Table 2). The second parameter 𝑙𝑔𝑤 indicates the number of bits that are encoded by eachhash chain that is used.8 𝑙𝑔𝑤 is 4 for all parameter sets in this standard. These parameters areused to compute four additional values:
𝑤 = 2𝑙𝑔𝑤

(5.1)

8𝑛
⌉
𝑙𝑔𝑤

(5.2)

log2 (𝑙𝑒𝑛1 ⋅ (𝑤 − 1))
⌋+1
𝑙𝑔𝑤

(5.3)

𝑙𝑒𝑛 = 𝑙𝑒𝑛1 + 𝑙𝑒𝑛2

(5.4)

𝑙𝑒𝑛1 = ⌈𝑙𝑒𝑛2 = ⌊When 𝑙𝑔𝑤 = 4, 𝑤 = 16, 𝑙𝑒𝑛1 = 2𝑛, 𝑙𝑒𝑛2 = 3, and 𝑙𝑒𝑛 = 2𝑛 + 3.
A WOTS+ private key consists of 𝑙𝑒𝑛 secret values of length 𝑛. In SLH-DSA, these are all generated
from an 𝑛-byte seed SK.seed using a PRF. Chains of length 𝑤 are then created from the secretvalues using a chaining function, and the end values from each of the chains are public values. The
WOTS+ public key is computed as the hash of these public values. In order to create a signature,
the 8𝑛-bit message is first converted into an array of 𝑙𝑒𝑛1 base-𝑤 integers. A checksum is thencomputed for this string, and the checksum is converted into an array of 𝑙𝑒𝑛2 base-𝑤 integers.
The signature consists of the appropriate entries from the chains for each of the integers in themessage and checksum arrays.
The WOTS+ functions make use of two helper functions: base_2b and chain. The base_2b function(Section 4.4) is used to break the message to be signed and the checksum value into arrays ofbase-𝑤 integers. The chain function (Algorithm 5) is used to compute the hash chains.
The chain function takes an 𝑛-byte string 𝑋 and integers 𝑠 and 𝑖 (where 𝑖 + 𝑠 < 𝑤) as input andreturns the result of iterating a hash function F on the input 𝑠 times, starting from an index of𝑖.9 The chain function also requires as input PK.seed, which is part of the SLH-DSA public key,
and an address ADRS. The type in ADRS must be set to WOTS_HASH, and the layer address,
tree address, key pair address, and chain address must be set to the address of the chain being
computed. The chain function updates the hash address in ADRS with each iteration to specify
the current position in the chain prior to ADRS’s use in F.

In [10], the Winternitz parameter 𝑤 is used as the second WOTS+ parameter, where 𝑤 indicates the length of thehash chains that are used. This standard uses the parameter 𝑙𝑔𝑤 = log2 (𝑤) to simplify notation.
9
A start index of 0 indicates the beginning of the chain.
817

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 5 chain(𝑋, 𝑖, 𝑠, PK.seed, ADRS)
Chaining function used in WOTS+ .
Input: Input string 𝑋, start index 𝑖, number of steps 𝑠, public seed PK.seed, address ADRS.
Output: Value of F iterated 𝑠 times on 𝑋.
1: 𝑡𝑚𝑝 ← 𝑋
2: for 𝑗 from 𝑖 to 𝑖 + 𝑠 − 1 do
3:
ADRS.setHashAddress(𝑗)4:𝑡𝑚𝑝 ← F(PK.seed, ADRS, 𝑡𝑚𝑝)
5: end for
6: return 𝑡𝑚𝑝

5.1 WOTS+ Public-Key Generation
The wots_pkGen function (Algorithm 6) generates WOTS+ public keys. It takes SK.seed andPK.seed from the SLH-DSA private key and an address as input. The type in the address ADRS
must be set to WOTS_HASH, and the layer address, tree address, and key pair address must encode
the address of the WOTS+ public key to be generated.
Lines 4 through 9 in Algorithm 6 generate the public values, as described in Section 5. For eachof the 𝑙𝑒𝑛 public values, the corresponding secret value is generated in lines 5 and 6, and thechain function is called to compute the end value of the chain of length 𝑤. Once the 𝑙𝑒𝑛 public
values are computed, they are compressed into a single 𝑛-byte value in lines 10 through 13.
Algorithm 6 wots_pkGen(SK.seed, PK.seed, ADRS)Generates a WOTS+ public key.
Input: Secret seed SK.seed, public seed PK.seed, address ADRS.
Output: WOTS+ public key 𝑝𝑘.
1: skADRS ← ADRS
▷ copy address to create key generation key address
2: skADRS.setTypeAndClear(WOTS_PRF)
3: skADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
4: for 𝑖 from 0 to 𝑙𝑒𝑛 − 1 do
5:
skADRS.setChainAddress(𝑖)6:𝑠𝑘 ← PRF(PK.seed, SK.seed, skADRS)▷ compute secret value for chain 𝑖
7:
ADRS.setChainAddress(𝑖)8:𝑡𝑚𝑝[𝑖] ← chain(𝑠𝑘, 0, 𝑤 − 1, PK.seed, ADRS) ▷ compute public value for chain 𝑖
9: end for
10: wotspkADRS ← ADRS
▷ copy address to create WOTS+ public key address
11: wotspkADRS.setTypeAndClear(WOTS_PK)
12: wotspkADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
13: 𝑝𝑘 ← T𝑙𝑒𝑛 (PK.seed, wotspkADRS, 𝑡𝑚𝑝)
▷ compress public key
14: return 𝑝𝑘

18

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

5.2 WOTS+ Signature Generation
A WOTS+ signature is an array of 𝑙𝑒𝑛 byte strings of length 𝑛, as shown in Figure 10. The wots_sign
function (Algorithm 7) generates the signature by converting the 𝑛-byte message 𝑀10 into anarray of 𝑙𝑒𝑛1 base-𝑤 integers (line 2). A checksum is computed over 𝑀 (lines 3 through 5). The
checksum is converted to a byte string, which is then converted into an array of 𝑙𝑒𝑛2 base-𝑤
integers (lines 6 and 7). The 𝑙𝑒𝑛2 integers that represent the checksum are appended to the 𝑙𝑒𝑛1
integers that represent the message (line 7).11 For each of the 𝑙𝑒𝑛 base-𝑤 integers, the signature
consists of the corresponding node in one of the hash chains. For each of these integers, lines
12 and 13 compute the secret value for the hash chain, and lines 14 and 15 compute the node in
the hash chain that corresponds to the integer. The selected nodes are concatenated to form
the WOTS+ signature.
sigots [0]⋯sigots [𝑙𝑒𝑛 − 1]

𝑛 bytes𝑛 bytesFigure 10. WOTS+ signature data format
In addition to the 𝑛-byte message to be signed, wots_sign takes SK.seed and PK.seed fromthe SLH-DSA private key and an address as input. The type in the address ADRS must be set to
WOTS_HASH, and the layer address, tree address, and key pair address must encode the addressof the WOTS+ key that is used to sign the message.

1011

In SLH-DSA, the message 𝑀 that is signed using WOTS+ is either an XMSS public key or a FORS public key.
In the case that 𝑙𝑔𝑤 = 4, the 𝑛-byte message is converted into an array of 2𝑛 base-16 integers (i.e., hexadecimal
digits). The checksum is encoded as two bytes with the least significant four bits being zeros, and the mostsignificant 12 bits are appended to the message as an array of three base-16 integers.

19

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 7 wots_sign(𝑀, SK.seed, PK.seed, ADRS)Generates a WOTS+ signature on an 𝑛-byte message.
Input: Message 𝑀, secret seed SK.seed, public seed PK.seed, address ADRS.
Output: WOTS+ signature 𝑠𝑖𝑔.
1: 𝑐𝑠𝑢𝑚 ← 0
2: 𝑚𝑠𝑔 ← base_2b (𝑀 , 𝑙𝑔𝑤 , 𝑙𝑒𝑛1 )▷ convert message to base 𝑤

3: for 𝑖 from 0 to 𝑙𝑒𝑛1 − 1 do
4:𝑐𝑠𝑢𝑚 ← 𝑐𝑠𝑢𝑚 + 𝑤 − 1 − 𝑚𝑠𝑔[𝑖]5: end for▷ compute checksum

6: 𝑐𝑠𝑢𝑚 ← 𝑐𝑠𝑢𝑚 ≪ ((8 − ((𝑙𝑒𝑛2 ⋅ 𝑙𝑔𝑤 ) mod 8)) mod 8)b

7: 𝑚𝑠𝑔 ← 𝑚𝑠𝑔 ∥ base_2▷ for 𝑙𝑔𝑤 = 4, left shift by 4
▷ convert to base 𝑤(toByte (𝑐𝑠𝑢𝑚, ⌈ 𝑙𝑒𝑛28⋅𝑙𝑔𝑤 ⌉) , 𝑙𝑔𝑤 , 𝑙𝑒𝑛2 )8: skADRS ← ADRS
▷ copy address to create key generation key address
9: skADRS.setTypeAndClear(WOTS_PRF)
10: skADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
11: for 𝑖 from 0 to 𝑙𝑒𝑛 − 1 do
12:
skADRS.setChainAddress(𝑖)13:𝑠𝑘 ← PRF(PK.seed, SK.seed, skADRS)▷ compute chain 𝑖 secret value
14:
ADRS.setChainAddress(𝑖)15:𝑠𝑖𝑔[𝑖] ← chain(𝑠𝑘, 0, 𝑚𝑠𝑔[𝑖], PK.seed, ADRS) ▷ compute chain 𝑖 signature value
16: end for
17: return 𝑠𝑖𝑔

20

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

5.3 Computing a WOTS+ Public Key From a Signature
Verifying a WOTS+ signature involves computing a public-key value from a message and signature
value. Verification succeeds if the correct public-key value is computed, which is determinedby using the computed public-key value along with other information to compute a candidate
PK.root value and then comparing that value to the known value of PK.root from the SLH-DSA
public key. This section describes wots_pkFromSig (Algorithm 8), a function that computes acandidate WOTS+ public key from a WOTS+ signature and corresponding message.
In addition to an 𝑛-byte message 𝑀 and a 𝑙𝑒𝑛 ⋅ 𝑛-byte signature 𝑠𝑖𝑔, which is interpreted as
an array of 𝑙𝑒𝑛 𝑛-byte strings, the wots_pkFromSig function takes PK.seed from the SLH-DSA
public key and an address as input. The type of the address ADRS must be set to WOTS_HASH,and the layer address, tree address, and key pair address must encode the address of the WOTS+
key that was used to sign the message.
Lines 1 through 7 of wots_pkFromSig are the same as lines 1 through 7 of wots_sign (Algorithm 7).
Lines 8 through 11 of wots_pkFromSig compute the end nodes for each of the chains using
the signature value as the starting point and the message value to determine the number of
iterations that need to be performed to get to the end node. Finally, as with lines 10 through 13
of Algorithm 6, the computed public-key values are compressed in lines 12 through 15.
Algorithm 8 wots_pkFromSig(𝑠𝑖𝑔, 𝑀, PK.seed, ADRS)
Computes a WOTS+ public key from a message and its signature.
Input: WOTS+ signature 𝑠𝑖𝑔, message 𝑀, public seed PK.seed, address ADRS.
Output: WOTS+ public key 𝑝𝑘𝑠𝑖𝑔 derived from 𝑠𝑖𝑔.
1: 𝑐𝑠𝑢𝑚 ← 0
2: 𝑚𝑠𝑔 ← base_2b (𝑀 , 𝑙𝑔𝑤 , 𝑙𝑒𝑛1 )▷ convert message to base 𝑤

3: for 𝑖 from 0 to 𝑙𝑒𝑛1 − 1 do
4:𝑐𝑠𝑢𝑚 ← 𝑐𝑠𝑢𝑚 + 𝑤 − 1 − 𝑚𝑠𝑔[𝑖]5: end for▷ compute checksum

6: 𝑐𝑠𝑢𝑚 ← 𝑐𝑠𝑢𝑚 ≪ ((8 − ((𝑙𝑒𝑛2 ⋅ 𝑙𝑔𝑤 ) mod 8)) mod 8)
7: 𝑚𝑠𝑔 ← 𝑚𝑠𝑔 ∥ base_2b (toByte (𝑐𝑠𝑢𝑚, ⌈▷ for 𝑙𝑔𝑤 = 4, left shift by 4
▷ convert to base 𝑤

𝑙𝑒𝑛2 ⋅𝑙𝑔𝑤⌉) , 𝑙𝑔𝑤 , 𝑙𝑒𝑛2 )8

8: for 𝑖 from 0 to 𝑙𝑒𝑛 − 1 do
9:
ADRS.setChainAddress(𝑖)10:𝑡𝑚𝑝[𝑖] ← chain(𝑠𝑖𝑔[𝑖], 𝑚𝑠𝑔[𝑖], 𝑤 − 1 − 𝑚𝑠𝑔[𝑖], PK.seed, ADRS)
11: end for
12: wotspkADRS ← ADRS
▷ copy address to create WOTS+ public key address
13: wotspkADRS.setTypeAndClear(WOTS_PK)
14: wotspkADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
15: 𝑝𝑘𝑠𝑖𝑔 ← T𝑙𝑒𝑛 (PK.seed, wotspkADRS, 𝑡𝑚𝑝)
16: return 𝑝𝑘𝑠𝑖𝑔

21

FIPS 205

6.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

eXtended Merkle Signature Scheme (XMSS)XMSS extends the WOTS+ signature scheme into one that can sign multiple messages. A Merkle′
tree [13] of height ℎ′ is used to allow 2ℎ WOTS+ public keys to be authenticated using a single
𝑛-byte XMSS public key, which is the root of the Merkle tree.12 As each WOTS+ key may be used′
to sign one message, the XMSS key may be used to sign 2ℎ messages.
An XMSS signature is (ℎ′ + 𝑙𝑒𝑛) ⋅ 𝑛 bytes in length and consists of a WOTS+ signature and anauthentication path (see Figure 11). The authentication path is an array of nodes from the Merkle
tree — one from each level of the tree, except for the root — that allows the verifier to computethe root of the tree when used in conjunction with the WOTS+ public key that can be computedfrom the WOTS+ signature.
SIGWOTS+AUTH[0]⋯AUTH[ℎ′ − 1]𝑙𝑒𝑛 ⋅ 𝑛bytes
𝑛 bytes𝑛 bytesFigure 11. XMSS signature data format

6.1 Generating a Merkle Hash Tree
The xmss_node function (Algorithm 9) computes the nodes of an XMSS tree. The xmss_node
function takes as input SK.seed and PK.seed from the SLH-DSA private key; a target node index
𝑖, which is the index of the node being computed; a target node height 𝑧, which is the height
within the Merkle tree of the node being computed; and an address. The address ADRS musthave the layer address and tree address set to the XMSS tree within which the node is being′
computed. The target node height and index must satisfy 𝑧 ≤ ℎ′ and 𝑖 < 2(ℎ −𝑧) .
Each node in an XMSS tree is the root of a subtree, and Algorithm 9 computes the root of thesubtree recursively. If the subtree consists of a single leaf node, then the function simply returns
the value of the node’s WOTS+ public key (lines 2 through 4). Otherwise, the function computes
the roots of the left subtree (line 6) and right subtree (line 7) and hashes them together (lines 8
through 11).

12′

The Merkle tree formed from the 2ℎ WOTS+ keys of an XMSS key is referred to in this standard as an XMSS tree.

22

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 9 xmss_node(SK.seed, 𝑖, 𝑧, PK.seed, ADRS)
Computes the root of a Merkle subtree of WOTS+ public keys.
Input: Secret seed SK.seed, target node index 𝑖, target node height 𝑧, public seed PK.seed,address ADRS.
Output: 𝑛-byte root 𝑛𝑜𝑑𝑒.
1: if 𝑧 = 0 then2:
ADRS.setTypeAndClear(WOTS_HASH)3:
ADRS.setKeyPairAddress(𝑖)4:𝑛𝑜𝑑𝑒 ← wots_pkGen(SK.seed, PK.seed, ADRS)
5: else6:
𝑙𝑛𝑜𝑑𝑒 ← xmss_node(SK.seed, 2𝑖, 𝑧 − 1, PK.seed, ADRS)
7:
𝑟𝑛𝑜𝑑𝑒 ← xmss_node(SK.seed, 2𝑖 + 1, 𝑧 − 1, PK.seed, ADRS)
8:
ADRS.setTypeAndClear(TREE)
9:
ADRS.setTreeHeight(𝑧)10:
ADRS.setTreeIndex(𝑖)11:𝑛𝑜𝑑𝑒 ← H(PK.seed, ADRS, 𝑙𝑛𝑜𝑑𝑒 ∥ 𝑟𝑛𝑜𝑑𝑒)
12: end if
13: return 𝑛𝑜𝑑𝑒

6.2 Generating an XMSS Signature
The xmss_sign function (Algorithm 10) creates an XMSS signature on an 𝑛-byte message 𝑀13 bycreating an authentication path (lines 1 through 4) and signing 𝑀 with the appropriate WOTS+
key (lines 5 through 7). In addition to 𝑀, xmss_sign takes SK.seed and PK.seed from the
SLH-DSA private key, an address, and an index as input. The address ADRS must have the layer
address and tree address set to the XMSS key that is being used to sign the message, and theindex 𝑖𝑑𝑥 must be the index of the WOTS+ key within the XMSS tree that will be used to sign themessage.
The authentication path consists of the sibling nodes of each node that is on the path fromthe WOTS+ key used to the root. For example, in Figure 12, if the message is signed with 𝐾2 ,then 𝐾2 , 𝑛1,1 , and 𝑛2,0 are the on path nodes, and the authentication path consists of 𝐾3 ,𝑛1,0 , and 𝑛2,1 . In line 2 of Algorithm 10, ⌊𝑖𝑑𝑥/2𝑗 ⌋ is the on path node, and ⌊𝑖𝑑𝑥/2𝑗 ⌋ ⊕ 1 is theauthentication path node. Line 3 computes the value of the authentication path node.

13

In SLH-DSA, the message 𝑀 that is signed using XMSS is either an XMSS public key or a FORS public key.

23

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 10 xmss_sign(𝑀, SK.seed, 𝑖𝑑𝑥, PK.seed, ADRS)Generates an XMSS signature.
Input: 𝑛-byte message 𝑀, secret seed SK.seed, index 𝑖𝑑𝑥, public seed PK.seed,address ADRS.
Output: XMSS signature SIG𝑋𝑀𝑆𝑆 = (𝑠𝑖𝑔 ∥ AUTH).
1: for 𝑗 from 0 to ℎ′ − 1 do
▷ build authentication path𝑗2:𝑘 ← ⌊𝑖𝑑𝑥/2 ⌋ ⊕ 1
3:
AUTH[𝑗] ← xmss_node(SK.seed, 𝑘, 𝑗, PK.seed, ADRS)
4: end for
5: ADRS.setTypeAndClear(WOTS_HASH)
6: ADRS.setKeyPairAddress(𝑖𝑑𝑥)
7: 𝑠𝑖𝑔 ← wots_sign(𝑀 , SK.seed, PK.seed, ADRS)
8: SIG𝑋𝑀𝑆𝑆 ← 𝑠𝑖𝑔 ∥ AUTH
9: return SIG𝑋𝑀𝑆𝑆

𝑛3,0 = H(𝑛2,0 ∥ 𝑛2,1 )


PP





PP

P
P

𝑛2,0 = H(𝑛1,0 ∥ 𝑛1,1 )

𝑛2,1 = H(𝑛1,2 ∥ 𝑛1,3 )

�
�

�
�

@
@

@
@

𝑛1,0 = H(𝐾0 ∥ 𝐾1 ) 𝑛1,1 = H(𝐾2 ∥ 𝐾3 ) 𝑛1,2 = H(𝐾4 ∥ 𝐾5 ) 𝑛1,3 = H(𝐾6 ∥ 𝐾7 )
�
�

𝐾0

@
@

𝐾1

�
�

𝐾2

@
@

�
�

𝐾3

@
@

𝐾4

Figure 12. Merkle hash tree

24

𝐾5

�
�

𝐾6

@
@

𝐾7

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

6.3 Computing an XMSS Public Key From a Signature
Verifying an XMSS signature involves computing a public-key value from a message and a signature
value. Verification succeeds if the correct public-key value is computed, which is determinedby using the computed public-key value along with other information to compute a candidate
PK.root value and then comparing that value to the known value of PK.root from the SLH-DSA
public key. This section describes xmss_pkFromSig (Algorithm 11), a function that computes acandidate XMSS public key from an XMSS signature and corresponding message.
In addition to an 𝑛-byte message 𝑀 and an (𝑙𝑒𝑛+ℎ′ )⋅𝑛-byte signature SIG𝑋𝑀𝑆𝑆 , xmss_pkFromSigtakes PK.seed from the SLH-DSA public key, an address, and an index as input. The address
ADRS must be set to the layer address and tree address of the XMSS key that was used to sign
the message, and the index 𝑖𝑑𝑥 must be the index of the WOTS+ key within the XMSS tree thatwas used to sign the message.
Algorithm 11 begins by computing the WOTS+ public key in lines 1 through 5. The root is thencomputed in lines 6 through 18. Starting with the leaf node (i.e., the WOTS+ public key), a
node at each level of the tree is computed by hashing together the node computed in theprevious iteration with the corresponding authentication path node. In lines 12 and 15, AUTH isinterpreted as an array of ℎ′ 𝑛-byte strings.
Algorithm 11 xmss_pkFromSig(𝑖𝑑𝑥, SIG𝑋𝑀𝑆𝑆 , 𝑀, PK.seed, ADRS)
Computes an XMSS public key from an XMSS signature.
Input: Index 𝑖𝑑𝑥, XMSS signature SIG𝑋𝑀𝑆𝑆 = (𝑠𝑖𝑔 ∥ AUTH), 𝑛-byte message 𝑀,
public seed PK.seed, address ADRS.
Output: 𝑛-byte root value 𝑛𝑜𝑑𝑒[0].
1: ADRS.setTypeAndClear(WOTS_HASH)▷ compute WOTS+ pk from WOTS+ 𝑠𝑖𝑔
2: ADRS.setKeyPairAddress(𝑖𝑑𝑥)
3: 𝑠𝑖𝑔 ← SIG𝑋𝑀𝑆𝑆 .getWOTSSig()▷ SIG𝑋𝑀𝑆𝑆 [0 ∶ 𝑙𝑒𝑛 ⋅ 𝑛]
4: AUTH ← SIG𝑋𝑀𝑆𝑆 .getXMSSAUTH()▷ SIG𝑋𝑀𝑆𝑆 [𝑙𝑒𝑛 ⋅ 𝑛 ∶ (𝑙𝑒𝑛 + ℎ′ ) ⋅ 𝑛]
5: 𝑛𝑜𝑑𝑒[0] ← wots_pkFromSig(𝑠𝑖𝑔, 𝑀 , PK.seed, ADRS)
6: ADRS.setTypeAndClear(TREE)▷ compute root from WOTS+ pk and AUTH
7: ADRS.setTreeIndex(𝑖𝑑𝑥)
8: for 𝑘 from 0 to ℎ′ − 1 do
9:
ADRS.setTreeHeight(𝑘 + 1)
10:
if ⌊𝑖𝑑𝑥/2𝑘 ⌋ is even then
11:
ADRS.setTreeIndex(ADRS.getTreeIndex()/2)
12:
𝑛𝑜𝑑𝑒[1] ← H(PK.seed, ADRS, 𝑛𝑜𝑑𝑒[0] ∥ AUTH[𝑘])
13:
else
14:
ADRS.setTreeIndex((ADRS.getTreeIndex() − 1)/2)
15:
𝑛𝑜𝑑𝑒[1] ← H(PK.seed, ADRS, AUTH[𝑘] ∥ 𝑛𝑜𝑑𝑒[0])16:
end if17:
𝑛𝑜𝑑𝑒[0] ← 𝑛𝑜𝑑𝑒[1]18: end for
19: return 𝑛𝑜𝑑𝑒[0]25FIPS 205

7.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

The SLH-DSA Hypertree

SLH-DSA requires a very large number of WOTS+ keys to sign FORS public keys. As it would
not be feasible for the parameter sets in this standard to have a single XMSS key with so many
WOTS+ keys, SLH-DSA uses a hypertree to sign the FORS keys. As depicted in Figure 1, a hypertreeis a tree of XMSS trees. The XMSS keys at the lowest layer are used to sign FORS public keys
(Section 8), and the XMSS keys at every other layer are used to sign the XMSS public keys at thelayer below.
The hypertree has 𝑑 layers of XMSS trees with each XMSS tree being a Merkle tree of height ℎ′ ,so the total height of the hypertree is ℎ = 𝑑 ⋅ ℎ′ (see Table 2). The top layer (layer 𝑑 − 1) is asingle XMSS tree, and the public key of this XMSS key pair (i.e., the root of the Merkle tree) is the′
public key of the hypertree (PK.root). The next layer down has 2ℎ XMSS trees, and the public′
key of each of these XMSS keys is signed by one of the 2ℎ WOTS+ keys that is part of the top′
layer’s XMSS key. The lowest layer has 2ℎ−ℎ XMSS trees, providing 2ℎ WOTS+ keys to sign FORS
keys.

7.1 Hypertree Signature Generation
A hypertree signature is (ℎ + 𝑑 ⋅ 𝑙𝑒𝑛) ⋅ 𝑛 bytes in length and consists of a sequence of 𝑑 XMSS
signatures, starting with a signature generated using an XMSS key at the lowest layer and ending
with a signature generated using the XMSS key at the top layer (see Figure 13).
XMSS signature SIGXMSS (layer 0)
XMSS signature SIGXMSS (layer 1)⋯
XMSS signature SIGXMSS (layer 𝑑 − 1)(ℎ′ + 𝑙𝑒𝑛) ⋅ 𝑛 bytes(ℎ′ + 𝑙𝑒𝑛) ⋅ 𝑛 bytes(ℎ′ + 𝑙𝑒𝑛) ⋅ 𝑛 bytes

Figure 13. HT signature data format
In addition to the 𝑛-byte message 𝑀,14 the ht_sign function (Algorithm 12) takes as input
SK.seed and PK.seed from the SLH-DSA private key, the index of the XMSS tree at the lowest
layer that will sign the message 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , and the index of the WOTS+ key within the XMSS treethat will sign the message 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 .
Algorithm 12 begins in lines 1 through 3 by signing 𝑀 with the specified XMSS key using the
WOTS+ key within that XMSS key specified by 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 . The XMSS public key is obtained (line 5 or14) for each successive layer and signed by the appropriate key at the next higher level (lines 7
through 11).

14

In SLH-DSA, the message 𝑀 that is provided to ht_sign is a FORS public key.

26

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 12 ht_sign(𝑀, SK.seed, PK.seed, 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 )Generates a hypertree signature.
Input: Message 𝑀, private seed SK.seed, public seed PK.seed, tree index 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ,leaf index 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 .
Output: HT signature SIG𝐻𝑇 .
1: ADRS ← toByte(0, 32)
2: ADRS.setTreeAddress(𝑖𝑑𝑥𝑡𝑟𝑒𝑒 )3: SIG𝑡𝑚𝑝 ← xmss_sign(𝑀 , SK.seed, 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , PK.seed, ADRS)
4: SIG𝐻𝑇 ← SIG𝑡𝑚𝑝
5: 𝑟𝑜𝑜𝑡 ← xmss_pkFromSig(𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , SIG𝑡𝑚𝑝 , 𝑀 , PK.seed, ADRS)
6: for 𝑗 from 1 to 𝑑 − 1 do′
7:
𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ← 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 mod 2ℎ▷ ℎ′ least significant bits of 𝑖𝑑𝑥𝑡𝑟𝑒𝑒′
8:
𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ← 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ≫ ℎ▷ remove least significant ℎ′ bits from 𝑖𝑑𝑥𝑡𝑟𝑒𝑒
9:
ADRS.setLayerAddress(𝑗)10:
ADRS.setTreeAddress(𝑖𝑑𝑥𝑡𝑟𝑒𝑒 )11:
SIG𝑡𝑚𝑝 ← xmss_sign(𝑟𝑜𝑜𝑡, SK.seed, 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , PK.seed, ADRS)12:SIG𝐻𝑇 ← SIG𝐻𝑇 ∥ SIG𝑡𝑚𝑝13:
if 𝑗 < 𝑑 − 1 then14:𝑟𝑜𝑜𝑡 ← xmss_pkFromSig(𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , SIG𝑡𝑚𝑝 , 𝑟𝑜𝑜𝑡, PK.seed, ADRS)
15:
end if
16: end for
17: return SIG𝐻𝑇27FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

7.2 Hypertree Signature Verification
Hypertree signature verification works by making 𝑑 calls to xmss_pkFromSig (Algorithm 11) andcomparing the result to the public key of the hypertree.
In addition to the 𝑛-byte message 𝑀 and the (ℎ + 𝑑 ⋅ 𝑙𝑒𝑛) ⋅ 𝑛-byte signature SIG𝐻𝑇 , ht_verify(Algorithm 13) takes as input PK.seed and PK.root from the SLH-DSA public key, the index of
the XMSS tree at the lowest layer that signed the message 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , and the index of the WOTS+
key within the XMSS tree that signed the message 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 .
At each layer, either the message 𝑀 or the computed public key of the XMSS key at the lower
layer is provided along with the appropriate XMSS signature to xmss_pkFromSig in order toobtain the layer’s computed XMSS public key. If the computed XMSS public key of the top layer
tree is the same as the known hypertree public key, PK.root, then verification succeeds.
Algorithm 13 ht_verify(𝑀, SIG𝐻𝑇 , PK.seed, 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , PK.root)
Verifies a hypertree signature.
Input: Message 𝑀, signature SIG𝐻𝑇 , public seed PK.seed, tree index 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , leaf index 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ,HT public key PK.root.
Output: Boolean.
1: ADRS ← toByte(0, 32)
2: ADRS.setTreeAddress(𝑖𝑑𝑥𝑡𝑟𝑒𝑒 )3: SIG𝑡𝑚𝑝 ← SIG𝐻𝑇 .getXMSSSignature(0)▷ SIG𝐻𝑇 [0 ∶ (ℎ′ + 𝑙𝑒𝑛) ⋅ 𝑛]
4: 𝑛𝑜𝑑𝑒 ← xmss_pkFromSig(𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , SIG𝑡𝑚𝑝 , 𝑀 , PK.seed, ADRS)
5: for 𝑗 from 1 to 𝑑 − 1 do′
6:𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ← 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 mod 2ℎ▷ ℎ′ least significant bits of 𝑖𝑑𝑥𝑡𝑟𝑒𝑒
7:
𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ← 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ≫ ℎ′
▷ remove least significant ℎ′ bits from 𝑖𝑑𝑥𝑡𝑟𝑒𝑒
8:
ADRS.setLayerAddress(𝑗)9:
ADRS.setTreeAddress(𝑖𝑑𝑥𝑡𝑟𝑒𝑒 )10:
SIG𝑡𝑚𝑝 ← SIG𝐻𝑇 .getXMSSSignature(𝑗) ▷ SIG𝐻𝑇 [𝑗 ⋅ (ℎ′ + 𝑙𝑒𝑛) ⋅ 𝑛 ∶ (𝑗 + 1)(ℎ′ + 𝑙𝑒𝑛) ⋅ 𝑛]11:
𝑛𝑜𝑑𝑒 ← xmss_pkFromSig(𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , SIG𝑡𝑚𝑝 , 𝑛𝑜𝑑𝑒, PK.seed, ADRS)
12: end for
13: if 𝑛𝑜𝑑𝑒 = PK.root then14:
return true
15: else
16:
return false
17: end if

28

FIPS 205

8.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Forest of Random Subsets (FORS)

FORS is a few-time signature scheme that is used to sign the digests of the actual messages.
Unlike WOTS+ , for which forgeries become feasible if a key is used twice [22], the security of a
FORS key degrades gradually as the number of signatures increases.
FORS uses two parameters: 𝑘 and 𝑡 = 2𝑎 (see Table 2). A FORS private key consists of 𝑘 sets of 𝑡
𝑛-byte strings, all of which are pseudorandomly generated from the seed SK.seed. Each of the𝑘 sets is formed into a Merkle tree, and the roots of the trees are hashed together to form the
FORS public key. A signature on a 𝑘 ⋅ 𝑎-bit message digest consists of 𝑘 elements from the private
key, one from each set selected using 𝑎 bits of the message digest, along with the authentication
paths for each of these elements (see Figure 14).
private key value (tree 0)𝑛 bytes

AUTH (tree 0)𝑎 ⋅ 𝑛 bytes⋯
private key value (tree 𝑘 − 1)

𝑛 bytes

AUTH (tree 𝑘 − 1)𝑎 ⋅ 𝑛 bytes

Figure 14. FORS signature data format

8.1 Generating FORS Secret Values
The fors_skGen function (Algorithm 14) generates the 𝑛-byte strings of the FORS private key. The
function takes SK.seed and PK.seed from the SLH-DSA private key, an address, and an index
as input. The 𝑡𝑦𝑝𝑒 in the address ADRS must be set to FORS_TREE, and the tree address andkey pair address must be set to the index of the WOTS+ key within the XMSS tree that signs the
FORS key. The layer address must be set to zero. The index 𝑖𝑑𝑥 is the index of the FORS secretvalue within the sets of FORS trees.
Algorithm 14 fors_skGen(SK.seed, PK.seed, ADRS, 𝑖𝑑𝑥)
Generates a FORS private-key value.
Input: Secret seed SK.seed, public seed PK.seed, address ADRS, secret key index 𝑖𝑑𝑥.
Output: 𝑛-byte FORS private-key value.
1: skADRS ← ADRS
▷ copy address to create key generation address
2: skADRS.setTypeAndClear(FORS_PRF)
3: skADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
4: skADRS.setTreeIndex(𝑖𝑑𝑥)
5: return PRF(PK.seed, SK.seed, skADRS)

29

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

8.2 Generating a Merkle Hash Tree
The fors_node function (Algorithm 15) computes the nodes of a Merkle tree. It is the same as
xmss_node, except that the leaf nodes are the hashes of the FORS secret values instead of WOTS+
public keys.
The fors_node function takes as input SK.seed and PK.seed from the SLH-DSA private key; atarget node index 𝑖, which is the index of the node being computed; a target node height 𝑧, whichis the height within the Merkle tree of the node being computed; and an address. The address
ADRS must have the layer address set to zero (since the XMSS tree that signs a FORS key isalways at layer 0), the tree address set to the XMSS tree that signs the FORS key, the 𝑡𝑦𝑝𝑒 set to
FORS_TREE, and the key pair address set to the index of the WOTS+ key within the XMSS treethat signs the FORS key. The target node height and index must satisfy 𝑧 ≤ 𝑎 and 𝑖 < 𝑘 ⋅ 2(𝑎−𝑧) .
Each node in the Merkle tree is the root of a subtree, and Algorithm 15 computes the root of a
subtree recursively. If the subtree consists of a single leaf node, then the function simply returns
a hash of the node’s private 𝑛-byte string (lines 2 through 5). Otherwise, the function computes
the roots of the left subtree (line 7) and right subtree (line 8) and hashes them together (lines 9through 11).
Algorithm 15 fors_node(SK.seed, 𝑖, 𝑧, PK.seed, ADRS)
Computes the root of a Merkle subtree of FORS public values.
Input: Secret seed SK.seed, target node index 𝑖, target node height 𝑧, public seed PK.seed,address ADRS.
Output: 𝑛-byte root 𝑛𝑜𝑑𝑒.
1: if 𝑧 = 0 then2:𝑠𝑘 ← fors_skGen(SK.seed, PK.seed, ADRS, 𝑖)
3:
ADRS.setTreeHeight(0)4:ADRS.setTreeIndex(𝑖)5:𝑛𝑜𝑑𝑒 ← F(PK.seed, ADRS, 𝑠𝑘)
6: else7:
𝑙𝑛𝑜𝑑𝑒 ← fors_node(SK.seed, 2𝑖, 𝑧 − 1, PK.seed, ADRS)
8:𝑟𝑛𝑜𝑑𝑒 ← fors_node(SK.seed, 2𝑖 + 1, 𝑧 − 1, PK.seed, ADRS)
9:ADRS.setTreeHeight(𝑧)10:
ADRS.setTreeIndex(𝑖)11:𝑛𝑜𝑑𝑒 ← H(PK.seed, ADRS, 𝑙𝑛𝑜𝑑𝑒 ∥ 𝑟𝑛𝑜𝑑𝑒)
12: end if
13: return 𝑛𝑜𝑑𝑒

8.3 Generating a FORS Signature
The fors_sign function (Algorithm 16) signs a 𝑘 ⋅ 𝑎-bit message digest 𝑚𝑑.15 In addition to themessage digest, fors_sign takes SK.seed and PK.seed from the SLH-DSA private key and an
address as input. The address ADRS must have the layer address set to zero (since the XMSS15

For convenience, fors_sign takes a ⌈ 𝑘⋅𝑎
8 ⌉ byte message digest as input and extracts 𝑘 ⋅ 𝑎 bits to sign.

30

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

tree that signs a FORS key is always at layer 0), the tree address set to the XMSS tree that signs
the FORS key, the 𝑡𝑦𝑝𝑒 set to FORS_TREE, and the key pair address set to the index of the WOTS+
key within the XMSS tree that signs the FORS key.
The fors_sign function splits 𝑘⋅𝑎 bits of 𝑚𝑑 into 𝑘 𝑎-bit strings (line 2), each of which is interpreted
as an integer between 0 and 𝑡 − 1. Each of these integers is used to select a secret value fromone of the 𝑘 sets (line 4). For each secret value selected, an authentication path is computed
and added to the signature (lines 5 through 9).
Algorithm 16 fors_sign(𝑚𝑑, SK.seed, PK.seed, ADRS)Generates a FORS signature.
Input: Message digest 𝑚𝑑, secret seed SK.seed, address ADRS, public seed PK.seed.
Output: FORS signature SIG𝐹 𝑂𝑅𝑆 .
1: SIG𝐹 𝑂𝑅𝑆 = NULL
▷ initialize SIG𝐹 𝑂𝑅𝑆 as a zero-length byte string
2: 𝑖𝑛𝑑𝑖𝑐𝑒𝑠 ← base_2b (𝑚𝑑, 𝑎, 𝑘)
3: for 𝑖 from 0 to 𝑘 − 1 do
▷ compute signature elements
4:
SIG𝐹 𝑂𝑅𝑆 ← SIG𝐹 𝑂𝑅𝑆 ∥ fors_skGen(SK.seed, PK.seed, ADRS, 𝑖 ⋅ 2𝑎 + 𝑖𝑛𝑑𝑖𝑐𝑒𝑠[𝑖])5:for 𝑗 from 0 to 𝑎 − 1 do
▷ compute auth path6:𝑠 ← ⌊𝑖𝑛𝑑𝑖𝑐𝑒𝑠[𝑖]/2𝑗 ⌋ ⊕ 1
7:AUTH[𝑗] ← fors_node(SK.seed, 𝑖 ⋅ 2𝑎−𝑗 + 𝑠, 𝑗, PK.seed, ADRS)
8:
end for
9:
SIG𝐹 𝑂𝑅𝑆 ← SIG𝐹 𝑂𝑅𝑆 ∥ AUTH
10: end for
11: return SIG𝐹 𝑂𝑅𝑆

8.4 Computing a FORS Public Key From a Signature
Verifying a FORS signature involves computing a public-key value from a message digest anda signature value. Verification succeeds if the correct public-key value is computed, which isdetermined by verifying the hypertree signature on the computed public-key value using the SLHDSA public key. This section describes fors_pkFromSig (Algorithm 17), a function that computes
a candidate FORS public key from a FORS signature and corresponding message digest.
In addition to a message digest 𝑚𝑑 and a 𝑘 ⋅ (𝑎 + 1) ⋅ 𝑛-byte signature SIG𝐹 𝑂𝑅𝑆 , fors_pkFromSigtakes PK.seed from the SLH-DSA public key and an address as input.16 The address ADRS
must have the layer address set to zero (since the XMSS tree that signs a FORS key is always atlayer 0), the tree address set to the XMSS tree that signs the FORS key, the 𝑡𝑦𝑝𝑒 set to FORS_TREE,
and the key pair address set to the index of the WOTS+ key within the XMSS tree that signs the
FORS key.
The fors_pkFromSig function begins by computing the roots of each of the 𝑘 Merkle trees (lines
2 through 20). As in fors_sign, 𝑘 ⋅ 𝑎 bits of the message digest are split into 𝑘 𝑎-bit strings (line1), each of which is interpreted as an integer between 0 and 𝑡 − 1. The integers are used todetermine the locations in the Merkle trees of the secret values from the signature (lines 3
16

As with fors_sign, fors_pkFromSig takes a ⌈ 𝑘⋅𝑎
8 ⌉ byte message digest as input and extracts 𝑘 ⋅ 𝑎 bits.

31

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

through 5). The hashes of the secret values are computed (line 6), and the hash values are usedalong with the corresponding authentication paths from the signature to compute the Merkle
tree roots (lines 7 through 19). Once all of the Merkle tree roots have been computed, they arehashed together to compute the FORS public key (lines 21 through 24).
Algorithm 17 fors_pkFromSig(SIG𝐹 𝑂𝑅𝑆 , 𝑚𝑑, PK.seed, ADRS)
Computes a FORS public key from a FORS signature.
Input: FORS signature SIG𝐹 𝑂𝑅𝑆 , message digest 𝑚𝑑, public seed PK.seed, address ADRS.
Output: FORS public key.
1: 𝑖𝑛𝑑𝑖𝑐𝑒𝑠 ← base_2b (𝑚𝑑, 𝑎, 𝑘)
2: for 𝑖 from 0 to 𝑘 − 1 do
3:𝑠𝑘 ← SIG𝐹 𝑂𝑅𝑆 .getSK(𝑖)▷ SIG𝐹 𝑂𝑅𝑆 [𝑖 ⋅ (𝑎 + 1) ⋅ 𝑛 ∶ (𝑖 ⋅ (𝑎 + 1) + 1) ⋅ 𝑛]
4:
ADRS.setTreeHeight(0)▷ compute leaf
5:
ADRS.setTreeIndex(𝑖 ⋅ 2𝑎 + 𝑖𝑛𝑑𝑖𝑐𝑒𝑠[𝑖])6:𝑛𝑜𝑑𝑒[0] ← F(PK.seed, ADRS, 𝑠𝑘)
7:
𝑎𝑢𝑡ℎ ← SIG𝐹 𝑂𝑅𝑆 .getAUTH(𝑖) ▷ SIG𝐹 𝑂𝑅𝑆 [(𝑖 ⋅ (𝑎 + 1) + 1) ⋅ 𝑛 ∶ (𝑖 + 1) ⋅ (𝑎 + 1) ⋅ 𝑛]
8:
for 𝑗 from 0 to 𝑎 − 1 do
▷ compute root from leaf and AUTH
9:
ADRS.setTreeHeight(𝑗 + 1)
10:
if ⌊𝑖𝑛𝑑𝑖𝑐𝑒𝑠[𝑖]/2𝑗 ⌋ is even then
11:
ADRS.setTreeIndex(ADRS.getTreeIndex()/2)
12:
𝑛𝑜𝑑𝑒[1] ← H(PK.seed, ADRS, 𝑛𝑜𝑑𝑒[0] ∥ 𝑎𝑢𝑡ℎ[𝑗])
13:
else
14:
ADRS.setTreeIndex((ADRS.getTreeIndex() − 1)/2)
15:
𝑛𝑜𝑑𝑒[1] ← H(PK.seed, ADRS, 𝑎𝑢𝑡ℎ[𝑗] ∥ 𝑛𝑜𝑑𝑒[0])16:
end if17:
𝑛𝑜𝑑𝑒[0] ← 𝑛𝑜𝑑𝑒[1]18:
end for19:
𝑟𝑜𝑜𝑡[𝑖] ← 𝑛𝑜𝑑𝑒[0]20: end for
21: forspkADRS ← ADRS
▷ copy address to create a FORS public-key address
22: forspkADRS.setTypeAndClear(FORS_ROOTS)
23: forspkADRS.setKeyPairAddress(ADRS.getKeyPairAddress())
24: 𝑝𝑘 ← T𝑘 (PK.seed, forspkADRS, 𝑟𝑜𝑜𝑡)▷ compute the FORS public key
25: return 𝑝𝑘

32

FIPS 205

9.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

SLH-DSA Internal Functions

SLH-DSA uses the hypertree and the FORS keys to create a stateless hash-based signature scheme.
The SLH-DSA private key contains a secret seed value and a secret PRF key. The public key consistsof a key identifier PK.seed and the root of the hypertree. A signature is created by hashing
the message, using part of the message digest to select a FORS key, signing other bits from themessage digest with the FORS key, and generating a hypertree signature for the FORS key. The
parameters for SLH-DSA are those specified previously for WOTS+ , XMSS, the SLH-DSA hypertree,
and FORS (see Table 2).
SLH-DSA uses one additional parameter 𝑚, which is the length in bytes of the message digest. It
is computed as:
𝑚=⌈

ℎ′
𝑘⋅𝑎
ℎ − ℎ′⌉+⌈ ⌉+⌈⌉
8
8
8

SLH-DSA uses ℎ bits of the message digest to select a FORS key: ℎ − ℎ′ bits to select an XMSS
tree at the lowest layer and ℎ′ bits to select a WOTS+ key and corresponding FORS key from thattree. 𝑘 ⋅ 𝑎 bits of the digest are signed by the selected FORS key. While only ℎ + 𝑘 ⋅ 𝑎 bits of themessage digest are used, implementation is simplified by extracting the necessary bits from aslightly larger digest.
This section describes the functions for SLH-DSA key generation, signature generation, andsignature verification. In the functions in this section, where randomness is required, the random
values are provided as inputs to the functions. The interfaces specified in this section will be used
when testing of SLH-DSA implementations is performed through the Cryptographic Algorithm
Validation Program (CAVP). The key generation function in this section may also be used to obtain
the assurance of private key possession via regeneration, as described in Section 3.1.
Other than for testing purposes, the interfaces for key generation and signature generation
specified in this section should not be made available to applications, as any random values
required for key generation and signature generation shall be generated by the cryptographic
module. Section 10 provides guidance on the interfaces to be made available to applications.

9.1 SLH-DSA Key Generation
SLH-DSA public keys contain two elements (see Figure 16). The first is an 𝑛-byte public seed
PK.seed, which is used in many hash function calls to provide domain separation between
different SLH-DSA key pairs. The second value is the hypertree public key (i.e., the root of the
top layer XMSS tree). PK.seed shall be generated using an approved random bit generator (seeSK.seedSK.prfPK.seedPK.root

𝑛 bytes𝑛 bytes𝑛 bytes𝑛 bytesPK.seedPK.root

𝑛 bytes𝑛 bytesFigure 16. SLH-DSA public key

Figure 15. SLH-DSA private key
33

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD[14, 15, 16]), where the instantiation of the random bit generator supports at least 8𝑛 bits of
security strength.
The SLH-DSA private key contains two random, secret 𝑛-byte values (see Figure 15). SK.seed isused to generate all of the WOTS+ and FORS private key elements. SK.prf is used to generate a
randomization value for the randomized hashing of the message in SLH-DSA. The private key
also includes a copy of the public key. Both SK.seed and SK.prf shall be generated using anapproved random bit generator, where the instantiation of the random bit generator supports
at least 8𝑛 bits of security strength.
Algorithm 18 generates an SLH-DSA key pair. Lines 1 through 3 compute the root of the top layer
XMSS tree. Line 4 bundles the three inputs and the computed PK.seed into the private andpublic keys.
SLH-DSA signing has two variants — “hedged” and deterministic (see Section 9.2) — whose keys
should only be used for the generation and verification of hedged and deterministic SLH-DSA
digital signatures, respectively.
Algorithm 18 slh_keygen_internal(SK.seed, SK.prf, PK.seed)
Generates an SLH-DSA key pair.
Input: Secret seed SK.seed, PRF key SK.prf, public seed PK.seed
Output: SLH-DSA key pair (SK, PK).
1: ADRS ← toByte(0, 32)▷ generate the public key for the top-level XMSS tree
2: ADRS.setLayerAddress(𝑑 − 1)
3: PK.root ← xmss_node(SK.seed, 0, ℎ′ , PK.seed, ADRS)
4: return ( (SK.seed, SK.prf, PK.seed, PK.root), (PK.seed, PK.root) )9.2 SLH-DSA Signature Generation
An SLH-DSA signature consists of a randomization string, a FORS signature, and a hypertree
signature, as shown in Figure 17.
Generating an SLH-DSA signature (Algorithm 19) begins by creating an 𝑚-byte message digest(lines 2 through 5). A PRF is used to create a message randomizer (line 3), and it is hashed alongwith the message to create the digest (line 5). Bits are then extracted from the message digest to
be signed by the FORS key (line 6), to select an XMSS tree (lines 7 and 9), and to select a WOTS+
key and corresponding FORS key within that XMSS tree (lines 8 and 10). Next, the FORS signature
is computed (lines 11 through 14), and the corresponding FORS public key is obtained (line 16).
Finally, the FORS public key is signed (line 17).
Randomness R
FORS signature SIGFORS
HT signature SIGHT

𝑛 bytes𝑘(1 + 𝑎) ⋅ 𝑛 bytes(ℎ + 𝑑 ⋅ 𝑙𝑒𝑛) ⋅ 𝑛 bytes

Figure 17. SLH-DSA signature data format
34

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 19 slh_sign_internal(𝑀, SK, 𝑎𝑑𝑑𝑟𝑛𝑑)
Generates an SLH-DSA signature.
Input: Message 𝑀, private key SK = (SK.seed, SK.prf, PK.seed, PK.root),(optional) additional randomness 𝑎𝑑𝑑𝑟𝑛𝑑.
Output: SLH-DSA signature SIG.
1: ADRS ← toByte(0, 32)
2: 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑 ← 𝑎𝑑𝑑𝑟𝑛𝑑▷ substitute 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑 ← PK.seed for the deterministic variant
3: 𝑅 ← PRF𝑚𝑠𝑔 (SK.prf, 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑, 𝑀 )▷ generate randomizer
4: SIG ← 𝑅
5: 𝑑𝑖𝑔𝑒𝑠𝑡 ← H𝑚𝑠𝑔 (𝑅, PK.seed, PK.root, 𝑀 )6: 𝑚𝑑 ← 𝑑𝑖𝑔𝑒𝑠𝑡 [0 ∶ ⌈ 𝑘⋅𝑎
8 ⌉]▷ compute message digest▷ first ⌈ 𝑘⋅𝑎
8 ⌉ bytesℎ−ℎ/𝑑▷ next ⌈ 8 ⌉ bytes

ℎ−ℎ/𝑑
8 ⌉]
ℎ−ℎ/𝑑
ℎ−ℎ/𝑑
𝑘⋅𝑎
ℎ
8: 𝑡𝑚𝑝_𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ← 𝑑𝑖𝑔𝑒𝑠𝑡 [⌈ 𝑘⋅𝑎
8 ⌉ + ⌈ 8 ⌉ ∶ ⌈ 8 ⌉ + ⌈ 8 ⌉ + ⌈ 8𝑑 ⌉]𝑘⋅𝑎
7: 𝑡𝑚𝑝_𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ← 𝑑𝑖𝑔𝑒𝑠𝑡 [⌈ 𝑘⋅𝑎
8 ⌉∶⌈ 8 ⌉+⌈ℎ▷ next ⌈ 8𝑑
⌉ bytes

9: 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ← toInt (𝑡𝑚𝑝_𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , ⌈

ℎ−ℎ/𝑑
ℎ−ℎ/𝑑
8 ⌉) mod 2ℎ
10: 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ← toInt (𝑡𝑚𝑝_𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , ⌈ 8𝑑⌉) mod 2ℎ/𝑑

11: ADRS.setTreeAddress(𝑖𝑑𝑥𝑡𝑟𝑒𝑒 )12: ADRS.setTypeAndClear(FORS_TREE)
13: ADRS.setKeyPairAddress(𝑖𝑑𝑥𝑙𝑒𝑎𝑓 )14: SIG𝐹 𝑂𝑅𝑆 ← fors_sign(𝑚𝑑, SK.seed, PK.seed, ADRS)
15: SIG ← SIG ∥ SIG𝐹 𝑂𝑅𝑆
16: PK𝐹 𝑂𝑅𝑆 ← fors_pkFromSig(SIG𝐹 𝑂𝑅𝑆 , 𝑚𝑑, PK.seed, ADRS)
17: SIG𝐻𝑇 ← ht_sign(PK𝐹 𝑂𝑅𝑆 , SK.seed, PK.seed, 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 )18: SIG ← SIG ∥ SIG𝐻𝑇
19: return SIG

35▷ get FORS key

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

The message randomizer may be set in either a non-deterministic or deterministic way, dependingon whether 𝑎𝑑𝑑𝑟𝑛𝑑 is provided as an input. For the “hedged” variant, 𝑎𝑑𝑑𝑟𝑛𝑑 is provided as an
input, and 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑 is set to 𝑎𝑑𝑑𝑟𝑛𝑑. The hedged variant is the default and should be used on
platforms where side-channel attacks are a concern. When using the hedged version, 𝑎𝑑𝑑𝑟𝑛𝑑
shall be an 𝑛-byte random value. While 𝑎𝑑𝑑𝑟𝑛𝑑 should ideally be generated by an approved
random bit generator, other methods for generating fresh random values may be used. For
the deterministic variant, 𝑎𝑑𝑑𝑟𝑛𝑑 is not provided as an input, and 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑 is set to PK.seed,
which results in signing being deterministic (i.e., signing the same message twice will result inthe same signature). The deterministic variant is available for platforms where a random bit
generator is not available.

9.3 SLH-DSA Signature Verification
As with signature generation, SLH-DSA signature verification (Algorithm 20) begins by computing
a message digest (line 8) and then extracting 𝑚𝑑 (line 9), 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 (lines 10 and 12), and 𝑖𝑑𝑥𝑙𝑒𝑎𝑓(lines 11 and 13) from the digest. A candidate FORS public key is then computed (line 17), andthe signature on the FORS key is verified (line 18). If this signature verification succeeds, thenthe correct FORS public key was computed, and the signature SIG on message 𝑀 is valid.
Algorithm 20 slh_verify_internal(𝑀, SIG, PK)
Verifies an SLH-DSA signature.
Input: Message 𝑀, signature SIG, public key PK = (PK.seed, PK.root).
Output: Boolean.
1: if |SIG| ≠ (1 + 𝑘(1 + 𝑎) + ℎ + 𝑑 ⋅ 𝑙𝑒𝑛) ⋅ 𝑛 then2:
return false
3: end if
4: ADRS ← toByte(0, 32)
5: 𝑅 ← SIG.getR()▷ SIG[0 ∶ 𝑛]
6: SIG𝐹 𝑂𝑅𝑆 ← SIG.getSIG_FORS()▷ SIG[𝑛 ∶ (1 + 𝑘(1 + 𝑎)) ⋅ 𝑛]
7: SIG𝐻𝑇 ← SIG.getSIG_HT()▷ SIG[(1 + 𝑘(1 + 𝑎)) ⋅ 𝑛 ∶ (1 + 𝑘(1 + 𝑎) + ℎ + 𝑑 ⋅ 𝑙𝑒𝑛) ⋅ 𝑛]
8: 𝑑𝑖𝑔𝑒𝑠𝑡 ← H𝑚𝑠𝑔 (𝑅, PK.seed, PK.root, 𝑀 )9: 𝑚𝑑 ← 𝑑𝑖𝑔𝑒𝑠𝑡 [0 ∶ ⌈ 𝑘⋅𝑎
8 ⌉]▷ compute message digest▷ first ⌈ 𝑘⋅𝑎
8 ⌉ bytesℎ−ℎ/𝑑▷ next ⌈ 8 ⌉ bytes

ℎ−ℎ/𝑑
8 ⌉]
ℎ−ℎ/𝑑
ℎ−ℎ/𝑑
ℎ
𝑘⋅𝑎
11: 𝑡𝑚𝑝_𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ← 𝑑𝑖𝑔𝑒𝑠𝑡 [⌈ 𝑘⋅𝑎
8 ⌉ + ⌈ 8 ⌉ ∶ ⌈ 8 ⌉ + ⌈ 8 ⌉ + ⌈ 8𝑑 ⌉]𝑘⋅𝑎
10: 𝑡𝑚𝑝_𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ← 𝑑𝑖𝑔𝑒𝑠𝑡 [⌈ 𝑘⋅𝑎
8 ⌉∶⌈ 8 ⌉+⌈ℎ▷ next ⌈ 8𝑑
⌉ bytes

12: 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 ← toInt (𝑡𝑚𝑝_𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , ⌈

ℎ−ℎ/𝑑
ℎ−ℎ/𝑑
8 ⌉) mod 2ℎ13: 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 ← toInt (𝑡𝑚𝑝_𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , ⌈ 8𝑑⌉) mod 2ℎ/𝑑

▷ compute FORS public key

14: ADRS.setTreeAddress(𝑖𝑑𝑥𝑡𝑟𝑒𝑒 )15: ADRS.setTypeAndClear(FORS_TREE)
16: ADRS.setKeyPairAddress(𝑖𝑑𝑥𝑙𝑒𝑎𝑓 )17: PK𝐹 𝑂𝑅𝑆 ← fors_pkFromSig(SIG𝐹 𝑂𝑅𝑆 , 𝑚𝑑, PK.seed, ADRS)
18: return ht_verify(PK𝐹 𝑂𝑅𝑆 , SIG𝐻𝑇 , PK.seed, 𝑖𝑑𝑥𝑡𝑟𝑒𝑒 , 𝑖𝑑𝑥𝑙𝑒𝑎𝑓 , PK.root)

36

FIPS 205

10.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

SLH-DSA External Functions

This section provides guidance on the key generation, signature generation, and signature
verification functions that should be provided for use by applications. The functions in thissection use the functions in Section 9 to implement the underlying SLH-DSA scheme.

10.1 SLH-DSA Key Generation
Algorithm 21 generates an SLH-DSA key pair. Lines 1 through 3 generate the random values
for the private and public keys, and line 7 calls slh_keygen_internal to compute PK.root andreturn the private and public key. PK.seed, SK.seed, and SK.prf shall be generated using anapproved random bit generator (see [14, 15, 16]), where the instantiation of the random bit
generator supports at least 8𝑛 bits of security strength.
Algorithm 21 slh_keygen()
Generates an SLH-DSA key pair.
Input: (none)
Output: SLH-DSA key pair (SK, PK).
$

1: SK.seed ←− 𝔹𝑛$

2: SK.prf ←−𝔹𝑛▷ set SK.seed, SK.prf, and PK.seed to random 𝑛-byte▷ strings using an approved random bit generator$

3: PK.seed ←− 𝔹𝑛
4: if SK.seed = NULL or SK.prf = NULL or PK.seed = NULL then5:
return ⊥▷ return an error indication if random bit generation failed
6: end if
7: return slh_keygen_internal(SK.seed, SK.prf, PK.seed)

10.2 SLH-DSA Signature Generation
This section presents two versions of SLH-DSA signature generation: a “pure” version (slh_sign)
and a “pre-hash” version (hash_slh_sign). Both versions use slh_sign_internal, but they differ
in how the message input to slh_sign_internal is created from the content to be signed. In thepure version, the content is signed by slh_sign_internal along with some domain separation
information. In the pre-hash version, a hash of the content is signed by slh_sign_internal alongwith some domain separation information.
Both versions take the content to be signed, the private key, and a context as input. The pre-hashversion also takes as input a hash function or XOF that is to be used to pre-hash the content tobe signed. The context string has a maximum length of 255 bytes. By default, the context is theempty string. However, applications may specify the use of a non-empty context string.
The identifier for a signature (e.g., the object identifier [OID]) should indicate whether thesignature is a pure signature or a pre-hash signature. In the case of pre-hash signatures, theidentifier should also indicate the hash function or XOF used to compute the pre-hash.17 While17

In the case of a XOF, this would also include the length of the output from the XOF.

37

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

a single key pair may be used for both pure and pre-hash signatures, it is recommended thateach key pair only be used for one version or the other. If a non-empty context string is to be
used, this should either be indicated by the signature’s identifier or the application with which
the signature is being used.
If the default hedged variant of slh_sign_internal is used, the 𝑛-byte random value 𝑎𝑑𝑑𝑟𝑛𝑑
shall be generated by the cryptographic module that runs slh_sign_internal. However, 𝑀 ′ inAlgorithms 22 and 23 may be constructed outside of the crytographic module. In the case ofhash_slh_sign, the hash or XOF of the content to be signed must be computed within a FIPS
140-validated cryptographic module, but it may be a different cryptographic module than the
one that runs slh_sign_internal.
In general, the pure version is preferred. However, for some cryptographic modules that generate
SLH-DSA signatures, performing lines 3 and 5 of Algorithm 19 may be infeasible if the message 𝑀
is large. This may, for example, be the result of the module having limited memory to store themessage to be signed. Similarly, for some cryptographic modules that verify SLH-DSA signatures,
performing line 8 of Algorithm 20 may be infeasible if the message 𝑀 is large. For some use
cases, these issues may be addressed by signing a digest of the content rather than signing thecontent directly.
In many cases where the content to be signed is large, hashing of the content is performed at
the application level. For example, in the Cryptographic Message Syntax [23], a digest of thecontent may be computed, and that digest is signed along with other attributes. In cases inwhich the content is not hashed at the application level, the pre-hash version of SLH-DSA signing(Section 10.2.2) may be used.
To maintain the same level of security strength when the content is hashed at the applicationlevel or when using the pre-hash version of SLH-DSA, the digest that is signed needs to begenerated using an approved hash function or XOF (e.g., from FIPS 180-4 [8] or FIPS 202 [6]) thatprovides at least 8𝑛 bits of classical security strength against both collision and second preimage
attacks [6, Table 4].18 Verification of a signature created in this way will require the verify function
to generate a digest from the message in the same way for input to the verification function.
Even if it is feasible to compute collisions on the hash functions or XOF used to instantiate H𝑚𝑠𝑔 ,PRF, PRF𝑚𝑠𝑔 , F, H, and T𝑙 , there is believed to be no adverse effect on the security of
SLH-DSA.19 However, if the input to the signing function is a digest of the content, then collisions
on the function used to compute the digest can result in forged messages.
10.2.1 Pure SLH-DSA Signature Generation
In the pure version, the content to be signed is prepended with a one-byte domain separator,
one byte that indicates the length of the context string, and the context string. The domain
separator, which has a value of zero for pure signing, is included to prevent pre-hash signaturesfrom verifying as pure signatures and vice versa. In the default case in which the context string
18

Obtaining at least 8𝑛 bits of classical security strength against collision attacks requires that the digest to besigned is at least 2𝑛 bytes in length.
19
As noted in Section 11, applications that require message-bound signatures may be adversely affected if it isfeasible to compute collisions on H𝑚𝑠𝑔 .

38

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

is empty, pure signing simply involves prepending two zero bytes to the content to be signed
and passing the result to slh_sign_internal along with the private key and, in the case of hedged
signing, an 𝑛-byte random value.
Algorithm 22 slh_sign(𝑀, 𝑐𝑡𝑥, SK)
Generates a pure SLH-DSA signature.
Input: Message 𝑀, context string 𝑐𝑡𝑥, private key SK.
Output: SLH-DSA signature SIG.
1: if |𝑐𝑡𝑥| > 255 thenreturn ⊥▷ return an error indication if the context string is too long2:
3: end if$

4: 𝑎𝑑𝑑𝑟𝑛𝑑 ←− 𝔹𝑛
5: if 𝑎𝑑𝑑𝑟𝑛𝑑 = NULL then6:
return ⊥7: end if▷ skip lines 4 through 7 for the deterministic variant▷ return an error indication if random bit generation failed

8: 𝑀 ′ ← toByte(0, 1) ∥ toByte(|𝑐𝑡𝑥|, 1) ∥ 𝑐𝑡𝑥 ∥ 𝑀▷ omit 𝑎𝑑𝑑𝑟𝑛𝑑 for the deterministic variant
9: SIG ← slh_sign_internal(𝑀 ′ , SK, 𝑎𝑑𝑑𝑟𝑛𝑑)
10: return SIG

10.2.2 HashSLH-DSA Signature Generation
In the pre-hash version, the message input to slh_sign_internal is the result of applying either ahash function or a XOF to the content to be signed. The output of the hash function or XOF isprepended by a one-byte domain separator, one byte that indicates the length of the context
string, the context string, and the distinguished encoding rules (DER) encoding of the hashfunction or XOF’s OID. The domain separator has a value of one for pre-hash signing. The DER
encoding of the OID includes the tag and length.
Algorithm 23 shows the DER encodings of the OIDs for SHA-256, SHA-512, SHAKE128, andSHAKE256. However, hash_slh_sign may be used with other hash functions or XOFs. SHA-256
and SHAKE128 are only appropriate for use with SLH-DSA parameter sets that are claimed to be
in security category 1 (see Section 11).

39

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 23 hash_slh_sign(𝑀, 𝑐𝑡𝑥, PH, SK)
Generates a pre-hash SLH-DSA signature.
Input: Message 𝑀, context string 𝑐𝑡𝑥, pre-hash function PH, private key SK.
Output: SLH-DSA signature SIG.
1: if |𝑐𝑡𝑥| > 255 then2:
return ⊥▷ return an error indication if the context string is too long
3: end if$

4: 𝑎𝑑𝑑𝑟𝑛𝑑 ←− 𝔹𝑛
5: if 𝑎𝑑𝑑𝑟𝑛𝑑 = NULL then6:
return ⊥7: end if▷ skip lines 4 through 7 for the deterministic variant▷ return an error indication if random bit generation failed

8: switch PH do
9:case SHA-256:
10:
OID ← toByte(0x0609608648016503040201, 11)11:PH𝑀 ← SHA-256(𝑀 )▷ 2.16.840.1.101.3.4.2.1

case SHA-512:
OID ← toByte(0x0609608648016503040203, 11)▷ 2.16.840.1.101.3.4.2.3
PH𝑀 ← SHA-512(𝑀 )15:case SHAKE128:
16:
OID ← toByte(0x060960864801650304020B, 11)▷ 2.16.840.1.101.3.4.2.11
17:
PH𝑀 ← SHAKE128(𝑀 , 256)18:case SHAKE256:
19:
OID ← toByte(0x060960864801650304020C, 11)▷ 2.16.840.1.101.3.4.2.12
20:
PH𝑀 ← SHAKE256(𝑀 , 512)21:
case …
▷ other approved hash functions or XOFs
22:…
23: end switch
24: 𝑀 ′ ← toByte(1, 1) ∥ toByte(|𝑐𝑡𝑥|, 1) ∥ 𝑐𝑡𝑥 ∥ OID ∥ PH𝑀
25: SIG ← slh_sign_internal(𝑀 ′ , SK, 𝑎𝑑𝑑𝑟𝑛𝑑)▷ omit 𝑎𝑑𝑑𝑟𝑛𝑑 for the deterministic variant
26: return SIG
12:
13:
14:

40

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

10.3 SLH-DSA Signature Verification
Algorithms 24 and 25 present the pure and pre-hash versions of SLH-DSA signature verificationthat correspond to the pure and pre-hash versions of SLH-DSA signature generation in Section 10.2. These functions construct 𝑀 ′ in the same way as Algorithms 22 and 23, respectively,
and pass the resulting 𝑀 ′ to slh_verify_internal for verification. As with signature generation,
𝑀 ′ may be constructed outside of the cryptographic module that performs slh_verify_internal.
However, in the case of hash_slh_verify, the hash or XOF of the content must be computed within
a FIPS 140-validated cryptographic module, which may be a different cryptographic module thanthe one that performs slh_verify_internal.
The identifier associated with the signature should indicate whether the pure or pre-hash versionof signature verification should be used, and in the pre-hash case, the hash function or XOF touse to compute the pre-hash. A non-empty context string should be used in verification if one is
specified in the signature’s identifier or by the application with which the signature is being used.
Algorithm 24 slh_verify(𝑀, SIG, 𝑐𝑡𝑥, PK)
Verifies a pure SLH-DSA signature.
Input: Message 𝑀, signature SIG, context string 𝑐𝑡𝑥, public key PK.
Output: Boolean.
1: if |𝑐𝑡𝑥| > 255 then2:
return false
3: end if
4: 𝑀 ′ ← toByte(0, 1) ∥ toByte(|𝑐𝑡𝑥|, 1) ∥ 𝑐𝑡𝑥 ∥ 𝑀
5: return slh_verify_internal(𝑀 ′ , SIG, PK)

41

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Algorithm 25 hash_slh_verify(𝑀, SIG, 𝑐𝑡𝑥, PH, PK)
Verifies a pre-hash SLH-DSA signature.
Input: Message 𝑀, signature SIG, context string 𝑐𝑡𝑥, pre-hash function PH, public key PK.
Output: Boolean.
1: if |𝑐𝑡𝑥| > 255 then2:
return false
3: end if
4: switch PH do
5:case SHA-256:
6:
OID ← toByte(0x0609608648016503040201, 11)7:PH𝑀 ← SHA-256(𝑀 )▷ 2.16.840.1.101.3.4.2.1

case SHA-512:
OID ← toByte(0x0609608648016503040203, 11)▷ 2.16.840.1.101.3.4.2.3
PH𝑀 ← SHA-512(𝑀 )11:case SHAKE128:
12:
OID ← toByte(0x060960864801650304020B, 11)▷ 2.16.840.1.101.3.4.2.11
13:
PH𝑀 ← SHAKE128(𝑀 , 256)14:case SHAKE256:
15:
OID ← toByte(0x060960864801650304020C, 11)▷ 2.16.840.1.101.3.4.2.12
16:
PH𝑀 ← SHAKE256(𝑀 , 512)17:case …
▷ other approved hash functions or XOFs
18:…
19: end switch
20: 𝑀 ′ ← toByte(1, 1) ∥ toByte(|𝑐𝑡𝑥|, 1) ∥ 𝑐𝑡𝑥 ∥ OID ∥ PH𝑀
21: return slh_verify_internal(𝑀 ′ , SIG, PK)
8:
9:
10:

42

FIPS 205

11.

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Parameter Sets

This standard approves 12 parameter sets for use with SLH-DSA. A parameter set consists ofparameters for WOTS+ (𝑛 and 𝑙𝑔𝑤 ), XMSS and the SLH-DSA hypertree (ℎ and 𝑑), and FORS (𝑘and 𝑎), as well as instantiations for the functions H𝑚𝑠𝑔 , PRF, PRF𝑚𝑠𝑔 , F, H, and Tℓ .
Table 2 lists the parameter sets that are approved for use.20 Each parameter set name indicatesthe hash function family (SHA2 or SHAKE) that is used to instantiate the hash functions, thelength in bits of the security parameter 𝑛, and whether the parameter set was designed to create
relatively small signatures (‘s’) or to have relatively fast signature generation (‘f’). There are six
sets of values for 𝑛, 𝑙𝑔𝑤 , ℎ, 𝑑, 𝑘, and 𝑎 that are approved for use.21 For each of the six sets ofvalues, the functions H𝑚𝑠𝑔 , PRF, PRF𝑚𝑠𝑔 , F, H, and Tℓ may be instantiated using either
SHAKE [6] or SHA-2 [8]. For the SHAKE parameter sets, the functions shall be instantiated as
specified in Section 11.1. For the SHA2 parameter sets, the functions shall be instantiated as
specified in Section 11.2.1 if 𝑛 = 16 and shall be instantiated as specified in Section 11.2.2 if
𝑛 = 24 or 𝑛 = 32.
Table 2. SLH-DSA parameter sets

SLH-DSA-SHA2-128s
SLH-DSA-SHAKE-128s
SLH-DSA-SHA2-128f
SLH-DSA-SHAKE-128f
SLH-DSA-SHA2-192s
SLH-DSA-SHAKE-192s
SLH-DSA-SHA2-192f
SLH-DSA-SHAKE-192f
SLH-DSA-SHA2-256s
SLH-DSA-SHAKE-256s
SLH-DSA-SHA2-256f
SLH-DSA-SHAKE-256f

pk
bytes

sig
bytes

𝑛

ℎ

𝑑

ℎ

𝑎

𝑘

𝑙𝑔𝑤

𝑚

security
category

16

63

7

9

12

14

4

30

1

32

7 856

16

66

22

3

6

33

4

34

1

32

17 088

24

63

7

9

14

17

4

39

3

48

16 224

24

66

22

3

8

33

4

42

3

48

35 664

32

64

8

8

14

22

4

47

5

64

29 792

32

68

17

4

9

35

4

49

5

64

49 856′The 12 parameter sets included in Table 2 were designed to meet certain security strengthcategories defined by NIST in its original Call for Proposals [25] with respect to existential unforgeability under chosen message attack (EUF-CMA) when each key pair is used to sign at most
264 messages.22 These security strength categories are explained further in SP 800-57, Part 1 [9].
20

SP 800-230 [24] specifies additional parameter sets that are approved for use. While key pairs generated for theparameter sets specified in this standard may be used to sign up to 264 messages, key pairs generated for theparameter sets in SP 800-230 are more limited in the number of signatures that may be generated.
21
In addition to 𝑛, 𝑙𝑔𝑤 , ℎ, 𝑑, 𝑘, and 𝑎, Table 2 also lists values for parameters that may be computed from thesevalues (ℎ′ , 𝑚, public-key size(pk bytes), and signature size(sig bytes)). The security category is the security
category in which the parameter set is claimed to be [10].
22
If a key pair were used to sign 10 billion (1010 ) messages per second, it would take over 58 years to sign 264
messages.

43

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Using this approach, security strength is not described by a single number, such as “128 bits of
security.” Instead, each parameter set is claimed to be at least as secure as a generic block cipher
with a prescribed key size. More precisely, it is claimed that the computational resources needed
to break SLH-DSA are greater than or equal to the computational resources needed to break theblock cipher when these computational resources are estimated using any realistic model ofcomputation. Different models of computation can be more or less realistic and, accordingly,
lead to more or less accurate estimates of security strength. Some commonly studied models
are discussed in [26].
Concretely, the parameter sets with 𝑛 = 16 are claimed to be in security category 1, theparameter sets with 𝑛 = 24 are claimed to be in security category 3, and the parameter sets with𝑛 = 32 are claimed to be in security category 5 [10]. For additional discussion of the security
strength of SLH-DSA, see [10, 27].
Some applications require a property known as message-bound signatures [28, 29], which
intuitively requires that it be infeasible for anyone to create a public key and a signature thatare valid for two different messages. Signature schemes are not required to have this property
under the EUF-CMA security definition used in assigning security categories. In the case of
SLH-DSA, the key pair owner could create two messages with the same signature by finding
a collision on H𝑚𝑠𝑔 . Due to the length of the output of H𝑚𝑠𝑔 , finding such a collision would
be expected to require fewer computational resources than specified for the parameter sets’claimed security categories in all cases except SLH-DSA-SHA2-128f and SLH-DSA-SHAKE-128f.23
Therefore, applications that require message-bound signatures should either take the expected
cost of finding collisions on H𝑚𝑠𝑔 into account when choosing an appropriate parameter set or
apply a technique (e.g., the BUFF transformation [29]) to obtain the message-bound signaturesproperty.

11.1 SLH-DSA Using SHAKE
H𝑚𝑠𝑔 , PRF, PRF𝑚𝑠𝑔 , F, H, and Tℓ shall be instantiated as follows for the SLH-DSA-SHAKE128s, SLH-DSA-SHAKE-128f, SLH-DSA-SHAKE-192s, SLH-DSA-SHAKE-192f, SLH-DSA-SHAKE-256s,
and SLH-DSA-SHAKE-256f parameter sets:
H𝑚𝑠𝑔 (𝑅, PK.seed, PK.root, 𝑀 ) = SHAKE256(𝑅 ∥ PK.seed ∥ PK.root ∥ 𝑀 , 8𝑚)
PRF(PK.seed, SK.seed, ADRS) = SHAKE256(PK.seed ∥ ADRS ∥ SK.seed, 8𝑛)
PRF𝑚𝑠𝑔 (SK.prf, 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑, 𝑀 ) = SHAKE256(SK.prf ∥ 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑 ∥ 𝑀 , 8𝑛)F(PK.seed, ADRS, 𝑀1 ) = SHAKE256(PK.seed ∥ ADRS ∥ 𝑀1 , 8𝑛)H(PK.seed, ADRS, 𝑀2 ) = SHAKE256(PK.seed ∥ ADRS ∥ 𝑀2 , 8𝑛)
Tℓ (PK.seed, ADRS, 𝑀ℓ ) = SHAKE256(PK.seed ∥ ADRS ∥ 𝑀ℓ , 8𝑛)11.2 SLH-DSA Using SHA2In Sections 11.2.1 and 11.2.2, the functions MGF1-SHA-256 and MGF1-SHA-512 are MGF1 from
Appendix B.2.1 of RFC 8017 [30], where Hash is SHA-256 or SHA-512, respectively. The functions

23

Finding a collision would be expected to require computing H𝑚𝑠𝑔 for approximately 2(ℎ+𝑘⋅𝑎)/2 different messages.

44

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

HMAC-SHA-256 and HMAC-SHA-512 are the HMAC function from FIPS 198-1 [31, 32], where 𝐻
is SHA-256 or SHA-512, respectively.
The functions in Sections 11.2.1 and 11.2.2 make use of a compressed version of ADRS (seeFigure 18). A compressed address (ADRS𝑐 ) is a 22-byte string that is the same as an ADRS
with the exceptions that the encodings of the layer address and type are reduced to one byte
each and the encoding of the tree address is reduced to eight bytes (i.e., ADRS𝑐 = ADRS[3] ∥ADRS[8 ∶ 16] ∥ ADRS[19] ∥ ADRS[20 ∶ 32]). For implementations of the SHA2 parameter
sets that store addresses in compressed form (i.e., 22 bytes), the member functions (Section 4.3)
are as shown in Table 3 rather than Table 1.

layer address

1 bytetree address

8 bytes𝑡𝑦𝑝𝑒

1 byte12 bytesFigure 18. Compressed address (ADRS𝑐 )Table 3. Member functions for compressed addresses
Member function
ADRS.setLayerAddress(𝑙)ADRS.setTreeAddress(𝑡)ADRS.setTypeAndClear(𝑌)ADRS.setKeyPairAddress(𝑖)ADRS.setChainAddress(𝑖)ADRS.setTreeHeight(𝑖)ADRS.setHashAddress(𝑖)ADRS.setTreeIndex(𝑖)𝑖 ← ADRS.getKeyPairAddress()𝑖 ← ADRS.getTreeIndex()
11.2.1

Expanded notation
ADRS ← toByte(𝑙, 1) ∥ ADRS[1 ∶ 22]
ADRS ← ADRS[0 ∶ 1] ∥ toByte(𝑡, 8) ∥ ADRS[9 ∶ 22]
ADRS ← ADRS[0 ∶ 9] ∥ toByte(𝑌 , 1) ∥ toByte(0, 12)
ADRS ← ADRS[0 ∶ 10] ∥ toByte(𝑖, 4) ∥ ADRS[14 ∶ 22]
ADRS ← ADRS[0 ∶ 14] ∥ toByte(𝑖, 4) ∥ ADRS[18 ∶ 22]
ADRS ← ADRS[0 ∶ 18] ∥ toByte(𝑖, 4)
𝑖 ← toInt(ADRS[10 ∶ 14], 4)𝑖 ← toInt(ADRS[18 ∶ 22], 4)

SLH-DSA Using SHA2 for Security Category 1

H𝑚𝑠𝑔 , PRF, PRF𝑚𝑠𝑔 , F, H, and Tℓ shall be instantiated as follows for the SLH-DSA-SHA2-128s
and SLH-DSA-SHA2-128f parameter sets:
H𝑚𝑠𝑔 (𝑅, PK.seed, PK.root, 𝑀 ) =MGF1-SHA-256(𝑅 ∥ PK.seed ∥ SHA-256(𝑅 ∥ PK.seed ∥ PK.root ∥ 𝑀 ), 𝑚)
45

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

PRF(PK.seed, SK.seed, ADRS) =Trunc𝑛 (SHA-256(PK.seed ∥ toByte(0, 64 − 𝑛) ∥ ADRS𝑐 ∥ SK.seed))
PRF𝑚𝑠𝑔 (SK.prf, 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑, 𝑀 ) =Trunc𝑛 (HMAC-SHA-256(SK.prf, 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑 ∥ 𝑀 ))F(PK.seed, ADRS, 𝑀1 ) =Trunc𝑛 (SHA-256(PK.seed ∥ toByte(0, 64 − 𝑛) ∥ ADRS𝑐 ∥ 𝑀1 ))H(PK.seed, ADRS, 𝑀2 ) =Trunc𝑛 (SHA-256(PK.seed ∥ toByte(0, 64 − 𝑛) ∥ ADRS𝑐 ∥ 𝑀2 ))Tℓ (PK.seed, ADRS, 𝑀ℓ ) =Trunc𝑛 (SHA-256(PK.seed ∥ toByte(0, 64 − 𝑛) ∥ ADRS𝑐 ∥ 𝑀ℓ ))11.2.2 SLH-DSA Using SHA2 for Security Categories 3 and 5
H𝑚𝑠𝑔 , PRF, PRF𝑚𝑠𝑔 , F, H, and Tℓ shall be instantiated as follows for the SLH-DSA-SHA2-192s,
SLH-DSA-SHA2-192f, SLH-DSA-SHA2-256s, and SLH-DSA-SHA2-256f parameter sets:
H𝑚𝑠𝑔 (𝑅, PK.seed, PK.root, 𝑀 ) =MGF1-SHA-512(𝑅 ∥ PK.seed ∥ SHA-512(𝑅 ∥ PK.seed ∥ PK.root ∥ 𝑀 ), 𝑚)
PRF(PK.seed, SK.seed, ADRS) =Trunc𝑛 (SHA-256(PK.seed ∥ toByte(0, 64 − 𝑛) ∥ ADRS𝑐 ∥ SK.seed))
PRF𝑚𝑠𝑔 (SK.prf, 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑, 𝑀 ) =Trunc𝑛 (HMAC-SHA-512(SK.prf, 𝑜𝑝𝑡_𝑟𝑎𝑛𝑑 ∥ 𝑀 ))F(PK.seed, ADRS, 𝑀1 ) =Trunc𝑛 (SHA-256(PK.seed ∥ toByte(0, 64 − 𝑛) ∥ ADRS𝑐 ∥ 𝑀1 ))H(PK.seed, ADRS, 𝑀2 ) =Trunc𝑛 (SHA-512(PK.seed ∥ toByte(0, 128 − 𝑛) ∥ ADRS𝑐 ∥ 𝑀2 ))Tℓ (PK.seed, ADRS, 𝑀ℓ ) =Trunc𝑛 (SHA-512(PK.seed ∥ toByte(0, 128 − 𝑛) ∥ ADRS𝑐 ∥ 𝑀ℓ ))46

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

References[1] National Institute of Standards and Technology (2023) Digital Signature Standard (DSS).
(Department of Commerce, Washington, D.C.), Federal Information Processing Standards
Publications (FIPS) NIST FIPS 186-5. https://doi.org/10.6028/NIST.FIPS.186-5.
[2] National Institute of Standards and Technology (2024) Guideline for Using Cryptographic
Standards in the Federal Government: Cryptographic Mechanisms. (National Institute ofStandards and Technology, Gaithersburg, MD), NIST Special Publication (SP) 800-175B, Rev.
2. [Forthcoming: will be available at https://csrc.nist.gov/publications].
[3] National Institute of Standards and Technology (2024) Recommendation for Obtaining
Assurances for Digital Signature Applications. (National Institute of Standards and Technology, Gaithersburg, MD), NIST Special Publication (SP) 800-89, Rev. 1. [Forthcoming: will beavailable at https://csrc.nist.gov/publications].
[4] Aumasson JP, Bernstein DJ, Beullens W, Dobraunig C, Eichlseder M, Fluhrer S, Gazdag
SL, Hülsing A, Kampanakis P, Kölbl S, Lange T, Lauridsen MM, Mendel F, Niederhagen R,
Rechberger C, Rijneveld J, Schwabe P, Westerbaan B (2020) SPHINCS+ – Submission to the
NIST post-quantum project, v.3.
[5] Barker EB, Chen L, Roginsky AL, Vassilev A, Davis R, Simon S (2019) Recommendation for
Pair-Wise Key-Establishment Using Integer Factorization Cryptography. (National Instituteof Standards and Technology, Gaithersburg, MD), NIST Special Publication (SP) 800-56B,
Rev. 2. https://doi.org/10.6028/NIST.SP.800-56Br2.
[6] National Institute of Standards and Technology (2015) SHA-3 Standard: Permutation-BasedHash and Extendable-Output Functions. (Department of Commerce, Washington, DC),
Federal Information Processing Standards Publication (FIPS) NIST FIPS 202. https://doi.org/
10.6028/NIST.FIPS.202.
[7] Kelsey JM, Chang SjH, Perlner RA (2016) SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and ParallelHash. (National Institute of Standards and Technology, Gaithersburg, MD),NIST Special Publication (SP) 800-185. https://doi.org/10.6028/NIST.SP.800-185.
[8] National Institute of Standards and Technology (2015) Secure Hash Standard (SHS). (Department of Commerce, Washington, D.C.), Federal Information Processing Standards
Publication (FIPS) NIST FIPS 180-4. https://doi.org/10.6028/NIST.FIPS.180-4.
[9] National Institute of Standards and Technology (2024) Recommendation for Key Management: Part 1 – General. (National Institute of Standards and Technology, Gaithersburg,
MD), NIST Special Publication (SP) 800-57 Part 1, Rev 6. [Forthcoming: will be available athttps://csrc.nist.gov/publications].
[10] Aumasson JP, Bernstein DJ, Beullens W, Dobraunig C, Eichlseder M, Fluhrer S, Gazdag
SL, Hülsing A, Kampanakis P, Kölbl S, Lange T, Lauridsen MM, Mendel F, Niederhagen R,
Rechberger C, Rijneveld J, Schwabe P, Westerbaan B (2022) SPHINCS+ – Submission to
the NIST post-quantum project, v.3.1. Available at https://sphincs.org/data/sphincs+-r3.1specification.pdf.

47

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD[11] Hülsing A, Butin D, Gazdag SL, Rijneveld J, Mohaisen A (2018) XMSS: eXtended Merkle
Signature Scheme. (Internet Research Task Force (IRTF)), IRTF Request for Comments (RFC)
8391. https://doi.org/10.17487/RFC8391.
[12] Cooper DA, Apon D, Dang QH, Davidson MS, Dworkin MJ, Miller CA (2020) Recommendationfor Stateful Hash-Based Signature Schemes. (National Institute of Standards and Technology,
Gaithersburg, MD), NIST Special Publication (SP) 800-208. https://doi.org/10.6028/NIST.SP.
800-208.
[13] Merkle RC (1979) Secrecy, Authentication, and Public Key Systems. Ph.D. thesis. Stanford
university, .
[14] Barker EB, Kelsey JM (2015) Recommendation for Random Number Generation Using
Deterministic Random Bit Generators. (National Institute of Standards and Technology,
Gaithersburg, MD), NIST Special Publication (SP) 800-90A, Rev. 1. https://doi.org/10.6028/
NIST.SP.800-90Ar1.
[15] Sönmez Turan M, Barker EB, Kelsey JM, McKay KA, Baish ML, Boyle M (2018) Recommendation for the Entropy Sources Used for Random Bit Generation. (National Instituteof Standards and Technology, Gaithersburg, MD), NIST Special Publication (SP) 800-90B.
https://doi.org/10.6028/NIST.SP.800-90B.
[16] Barker EB, Kelsey JM, McKay KA, Roginsky AL, Sönmez Turan M (2022) Recommendation for
Random Bit Generator (RBG) Constructions. (National Institute of Standards and Technology,
Gaithersburg, MD), NIST Special Publication (SP) 800-90C 4pd. https://doi.org/10.6028/
NIST.SP.800-90C.4pd.
[17] Kannwischer MJ, Genêt A, Butin D, Krämer J, Buchmann J (2018) Differential Power Analysis
of XMSS and SPHINCS. Constructive Side-Channel Analysis and Secure Design, eds Fan J,
Gierlichs B (Springer International Publishing, Cham), pp 168–188. https://doi.org/10.1007/
978-3-319-89641-0_10.
[18] Castelnovi L, Martinelli A, Prest T (2018) Grafting Trees: A Fault Attack Against the SPHINCS
Framework. Post-Quantum Cryptography, eds Lange T, Steinwandt R (Springer International
Publishing, Cham), pp 165–184. https://doi.org/10.1007/978-3-319-79063-3_8.
[19] Genêt A, Kannwischer MJ, Pelletier H, McLauchlan A (2018) Practical Fault Injection Attacks
on SPHINCS, Cryptology ePrint Archive preprint. https://ia.cr/2018/674.
[20] Amiet D, Leuenberger L, Curiger A, Zbinden P (2020) FPGA-based SPHINCS+ Implementations: Mind the Glitch. 2020 23rd Euromicro Conference on Digital System Design (DSD), pp
229–237. https://doi.org/10.1109/DSD51259.2020.00046.
[21] Genêt A (2023) On Protecting SPHINCS+ Against Fault Attacks. IACR Transactions on Cryptographic Hardware and Embedded Systems 2023(2):80–114. https://doi.org/10.46586/
tches.v2023.i2.80-114.
[22] Groot Bruinderink L, Hülsing A (2018) “Oops, I Did It Again” – Security of One-Time Signatures
Under Two-Message Attacks. Selected Areas in Cryptography – SAC 2017, eds Adams C,
Camenisch J (Springer International Publishing, Cham), pp 299–322. https://doi.org/10.
1007/978-3-319-72565-9_15.
48

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD[23] Housley R (2009) Cryptographic Message Syntax (CMS). (Internet Engineering Task Force(IETF)), IETF Request for Comments (RFC) 5652. https://doi.org/10.17487/RFC5652.
[24] National Institute of Standards and Technology (2024) Recommendation for Additional
Stateless Hash-Based Digital Signature Parameter Sets. (National Institute of Standards andTechnology, Gaithersburg, MD), NIST Special Publication (SP) 800-230. [Forthcoming: will
be available at https://csrc.nist.gov/publications].
[25] National Institute of Standards and Technology (2016) Submission Requirements and Evaluation Criteria for the Post-Quantum Cryptography Standardization Process. Available
at https://csrc.nist.gov/CSRC/media/Projects/Post-Quantum-Cryptography/documents/
call-for-proposals-final-dec-2016.pdf.
[26] Alagic G, Apon D, Cooper DA, Dang QH, Dang T, Kelsey JM, Lichtinger J, Liu YK, Miller CA,
Moody D, Peralta R, Perlner RA, Robinson A, Smith-Tone D (2022) Status Report on the
Third Round of the NIST Post-Quantum Cryptography Standardization Process. (National
Institute of Standards and Technology, Gaithersburg, MD), NIST Interagency or Internal
Report (IR) NIST IR 8413-upd1, includes updates as of September 26, 2022. https://doi.org/
10.6028/NIST.IR.8413-upd1.
[27] Hülsing A, Kudinov M (2022) Recovering the Tight Security Proof of SPHINCS+ . Advances in
Cryptology – ASIACRYPT 2022, eds Agrawal S, Lin D (Springer Nature Switzerland, Cham),
pp 3–33. https://doi.org/10.1007/978-3-031-22972-5_1.
[28] Stern J, Pointcheval D, Malone-Lee J, Smart NP (2002) Flaws in Applying Proof Methodologies
to Signature Schemes. Advances in Cryptology — CRYPTO 2002, ed Yung M (Springer Berlin
Heidelberg, Berlin, Heidelberg), pp 93–110. https://doi.org/10.1007/3-540-45708-9_7.
[29] Cremers C, Düzlü S, Fiedler R, Janson C, Fischlin M (2021) BUFFing Signature Schemes
Beyond Unforgeability and the Case of Post-Quantum Signatures. 2021 IEEE Symposium on
Security and Privacy (SP) (IEEE Computer Society, Los Alamitos, CA, USA), pp 1696–1714.
https://doi.org/10.1109/SP40001.2021.00093.
[30] Moriarty K, Kaliski B, Jonsson J, Rusch A (2016) PKCS #1: RSA Cryptography Specifications
Version 2.2. (Internet Engineering Task Force (IETF)), IETF request for comments (RFC) 8017.
https://doi.org/10.17487/RFC8017.
[31] National Institute of Standards and Technology (2008) The Keyed-Hash Message Authentication Code (HMAC). (Department of Commerce, Washington, DC), Federal Information Processing Standards Publication (FIPS) NIST FIPS 198-1. https://doi.org/10.6028/NIST.FIPS.1981.
[32] Krawczyk H, Bellare M, Canetti R (1997) HMAC: Keyed-Hashing for Message Authentication.
(Internet Engineering Task Force (IETF)), IETF request for comments (RFC) 2104. https://doi.org/10.17487/RFC2104.
[33] Stern M (2021) Re: Diversity of signature schemes. Available at https://groups.google.com/
a/list.nist.gov/g/pqc-forum/c/2LEoSpskELs/m/LkUdQ5mKAwAJ.
[34] Antonov S (2022) ROUND 3 OFFICIAL COMMENT: SPHINCS+. Available at https://groups.
google.com/a/list.nist.gov/g/pqc-forum/c/FVItvyRea28/m/mGaRi5iZBwAJ.
49

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD[35] Perlner R, Kelsey J, Cooper D (2022) Breaking Category Five SPHINCS+ with SHA-256. PostQuantum Cryptography, eds Cheon JH, Johansson T (Springer International Publishing,Cham), pp 501–522. https://doi.org/10.1007/978-3-031-17234-2_23.

50

FIPS 205

STATELESS HASH-BASED DIGITAL SIGNATURE STANDARD

Appendix A — Differences From the SPHINCS+ Submission
This standard is based on Version 3.1 of the SPHINCS+ specification [10] and contains several
minor modifications compared to Version 3 [4], which was submitted at the beginning of roundthree of the NIST PQC Standardization process:• Two new address types — WOTS_PRF and FORS_PRF — were defined for WOTS+ and FORS
secret key value generation.
• PK.seed was added as an input to PRF in order to mitigate multi-key attacks.
• For the category 3 and 5 SHA2 parameter sets, SHA-256 was replaced by SHA-512 in H𝑚𝑠𝑔 ,PRF𝑚𝑠𝑔 , H, and Tℓ based on weaknesses that were discovered when using SHA-256 toobtain category 5 security [33, 34, 35].
• 𝑅 and PK.seed were added as inputs to MGF1 when computing H𝑚𝑠𝑔 for the SHA2
parameter sets in order to mitigate multi-target long-message second preimage attacks.
This standard also differs from the Version 3 specification in its method for extracting bits fromthe message digest to select a FORS key. This change was made in order to align with thereference implementation that was submitted along with the round three specification. The
description of the method for extracting indices for FORS signature generation and verificationfrom the message digest was also changed due to ambiguity in the submitted specification. The
method described in this standard is not compatible with the method used in the reference
implementation that was submitted along with the round three specification. Additionally, line 6
in both wots_sign and wots_pkFromSig were changed to match the reference implementation,
as the pseudocode in [10, 4] will sometimes shift 𝑐𝑠𝑢𝑚 by the incorrect amount when 𝑙𝑔𝑤 is not
4.
This standard approves the use of only 12 of the 36 parameter sets defined in [10, 4]. As specified
in Section 11, only the ‘simple’ instances of the SHA2 and SHAKE parameter sets are approved.

A.1

Changes From FIPS 205 Initial Public Draft

The differences from Version 3 of the SPHINCS+ specification described in Appendix A were
included in the draft version of this standard (FIPS 205 ipd) that was posted on August 24, 2023.
Based on comments that were submitted on FIPS 205 ipd, the SLH-DSA signature generation andverification functions were modified to include domain separation cases in which the message
is signed directly and in which a digest of the message is signed. The changes were made bymodifying the inputs to the signing and verification functions (see Algorithms 22, 23, 24, and25).

51