diff --git a/docs/cryptodoc/src/05_08_ml_dsa.rst b/docs/cryptodoc/src/05_08_ml_dsa.rst index e18a6041..b50bd30a 100644 --- a/docs/cryptodoc/src/05_08_ml_dsa.rst +++ b/docs/cryptodoc/src/05_08_ml_dsa.rst @@ -46,62 +46,223 @@ the commitment and the message to be signed. .. table:: ML-DSA Components and File Locations - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | Component | Source Location | Purpose | Section in [FIPS-204]_ | - +==========================================================+========================================================================================+================================================================+==========================+ - | :ref:`Types ` | :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_types.h` | Strong Types | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | :ref:`Constants ` | :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_constants.h` | Parameter set instantiation | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | :ref:`Polynomials ` | :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_polynomial.h` | Polynomials, Structures on Polynomials and Operations | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | :ref:`Algorithms ` | :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.h` | Encoding, Sampling, Key Expansion, Hint Generation, Rounding | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | :ref:`Symmetric Primitives ` | :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_symmetric_primitives.h` | ML-DSA abstractions for PRFs, XOFs, Hashes, and KDFs | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | :ref:`Internal Keys ` | :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_keys.h` | Internal key representation and serialization | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | :ref:`ML-DSA Implementation ` | :srcref:`[src/lib/pubkey/dilithium/ml_dsa]/ml_dsa_impl.h` | Functional disambiguation to (also provided) Dilithium | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ - | :ref:`ML-DSA ` | :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium.h` | Public ML-DSA API | TBD | - +----------------------------------------------------------+----------------------------------------------------------------------------------------+----------------------------------------------------------------+--------------------------+ + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | Component | Purpose | [FIPS-204]_ | + +=======================================================================================================================================================+================================================================+===============+ + | :ref:`Types ` (:srcref:`src <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_types.h>`) | Strong Types | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | :ref:`Constants ` (:srcref:`src <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_constants.h>`) | Parameter set instantiation | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | :ref:`Polynomials ` (:srcref:`src <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_polynomial.h>`) | Polynomials, Structures on Polynomials and Operations | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | :ref:`Algorithms ` (:srcref:`src <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.h>`) | Encoding, Sampling, Key Expansion, Hint Generation, Rounding | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | :ref:`Symmetric Primitives ` (:srcref:`src <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_symmetric_primitives.h>`) | ML-DSA abstractions for PRFs, XOFs, Hashes, and KDFs | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | :ref:`Internal Keys ` (:srcref:`src <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_keys.h>`) | Internal key representation and serialization | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | :ref:`ML-DSA Implementation ` (:srcref:`src <[src/lib/pubkey/dilithium/ml_dsa]/ml_dsa_impl.h>`) | Functional disambiguation to (also provided) Dilithium | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ + | :ref:`ML-DSA ` (:srcref:`src <[src/lib/pubkey/dilithium/dilithium_common]/dilithium.h>`) | Public ML-DSA API | TBD | + +-------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------------------------------------------------+---------------+ .. _pubkey/ml_dsa/types: Strong Types ^^^^^^^^^^^^ +ML-DSA uses strong types and type aliases to represent the various value +types involved in the algorithm. This approach binds the semantic meaning of +values to their types, resulting in a more robust interface and self-documenting +code. Type aliases are defined for ML-DSA polynomials, polynomial vectors, and +polynomial matrices, as well as their NTT representations. All bitstrings, +including various hash values, random seeds, and others, are encapsulated as +strong types. + .. _pubkey/ml_dsa/constants: Paramter Instantiations ^^^^^^^^^^^^^^^^^^^^^^^ +Botan's ``DilithiumConstants`` class contains all parameters and constants +outlined in Section 4 of [FIPS-204]_ (see :ref:`pubkey/ml_dsa/params`). +Additionally, the class contains parameters implicitly derived from these +constants, such as key and ciphertext sizes, along with various intermediate +value sizes required within internal algorithms. + +Also, this class contains the theoretical XOF-bounds outlined in Appendix C of +[FIPS-204]_ used as a guard rail for the various rejection sampling operations +within the ML-DSA implementation. + .. _pubkey/ml_dsa/polynomials: Polynomial Operations ^^^^^^^^^^^^^^^^^^^^^ +ML-DSA relies extensively on polynomials within the polynomial ring :math:`R_q`, +utilizing vectors and matrices of polynomials, both inside and outside the NTT +domain. Botan uses :ref:`strong types ` to distinguish +polynomials and polynomial vectors as ``DilithiumPoly`` and +``DilithiumPolyVec``, as well as their NTT counterparts ``DilithiumPolyNTT`` and +``DilithiumPolyVecNTT``. Matrices only appear in the NTT domain and are +represented by the class ``DilithiumPolyMatNTT``. + +ML-KEM, as defined in [FIPS-202]_, also employs polynomials, leading to shared +polynomial logic between the two algorithms. This shared logic is located in +:srcref:`[src/lib/pubkey]/pqcrystals/pqcrystals.h`, encompassing common +operations on vectors and matrices, as well as algorithm-independent operations +like polynomial addition and subtraction. The ML-DSA specific logic implemented +in :srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_polynomial.h` +supplements this construction by including the NTT (Algorithm 41 of [FIPS-204]_) +and inverse NTT (Algorithm 42 of [FIPS-204]_) operations, along with NTT +polynomial multiplication (Algorithms 45 [FIPS-204]_). + +Due to this type-based construction, the C++ compiler can detect specific +implementation issues statically. For instance, the polynomial +multiplication operation is only defined for the ``PolyVecNTT`` type. Misuse +would result in a compile-time error. + +Botan utilizes Montgomery as well as Barrett reduction and conditional addition +of :math:`q`, for modular reduction and handling of negative values, depending +on the expected result range of certain operations. Those operations are +explicitly applied in the implementation as needed. + .. _pubkey/ml_dsa/algorithms: Internal Algorithms ^^^^^^^^^^^^^^^^^^^ +The ``Dilithium_Algos`` namespace includes a variety of internal functions to +support the primary algorithm. Table :ref:`pubkey/ml_dsa/algos` offers a summary +of those functions that are exposed to the rest of the implementation. The +:srcref:`[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp` +contains additional functions that are used within this module only, such as the +encoding functionality from [FIPS-204]_ Section 7.1. + +.. _pubkey/ml_dsa/algos: + +.. table:: ML-DSA Algorithms Overview + + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | Function | Description | [FIPS-204]_ | + +=======================================================================================================================================+============================================================================================+=============+ + | :srcref:`encode_public_key <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:327|encode_public_key>` | Byte encoding of a public key | 7.2 A. 22 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`decode_public_key <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:345|decode_public_key>` | Decoding a public key from bytes | 7.2 A. 23 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`encode_keypair <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:368|encode_keypair>` [#dilithium_comp]_ | Byte encoding of a private key | 7.2 A. 24 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`decode_keypair <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:409|decode_keypair>` [#dilithium_comp]_ | Decoding a private key from bytes | 7.2 A. 25 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`encode_signature <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:474|encode_signature>` | Byte encoding of a signature | 7.2 A. 26 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`decode_signature <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:493|decode_signature>` | Decoding a signature from bytes | 7.2 A. 27 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`encode_commitment <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:518|encode_commitment>` | Byte encoding of a commitment | 7.2 A. 28 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`sample_in_ball <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:532|sample_in_ball>` | Sample a challenge from the commitment hash | 7.3 A. 29 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`expand_keypair <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:665|expand_keypair>` | Expand a private key from a seed :math:`\xi` | 6.1 A. 6 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`expand_A <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:695|expand_A>` | Expand matrix :math:`A` from a seed :math:`\rho` | 7.3 A. 32 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`expand_s <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:708|expand_s>` | Expand vectors :math:`s1` and :math:`s2` from a seed :math:`\rho` | 7.3 A. 33 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`expand_mask <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:728|expand_mask>` | Samples a vector :math:`y` from a seed :math:`\rho'` and a nonce :math:`\kappa` | 7.3 A. 34 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`decompose <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:819|decompose>` | Decompose coefficients in a vector :math:`w` into high and low bits | 7.4 A. 36 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`make_hint <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:843|make_hint>` | Allows the signer to compress the signature | 7.4 A. 39 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`use_hint <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:918|use_hint>` | Lets the verifier decompress the signature | 7.4 A. 40 | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + | :srcref:`infinity_norm_within_bound <[src/lib/pubkey/dilithium/dilithium_common]/dilithium_algos.cpp:936|infinity_norm_within_bound>` | Given vector :math:`v` and :math:`bound`, validates that :math:`\|v\|_{\infty} \geq bound` | n/a | + +---------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------+-------------+ + +.. [#dilithium_comp] The private key encoding and decoding functions are used + for the legacy support of Dilithium (round 3) only. Botan's ML-DSA + implementation exclusively store its private keys as the secret seed + :math:`\xi`. + .. _pubkey/ml_dsa/primitives: Symmetric Primitives ^^^^^^^^^^^^^^^^^^^^ +This module provides an interface to the symmetric primitives required to +implement ML-DSA: namely XOFs, hash functions and KDFs. + +To allow sharing significant portions of the ML-DSA implementation with the +pre-standard Dilithium and Dilithium-AES algorithms that Botan currently keeps +supporting, these primitives are accessible via the polymorphic base classes +:srcref:`Dilithium_Symmetric_Primitives_Base +`, +:srcref:`DilithiumXOF +`, +and :srcref:`DilithiumMessageHash +`. + +The concrete implementations relevant for ML-DSA may +be found in :srcref:`[src/lib/pubkey/dilithium]/ml_dsa/ml_dsa_impl.h` and +:srcref:`[src/lib/pubkey/dilithium/dilithium_common/dilithium_shake]/dilithium_shake_xof.h`. + .. _pubkey/ml_dsa/keys: Internal Key Representation ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The :srcref:`Dilithium_PublicKeyInternal +` +and :srcref:`Dilithium_PrivateKeyInternal +` +classes are the internal representation of the ML-DSA key pair in expandedd form. + +Additionally, the :srcref:`Dilithium_Keypair_Codec +` +serves as a customization point for the key encoding and decoding functions that +differ between ML-DSA (:math:`\xi` only) and Dilithium (round 3) (partially +expanded key format as specified in [FIPS-204]_). By *always* expanding the +private key from the secret seed :math:`\xi`, sanity checks during decoding of +the key pair can be omitted. + .. _pubkey/ml_dsa/ml_dsa_impl: ML-DSA Specifics ^^^^^^^^^^^^^^^^ +This module provides concrete ML-DSA specific implementations for the +customization points outlined in :ref:`pubkey/ml_dsa/primitives` and +:ref:`pubkey/ml_dsa/keys`. Namely: + + * :srcref:`ML_DSA_Expanding_Keypair_Codec ` + Implements encoding and decoding of ML-DSA private keys by serializing the + private seed :math:`\xi` and/or expanding the deserialized seed into the + private key representation outlined in :ref:`pubkey/ml_dsa/keys`. + * :srcref:`ML_DSA_MessageHash ` + Implements the transformation of the user-provided message :math:`M` into + the message representation :math:`\mu`. This includes the incorporation of + the domain separations outlined in [FIPS-204]_ Sectoin 5.2 Algorithm 2. + * :srcref:`ML_DSA_Symmetric_Primitives + ` + Implements the ML-DSA specific symmetric primitives based on the specified + SHAKE-based XOFs, the optional hedged randomization of :math:`H(K \| rnd \| \mu)`, + and the domain separator for expanding :math:`\rho`, :math:`\rho'`, and + :math:`K` from the private seed :math:`\xi`. + .. _pubkey/ml_dsa/ml_dsa_api: Public API ^^^^^^^^^^ + +The :srcref:`Dilithium_PublicKey +` +and :srcref:`Dilithium_PrivateKey +` +classes serve as Botan's public API for public and private ML-DSA keys, +respectively. The :srcref:`DilithiumMode +` class +is used to select the desired parameter set. + +New applications that do not rely on the pre-standard Dilithium round 3 +implementations are strongly advised to use the type aliases for ML-DSA defined +in :srcref:`[src/lib/pubkey/dilithium/ml_dsa]/ml_dsa.h`.