Nist Fips 204
Nist Fips 204
Module-Lattice-Based Digital
Signature Standard
Category: Computer Security Subcategory: Cryptography
Abstract
Digital signatures are used to detect unauthorized modifications to data and to authenticate the identity
of the signatory. In addition, the recipient of signed data can use a digital 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. This
standard specifies ML-DSA, a set of algorithms that can be used to generate and verify digital signatures.
ML-DSA is believed to be secure, even against adversaries in possession of a large-scale quantum computer.
Keywords: cryptography; digital signatures; Federal Information Processing Standards; lattice; post-
quantum; public-key cryptography.
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Announcing the
Module-Lattice-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 Secretary of Commerce under
40 U.S.C. 11331.
3. Explanation. This standard specifies ML-DSA, a lattice-based digital signature algorithm 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 a string of bits and computed using a set of rules
and parameters that allow the identity of the signatory 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
key-pair composed of a private key and a corresponding public key. 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 generate a signature that can
be verified by the corresponding public key.
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 ML-DSA that are approved for use. Additional
parameter sets may be specified and approved in future NIST Special Publications.
6. Applicability. This standard is applicable to all federal departments and agencies for the protection 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 205, FIPS 186-5, or NIST
Special Publication 800-208 shall be used in designing and implementing public-key-based signature
systems that federal departments and agencies operate or that are operated for them under contract.
In the future, additional digital signature schemes may be specified and approved in FIPS or NIST
Special Publications.
The adoption and use of this standard are available to private and commercial organizations.
i
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
7. Applications. A digital signature algorithm allows an entity to authenticate the integrity of signed
data and the identity of the signatory. The recipient of a signed message can use a digital 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 and data 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 algorithm in this standard. For every computational procedure that is specified in
this standard, a conforming implementation may replace the given set of steps with any mathematically
equivalent set of steps. 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-standards
-and-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 this standard
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 Standards (FIPS) publication,
b. Adopted in a FIPS or NIST recommendation, or
c. 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 Standards (FIPS) 204, Module-Lattice-Based Digital
Signature Standard (affixed).
14. Qualifications. The security of a digital signature system depends on maintaining the secrecy of the
signatory’s private keys. Signatories shall, therefore, guard against the disclosure of their private
keys. While it is the intent of this standard to specify general security requirements for generating
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 module that 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.
ii
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Since a standard of this nature must be flexible enough to adapt to advancements and innovations 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 not allow 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 204 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) Module-Lattice-Based Digital Signa-
ture Standard. (Department of Commerce, Washington, D.C.), Federal Information Pro-
cessing Standards Publication (FIPS) NIST FIPS 204. https://doi.org/10.6028/NIST.FIPS.204
18. Inquiries and Comments. Inquiries and comments about this FIPS may be submitted to fips-204-
[email protected].
iii
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Table of Contents
1 Introduction 1
1.1 Purpose and Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
4 Parameter Sets 15
5 External Functions 17
5.1 ML-DSA Key Generation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.2 ML-DSA Signing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
5.3 ML-DSA Verifying . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
iv
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
6 Internal Functions 22
6.1 ML-DSA Key Generation (Internal) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
6.2 ML-DSA Signing (Internal) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
6.3 ML-DSA Verifying (Internal) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7 Auxiliary Functions 28
7.1 Conversion Between Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
7.2 Encodings of ML-DSA Keys and Signatures . . . . . . . . . . . . . . . . . . . . . . . . 33
7.3 Pseudorandom Sampling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
7.4 High-Order and Low-Order Bits and Hints . . . . . . . . . . . . . . . . . . . . . . . . 39
7.5 NTT and NTT−1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
7.6 Arithmetic Under NTT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
References 47
v
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
List of Tables
Table 1 ML-DSA parameter sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Table 2 Sizes (in bytes) of keys and signatures of ML-DSA . . . . . . . . . . . . . . . . . . 16
Table 3 While loop and XOF output limits for a 2−256 or less probability of failure . . . . . 52
List of Algorithms
Algorithm 1 ML-DSA.KeyGen() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Algorithm 2 ML-DSA.Sign(𝑠𝑘, 𝑀 , 𝑐𝑡𝑥) . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Algorithm 3 ML-DSA.Verify(𝑝𝑘, 𝑀 , 𝜎, 𝑐𝑡𝑥) . . . . . . . . . . . . . . . . . . . . . . . . . 18
Algorithm 4 HashML-DSA.Sign(𝑠𝑘, 𝑀 , 𝑐𝑡𝑥, PH) . . . . . . . . . . . . . . . . . . . . . . 20
Algorithm 5 HashML-DSA.Verify(𝑝𝑘, 𝑀 , 𝜎, 𝑐𝑡𝑥, PH) . . . . . . . . . . . . . . . . . . . . 21
Algorithm 6 ML-DSA.KeyGen_internal(𝜉) . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Algorithm 7 ML-DSA.Sign_internal(𝑠𝑘, 𝑀 ′ , 𝑟𝑛𝑑) . . . . . . . . . . . . . . . . . . . . . . 25
Algorithm 8 ML-DSA.Verify_internal(𝑝𝑘, 𝑀 ′ , 𝜎) . . . . . . . . . . . . . . . . . . . . . . 27
Algorithm 9 IntegerToBits(𝑥, 𝛼) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Algorithm 10 BitsToInteger(𝑦, 𝛼) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Algorithm 11 IntegerToBytes(𝑥, 𝛼) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Algorithm 12 BitsToBytes(𝑦) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Algorithm 13 BytesToBits(𝑧) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Algorithm 14 CoeffFromThreeBytes(𝑏0 , 𝑏1 , 𝑏2 ) . . . . . . . . . . . . . . . . . . . . . . . . 29
Algorithm 15 CoeffFromHalfByte(𝑏) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Algorithm 16 SimpleBitPack(𝑤, 𝑏) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Algorithm 17 BitPack(𝑤, 𝑎, 𝑏) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Algorithm 18 SimpleBitUnpack(𝑣, 𝑏) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Algorithm 19 BitUnpack(𝑣, 𝑎, 𝑏) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Algorithm 20 HintBitPack(𝐡) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Algorithm 21 HintBitUnpack(𝑦) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Algorithm 22 pkEncode(𝜌, 𝐭1 ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Algorithm 23 pkDecode(𝑝𝑘) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Algorithm 24 skEncode(𝜌, 𝐾, 𝑡𝑟, 𝐬1 , 𝐬2 , 𝐭0 ) . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Algorithm 25 skDecode(𝑠𝑘) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Algorithm 26 sigEncode(𝑐,̃ 𝐳, 𝐡) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Algorithm 27 sigDecode(𝜎) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Algorithm 28 w1Encode(𝐰1 ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Algorithm 29 SampleInBall(𝜌) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Algorithm 30 RejNTTPoly(𝜌) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Algorithm 31 RejBoundedPoly(𝜌) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Algorithm 32 ExpandA(𝜌) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Algorithm 33 ExpandS(𝜌) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Algorithm 34 ExpandMask(𝜌, 𝜇) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Algorithm 35 Power2Round(𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Algorithm 36 Decompose(𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Algorithm 37 HighBits(𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Algorithm 38 LowBits(𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
vi
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 39 MakeHint(𝑧, 𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Algorithm 40 UseHint(ℎ, 𝑟) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Algorithm 41 NTT(𝑤) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Algorithm 42 NTT−1 (𝑤)̂ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Algorithm 43 BitRev8 (𝑚) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Algorithm 44 AddNTT(𝑎,̂ 𝑏)̂ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Algorithm 45 MultiplyNTT(𝑎,̂ 𝑏)̂ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Algorithm 46 AddVectorNTT(𝐯,̂ 𝐰) ̂ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Algorithm 47 ScalarVectorNTT(𝑐,̂ 𝐯)̂ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Algorithm 48 MatrixVectorNTT(𝐌, ̂ 𝐯)̂ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Algorithm 49 MontgomeryReduce(𝑎) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
vii
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
1. Introduction
1.1 Purpose and Scope
This standard defines a digital signature scheme, which includes a method for digital signature generation
that can be used for the protection of binary data (commonly called a “message”) and a method for the
verification and validation of those digital signatures. 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.
This standard specifies the mathematical steps that need to be performed for key generation, signature
generation, and signature verification. In order for digital signatures to be valid, additional assurances
are required, such as assurance of identity and of private key possession. SP 800-89, Recommendation
for Obtaining Assurances for Digital Signature Applications [3], specifies the required assurances and the
methods for obtaining them.
The digital signature scheme approved in this standard is the Module-Lattice-Based Digital Signature
Algorithm (ML-DSA), which is based on the Module Learning With Errors problem [4]. ML-DSA is believed
to be secure, even against adversaries in possession of a large-scale fault-tolerant quantum computer. In
particular, ML-DSA is believed to be strongly unforgeable, which implies that the scheme can be used to
detect unauthorized modifications to data and to authenticate the identity of the signatory (one bound
to the possession of the private-key). In addition, a signature generated by this scheme can be used
as evidence in demonstrating to a third party that the signature was, in fact, generated by the claimed
signatory. The latter property is known as non-repudiation since the signatory cannot easily repudiate the
signature at a later time.
This standard gives algorithms for ML-DSA key generation, signature generation, and signature verification
(Section 5), and for supporting algorithms used by them (Section 7). ML-DSA is standardized with three
possible parameter sets, each of which corresponds to a different security strength. Section 4 describes
the global parameters used by these algorithms and enumerates the parameter sets for ML-DSA that are
approved by this standard. ML-DSA can be used in place of other digital signature schemes specified in
NIST FIPS and Special Publications (e.g., FIPS 186-5, Digital Signature Standard (DSS) [1]).
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-scale quantum 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.
ML-DSA is derived from one of the selected schemes, CRYSTALS-DILITHIUM [5, 6], and is intended to protect
sensitive U.S. Government information well into the foreseeable future, including after the advent of
cryptographically relevant quantum computers. For the differences between ML-DSA and CRYSTALS-
DILITHIUM, see Appendix D.
1
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
assurance of Confidence that an entity possesses a private key and any associated keying
possession material.
asymmetric Cryptography that uses two separate keys to exchange data — one to encrypt
cryptography or digitally sign the data and one to decrypt the data or verify the digital
signature. Also known as public-key cryptography.
certificate A set of data that uniquely identifies a public key that has a corresponding
private key and an owner that is authorized to use the key pair. The certificate
contains the owner’s public key and possibly other information and is digitally
signed by a certification authority (i.e., a trusted party), thereby binding the
public key to the owner.
certification authority The entity in a public-key infrastructure (PKI) that is responsible for issuing
(CA) certificates and exacting compliance with a PKI policy.
claimed signatory From the verifier’s perspective, the claimed signatory is the entity that pur-
portedly generated a digital signature.
destroy An action applied to a key or a piece of secret data. After a key or a piece of
secret data is destroyed, no information about its value can be recovered.
digital signature The result of a cryptographic transformation of data that, when properly
implemented, provides a mechanism to verify origin authenticity and data
integrity and to enforce signatory non-repudiation.
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).
eXtendable-Output A function on bit strings in which the output can be extended to any desired
Function (XOF) length. Approved XOFs (e.g., those specified in FIPS 202 [7]) are designed
to satisfy the following properties as long as the specified output length is
sufficiently long to prevent trivial attacks:
2
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
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] and FIPS 202 [7]) are
designed to satisfy the following properties:
1. (One-way) It is computationally infeasible to find any input that maps to
any new pre-specified output.
2. (Collision-resistant) It is computationally infeasible to find any two dis-
tinct inputs that map to the same output.
little-endian The property of a byte string having its bytes positioned in order of increasing
significance. In particular, the leftmost (first) byte is the least significant,
and the rightmost (last) byte is the most significant. The term “little-endian”
may also be applied in the same manner to bit strings (e.g., the 8-bit string
11010001 corresponds to the byte 20 + 21 + 23 + 27 = 139).
message The data that is signed. Also known as signed data during the signature
verification and validation process.
message digest The result of applying a hash function to a message. Also known as a hash
value.
non-repudiation A service that is used to provide assurance of the integrity and origin of data
in such a way that the integrity and origin can be verified and validated by
a third party as having originated from a specific entity in possession of the
private key (i.e., the signatory).
owner A key pair owner is the entity authorized to use the private key of a key pair.
public-key A framework that is established to issue, maintain, and revoke public key
infrastructure (PKI) certificates.
3
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
private key A cryptographic key that is used with an asymmetric (public-key) cryptographic
algorithm. The private key is uniquely associated with the owner and is not
made public. The private key is used to compute a digital signature that may
be verified using the corresponding public key.
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 case of digital signatures, the
public key is used to verify a digital signature that was generated using the
corresponding private key.
security category A number associated with the security strength of a post-quantum crypto-
graphic algorithm, as specified by NIST (see [9, Sect. 5.6]).
security strength A number associated with the amount of work (i.e., the number of operations)
that is required to break a cryptographic algorithm or system.
signatory The entity that generates a digital signature on data using a private key.
signature generation The process of using a digital signature algorithm and a private key to generate
a digital signature on data.
signature validation The mathematical verification of the digital signature along with obtaining the
appropriate assurances (e.g., public-key validity, private-key possession, etc.).
signature verification The process of using a digital signature algorithm and a public key to verify a
digital signature on data.
signed data The data or message upon which a digital signature has been computed. Also
see message.
trusted third party An entity other than the key pair owner and the verifier that is trusted by the
(TTP) owner, the verifier, or both. Sometimes shortened to “trusted party.”
verifier The entity that verifies the authenticity of a digital signature using the public
key of the signatory.
4
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
2.2 Acronyms
AES Advanced Encryption Standard
SP Special Publication
ℤ𝑛
𝑚 The set of 𝑛-tuples over ℤ𝑚 equipped with the ℤ-module structure.
𝐵𝜏 The set of all polynomials 𝑝 = ∑255 𝑝 𝑋 𝑖 in 𝑅𝑞 that are such that exactly 𝜏 of the
𝑖=0 𝑖
coefficients of 𝑝𝑖 are from the set {−1, 1}, and all other coefficients are zero. (See
Section 7.3.)
Π Used to denote a direct product of two or more rings, where addition and multipli-
cation are performed componentwise.
𝑇𝑞 The ring Π255
𝑗=0 ℤ𝑞 .
𝑥∈𝑆←𝑦 Type casting. The variable 𝑥 is assigned a value in a set 𝑆 that is constructed from
the value of an expression 𝑦 in a possibly different set 𝑇. The set 𝑇 and the mapping
from 𝑇 to 𝑆 are not explicitly specified, but they should be obvious from the context
in which this statement appears.
[[𝑎 < 𝑏]] A Boolean predicate. A comparison operator inside double square brackets [[𝑎 < 𝑏]]
denotes that the expression should be evaluated as a Boolean. Booleans can also
be interpreted as elements of ℤ2 with 1 denoting true and 0 denoting false.
⟨⟨𝑓(𝑥)⟩⟩ A temporary variable that stores the output of a computation 𝑓(𝑥) so that it can be
used many times without needing to be recomputed. This is equivalent to defining a
temporary variable 𝑦 ← 𝑓(𝑥). Naming the variable ⟨⟨𝑓(𝑥)⟩⟩ makes the pseudocode
less cluttered.
𝑎/𝑏 Division of integers. When this notation is used, 𝑎 and 𝑏 are always integers. If 𝑏
cannot be assumed to divide 𝑎, then either ⌊𝑎/𝑏⌋ or ⌈𝑎/𝑏⌉ is used.
⊥ Blank symbol that indicates failure or the lack of an output from an algorithm.
2.4 Notation
2.4.1 Rings
Elements of the rings ℤ, ℤ𝑞 , ℤ2 , 𝑅, and 𝑅𝑞 are denoted by italicized lowercase letters (e.g., 𝑤). Elements
of the ring 𝑇𝑞 are length-256 arrays of elements of ℤ𝑞 , and they are denoted by italicized letters with a
hat symbol (e.g., 𝑤̂ ). The addition and multiplication of elements of 𝑇𝑞 are performed entry-wise. Thus,
the 𝑖th entry of the product of two elements 𝑢̂ and 𝑣̂ of 𝑇𝑞 is 𝑢[𝑖]
̂ ⋅ 𝑣[𝑖]
̂ ∈ ℤ𝑞 . The multiplication operation
in 𝑇𝑞 is denoted by the symbol ∘ (see Section 2.3).
When a product 𝑎 ⋅ 𝑏 or a sum 𝑎 + 𝑏 is written and either 𝑎 or 𝑏 is a congruence class modulo 𝑚 (i.e., if
either 𝑎 or 𝑏 is an element of ℤ𝑚 or 𝑅𝑚 ), then the product or sum is also understood to be a congruence
class modulo 𝑚 (i.e., an element of ℤ𝑚 or 𝑅𝑚 ). Likewise, an element of 𝑅 or ℤ may be “typecast” to an
element of 𝑅𝑚 or ℤ𝑚 , respectively, and may be used as the input of a function specified to act on an
element of 𝑅𝑚 or ℤ𝑚 , respectively. In both cases, the element itself or its coefficients are mapped from
ℤ to ℤ𝑚 by taking the unique congruence class modulo 𝑚 that contains the integer.
The coefficients of an element 𝑤 of 𝑅 or 𝑅𝑚 are denoted by 𝑤𝑖 so that 𝑤 = 𝑤0 + 𝑤1 𝑋 + … + 𝑤255 𝑋 255 .
If 𝑤 is in 𝑅 (respectively, 𝑅𝑚 ) and 𝑡 is in ℤ (respectively, ℤ𝑑 ), then 𝑤(𝑡) denotes the polynomial 𝑤 =
𝑤0 + 𝑤1 𝑋 + … + 𝑤255 𝑋 255 evaluated at 𝑋 = 𝑡.
7
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
If 𝑆 is a ring and 𝐯 is a length-𝐿 vector over 𝑆, then the entries in the vector 𝐯 are expressed as
The entries of a 𝐾 × 𝐿 matrix 𝐀 over 𝑆 are denoted as 𝐀[𝑖, 𝑗], where 0 ≤ 𝑖 < 𝐾 and 0 ≤ 𝑗 < 𝐿.
The set of all length-𝐿 vectors over 𝑆 is denoted by 𝑆 𝐿 . The set of all 𝐾 × 𝐿 matrices over 𝑆 is denoted
by 𝑆 𝐾×𝐿 . A length-𝐿 vector can also be treated as an 𝐿 × 1 matrix.
where 𝜁𝑖 = 𝑤(𝜁 2BitRev8 (𝑖)+1 ) mod 𝑞. See Section 7.5 for an implementation discussion for NTT and NTT−1 .
The motivation for using NTT is that multiplication is considerably faster in the ring 𝑇𝑞 . Since NTT is an
isomorphism, for any 𝑎, 𝑏 ∈ 𝑅𝑞 ,
NTT(𝑎𝑏) = NTT(𝑎) ∘ NTT(𝑏). (2.2)
If 𝐀 is a matrix with entries from 𝑅𝑞 , then NTT(𝐀) denotes the matrix computed via the entry-wise
application of NTT to 𝐀. The symbol ∘ is also used to denote the matrix multiplication of matrices with
entries in 𝑇𝑞 . Thus, NTT(𝐀𝐁) = NTT(𝐀) ∘ NTT(𝐁). Explicit algorithms for linear algebra over 𝑇𝑞 are
given in Section 7.6.
8
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
1. Commitment: The prover generates a random positive integer 𝑟 that is less than the order of 𝑔 and
commits to its value by sending 𝑔𝑟 to the verifier.
2. Challenge: The verifier sends a random positive integer 𝑐 that is less than the order of 𝑔 to the
prover.
2
Specifically, the LWE problem is to solve a system of equations of the form 𝐀𝐬 + 𝐞 = 𝑏, where 𝐀 and 𝑏 are given
and 𝐞 is not given but known to be small.
9
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
3. Response: The prover returns 𝑠 = 𝑟 − 𝑐𝑥 reduced modulo the order of 𝑔, and the verifier checks
whether 𝑔𝑠 ⋅ 𝑦𝑐 = 𝑔𝑟 .
This protocol is made noninteractive and turned into a signature scheme by replacing the verifier’s random
choice of 𝑐 in step 2 with a deterministic process that pseudorandomly derives 𝑐 from a hash of the
commitment 𝑔𝑟 concatenated with the message to be signed. For this signature scheme, 𝑦 is the public
key, and 𝑥 is the private key.
The basic idea of ML-DSA and similar lattice signature schemes is to build a signature scheme from
an analogous interactive protocol, where a prover who knows matrices 𝐀 ∈ ℤ𝐾×𝐿 𝑞 , 𝐒1 ∈ ℤ𝑞𝐿×𝑛 , and
𝐒2 ∈ ℤ𝐾×𝑛
𝑞 with small coefficients (for 𝐒1 and 𝐒2 ) demonstrates knowledge of these matrices to a verifier
who knows 𝐀 and 𝐓 ∈ ℤ𝐾×𝑛 𝑞 = 𝐀𝐒1 + 𝐒2 . Such an interactive protocol would proceed as follows:
1. Commitment: The prover generates 𝐲 ∈ ℤ𝐿 𝑞 with small coefficients and commits to its value by
sending 𝐰Approx = 𝐀𝐲 + 𝐲2 to the verifier, where 𝐲2 ∈ ℤ𝐾 𝑞 is a vector with small coefficients.
3. Response: The prover returns 𝐳 = 𝐲 + 𝐒1 𝐜, and the verifier checks that 𝐳 has small coefficients
and that 𝐀𝐳 − 𝐓𝐜 ≈ 𝐰Approx .
As written, the above protocol has a security flaw: the response 𝐳 will be biased in a direction related
to the private value 𝐒1 . Likewise 𝐫 = 𝐰Approx − 𝐀𝐳 + 𝐓𝐜 = 𝐲2 + 𝐒2 𝐜 is biased in a direction related
to the private value 𝐒2 . However, this flaw can be corrected when converting the interactive protocol
into a signature scheme. As with Schnorr signatures, the signer derives the challenge by a pseudorandom
process from a hash of the commitment concatenated with the message. To correct the bias, the signer
applies rejection sampling to 𝐳; if coefficients of 𝐳 fall outside of a specified range, the signing process is
aborted, and the signer starts over from a new value of 𝐲. Likewise, similar rejection sampling must also
be applied to 𝐫. These checks are analogous to those done at Line 23 of Algorithm 7. In the simplified
Fiat-Shamir With Aborts signature, the public key is (𝐀, 𝐓), and the private key is (𝐒1 , 𝐒2 ).
In the ML-DSA standard, a number of tweaks and modifications are added to this basic framework for
security or efficiency reasons:
• To reduce key and signature size and to use fast NTT-based polynomial multiplication, ML-DSA
uses module-structured matrices. Relative to the basic scheme described above, it replaces
dimension-𝑛 × 𝑛 blocks of matrices and dimension-𝑛 blocks of vectors with polynomials in the ring
𝑅𝑞 . Thus, instead of 𝐀 ∈ ℤ𝐾×𝐿
𝑞 , 𝐓 ∈ ℤ𝐾×𝑛
𝑞 , 𝐒1 ∈ ℤ𝑞𝐿×𝑛 , 𝐒𝟐 ∈ ℤ𝐾×𝑛
𝑞 , 𝐲 ∈ ℤ𝐿 𝑛
𝑞 , 𝐜 ∈ ℤ𝑞 , ML-DSA
has 𝐀 ∈ 𝑅𝑞𝑘×ℓ , 𝐭 ∈ 𝑅𝑞𝑘 , 𝐬1 ∈ 𝑅𝑞ℓ , 𝐬2 ∈ 𝑅𝑞𝑘 , 𝐲 ∈ 𝑅𝑞ℓ , 𝑐 ∈ 𝑅𝑞 , where ℓ = 𝐿/𝑛 and 𝑘 = 𝐾/𝑛.
• To further reduce the size of the public key, the matrix 𝐀 is pseudorandomly derived from a 256-bit
public seed 𝜌, which is included in the ML-DSA public key in place of 𝐀.
• For a still further reduction in public key size, the ML-DSA public key substitutes a compressed
value 𝐭1 for 𝐭, which drops the 𝑑 low-order bits of each coefficient.
• To obtain beyond unforgeability (BUFF) properties noted in [14], ML-DSA does not directly sign
the message 𝑀 but rather signs a message representative 𝜇 that is obtained by hashing the
concatenation of a hash of the public key and 𝑀 .
10
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
• To reduce signature size, rather than including the commitment 𝐰Approx = 𝐀𝐲+𝐲2 in the signature,
the ML-DSA signature uses a rounded version of 𝐰 = 𝐀𝐲 as a commitment 𝐰1 and includes only
the hash 𝑐 ̃ of 𝐰1 ||𝜇.
• To ensure that 𝐰1 can be reconstructed by the verifier from 𝐳 and the compressed value 𝐭1 , the
signature must also include a hint 𝐡 ∈ 𝑅2𝑘 computed by the signer using the signer’s private key.
• Additionally, to ensure correctness, a second stage of rejection sampling must be included (Line 28
of Algorithm 7)
In this document, the abbreviations ML-DSA-44, ML-DSA-65, and ML-DSA-87 are used to refer to ML-DSA
with the parameter choices given in Table 1. In these abbreviations, the numerical suffix refers to the
dimension of the matrix 𝐀. For example, in ML-DSA-65, the matrix 𝐀 is a 6 × 5 matrix over 𝑅𝑞 .
11
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
1. The seed 𝜉 generated in step 1 of ML-DSA.KeyGen can be stored for the purpose of later expansion
3
In addition, when signing is deterministic, there is leakage through timing side channels of information about
the message but not the private key). If the signer does not want to reveal the message being signed, hedged
signatures should be used (see Section 3.2 in [6]).
12
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
using ML-DSA.KeyGen_internal. As the seed can be used to compute the private key, it is sensitive
data and shall be treated with the same safeguards as a private key.
2. The matrix 𝐀̂ generated in step 3 of ML-DSA.KeyGen_internal can be stored so that it need not
be recomputed in later operations. Likewise, the matrix 𝐀̂ generated in step 5 of the verification
algorithm ML-DSA.Verify_internal can also be stored. In either case, the matrix 𝐀̂ is data that is
easily computed from the public key and does not require any special protections.
In certain situations (e.g., deterministic signing and the verification of confidential messages and signa-
tures), additional care must be taken to protect implementations against side-channel attacks or fault
attacks. A cryptographic device may leak critical information through side channels, which allows internal
data or keying material to be extracted without breaking the cryptographic primitives.
In addition to using a mostly byte-oriented variant of the API defined in FIPS 202 for SHAKE256 and
SHAKE128, this standard sometimes makes use of the incremental API defined in SP 800-185 [25]. This API
consists of three functions for each variant of SHAKE. These functions can be used to absorb a sequence
of arbitrary-length strings and squeeze a sequence of arbitrary-length strings. These functions perform
buffering to handle any incomplete data blocks while absorbing or squeezing. For example, for SHAKE256:
• ctx ← SHAKE256.Init()
Initializes a hash function context.
13
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
While the above functions are specified in terms of the Keccak-𝑓 permutation rather than the eXtendable-
Output Function (XOF), SHAKE256, they are defined so that any series of commands of the following
form:
1. ctx ← SHAKE256.Init()
This equivalence holds whether or not |str𝑖 | and 𝑏𝑗 are multiples of the SHAKE256 block length.
Since all outputs of SHAKE128 and SHAKE256 in this document give a whole number of bytes, the wrapper
functions H and G are defined as follows:
3. H.Init() = SHAKE256.Init()
4. G.Init() = SHAKE128.Init()
In addition to SHAKE128 and SHAKE256, HashML-DSA.Sign and HashML-DSA.Verify may call other
approved hash functions for pre-hashing. The pseudocode in this standard also treats these functions
as returning a byte string as output while supporting either a bit string or a byte string as input. Here, it
should be noted that the hash functions defined in [8] use different rules (i.e., big-endian ordering) to
relate bits, bytes, and words.
14
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
4. Parameter Sets
Three ML-DSA parameter sets are included in Table 1. Each parameter set assigns values for all of the
parameters used in the ML-DSA algorithms for key generation, signing, and verification. For informational
purposes, some parameters used in the analysis of these algorithms are also included in the table. In
particular, “repetitions” refers to the expected number of repetitions of the main loop in the signing
algorithm from eq. 5 in [5]. The names of the parameter sets are of the form “ML-DSA-𝑘ℓ,” where (𝑘, ℓ)
are the dimensions of the matrix 𝐀.
These parameter sets were designed to meet certain security strength categories defined by NIST in its
original Call for Proposals [26]. These security strength categories are explained further in SP 800-57, Part
1 [9].
Using this approach, security strength is not described by a single number, such as “128 bits of security.”
Instead, each ML-DSA parameter set is claimed to be at least as secure as a generic block cipher with a
prescribed key size or a generic hash function with a prescribed output length. More precisely, it is claimed
that the computational resources needed to break ML-DSA are greater than or equal to the computational
resources needed to break the block cipher or hash function when these computational resources are
estimated using any realistic model of computation. 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 [27].
Concretely, the parameter set ML-DSA-44 is claimed to be in security strength category 2, ML-DSA-65 is
claimed to be in category 3, and ML-DSA-87 is claimed to be in category 5 [6]. For additional discussion of
the security strength of MLWE-based cryptosystems, see [28].
The sizes of keys and signatures that correspond to each parameter set are given in Table 2. Certain
optimizations are possible when storing ML-DSA public and private keys. If additional space is available,
one can precompute and store 𝐀̂ to speed up signing and verifying. Alternatively, if one wants to reduce
15
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
the space needed for the private key, one can store only the 32-byte seed 𝜉, which is sufficient to generate
the other parts of the private key. For additional details, see Section 3.1 in [6].
16
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
5. External Functions
The signing, verifying, and key generation functions can be split into “external” and “internal” components
to simplify APIs and Cryptographic Algorithm Validation Program (CAVP) testing. The external components
generate randomness and perform various checks before calling their internal counterparts. The internal
components are deterministic and can assume that the external components did not encounter error
conditions.
The distinction between external and internal functions also simplifies the presentation of algorithms
for signing and verification by grouping the operations that are shared between ML-DSA.Sign and
HashML-DSA.Sign in ML-DSA.Sign_internal and grouping the operations that are shared between
ML-DSA.Verify and HashML-DSA.Verify in ML-DSA.Verify_internal.
Algorithm 1 ML-DSA.KeyGen()
Generates a public-private key pair.
Output: Public key 𝑝𝑘 ∈ 𝔹32+32𝑘(bitlen (𝑞−1)−𝑑)
and private key 𝑠𝑘 ∈ 𝔹32+32+64+32⋅((ℓ+𝑘)⋅bitlen (2𝜂)+𝑑𝑘) .
1: 𝜉 ← 𝔹32 ▷ choose random seed
2: if 𝜉 = NULL then
3: return ⊥ ▷ return an error indication if random bit generation failed
4: end if
5: return ML-DSA.KeyGen_internal (𝜉)
4
By default, the context is the empty string, though applications may specify the use of a non-empty context string.
17
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
the platform may require hardware support for hashing to achieve acceptable performance but lack
hardware support for SHAKE256 specifically. For some use cases, this may be addressed by signing a
digest of the message along with some domain separation information rather than signing the message
directly. This version of ML-DSA is known as “pre-hash” ML-DSA or HashML-DSA . In general, the “pure”
ML-DSA version is preferred.
While key generation for HashML-DSA is the same as for ML-DSA, it is not the same for the signing algorithm
HashML-DSA.Sign or the verification algorithm HashML-DSA.Verify. Like ML-DSA, the signing algorithm
of HashML-DSA takes the content to be signed, the private key, and a context as input, as well as a hash
function or XOF that is to be used to pre-hash the content to be signed. The context string has a maximum
length of 255 bytes. By default, the context is the empty string, though 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 the signature is a
ML-DSA signature or a pre-hash HashML-DSA signature. In the case of pre-hash signatures, the identifier
should also indicate the hash function or XOF used to compute the pre-hash. 5 While a single key pair
may be used for both ML-DSA and HashML-DSA signatures, it is recommended that each 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 by the application with which the signature is being used.
If the default “hedged” variant of is used, the 32-byte random value 𝑟𝑛𝑑 shall be generated by the
cryptographic module that generates the signature (i.e., that runs ML-DSA.Sign_internal). However, all
other steps of signing may be performed outside of the cryptographic module that generates the signature.
In the case of pre-hashing, 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
generates the signature.
If the content to be signed is large, hashing of the content is often performed at the application level.
For example, in the Cryptographic Message Syntax [29], a digest of the content may be computed, and
that digest is signed along with other attributes. If the content is not hashed at the application level, the
pre-hash version of ML-DSA signing may be used.
In order to maintain the same level of security strength when the content is hashed at the application level
or using HashML-DSA , the digest that is signed needs to be generated using an approved hash function
or XOF (e.g., from FIPS 180 [8] or FIPS 202 [7]) that provides at least 𝜆 bits of classical security strength
against both collision and second preimage attacks [7, Table 4].6 The verification of a signature that is
created in this way will require the verify function to generate a digest from the message in the same way
to be used as input for the verification function.
5
In the case of a XOF this would also include the length of the output from the XOF.
6
Obtaining at least 𝜆 bits of classical security strength against collision attacks requires that the digest to be signed
be at least 2𝜆 bits in length.
19
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 4 shows the DER encodings of the OIDs for SHA-256, SHA-512, and SHAKE128. However, it may
be used with other hash functions or XOFs.
Algorithm 5 presents the signature verification for HashML-DSA . This function constructs 𝑀 ′ in the same
way as Algorithm 4 and passes the resulting 𝑀 ′ to Algorithm ML-DSA.Verify_internal for verification. As
with the pre-hash signature generation, 𝑀 ′ may be constructed outside of the cryptographic module
that performs ML-DSA.Verify_internal. However, in the case of HashML-DSA , the hash or XOF of the
content must be computed within a FIPS 140-validated cryptographic module, which may be a different
cryptographic module than the one that performs ML-DSA.Verify_internal.
As noted in Section 5.4, the identifier associated with the signature should indicate whether ML-DSA or
the pre-hash version HashML-DSA of signature verification should be used, as well as the hash function or
XOF to be used to compute the pre-hash. A non-empty context string should be used in verification if one
is specified either in the signature’s identifier or by the application with which the signature is being used.
20
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
21
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
6. Internal Functions
This section describes the functions for ML-DSA key generation, signature generation, and signature
verification. 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 ML-DSA implementations is performed
through the CAVP.
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 5 provides
guidance on the interfaces to be made available to applications.7
• A 32-byte public random seed 𝜌. Using this seed, a polynomial matrix 𝐀 ∈ 𝑅𝑞𝑘×ℓ is pseudorandomly
sampled9 from 𝑅𝑞𝑘×ℓ .
• A 64-byte private random seed 𝜌′ . Using this seed, the polynomial vectors 𝐬1 ∈ 𝑅𝑞ℓ and 𝐬2 ∈ 𝑅𝑞𝑘
are pseudorandomly sampled from the subset of polynomial vectors whose coordinate polynomials
have short coefficients (i.e., in the range [−𝜂, 𝜂]).
• A 32-byte private random seed 𝐾 for use during signing.
𝐭 = 𝐀𝐬1 + 𝐬2 .
The vector 𝐭 together with the matrix 𝐀 may be considered an expanded form of the public key. The vector
𝐭 is compressed in the actual public key by dropping the 𝑑 least significant bits from each coefficient, thus
producing the polynomial vector 𝐭1 . This compression is an optimization for performance, not security.
The low-order bits of 𝐭 can be reconstructed from a small number of signatures and, therefore, need not
be regarded as secret.
The ML-DSA public key 𝑝𝑘 is a byte encoding of the public random seed 𝜌 and the compressed polynomial
vector 𝐭1 .
The ML-DSA private key 𝑠𝑘 is a byte encoding of the public random seed 𝜌, a private random seed 𝐾
for use during signing, a 64-byte hash 𝑡𝑟 of the public key for use during signing, the secret polynomial
7
In some cases, it is permissible to modify the format of the private key in these interfaces (see Sections 4 and 3.6.3.)
8
Single-byte encodings of the parameters 𝑘 and ℓ are included in the XOF input for domain separation. For
implementations that use the seed in place of the private key, this ensures that the expansion will produce an
unrelated key if the seed is mistakenly expanded using a parameter set other than the one originally intended.
9
More precisely, since only the NTT form of 𝐀, 𝐀̂ ∈ 𝑇𝑞𝑘×ℓ = NTT(𝐀) is needed in subsequent calculations, the
code actually computes 𝐀̂ as a pseudorandom sample over 𝑇𝑞𝑘×ℓ , and the sampling of 𝐀 = NTT−1 (𝐀) ̂ is only
implicit (i.e., it could be computed but is not).
22
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
vectors 𝐬1 and 𝐬2 , and a polynomial vector 𝐭0 encoding the 𝑑 least significant bits of each coefficient of
the uncompressed public-key polynomial 𝐭.
Algorithm 6 ML-DSA.KeyGen_internal(𝜉)
Generates a public-private key pair from a seed.
Input: Seed 𝜉 ∈ 𝔹32
Output: Public key 𝑝𝑘 ∈ 𝔹32+32𝑘(bitlen (𝑞−1)−𝑑)
and private key 𝑠𝑘 ∈ 𝔹32+32+64+32⋅((ℓ+𝑘)⋅bitlen (2𝜂)+𝑑𝑘) .
1: (𝜌, 𝜌′ , 𝐾) ∈ 𝔹32 × 𝔹64 × 𝔹32 ← H(𝜉||IntegerToBytes(𝑘, 1)||IntegerToBytes(ℓ, 1), 128)
2: ▷ expand seed
3: 𝐀̂ ← ExpandA(𝜌) ▷ 𝐀 is generated and stored in NTT representation as 𝐀̂
4: (𝐬1 , 𝐬2 ) ← ExpandS(𝜌′ )
5: 𝐭 ← NTT−1 (𝐀̂ ∘ NTT(𝐬1 )) + 𝐬2 ▷ compute 𝐭 = 𝐀𝐬1 + 𝐬2
6: (𝐭1 , 𝐭0 ) ← Power2Round(𝐭) ▷ compress 𝐭
7: ▷ PowerTwoRound is applied componentwise (see explanatory text in Section 7.4)
8: 𝑝𝑘 ← pkEncode(𝜌, 𝐭1 )
9: 𝑡𝑟 ← H(𝑝𝑘, 64)
10: 𝑠𝑘 ← skEncode(𝜌, 𝐾, 𝑡𝑟, 𝐬1 , 𝐬2 , 𝐭0 ) ▷ 𝐾 and 𝑡𝑟 are for use in signing
11: return (𝑝𝑘, 𝑠𝑘)
and (aside from the rejection step) is similar in structure to Schnorr signatures [30] (e.g., EdDSA [31]). The
signer first produces a “commitment” 𝐰1 and then pseudorandomly derives a “challenge” 𝑐 from 𝐰1 and
the message representative 𝜇. Finally, the signer computes a response 𝐳.
In more detail, the main computations involved in the rejection sampling loop are as follows:
• Using the ExpandMask function (Algorithm 34), the seed 𝜌″ , and a counter 𝜅, a polynomial vector
𝐲 ∈ 𝑅𝑞ℓ is pseudorandomly sampled from the subset of polynomial vectors whose coefficients are
moderately short (i.e., in the range [−𝛾1 + 1, 𝛾1 ]).
• From 𝐲, the signer computes the commitment 𝐰1 by computing 𝐰 = 𝐀𝐲 and then rounding to a
nearby multiple of 2𝛾2 using HighBits (Algorithm 37).
• 𝐰1 and 𝜇 are concatenated and hashed to produce the commitment hash 𝑐.̃ This uses the function
w1Encode (Algorithm 28). The byte string 𝑐 ̃is used to pseudorandomly sample a polynomial 𝑐 ∈ 𝑅𝑞
that has coefficients in {−1, 0, 1} and Hamming weight 𝜏. The sampling is done with the function
SampleInBall (Algorithm 29).11
• The signer computes the response 𝐳 = 𝐲 + 𝑐𝐬1 and performs various validity checks. If any of the
checks fails, the signer will continue the rejection sampling loop.
• If the checks pass, the signer can compute a hint polynomial 𝐡, which will allow the verifier to
reconstruct 𝐰1 using the compressed public key along with the other components of the signature.
This uses the function MakeHint (Algorithm 39). The signer will then output the final signature,
which is a byte encoding of the commitment hash 𝑐,̃ the response 𝐳, and the hint 𝐡.
In addition, there is an alternative way of implementing the validity checks on 𝐳 and the computation of
𝐡, which is described in Section 5.1 of [6]. This method may also be used in implementations of ML-DSA.
In Algorithm 7, variables are sometimes used to store products to avoid recomputing them later in the
signing algorithm. These precomputed products are denoted in the pseudocode by a pair of double angle
brackets enclosing the variables being multiplied (e.g., ⟨⟨𝑐𝐬1 ⟩⟩).
option is used and the maximum number of iterations is exceeded without producing a valid signature, the signing
algorithm shall return a constant that represents an error and no other output, destroying the results of the
unsuccessful signing attempts. See Appendix C.
11
The length of 𝑐 ̃ is determined by the desired security with respect to the “message-bound signatures” property
described in [14]. Here, a length of 𝜆/4 bytes or equivalently 2𝜆 bits is required for 𝜆 bits of classical security.
24
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
34: return 𝜎
required for ML-DSA.Verify_internal. It produces a Boolean value (i.e., a value that is true if the signature
is valid with respect to the message and public key and false if the signature is invalid) as output. Algorithm 8
specifies the lengths of the signature 𝜎 and the public key 𝑝𝑘 in terms of the parameters described in
Table 1. If an implementation of ML-DSA.Verify_internal can accept inputs for 𝜎 or 𝑝𝑘 of any other
length, it shall return false whenever the length of either of these inputs differs from its specified length.
The verifier first extracts the public random seed 𝜌 and the compressed polynomial vector 𝐭1 from the
public key 𝑝𝑘 and then extracts the signer’s commitment hash 𝑐,̃ response 𝐳, and hint 𝐡 from the signature
𝜎. The verifier may find that the hint was not properly byte-encoded, denoted by the symbol “⊥,” in
which case the verification algorithm will immediately return false to indicate that the signature is invalid.
Assuming that the signature is successfully extracted from its byte encoding, the verifier pseudorandomly
derives 𝐀 from 𝜌, as is done in key generation and signing, and creates a message representative 𝜇 by
hashing the concatenation of 𝑡𝑟 (i.e., the hash of the public key 𝑝𝑘) and the message 𝑀. The verifier
then attempts to reconstruct the signer’s commitment (i.e., the polynomial vector 𝐰1 ) from the public
key 𝑝𝑘 and the signature 𝜎. In ML-DSA.Sign_internal, 𝐰1 is computed by rounding 𝐰 = 𝐀𝐲. In
ML-DSA.Verify_internal, the reconstructed value of 𝐰1 is called 𝐰′1 since it may have been computed in
a different way if the signature is invalid. This 𝐰′1 is computed through the following process:
• Derive the challenge polynomial 𝑐 from the signer’s commitment hash 𝑐,̃ just as similarly is done in
ML-DSA.Sign_internal.
𝐰′Approx = 𝐀𝐳 − 𝑐𝐭1 ⋅ 2𝑑 .
Finally, the verifier checks that the signer’s response 𝐳 and the signer’s hint 𝐡 are valid and that the
reconstructed 𝐰′1 is consistent with the signer’s commitment hash 𝑐.̃ More precisely, the verifier checks
that all of the coefficients of 𝐳 are sufficiently small (i.e., in the range (−(𝛾1 − 𝛽), 𝛾1 − 𝛽)), 𝐡 contains no
more than 𝜔 nonzero coefficients, and 𝑐 ̃matches the hash 𝑐′̃ of the message representative 𝜇 concatenated
with 𝐰′1 (represented as a byte string). If all of these checks succeed, then ML-DSA.Verify_internal returns
true. Otherwise, it returns false.
26
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 8 ML-DSA.Verify_internal(𝑝𝑘, 𝑀 ′ , 𝜎)
Internal function to verify a signature 𝜎 for a formatted message 𝑀 ′ .
Input: Public key 𝑝𝑘 ∈ 𝔹32+32𝑘(bitlen (𝑞−1)−𝑑) and message 𝑀 ′ ∈ {0, 1}∗ .
Input: Signature 𝜎 ∈ 𝔹𝜆/4+ℓ⋅32⋅(1+bitlen (𝛾1 −1))+𝜔+𝑘 .
Output: Boolean
1: (𝜌, 𝐭1 ) ← pkDecode(𝑝𝑘)
2: (𝑐,̃ 𝐳, 𝐡) ← sigDecode(𝜎) ▷ signer’s commitment hash 𝑐,̃ response 𝐳, and hint 𝐡
3: if 𝐡 = ⊥ then return false ▷ hint was not properly encoded
4: end if
5: 𝐀̂ ← ExpandA(𝜌) ▷ 𝐀 is generated and stored in NTT representation as 𝐀̂
6: 𝑡𝑟 ← H(𝑝𝑘, 64)
7: 𝜇 ← (H(BytesToBits(𝑡𝑟)||𝑀 ′ , 64)) ▷ message representative that may optionally be
computed in a different cryptographic module
8: 𝑐 ∈ 𝑅𝑞 ← SampleInBall(𝑐)̃ ▷ compute verifier’s challenge from 𝑐 ̃
9: 𝐰Approx ← NTT (𝐀 ∘ NTT(𝐳) − NTT(𝑐) ∘ NTT(𝐭1 ⋅ 2𝑑 ))
′ −1 ̂ ′
▷ 𝐰Approx = 𝐀𝐳 − 𝑐𝐭1 ⋅ 2𝑑
10: 𝐰1 ← UseHint(𝐡, 𝐰Approx )
′ ′
▷ reconstruction of signer’s commitment
11: ▷ UseHint is applied componentwise (see explanatory text in Section 7.4)
12: 𝑐 ′̃ ← H(𝜇||w1Encode(𝐰′1 ), 𝜆/4) ▷ hash it; this should match 𝑐 ̃
′
13: return [[ ||𝐳||∞ < 𝛾1 − 𝛽]] and [[𝑐 ̃ = 𝑐 ̃ ]]
27
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
7. Auxiliary Functions
This section provides pseudocode for subroutines utilized by ML-DSA, including functions for data-type
conversions, arithmetic, and sampling.
Algorithm 9 IntegerToBits(𝑥, 𝛼)
Computes a base-2 representation of 𝑥 mod 2𝛼 using little-endian order.
Input: A nonnegative integer 𝑥 and a positive integer 𝛼.
Output: A bit string 𝑦 of length 𝛼.
1: for 𝑖 from 0 to 𝛼 − 1 do
2: 𝑦[𝑖] ← 𝑥 mod 2
3: 𝑥 ← ⌊𝑥/2⌋
4: end for
5: return 𝑦
Algorithm 10 BitsToInteger(𝑦, 𝛼)
Computes the integer value expressed by a bit string using little-endian order.
Input: A positive integer 𝛼 and a bit string 𝑦 of length 𝛼.
Output: A nonnegative integer 𝑥.
1: 𝑥 ← 0
2: for 𝑖 from 1 to 𝛼 do
3: 𝑥 ← 2𝑥 + 𝑦[𝛼 − 𝑖]
4: end for
5: return 𝑥
Algorithm 11 IntegerToBytes(𝑥, 𝛼)
Computes a base-256 representation of 𝑥 mod 256𝛼 using little-endian order.
Input: A nonnegative integer 𝑥 and a positive integer 𝛼.
Output: A byte string 𝑦 of length 𝛼.
1: for 𝑖 from 0 to 𝛼 − 1 do
2: 𝑦[𝑖] ← 𝑥 mod 256
3: 𝑥 ← ⌊𝑥/256⌋
4: end for
5: return 𝑦
28
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 12 BitsToBytes(𝑦)
Converts a bit string into a byte string using little-endian order.
Input: A bit string 𝑦 of length 𝛼.
Output: A byte string 𝑧 of length ⌈𝛼/8⌉.
1: 𝑧 ∈ 𝔹⌈𝛼/8⌉ ← 0⌈𝛼/8⌉
2: for 𝑖 from 0 to 𝛼 − 1 do
3: 𝑧 [⌊𝑖/8⌋] ← 𝑧 [⌊𝑖/8⌋] + 𝑦[𝑖] ⋅ 2𝑖 mod 8
4: end for
5: return 𝑧
Algorithm 13 BytesToBits(𝑧)
Converts a byte string into a bit string using little-endian order.
Input: A byte string 𝑧 of length 𝛼.
Output: A bit string 𝑦 of length 8𝛼.
1: for 𝑖 from 0 to 𝛼 − 1 do
2: for 𝑗 from 0 to 7 do ▷ convert the byte 𝑧[𝑖] into 8 bits
3: 𝑦[8𝑖 + 𝑗] ← 𝑧[𝑖] mod 2
4: 𝑧[𝑖] ← ⌊𝑧[𝑖]/2⌋
5: end for
6: end for
7: return 𝑦
Algorithm 14 CoeffFromThreeBytes(𝑏0 , 𝑏1 , 𝑏2 )
Generates an element of {0, 1, 2, … , 𝑞 − 1} ∪ {⊥}.
Input: Bytes 𝑏0 , 𝑏1 , 𝑏2 .
Output: An integer modulo 𝑞 or ⊥.
1: 𝑏2′ ← 𝑏2
2: if 𝑏2′ > 127 then
3: 𝑏2′ ← 𝑏2′ − 128 ▷ set the top bit of 𝑏2′ to zero
4: end if
5: 𝑧 ← 216 ⋅ 𝑏2′ + 28 ⋅ 𝑏1 + 𝑏0 ▷ 0 ≤ 𝑧 ≤ 223 − 1
6: if 𝑧 < 𝑞 then return 𝑧 ▷ rejection sampling
7: else return ⊥
8: end if
29
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 15 CoeffFromHalfByte(𝑏)
Let 𝜂 ∈ {2, 4}. Generates an element of {−𝜂, −𝜂 + 1, … , 𝜂} ∪ {⊥}.
Input: Integer 𝑏 ∈ {0, 1, … , 15}.
Output: An integer between −𝜂 and 𝜂, or ⊥.
1: if 𝜂 = 2 and 𝑏 < 15 then return 2 − (𝑏 mod 5) ▷ rejection sampling from {−2, … , 2}
2: else
3: if 𝜂 = 4 and 𝑏 < 9 then return 4 − 𝑏 ▷ rejection sampling from {−4, … , 4}
4: else return ⊥
5: end if
6: end if
Algorithms 16–19 efficiently translate an element 𝑤 ∈ 𝑅 into a byte string and vice versa under the
assumption that the coefficients of 𝑤 are in a restricted range. SimpleBitPack assumes that 𝑤𝑖 ∈ [0, 𝑏]
for some positive integer 𝑏 and packs 𝑤 into a byte string of length 32 ⋅ bitlen 𝑏. BitPack allows for the
more general restriction 𝑤𝑖 ∈ [−𝑎, 𝑏]. The BitPack algorithm works by merely subtracting 𝑤 from the
255
polynomial ∑𝑖=0 𝑏𝑋 𝑖 .
Algorithm 16 SimpleBitPack(𝑤, 𝑏)
Encodes a polynomial 𝑤 into a byte string.
Input: 𝑏 ∈ ℕ and 𝑤 ∈ 𝑅 such that the coefficients of 𝑤 are all in [0, 𝑏].
Output: A byte string of length 32 ⋅ bitlen 𝑏.
1: 𝑧 ← () ▷ set 𝑧 to the empty bit string
2: for 𝑖 from 0 to 255 do
3: 𝑧 ← 𝑧||IntegerToBits(𝑤𝑖 , bitlen 𝑏)
4: end for
5: return BitsToBytes(𝑧)
Algorithm 17 BitPack(𝑤, 𝑎, 𝑏)
Encodes a polynomial 𝑤 into a byte string.
Input: 𝑎, 𝑏 ∈ ℕ and 𝑤 ∈ 𝑅 such that the coefficients of 𝑤 are all in [−𝑎, 𝑏].
Output: A byte string of length 32 ⋅ bitlen (𝑎 + 𝑏).
1: 𝑧 ← () ▷ set 𝑧 to the empty bit string
2: for 𝑖 from 0 to 255 do
3: 𝑧 ← 𝑧||IntegerToBits(𝑏 − 𝑤𝑖 , bitlen (𝑎 + 𝑏))
4: end for
5: return BitsToBytes(𝑧)
SimpleBitUnpack and BitUnpack are used to decode the byte strings produced by the above functions.
For some choices of 𝑎 and 𝑏, there exist malformed byte strings that will cause SimpleBitUnpack and
BitUnpack to output polynomials whose coefficients are not in the ranges [0, 𝑏] and [−𝑎, 𝑏], respectively.
This can be a concern when running SimpleBitUnpack and BitUnpack on inputs that may come from an
untrusted source.
30
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 18 SimpleBitUnpack(𝑣, 𝑏)
Reverses the procedure SimpleBitPack.
Input: 𝑏 ∈ ℕ and a byte string 𝑣 of length 32 ⋅ bitlen 𝑏.
Output: A polynomial 𝑤 ∈ 𝑅 with coefficients in [0, 2𝑐 − 1], where 𝑐 = bitlen 𝑏.
When 𝑏 + 1 is a power of 2, the coefficients are in [0, 𝑏].
1: 𝑐 ← bitlen 𝑏
2: 𝑧 ← BytesToBits(𝑣)
3: for 𝑖 from 0 to 255 do
4: 𝑤𝑖 ← BitsToInteger((𝑧[𝑖𝑐], 𝑧[𝑖𝑐 + 1], … 𝑧[𝑖𝑐 + 𝑐 − 1]), 𝑐)
5: end for
6: return 𝑤
Algorithm 19 BitUnpack(𝑣, 𝑎, 𝑏)
Reverses the procedure BitPack.
Input: 𝑎, 𝑏 ∈ ℕ and a byte string 𝑣 of length 32 ⋅ bitlen (𝑎 + 𝑏).
Output: A polynomial 𝑤 ∈ 𝑅 with coefficients in [𝑏 − 2𝑐 + 1, 𝑏], where 𝑐 = bitlen (𝑎 + 𝑏).
When 𝑎 + 𝑏 + 1 is a power of 2, the coefficients are in [−𝑎, 𝑏].
1: 𝑐 ← bitlen (𝑎 + 𝑏)
2: 𝑧 ← BytesToBits(𝑣)
3: for 𝑖 from 0 to 255 do
4: 𝑤𝑖 ← 𝑏 − BitsToInteger((𝑧[𝑖𝑐], 𝑧[𝑖𝑐 + 1], … 𝑧[𝑖𝑐 + 𝑐 − 1]), 𝑐)
5: end for
6: return 𝑤
Algorithms 20 and 21 carry out byte-string-to-polynomial conversions for polynomials with sparse binary
coefficients. In particular, the signing and verification algorithms (Sections 6.2 and 6.3) make use of a “hint,”
which is a vector of polynomials 𝐡 ∈ 𝑅2𝑘 such that the total number of coefficients in 𝐡[0], 𝐡[1], … , 𝐡[𝑘−1]
that are equal to 1 is no more than 𝜔. This constraint enables encoding and decoding procedures that are
more efficient (although more complex) than BitPack and BitUnpack.
HintBitPack (𝐡) outputs a byte string 𝑦 of length 𝜔 + 𝑘. The last 𝑘 bytes of 𝑦 contain information about
how many nonzero coefficients are present in each of the polynomials 𝐡[0], 𝐡[1], … , 𝐡[𝑘 − 1], and the
first 𝜔 bytes of 𝑦 contain information about exactly where those nonzero terms occur. HintBitUnpack
reverses the procedure performed by HintBitPack and recovers the vector 𝐡.
31
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 20 HintBitPack(𝐡)
Encodes a polynomial vector 𝐡 with binary coefficients into a byte string.
Input: A polynomial vector 𝐡 ∈ 𝑅2𝑘 such that the polynomials 𝐡[0], 𝐡[1],...,𝐡[𝑘 − 1] have
collectively at most 𝜔 nonzero coefficients.
Output: A byte string 𝑦 of length 𝜔 + 𝑘 that encodes 𝐡 as described above.
1: 𝑦 ∈ 𝔹𝜔+𝑘 ← 0𝜔+𝑘
2: Index ← 0 ▷ Index for writing the first 𝜔 bytes of 𝑦
3: for 𝑖 from 0 to 𝑘 − 1 do ▷ look at 𝐡[𝑖]
4: for 𝑗 from 0 to 255 do
5: if 𝐡[𝑖]𝑗 ≠ 0 then
6: 𝑦[Index] ← 𝑗 ▷ store the locations of the nonzero coefficients in 𝐡[𝑖]
7: Index ← Index + 1
8: end if
9: end for
10: 𝑦[𝜔 + 𝑖] ← Index ▷ after processing 𝐡[𝑖], store the value of Index
11: end for
12: return 𝑦
Algorithm 21 HintBitUnpack(𝑦)
Reverses the procedure HintBitPack.
Input: A byte string 𝑦 of length 𝜔 + 𝑘 that encodes 𝐡 as described above.
Output: A polynomial vector 𝐡 ∈ 𝑅2𝑘 or ⊥.
1: 𝐡 ∈ 𝑅2𝑘 ← 0𝑘
2: Index ← 0 ▷ Index for reading the first 𝜔 bytes of 𝑦
3: for 𝑖 from 0 to 𝑘 − 1 do ▷ reconstruct 𝐡[𝑖]
4: if 𝑦[𝜔 + 𝑖] < Index or 𝑦[𝜔 + 𝑖] > 𝜔 then return ⊥ ▷ malformed input
5: end if
6: First ← Index
7: while Index < 𝑦[𝜔 + 𝑖] do ▷ 𝑦[𝜔 + 𝑖] says how far one can advance Index
8: if Index > First then
9: if 𝑦[Index − 1] ≥ 𝑦[Index] then return ⊥ ▷ malformed input
10: end if
11: end if
12: 𝐡[𝑖]𝑦[Index] ← 1 ▷ 𝑦[Index] says which coefficient in 𝐡[𝑖] should be 1
13: Index ← Index + 1
14: end while
15: end for
16: for 𝑖 from Index to 𝜔 − 1 do ▷ read any leftover bytes in the first 𝜔 bytes of 𝑦
17: if 𝑦[𝑖] ≠ 0 then return ⊥ ▷ malformed input
18: end if
19: end for
20: return 𝐡
32
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 22 pkEncode(𝜌, 𝐭1 )
Encodes a public key for ML-DSA into a byte string.
Input:𝜌 ∈ 𝔹32 , 𝐭1 ∈ 𝑅𝑘 with coefficients in [0, 2bitlen (𝑞−1)−𝑑 − 1].
Output: Public key 𝑝𝑘 ∈ 𝔹32+32𝑘(bitlen (𝑞−1)−𝑑) .
1: 𝑝𝑘 ← 𝜌
2: for 𝑖 from 0 to 𝑘 − 1 do
3: 𝑝𝑘 ← 𝑝𝑘 || SimpleBitPack (𝐭1 [𝑖], 2bitlen (𝑞−1)−𝑑 − 1)
4: end for
5: return 𝑝𝑘
Algorithm 23 pkDecode(𝑝𝑘)
Reverses the procedure pkEncode.
Input: Public key 𝑝𝑘 ∈ 𝔹32+32𝑘(bitlen (𝑞−1)−𝑑) .
Output: 𝜌 ∈ 𝔹32 , 𝐭1 ∈ 𝑅𝑘 with coefficients in [0, 2bitlen (𝑞−1)−𝑑 − 1].
𝑘
1: (𝜌, 𝑧0 , … , 𝑧𝑘−1 ) ∈ 𝔹32 × (𝔹32(bitlen (𝑞−1)−𝑑) ) ← 𝑝𝑘
2: for 𝑖 from 0 to 𝑘 − 1 do
3: 𝐭1 [𝑖] ← SimpleBitUnpack(𝑧𝑖 , 2bitlen (𝑞−1)−𝑑 − 1) ▷ This is always in the correct range
4: end for
5: return (𝜌, 𝐭1 )
Next, skEncode and skDecode translate ML-DSA secret keys into byte strings and vice versa. Note that
there exist malformed inputs that can cause skDecode to return values that are not in the correct range.
Hence, skDecode should only be run on inputs that come from trusted sources.
33
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 25 skDecode(𝑠𝑘)
Reverses the procedure skEncode.
Input: Private key 𝑠𝑘 ∈ 𝔹32+32+64+32⋅((ℓ+𝑘)⋅bitlen (2𝜂)+𝑑𝑘) .
Output: 𝜌 ∈ 𝔹32 , 𝐾 ∈ 𝔹32 , 𝑡𝑟 ∈ 𝔹64 ,
𝐬1 ∈ 𝑅ℓ , 𝐬2 ∈ 𝑅𝑘 , 𝐭0 ∈ 𝑅𝑘 with coefficients in [−2𝑑−1 + 1, 2𝑑−1 ].
ℓ
1: (𝜌, 𝐾, 𝑡𝑟, 𝑦0 , … , 𝑦ℓ−1 , 𝑧0 , … , 𝑧𝑘−1 , 𝑤0 , … , 𝑤𝑘−1 ) ∈ 𝔹32 × 𝔹32 × 𝔹64 × (𝔹32⋅bitlen (2𝜂) ) ×
𝑘 𝑘
(𝔹32⋅bitlen (2𝜂) ) × (𝔹32𝑑 ) ← 𝑠𝑘
2: for 𝑖 from 0 to ℓ − 1 do
3: 𝐬1 [𝑖] ← BitUnpack(𝑦𝑖 , 𝜂, 𝜂) ▷ this may lie outside [−𝜂, 𝜂] if input is malformed
4: end for
5: for 𝑖 from 0 to 𝑘 − 1 do
6: 𝐬2 [𝑖] ← BitUnpack(𝑧𝑖 , 𝜂, 𝜂) ▷ this may lie outside [−𝜂, 𝜂] if input is malformed
7: end for
8: for 𝑖 from 0 to 𝑘 − 1 do
9: 𝐭0 [𝑖] ← BitUnpack(𝑤𝑖 , 2𝑑−1 − 1, 2𝑑−1 ) ▷ this is always in the correct range
10: end for
11: return (𝜌, 𝐾, 𝑡𝑟, 𝐬1 , 𝐬2 , 𝐭0 )
Next, sigEncode and sigDecode translate ML-DSA signatures into byte strings and vice versa. When
verifying a signature, sigDecode might take input that comes from an untrusted source. Thus, care is
required when using BitUnpack. As used here, BitUnpack always returns values in the correct range.
34
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 26 sigEncode(𝑐,̃ 𝐳, 𝐡)
Encodes a signature into a byte string.
Input: 𝑐 ̃ ∈ 𝔹𝜆/4 , 𝐳 ∈ 𝑅ℓ with coefficients in [−𝛾1 + 1, 𝛾1 ], 𝐡 ∈ 𝑅2𝑘 .
Output: Signature 𝜎 ∈ 𝔹𝜆/4+ℓ⋅32⋅(1+bitlen (𝛾1 −1))+𝜔+𝑘 .
1: 𝜎 ← 𝑐 ̃
2: for 𝑖 from 0 to ℓ − 1 do
3: 𝜎 ← 𝜎 || BitPack (𝐳[𝑖], 𝛾1 − 1, 𝛾1 )
4: end for
5: 𝜎 ← 𝜎 || HintBitPack (𝐡)
6: return 𝜎
Algorithm 27 sigDecode(𝜎)
Reverses the procedure sigEncode.
Input: Signature 𝜎 ∈ 𝔹𝜆/4+ℓ⋅32⋅(1+bitlen (𝛾1 −1))+𝜔+𝑘 .
Output: 𝑐 ̃ ∈ 𝔹𝜆/4 , 𝐳 ∈ 𝑅ℓ with coefficients in [−𝛾1 + 1, 𝛾1 ], 𝐡 ∈ 𝑅2𝑘 , or ⊥.
ℓ
1: (𝑐,̃ 𝑥0 , … , 𝑥ℓ−1 , 𝑦) ∈ 𝔹𝜆/4 × (𝔹32⋅(1+bitlen (𝛾1 −1)) ) × 𝔹𝜔+𝑘 ← 𝜎
2: for 𝑖 from 0 to ℓ − 1 do
3: 𝐳[𝑖] ← BitUnpack(𝑥𝑖 , 𝛾1 − 1, 𝛾1 ) ▷ this is in the correct range, as 𝛾1 is a power of 2
4: end for
5: 𝐡 ← HintBitUnpack(𝑦)
6: return (𝑐,̃ 𝐳, 𝐡)
w1Encode is a specific subroutine used in ML-DSA.Sign. The procedure w1Encode encodes a polynomial
vector 𝐰1 into a string of bytes so that it can be processed by the function H.
Algorithm 28 w1Encode(𝐰1 )
Encodes a polynomial vector 𝐰1 into a byte string.
Input: 𝐰1 ∈ 𝑅𝑘 whose polynomial coordinates have coefficients in [0, (𝑞 − 1)/(2𝛾2 ) − 1].
Output: A byte string representation 𝐰̃ 1 ∈ 𝔹32𝑘⋅bitlen ((𝑞−1)/(2𝛾2 )−1) .
1: 𝐰̃ 1 ← ()
2: for 𝑖 from 0 to 𝑘 − 1 do
3: 𝐰̃ 1 ← 𝐰̃ 1 || SimpleBitPack (𝐰1 [𝑖], (𝑞 − 1)/(2𝛾2 ) − 1)
4: end for
5: return 𝐰̃ 1
35
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
SampleInBall pseudorandomly generates an element of 𝐵𝜏 using the XOF of a seed 𝜌. The procedure
is based on the Fisher-Yates shuffle. H is applied to 𝜌, and the first 8 bytes of the output are used to
choose the signs of the nonzero entries of 𝑐.12 Subsequent bytes are used to choose the positions of
those nonzero entries.
Algorithm 29 SampleInBall(𝜌)
Samples a polynomial 𝑐 ∈ 𝑅 with coefficients from {−1, 0, 1} and Hamming weight 𝜏 ≤ 64.
Input: A seed 𝜌 ∈ 𝔹𝜆/4
Output: A polynomial 𝑐 in 𝑅.
1: 𝑐 ← 0
2: ctx ← H.Init()
3: ctx ← H.Absorb(ctx, 𝜌)
4: (ctx, 𝑠) ← H.Squeeze(ctx, 8)
5: ℎ ← BytesToBits(𝑠) ▷ ℎ is a bit string of length 64
6: for 𝑖 from 256 − 𝜏 to 255 do
7: (ctx, 𝑗) ← H.Squeeze(ctx, 1)
8: while 𝑗 > 𝑖 do ▷ rejection sampling in {0, … , 𝑖}
9: (ctx, 𝑗) ← H.Squeeze(ctx, 1)
10: end while ▷ 𝑗 is a pseudorandom byte that is ≤ 𝑖
11: 𝑐𝑖 ← 𝑐 𝑗
12: 𝑐𝑗 ← (−1)ℎ[𝑖+𝜏−256]
13: end for
14: return 𝑐
Algorithms 30–34 are the pseudorandom procedures RejNTTPoly, RejBoundedPoly, ExpandA, ExpandS,
and ExpandMask. Each generates elements of 𝑅 or 𝑇𝑞 under different input and output conditions.
RejNTTPoly and ExpandA make use of the more efficient XOF G, whereas the other three procedures
use the XOF H.
The procedure ExpandMask (Algorithm 34) generates a polynomial vector 𝐲 in 𝑅𝑘 that disguises the
secret key in the ML-DSA.Sign_internal procedure (Algorithm 7). In addition to the seed 𝜌, ExpandMask
also accepts an integer input 𝜇 that is incorporated into the pseudorandom procedure that generates 𝐬.
12
The parameter 𝜏 is always less than or equal to 64, and thus 8 bytes are sufficient to choose the signs for all 𝜏
nonzero entries of 𝐜.
36
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 30 RejNTTPoly(𝜌)
Samples a polynomial ∈ 𝑇𝑞 .
Input: A seed 𝜌 ∈ 𝔹34 .
Output: An element 𝑎̂ ∈ 𝑇𝑞 .
1: 𝑗 ← 0
2: ctx ← G.Init()
3: ctx ← G.Absorb(ctx, 𝜌)
4: while 𝑗 < 256 do
5: (ctx, 𝑠) ← G.Squeeze(ctx, 3)
6: ̂ ← CoeffFromThreeBytes(𝑠[0], 𝑠[1], 𝑠[2])
𝑎[𝑗]
7: if 𝑎[𝑗]
̂ ≠ ⊥ then
8: 𝑗 ←𝑗+1
9: end if
10: end while
11: return 𝑎̂
Algorithm 31 RejBoundedPoly(𝜌)
Samples an element 𝑎 ∈ 𝑅 with coefficients in [−𝜂, 𝜂] computed via rejection sampling from 𝜌.
Input: A seed 𝜌 ∈ 𝔹66 .
Output: A polynomial 𝑎 ∈ 𝑅.
1: 𝑗 ← 0
2: ctx ← H.Init()
3: ctx ← H.Absorb(ctx, 𝜌)
4: while 𝑗 < 256 do
5: 𝑧 ← H.Squeeze(ctx, 1)
6: 𝑧0 ← CoeffFromHalfByte(𝑧 mod 16)
7: 𝑧1 ← CoeffFromHalfByte(⌊𝑧/16⌋)
8: if 𝑧0 ≠ ⊥ then
9: 𝑎𝑗 ← 𝑧0
10: 𝑗 ←𝑗+1
11: end if
12: if 𝑧1 ≠ ⊥ and 𝑗 < 256 then
13: 𝑎𝑗 ← 𝑧1
14: 𝑗 ←𝑗+1
15: end if
16: end while
17: return 𝑎
37
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 32 ExpandA(𝜌)
Samples a 𝑘 × ℓ matrix 𝐀̂ of elements of 𝑇𝑞 .
Input: A seed 𝜌 ∈ 𝔹32 .
Output: Matrix 𝐀̂ ∈ (𝑇𝑞 )𝑘×ℓ .
1: for 𝑟 from 0 to 𝑘 − 1 do
2: for 𝑠 from 0 to ℓ − 1 do
3: 𝜌′ ← 𝜌||IntegerToBytes(𝑠, 1)||IntegerToBytes(𝑟, 1)
4: ̂ 𝑠] ← RejNTTPoly(𝜌′ )
𝐀[𝑟, ▷ seed 𝜌′ depends on 𝑠 and 𝑟
5: end for
6: end for
7: return 𝐀̂
Algorithm 33 ExpandS(𝜌)
Samples vectors 𝐬1 ∈ 𝑅ℓ and 𝐬2 ∈ 𝑅𝑘 , each with polynomial coordinates whose coefficients are
in the interval [−𝜂, 𝜂].
Input: A seed 𝜌 ∈ 𝔹64 .
Output: Vectors 𝐬1 , 𝐬2 of polynomials in 𝑅.
1: for 𝑟 from 0 to ℓ − 1 do
2: 𝐬𝟏 [𝑟] ← RejBoundedPoly(𝜌||IntegerToBytes(𝑟, 2)) ▷ seed depends on 𝑟
3: end for
4: for 𝑟 from 0 to 𝑘 − 1 do
5: 𝐬𝟐 [𝑟] ← RejBoundedPoly(𝜌||IntegerToBytes(𝑟 + ℓ, 2)) ▷ seed depends on 𝑟 + ℓ
6: end for
7: return (𝐬𝟏 , 𝐬𝟐 )
Algorithm 34 ExpandMask(𝜌, 𝜇)
Samples a vector 𝐲 ∈ 𝑅ℓ such that each polynomial 𝐲[𝑟] has coefficients between −𝛾1 + 1 and
𝛾1 .
Input: A seed 𝜌 ∈ 𝔹64 and a nonnegative integer 𝜇.
Output: Vector 𝐲 ∈ 𝑅ℓ .
1: 𝑐 ← 1 + bitlen (𝛾1 − 1) ▷ 𝛾1 is always a power of 2
2: for 𝑟 from 0 to ℓ − 1 do
3: 𝜌′ ← 𝜌||IntegerToBytes(𝜇 + 𝑟, 2)
4: 𝑣 ← H(𝜌′ , 32𝑐) ▷ seed depends on 𝜇 + 𝑟
5: 𝐲[𝑟] ← BitUnpack(𝑣, 𝛾1 − 1, 𝛾1 )
6: end for
7: return 𝐲
38
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
These algorithms are used to support the key compression optimization of ML-DSA. They involve dropping
the 𝑑 low-order bits of each coefficient of the polynomial vector 𝐭 from the public key using the function
Power2Round. However, in order to make this optimization work, additional information called a “hint”
needs to be provided in the signature to allow the verifier to reconstruct enough of the information in
the dropped public-key bits to verify the signature. Hints are created during signing and used during
verification by the functions MakeHint and UseHint, respectively. In the verification of a valid signature,
the hint allows the verifier to recover 𝐰1 ∈ 𝑅𝑘 , which represents 𝐰 ∈ 𝑅𝑞𝑘 rounded to a nearby multiple
of 𝛼 = 2𝛾2 . The signer directly obtains 𝐰1 using the function HighBits, and the part rounded off (i.e., 𝐫0 )
is obtained by LowBits. 𝐫0 is used by the signer in the rejection sampling procedure.
Power2Round decomposes an input 𝑟 ∈ ℤ𝑞 into integers that represent the high- and low-order bits of
𝑟 mod 𝑞 in the straightforward bitwise way, 𝑟 mod 𝑞 = 𝑟1 ⋅ 2𝑑 + 𝑟0 , where 𝑟0 = (𝑟 mod 𝑞) mod± 2𝑑 and
𝑟1 = (𝑟 mod 𝑞 − 𝑟0 )/2𝑑 .
However, for the purpose of computations related to hints, this method of decomposing 𝑟 has the
undesirable property that when 𝑟 is close to 𝑞 − 1 or 0, a small rounding error in 𝑟 can cause 𝑟1 to change
by more than 1, even accounting for wrap-around. In contrast to other unequal pairs of values of 𝑟1 ⋅ 2𝑑
and 𝑟1′ ⋅ 2𝑑 , the distance (mod𝑞) between ⌊𝑞/2𝑑 ⌋ ⋅ 2𝑑 and 0 may be very small.
39
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
To avoid this problem, this specification defines Decompose, which is similar to Power2Round except:
• If the straightforward rounding procedure would return (𝑟1 = (𝑞 − 1)/𝛼, 𝑟0 ∈ [−(𝛼/2) + 1, 𝛼/2]),
Decompose instead returns (𝑟1 = 0, 𝑟0 − 1).
The functions HighBits and LowBits — which only return 𝑟1 and 𝑟0 , respectively — and MakeHint and
UseHint use Decompose. For additional discussion of the mathematical properties of these functions
that are relevant to the correctness and security of ML-DSA, see Section 2.4 in [6].
Algorithm 35 Power2Round(𝑟)
Decomposes 𝑟 into (𝑟1 , 𝑟0 ) such that 𝑟 ≡ 𝑟1 2𝑑 + 𝑟0 mod 𝑞.
Input: 𝑟 ∈ ℤ𝑞 .
Output: Integers (𝑟1 , 𝑟0 ).
1: 𝑟+ ← 𝑟 mod 𝑞
±
2: 𝑟0 ← 𝑟+ mod 2𝑑
3: return ((𝑟+ − 𝑟0 )/2𝑑 , 𝑟0 )
Algorithm 36 Decompose(𝑟)
Decomposes 𝑟 into (𝑟1 , 𝑟0 ) such that 𝑟 ≡ 𝑟1 (2𝛾2 ) + 𝑟0 mod 𝑞.
Input: 𝑟 ∈ ℤ𝑞 .
Output: Integers (𝑟1 , 𝑟0 ).
1: 𝑟+ ← 𝑟 mod 𝑞
±
2: 𝑟0 ← 𝑟+ mod (2𝛾2 )
3: if 𝑟+ − 𝑟0 = 𝑞 − 1 then
4: 𝑟1 ← 0
5: 𝑟0 ← 𝑟 0 − 1
6: else 𝑟1 ← (𝑟+ − 𝑟0 )/(2𝛾2 )
7: end if
8: return (𝑟1 , 𝑟0 )
Algorithm 37 HighBits(𝑟)
Returns 𝑟1 from the output of Decompose (𝑟).
Input: 𝑟 ∈ ℤ𝑞 .
Output: Integer 𝑟1 .
1: (𝑟1 , 𝑟0 ) ← Decompose(𝑟)
2: return 𝑟1
40
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 38 LowBits(𝑟)
Returns 𝑟0 from the output of Decompose (𝑟).
Input: 𝑟 ∈ ℤ𝑞 .
Output: Integer 𝑟0 .
1: (𝑟1 , 𝑟0 ) ← Decompose(𝑟)
2: return 𝑟0
Algorithm 39 MakeHint(𝑧, 𝑟)
Computes hint bit indicating whether adding 𝑧 to 𝑟 alters the high bits of 𝑟.
Input: 𝑧, 𝑟 ∈ ℤ𝑞 .
Output: Boolean.
1: 𝑟1 ← HighBits(𝑟)
2: 𝑣1 ← HighBits(𝑟 + 𝑧)
3: return [[𝑟1 ≠ 𝑣1 ]]
Algorithm 40 UseHint(ℎ, 𝑟)
Returns the high bits of 𝑟 adjusted according to hint ℎ.
Input: Boolean ℎ, 𝑟 ∈ ℤ𝑞 .
𝑞−1
Output: 𝑟1 ∈ ℤ with 0 ≤ 𝑟1 ≤ 2𝛾2 .
1: 𝑚 ← (𝑞 − 1)/(2𝛾2 )
2: (𝑟1 , 𝑟0 ) ← Decompose(𝑟)
3: if ℎ = 1 and 𝑟0 > 0 return (𝑟1 + 1) mod 𝑚
4: if ℎ = 1 and 𝑟0 ≤ 0 return (𝑟1 − 1) mod 𝑚
5: return 𝑟1
41
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
42
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 41 NTT(𝑤)
Computes the NTT.
255
Input: Polynomial 𝑤(𝑋) = ∑𝑗=0 𝑤𝑗 𝑋 𝑗 ∈ 𝑅𝑞 .
Output: 𝑤̂ = (𝑤[0], ̂ … , 𝑤[255])
̂ ∈ 𝑇𝑞 .
1: for 𝑗 from 0 to 255 do
2: 𝑤[𝑗]
̂ ← 𝑤𝑗
3: end for
4: 𝑚 ← 0
5: 𝑙𝑒𝑛 ← 128
6: while 𝑙𝑒𝑛 ≥ 1 do
7: 𝑠𝑡𝑎𝑟𝑡 ← 0
8: while 𝑠𝑡𝑎𝑟𝑡 < 256 do
9: 𝑚←𝑚+1
10: 𝑧 ← zetas[𝑚] ▷ 𝑧 ← 𝜁 BitRev8 (𝑚) mod 𝑞
11: for 𝑗 from 𝑠𝑡𝑎𝑟𝑡 to 𝑠𝑡𝑎𝑟𝑡 + 𝑙𝑒𝑛 − 1 do
12: 𝑡 ← (𝑧 ⋅ 𝑤[𝑗 ̂ + 𝑙𝑒𝑛]) mod 𝑞
13: 𝑤[𝑗 ̂ + 𝑙𝑒𝑛] ← (𝑤[𝑗]̂ − 𝑡) mod 𝑞
14: 𝑤[𝑗] ̂ ← (𝑤[𝑗] ̂ + 𝑡) mod 𝑞
15: end for
16: 𝑠𝑡𝑎𝑟𝑡 ← 𝑠𝑡𝑎𝑟𝑡 + 2 ⋅ 𝑙𝑒𝑛
17: end while
18: 𝑙𝑒𝑛 ← ⌊𝑙𝑒𝑛/2⌋
19: end while
20: return 𝑤̂
43
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
44
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 46 AddVectorNTT(𝐯,̂ 𝐰)
̂
Computes the sum 𝐯̂ + 𝐰̂ of two vectors 𝐯,̂ 𝐰̂ over 𝑇𝑞 .
Input: ℓ ∈ ℕ, 𝐯̂ ∈ 𝑇𝑞ℓ , 𝐰̂ ∈ 𝑇𝑞ℓ .
Output: 𝐮̂ ∈ 𝑇𝑞ℓ .
1: for 𝑖 from 0 to ℓ − 1 do
2: ̂ ← AddNTT(𝐯[𝑖],
𝐮[𝑖] ̂ 𝐰[𝑖])
̂
3: end for
4: return 𝐮̂
45
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Algorithm 48 MatrixVectorNTT(𝐌,
̂ 𝐯)̂
46
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
References
[1] National Institute of Standards and Technology (2023) Digital signature standard (DSS), (U.S. Depart-
ment of Commerce, Washington, DC), Federal Information Processing Standards Publication (FIPS)
186-5. https://doi.org/10.6028/NIST.FIPS.186-5.
[2] Barker E (2020) Guideline for using cryptographic standards in the federal government: Cryptographic
mechanisms, (National Institute of Standards and Technology, Gaithersburg, MD), NIST Special
Publication (SP) 800-175B, Rev. 1 [or as amended]. https://doi.org/10.6028/NIST.SP.800-175Br1.
[3] Barker E (2006) Recommendation for obtaining assurances for digital signature applications, National
Institute of Standards and Technology, Gaithersburg, MD. NIST Special Publication (SP) 800-89 [or as
amended]. https://doi.org/10.6028/NIST.SP.800-89.
[4] Langlois A, Stehlé D (2015) Worst-case to average-case reductions for module lattices. Designs, Codes
and Cryptography 75(3):565–599. https://doi.org/10.1007/s10623-014-9938-4.
[5] Bai S, Ducas L, Kiltz E, Lepoint T, Lyubashevsky V, Schwabe P, Seiler G, Stehlé D (2020) CRYSTALS-
Dilithium: Algorithm specifications and supporting documentation, Submission to the NIST’s post-
quantum cryptography standardization process. Available at https://csrc.nist.gov/Projects/post-qua
ntum-cryptography/post-quantum-cryptography-standardization/round-3-submissions.
[6] Bai S, Ducas L, Kiltz E, Lepoint T, Lyubashevsky V, Schwabe P, Seiler G, Stehlé D (2021) CRYSTALS-
Dilithium: Algorithm specifications and supporting documentation (Version 3.1). Available at https:
//pq-crystals.org/dilithium/data/dilithium-specification-round3-20210208.pdf.
[7] National Institute of Standards and Technology (2015) SHA-3 standard: Permutation-based hash and
extendable-output functions, (U.S. Department of Commerce, Washington, DC), Federal Information
Processing Standards Publication (FIPS) 202. https://doi.org/10.6028/NIST.FIPS.202.
[8] National Institute of Standards and Technology (2015) Secure hash standard (SHS), (U.S. Department
of Commerce, Washington, DC), Federal Information Processing Standards Publication (FIPS) 180-4.
https://doi.org/10.6028/NIST.FIPS.180-4.
[9] Barker E (2020) Recommendation for key management: Part 1 - general, (National Institute of
Standards and Technology, Gaithersburg, MD), NIST Special Publication (SP) 800-57 Part 1, Rev. 5 [or
as amended]. https://doi.org/10.6028/NIST.SP.800-57pt1r5.
[10] Lyubashevsky V (2009) Fiat-Shamir with aborts: Applications to lattice and factoring-based signa-
tures. Advances in Cryptology – ASIACRYPT 2009, ed Matsui M (Springer Berlin Heidelberg, Berlin,
Heidelberg), pp 598–616. https://doi.org/10.1007/978-3-642-10366-7_35.
[11] Lyubashevsky V (2012) Lattice signatures without trapdoors. EUROCRYPT (Springer), Lecture Notes
in Computer Science, Vol. 7237, pp 738–755. https://doi.org/10.1007/978-3-642-29011-4_43.
[13] Bai S, Galbraith SD (2014) An improved compression technique for signatures based on learning with
errors. Topics in Cryptology – CT-RSA 2014, ed Benaloh J (Springer International Publishing, Cham),
pp 28–47. https://doi.org/10.1007/978-3-319-04852-9_2.
47
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
[14] 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.110
9/SP40001.2021.00093.
[15] Regev O (2005) On lattices, learning with errors, random linear codes, and cryptography. Proceedings
of the Thirty-Seventh Annual ACM Symposium on Theory of Computing STOC ’05 (Association for
Computing Machinery, New York, NY, USA), p 84–93. https://doi.org/10.1145/1060590.1060603.
[16] Kiltz E, Lyubashevsky V, Schaffner C (2018) A concrete treatment of Fiat-Shamir signatures in the
quantum random-oracle model. Advances in Cryptology – EUROCRYPT 2018, eds Nielsen JB, Rijmen
V (Springer International Publishing, Cham), pp 552–586. https://doi.org/10.1007/978-3-319-78372
-7_18.
[17] Barker E, Barker W (2019) Recommendation for key management: Part 2 - best practices for key
management organizations, National Institute of Standards and Technology, Gaithersburg, MD. NIST
Special Publication (SP) 800-57 Part 2, Rev. 1. https://doi.org/10.6028/NIST.SP.800-57pt2r1.
[18] Barker E, Dang Q (2019) Recommendation for key management: Part 3 - application-specific key
management guidance, National Institute of Standards and Technology, Gaithersburg, MD. NIST
Special Publication (SP) 800-57 Part 3, Rev. 1. http://doi.org/10.6028/NIST.SP.800-57pt3r1.
[19] Barker E, Kelsey J (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.
[20] Sönmez Turan M, Barker E, Kelsey J, McKay K, Baish M, Boyle M (2018) Recommendation for the
entropy sources used for random bit generation, (National Institute of Standards and Technology,
Gaithersburg, MD), NIST Special Publication (SP) 800-90B. https://doi.org/10.6028/NIST.SP.800-90B.
[21] Barker E, Kelsey J, McKay K, Roginsky A, Turan MS (2024) 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.
[22] Bruinderink LG, Pessl P (2018) Differential fault attacks on deterministic lattice signatures. IACR
Transactions on Cryptographic Hardware and Embedded Systems (3):21–43. https://doi.org/10.131
54/tches.v2018.i3.21-43.
[23] Poddebniak D, Somorovsky J, Schinzel S, Lochter M, Rösler P (2018) Attacking deterministic signature
schemes using fault attacks. 2018 IEEE European Symposium on Security and Privacy (EuroS&P)
(IEEE), pp 338–352. https://doi.org/10.1109/EuroSP.2018.00031.
[24] Samwel N, Batina L, Bertoni G, Daemen J, Susella R (2018) Breaking ed25519 in wolfssl. Topics in
Cryptology–CT-RSA 2018: The Cryptographers’ Track at the RSA Conference 2018, San Francisco, CA,
USA, April 16-20, 2018, Proceedings (Springer), pp 1–20. https://doi.org/10.1007/978-3-319-76953
-0_1.
[25] Kelsey J, Chang S, Perlner R (2016) SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and Parallel-
Hash, (National Institute of Standards and Technology, Gaithersburg, MD), NIST Special Publication
(SP) 800-185 [or as amended]. https://doi.org/10.6028/NIST.SP.800-185.
[26] National Institute of Standards and Technology (2016) Submission requirements and evaluation
criteria for the post-quantum cryptography standardization process. Available at https://csrc.nist.go
48
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
v/CSRC/media/Projects/Post-Quantum-Cryptography/documents/call-for-proposals-final-dec-201
6.pdf.
[27] Alagic G, Apon D, Cooper D, Dang Q, Dang T, Kelsey J, Lichtinger J, Liu YK, Miller C, Moody D, Peralta R,
Perlner R, 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) 8413. https://doi.org/10.6028/NIST.IR.8413-upd1.
[28] Avanzi R, Bos J, Ducas L, Kiltz E, Lepoint T, Lyubashevsky V, Schanck JM, Schwabe P, Seiler G,
Stehlé D (2020) CRYSTALS-Kyber algorithm specifications and supporting documentation, 3rd
Round submission to the NIST’s post-quantum cryptography standardization process. Available
at https://csrc.nist.gov/Projects/post-quantum-cryptography/post-quantum-cryptography-standar
dization/round-3-submissions.
[29] Housley R (2009) Cryptographic Message Syntax (CMS), Internet Engineering Task Force (IETF) request
for comments (RFC) 5652, https://doi.org/10.17487/RFC5652.
[30] Schnorr C (1990) Efficient identification and signatures for smart cards. Advances in Cryptology —
CRYPTO’ 89 Proceedings, ed Brassard G (Springer New York, New York, NY), pp 239–252. https:
//doi.org/10.1007/0-387-34805-0_22.
[31] Josefsson S, Liusvaara I (2017) Edwards-Curve Digital Signature Algorithm (EdDSA), RFC 8032. https:
//doi.org/10.17487/RFC8032.
[34] Mattsson (on behalf of Sönke Jendral) JP (2024) Dilithium hint unpacking. Available at https://grou
ps.google.com/a/list.nist.gov/g/pqc-forum/c/TQo-qFbBO1A/m/sLjseYlSAwAJ.
49
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Suppose that two integers 𝑢 and 𝑣 modulo 𝑞 are in Montgomery form. Their product modulo 𝑞 is
𝑐 = 𝑢 ⋅ 𝑣 ⋅ 2−32 , which is also in Montgomery form. If the integer product of 𝑢 and 𝑣 does not overflow a
64-bit signed integer, then one can compute 𝑐 by first performing the integer multiplication 𝑢 ⋅ 𝑣 and then
“reducing” the product by multiplying by 2−32 modulo 𝑞. This last operation can be done efficiently as
follows.
The Montgomery_Reduce function takes an integer 𝑎 with absolute value at most 231 𝑞 as input. It returns
an integer 𝑟 such that 𝑟 = 𝑎 ⋅ 2−32 mod 𝑞. The output is in Montgomery form with multiplier 232 mod 𝑞.
An implementation would typically input a 64-bit input and return a 32-bit output. The “modulo 232 ”
operation simply extracts the 32 least significant bits of a 64-bit value. The value (𝑎 − 𝑡 ⋅ 𝑞) on line 3 is an
integer divisible by 232 . Therefore, the division consists of simply taking the most significant 32 bits of a
64-bit value. Extracting the four low- or high-order bytes is often done using typecasting.
Algorithm 49 MontgomeryReduce(𝑎)
Computes 𝑎 ⋅ 2−32 mod 𝑞.
Input: Integer 𝑎 with −231 𝑞 ≤ 𝑎 ≤ 231 𝑞.
Output: 𝑟 ≡ 𝑎 ⋅ 2−32 mod 𝑞.
1: QINV ← 58728449 ▷ the inverse of 𝑞 modulo 232
2: 𝑡 ← ((𝑎 mod 232 ) ⋅ QINV) mod 232
3: 𝑟 ← (𝑎 − 𝑡 ⋅ 𝑞)/232
4: return 𝑟
With this algorithm, the modular product of 𝑎 and 𝑏 is 𝑐 = Montgomery_Reduce(𝑎 ⋅ 𝑏), where 𝑎, 𝑏, and 𝑐
are in Montgomery form. The return value of the algorithm is not necessarily less than 𝑞 in absolute value,
but it is less than 2𝑞 in absolute value. This is not a concern in practice since the objective of Montgomery
Multiplication is to efficiently work with modular values that fit in a 32-bit register. If necessary, the result
can be normalized to an integer in (−𝑞, 𝑞) using a comparison and an integer addition.
Converting an integer modulo 𝑞 to Montgomery form by multiplying by 232 modulo 𝑞 is an expensive
operation. When a sequence of modular operations is to be performed, the operands are converted once
to Montgomery form. The operations are then performed, and the factor 232 is extracted from the final
result.
13
This section does not distinguish between different versions of the “mod” operator. There are three such versions
of “𝑥 = 𝑎 modulo 𝑞”: i) 𝑥 ∈ [0, 𝑞 − 1]; ii) 𝑥 ∈ [−⌈𝑞/2⌉, ⌊𝑞/2⌋] ; iii) 𝑥 ∈ [−𝑞 + 1, 𝑞 − 1]. The last version
corresponds to the ‶ %″ operator in most programming languages.
50
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
The values 𝜁 BitRev8 (𝑘) mod 𝑞 for 𝑘 = 1, … , 255 used in the NTT Algorithms 41 and 42 may be pre-computed
and stored in an array zetas[1..255]. This table of zetas is given below.
zetas[0..255] = {
51
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
Table 3. While loop and XOF output limits for a 2−256 or less probability of failure
Implementations may limit the number of iterations of a while loop or the number of bytes drawn from
the XOF to not exceed the maximum values in Table 3. If this option is used and the maximum number of
iterations or XOF output bytes is exceeded, the algorithm shall destroy all intermediate results. If a return
value or exception is produced, it shall be the same for any execution in which the maximum number of
iterations or output bytes is exceeded.
There is essentially no performance penalty for using a larger than necessary limit, as the limit will only
be reached on a faulty execution of the loop. Because of this, limits were chosen that lower-bound the
probability of reaching them to 2−256 .
ML-DSA.Sign_internal
Table 1 contains the expected repetitions in the rejection sampling loop of ML-DSA.Sign_internal. These
are 4.25, 5.1, and 3.85 for Categories 2, 3, and 5, respectively. Therefore, the probability that the number
𝑛 5.1−1 𝑛
of repetitions exceeds 𝑛 is less than or equal to ( 5.1−1
5.1 ) for all categories. Solving ( 5.1 ) ≤ 2
−256
yields 𝑛 = 814.
RejBoundedPoly
Let 𝑋 be the number of coefficients generated in 𝑛 iterations of the while loop of RejBoundedPoly15 .
9 15 9
Then 𝑋 is 𝐵𝑖𝑛𝑜𝑚𝑖𝑎𝑙(2𝑛, 𝜃), where 𝜃 is either 16 or 16 , depending on the parameter 𝜂. For 𝜃 = 16 ,
the probability that fewer than 256 coefficients are generated in 481 iterations of the main loop in
RejBoundedPoly is less than 2−256 . Each iteration consumes one byte of output from H.
14
RejBoundedPoly, RejNTTPoly, and SampleInBall use the incremental APIs described in Section 3.7 in order to
extract the amount of output needed from the XOFs, given that the amount needed is not known in advance.
15
Note that 0, 1, or 2 coefficients are generated in each iteration.
52
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
RejNTTPoly
The number of valid coefficients generated in 𝑛 calls to G.Squeeze in RejNTTPoly is 𝐵𝑖𝑛𝑜𝑚𝑖𝑎𝑙(𝑛, 2−23 𝑞).
It follows that after 298 calls, the probability of failure is less than 2−256 . Each iteration consumes three
bytes of output from G.
SampleInBall
Step 9 in SampleInBall is executed every time a pseudorandom byte is greater than a value 𝑖 in the range
[256 − 𝜏 , 255]. The parameter 𝜏 is 39, 49, and 60 for categories 2, 3, and 5, respectively. Therefore, the
probability that this step is executed more than 𝑛 times in a single iteration of the for loop is less than or
59 𝑛 𝜏 𝑛 59 𝑛
equal to ( 256 ) ≤ ( 256 ) . Solving ( 256 ) ≤ 2−256 yields a bound of 𝑛 = 121 for the while loop on step
8 of SampleInBall. Each iteration consumes one byte of output from H.
Each call to SampleInBall extracts eight bytes from H and then performs 𝜏 iterations of the for loop, each
of which extracts an indeterminate amount of data from H. The probability that more than 𝑛 bytes of
output will be required from H during an execution of SampleInBall for a given value of 𝜏 is
⎧ 1 if 𝑛 ≤ 8
{
𝑃 (𝑛, 𝜏 ) = ⎨ 0 if 𝜏 = 1 and 𝑛 > 8 .
{ ( 257−𝜏 ) 𝑃 (𝑛 − 1, 𝜏 − 1) + ( 𝜏−1 ) 𝑃 (𝑛 − 1, 𝜏 ) if 𝜏 > 1 and 𝑛 > 8
⎩ 256 256
𝑃 (𝑛, 60) is less than 2−256 when 𝑛 is 221 or greater. Implementations may limit the number of bytes
extracted from H to 𝑛 ≥ 221. Such implementations must stop the execution of SampleInBall, return a
constant that represents an error and no other output, and destroy all intermediate results after 𝑛 bytes
of output have been consumed.
53
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
D.1 Differences Between Version 3.1 and the Round 3 Version of CRYSTALS-
DILITHIUM
The lengths of the variables 𝜌′ (private random seed) and 𝜇 (message representative) in the signing
algorithm were increased from 384 to 512 bits. The increase in the length of 𝜇 corrects a security flaw
that appeared in the third-round submission, where a collision attack against SHAKE256 with a 384-bit
output would make it so that parameters targeting NIST security strength category 5 could only meet
category 4 [32].
Additionally, the length of the variable 𝑡𝑟 (the hash of the public key) was reduced from 384 to 256 bits.
In key generation, the variable 𝜍 was relabeled as 𝜌′ and increased in size from 256 bits to 512 bits.
54
FIPS 204 MODULE-LATTICE-BASED DIGITAL SIGNATURE STANDARD
that call an internal function corresponding to the signing or verification functions from the draft FIPS.
Domain separation is included in the input to the internal function (see Algorithms 2, 3, 4, 5, 7, and 8).
To simplify APIs and for testing purposes, this document also introduced a similar external/internal split
for key generation (see Algorithms 1 and 6), but this is a purely editorial change, as the external key
generation algorithm is functionally equivalent to the key-generation algorithm from the draft FIPS.
Finally, to offer misuse resistance against the possibility that keys for different parameter sets might be
expanded from the same seed [35], domain separation was added to line 1 of Algorithm 6.
55