From 62d9c3b2da542c0855a778c418042feb1af84126 Mon Sep 17 00:00:00 2001 From: Fabian Albert Date: Wed, 14 Feb 2024 15:20:13 +0100 Subject: [PATCH 1/6] Classic McEliece Crypto Documentation --- docs/cryptodoc/src/05_00_pubkey.rst | 1 + docs/cryptodoc/src/05_10_cmce.rst | 469 ++++++++++++++++++++++++ docs/cryptodoc/src/90_bibliographie.rst | 17 + 3 files changed, 487 insertions(+) create mode 100644 docs/cryptodoc/src/05_10_cmce.rst diff --git a/docs/cryptodoc/src/05_00_pubkey.rst b/docs/cryptodoc/src/05_00_pubkey.rst index 02ef2f0e..803e0772 100644 --- a/docs/cryptodoc/src/05_00_pubkey.rst +++ b/docs/cryptodoc/src/05_00_pubkey.rst @@ -22,3 +22,4 @@ encapsulation and decapsulation or the key exchange mechanism. 05_07_dilithium 05_08_kyber 05_09_frodokem + 05_10_cmce diff --git a/docs/cryptodoc/src/05_10_cmce.rst b/docs/cryptodoc/src/05_10_cmce.rst new file mode 100644 index 00000000..d0249a80 --- /dev/null +++ b/docs/cryptodoc/src/05_10_cmce.rst @@ -0,0 +1,469 @@ +.. _pubkey/cmce: + +Classic McEliece +================ + +Botan implements the Classic McEliece Key Encapsulation Mechanism (KEM) as defined in the +Round 4 NIST submission [CMCE-R4]_ and the ClassicMcEliece ISO Draft [CMCE-ISO]_. It +supports all parameter sets defined in both documents, listed +in Table :ref:`Supported Classic McEliece Parameter Sets `. + +.. _pubkey/cmce/parameter_table: + + +.. table:: Supported Classic McEliece parameter sets (see [CMCE-ISO]_ Section 10 and [CMCE-R4]_ Section 7). ```` and ```` indicate that sets with and without f and pc are supported. + + +----------------------------+-----------+-----------+-----------+----------------------------+---------------------------------+ + | Parameter Set | :math:`m` | :math:`n` | :math:`t` | :math:`f(z)` | :math:`F(y)` | + +============================+===========+===========+===========+============================+=================================+ + | ``mceliece348864`` | 12 | 3488 | 64 | :math:`z^{12}+z^3+1` | :math:`y^{64}+y^3+y+z` | + +----------------------------+-----------+-----------+-----------+----------------------------+---------------------------------+ + | ``mceliece460896`` | 13 | 4608 | 96 | :math:`z^{13}+z^4+z^3+z+1` | :math:`y^{96}+y^{10}+y^9+y^6+1` | + +----------------------------+-----------+-----------+-----------+----------------------------+---------------------------------+ + | ``mceliece6688128`` | 13 | 6688 | 128 | :math:`z^{13}+z^4+z^3+z+1` | :math:`y^{128}+y^7+y^2+y+1` | + +----------------------------+-----------+-----------+-----------+----------------------------+---------------------------------+ + | ``mceliece6960119`` | 13 | 6960 | 119 | :math:`z^{13}+z^4+z^3+z+1` | :math:`y^{119}+y^8+1` | + +----------------------------+-----------+-----------+-----------+----------------------------+---------------------------------+ + | ``mceliece8192128`` | 13 | 8192 | 128 | :math:`z^{13}+z^4+z^3+z+1` | :math:`y^{128}+y^7+y^2+y+1` | + +----------------------------+-----------+-----------+-----------+----------------------------+---------------------------------+ + +.. _pubkey/cmce/key_generation: + +Algorithm Internals +------------------- + +The implementation of Classic McEliece is organized based on the algorithm's +operations and structures. Table :ref:`Classic McEliece components +` shows an overview of the components and +their corresponding file locations. Classic McEliece, like all Key Encapsulation +Mechanisms (KEMs), consists of three main algorithms: Key generation, key +encapsulation, and key decapsulation. In the case of Classic McEliece, the key +generation process involves creating a field ordering and an irreducible +polynomial. These two components define the randomly chosen Goppa code, the +secret information stored in the private key. A parity check matrix in +systematic form is derived from the Goppa code to generate the public key used +for encapsulation. More detailed information about these processes can be found +in the following sections. + +.. _pubkey/cmce/component_table: + +.. table:: Classic McEliece components and file locations. Its files are located at :srcref:`src/lib/pubkey/classic_mceliece/`. + :widths: 21 29 40 + + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | Component | File | Purpose | + +========================================================+==================================================================+============================================================================+ + | :ref:`Types ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_types.h` | Strong types | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Galois Field Arithmetic ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_gf.h` | Galois field data structure and logic | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Field Ordering ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_field_ordering.h`| Field ordering creation and Beneš network computation | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Polynomial Arithmetic ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_poly.h` | Polynomial data structure, logic, and minimal polynomial creation | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Bit Vector Arithmetic ` | :srcref:`src/lib/utils/bitvector.h` | Representation of bit-vectors and bit-vector arithmetic | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Matrix Operations ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_matrix.h` | Binary matrix data structure, creation, and systematic form transformation | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Key Pair ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_keys_internal.h` | Key pair container and key generation | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Key Encapsulation ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_encaps.h` | Encapsulation logic | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Key Decapsulation ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_decaps.h` | Decapsulation logic, including Berlekamp's algorithm | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Parameter Set ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_parameter_set.h` | Parameter set enum, parsing, and serialization | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | :ref:`Parameters ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_parameters.h` | Classic McEliece parameter container | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + | Classic McEliece | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce.h` | Classic McEliece public and private key interface | + +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ + + +.. _pubkey/cmce/types: + +Types +^^^^^ + +In implementing Botan's Classic McEliece, strong types are utilized to +ensure the correct data usage within the code. These strong types are +fundamental to separate the domain of the various byte sequences involved in +Classic McEliece, such as multiple types of seeds, random byte sequences for different +algorithms, and bit-vectors with different semantic contexts. Specific integers, +like raw Galois Field elements and their modulus, are +also represented as strong types. This reliance on strong types is similar to using them +in :ref:`SPHINCS+ ` for +similar reasons. The Classic McEliece implementation enhances readability, +clarity, and reliability by employing strong types. + + +.. _pubkey/cmce/gf: + +Galois Field Arithmetic +^^^^^^^^^^^^^^^^^^^^^^^ + +The Goppa code is based on the Galois field (GF) :math:`\mathbb{F}_{q}`, where :math:`q=2^m`. +To represent GF elements, we utilize the class ``Classic_McEliece_GF``. Each +element is defined by two polynomials: one defines its value, and the other +defines the modulus of the field. These values are represented as unsigned +integers. For example, the element :math:`z^3+z+1` is represented by the unsigned +integer ``0b1011``. + +The GF elements support various operations such as addition, multiplication, +and inversion. These operations are implemented in constant time for operands +within the same field. Multiplication is performed using a constant-time +schoolbook multiplication algorithm with a consecutive constant-time reduction. +Inversion is achieved using Fermat's little theorem: :math:`a^{-1} = a^{q-2}`. +For that, exponentiation is implemented using a simple square-and-multiply +algorithm. It is worth noting that square-and-multiply has no timing +side-channel vulnerabilities since the exponent remains constant for each field. + +.. _pubkey/cmce/field_ordering: + +Field Ordering +^^^^^^^^^^^^^^ + +Section 8.2 of [CMCE-ISO]_ defines the field ordering as a permutation +of elements in the Galois field :math:`\mathbb{F}_{q}`. This ordering is +required for generating a random sequence :math:`\alpha_0,...,\alpha_{n-1}` of distinct +:math:`\mathbb{F}_{q}` elements, which is necessary for creating the Goppa +code. Botan's ``Classic_McEliece_Field_Ordering`` serves as a container for the +field ordering and includes the algorithm to generate it. To sort the pairs +:math:`(a_i, i)` (as described in Step 3 of Section 8.2 in [CMCE-ISO]_), a +constant-time bitonic sort implementation is utilized. This sorting algorithm is +particularly suitable for sets with a power of two elements. + +Another vital role of the field ordering class is managing the Beneš network. +As Section 9.2.10 of [CMCE-ISO]_ outlines, the Beneš network stores the field +ordering as control bits in a compact form. Botan employs +a constant-time implementation of the ``controlbits`` algorithm presented in +Fig. 7.1 of [CBits]_ to create control bits, and the ``permutation`` algorithm +to reconstruct the field ordering from the control bits. The creation +algorithm also utilizes constant-time bitonic sorting. + + +.. _pubkey/cmce/poly: + +Polynomial Arithmetic +^^^^^^^^^^^^^^^^^^^^^ + +The Classic McEliece algorithm uses elements in the polynomial ring +:math:`\mathbb{F}_q [y]` in multiple places. The monic irreducible +polynomial defines the Goppa code, and performing decapsulation requires an +error locator polynomial. Botan's ``Classic_McEliece_Poly`` class is designed +to represent these polynomials. It consists of a vector of GF elements, which +serve as the polynomial coefficients. Additionally, this class provides +the necessary logic to evaluate the polynomial at a given point in +:math:`\mathbb{F}_q`. + +Polynomial arithmetic is required to obtain the monic irreducible polynomial +:math:`g` from a random element :math:`\beta \in \mathbb{F}_{q} [y]/F(y)`, as +described in Step 3 of Section 8.1 in [CMCE-ISO]_. This arithmetic +is implemented in the ``Classic_McEliece_Polynomial_Ring`` class, representing +the polynomial ring :math:`\mathbb{F}_{q} [y]/F(y)` and supporting the +multiplication of two polynomials. + +Following the recommendation in the implementors' guide Section 6.1 that +accompanies [CMCE-R4]_, the minimal polynomial is computed by finding a unique +solution to the equation :math:`g_0\beta^0 + ... + g_{t-1}\beta^{t-1} = \beta^t`. +A constant-time Gauss elimination algorithm is used to solve this equation. +The algorithm aborts if the solution is non-unique. The minimal polynomial +is then represented as a ``Classic_McEliece_Minimal_Polynomial`` object, which +includes logic for serialization and deserialization as described in +Section 9.2.9 of [CMCE-ISO]_. + + +.. _pubkey/cmce/bitvector: + +Bit Vector Arithmetic +^^^^^^^^^^^^^^^^^^^^^ + +Botan's ``bitvector`` class is a versatile tool for working with bits. +One such application is the Classic McEliece algorithm, where it handles +binary matrices, error vectors, code words, and the column selections in the private +key. The ``bitvector`` class provides a range of useful methods for these tasks. + +A ``bitvector`` can be dynamically initialized with any length. It can be created +from a vector of bytes and serialized back to it, as described in Section 9.2.1 +of [CMCE-ISO]_. The class allows for adding or removing bits, accessing and +manipulating individual bits, and obtaining specific properties of the vector, +such as the Hamming weight or checking if the vector is all-zero. Sub-vectors +can also be extracted from an existing ``bitvector``. + +Furthermore, the ``bitvector`` class supports binary operations between two vectors +of the same length, including AND, OR, and XOR. These operations are optimized +for performance, especially in the context of Classic McEliece. + +The design of the ``bitvector`` class prioritizes constant times, particularly +for Classic McEliece. The time taken for bit accesses and manipulations depends +only on the bit's position, not its value. Operations between two vectors +are also constant-time when the operands have the same length. The timing of +helper functions, such as the Hamming weight, is also implemented with +constant time in mind. + + +.. _pubkey/cmce/matrix: + +Matrix Operations +^^^^^^^^^^^^^^^^^ + +Classic McEliece's key generation algorithm utilizes its Goppa code, defined by a +field ordering and a monic irreducible polynomial, to create a binary parity +check matrix :math:`H` in systematic form. This matrix is represented by the +``Classic_McEliece_Matrix`` class. + +The class follows the process outlined in Section 7.2 of [CMCE-ISO]_ for matrix +creation. Initially, a binary :math:`mt \times n` matrix is created as +described in Steps 1 and 2 of Section 7.2.2. Each row of the matrix is +represented as a ``bitvector`` object. Subsequently, a constant-time Gauss +algorithm is applied to reduce the matrix to the systematic form :math:`H=(I_{mt}|T)`. +The algorithm achieves this by systematically applying XOR operations on pairs +of matrix rows, resulting in the identity matrix on the left. Finally, the +submatrix `T` is stored in the matrix object, mirroring its representation in +the public key specified in Section 9.2.7 of [CMCE-ISO]_. + +Classic McEliece instances with the suffix ``f`` employ a semi-systematic transformation +strategy, utilizing the parameters :math:`(\mu, \nu) = (32, 64)`, as described +in Section 7.2.3 of [CMCE-ISO]_. Following the recommendation in Section 6.1 of +the implementation guide accompanying [CMCE-R4]_, a Gauss algorithm is executed +to create an identity matrix for the first :math:`mt-\mu` rows. Subsequently, a +modified Gauss algorithm achieves a reduced row-echelon form for +the :math:`\mu \times \nu` submatrix at position :math:`(\mu, \mu)`. +This process determines the column selection, i.e., the indices of the non-zero +columns. As Section 7.2.3 Step 5 of [CMCE-ISO]_ outlines, the matrix's +columns and the field ordering are permuted according to the pivots. The main +Gauss algorithm concludes at this point, leaving the matrix in its modified +and systematic form. + +For encapsulation, the matrix :math:`H` is multiplied by an error vector +:math:`e`. This multiplication is performed by computing the parity of the +Hamming weight of :math:`e\ \textrm{XOR}\ r` for each row :math:`r` of :math:`H`. +Matrix creation and multiplication are implemented in constant time for matrices +with fixed dimensions. + + +.. _pubkey/cmce/keys_internal: + +Key Pair +^^^^^^^^ + +Botan's key pair for Classic McEliece consists of two classes: +``Classic_McEliece_PrivateKeyInternal`` and ``Classic_McEliece_PublicKeyInternal``. +As defined in Section 9.2.12, the private key stores the key generation seed, +column selection, monic irreducible polynomial, field ordering control bits, +and the seed for implicit rejection. On the other hand, the public key +contains the sub-matrix :math:`T` of the binary parity check matrix +:math:`H = (I_{mt}|T)`. + +The class ``Classic_McEliece_KeyPair_Internal`` holds both the private and public +keys and contains key generation method. Details are discussed in Section +:ref:`Key Generation `. + + +.. _pubkey/cmce/encaps_internal: + +Encapsulation Internals +^^^^^^^^^^^^^^^^^^^^^^^ + +The class ``Classic_McEliece_Encryptor`` implements Botan's key +encapsulation interface. Performing encapsulation requires two building blocks: +Fixed weight vector creation and error vector encoding. + +The algorithm described in Section 8.4 of [CMCE-ISO]_ is followed to create a +fixed weight error vector. Random elements :math:`d_0,...,d_{\tau-1}` are +generated, where the first :math:`t` elements smaller than :math:`n` are selected as +:math:`a_0,...,a_{t-1}`. It is important to note that selecting +:math:`d_i` elements for :math:`a_j` elements may leak through timing +side-channels. However, the content of these elements remains undisclosed, +preventing attackers from gaining helpful information from this side channel. + +Next, all possible pairs are compared to ensure that all elements of +:math:`a_0,...,a_{t-1}` are distinct. Finally, a binary error vector :math:`e` +is created with set bits at the locations of :math:`a_0,...,a_{t-1}`. This +creation process also considers constant times. + +For encoding, the parity check matrix :math:`H` is multiplied with :math:`e` as +Section :ref:`Matrix Operations ` describes. The +encapsulation algorithm used in Botan is outlined in Section +:ref:`Key Encapsulation `. + + +.. _pubkey/cmce/decaps_internal: + +Decapsulation Internals +^^^^^^^^^^^^^^^^^^^^^^^ + +The class ``Classic_McEliece_Decryptor`` in Botan is responsible for +key decapsulation. One of the crucial steps in the decapsulation algorithm of +Classic McEliece is the decoding subroutine described in Section 7.4 of +[CMCE-ISO]_. This subroutine is implemented based on the recommendations +provided in [McBits]_. The decoding process utilizes Berlekamp's algorithm for +Goppa decoding. + +To begin with, the code word :math:`C` that needs to be decoded is extended by +appending zeros. This results in a binary vector :math:`\nu = (C,0,\dots,0) \in \mathbb{F}_2^{n}`, +as Section 7.2 Step 1 of [CMCE-ISO]_ defines. Subsequently, the syndrome for +Berlekamp's method is computed from :math:`\nu`. The syndrome is a vector given by +:math:`\left( \sum\nolimits_{i} \frac{\nu_i\alpha_i^0}{g(\alpha_i)^2},\dots,\sum\nolimits_{i} \frac{\nu_i\alpha_i^{n-1}}{g(\alpha_i)^2} \right)`, +where :math:`\alpha_i` are the first :math:`n` field ordering elements and +:math:`g` is the Goppa polynomial. + +Next, the error locator polynomial :math:`\sigma` is computed using the +Berlekamp-Massey algorithm on the syndrome. The resulting polynomial has a +particular property concerning the error vector :math:`e` we search for. +Specifically, :math:`\sigma(\alpha_i) = 0` if and only if +:math:`e_i = 1`. By evaluating :math:`\sigma` at :math:`\alpha_0,\dots,\alpha_{n-1}`, +we can reconstruct the error vector :math:`e`. + +To ensure accurate decoding, Botan follows the recommendation in Section 6.3 of +the implementation guide of [CMCE-R4]_. It computes the syndrome for the error +vector :math:`e` and compares it with the syndrome for :math:`\nu`. If the +comparison holds and the weight of :math:`e` is equal to :math:`t`, we consider +the decoding successful. Otherwise, it is flagged as a failure. + +It is worth noting that the syndrome computation, Berlekamp-Massey algorithm, and +locator polynomial evaluation are implemented in constant time. Additionally, +the checks for the weight of :math:`e` and the syndrome comparison are designed +to avoid early abortion if any check fails. + + +.. _pubkey/cmce/params: + +Parameters +^^^^^^^^^^ + +The ``Classic_McEliece_Parameter_Set`` enum contains all instances of the +Classic McEliece algorithm listed in Table :ref:`Supported Classic McEliece +Parameter Sets `. These parameter sets serve as +the basis for deriving all the necessary parameters used within the algorithm. +They are collected in a ``Classic_McElice_Parameters`` object, which includes +all the parameters defined in the specifications [CMCE-ISO]_ and [CMCE-R4]_. +This object is passed to all algorithm components, ensuring consistent +parameter usage. + + +.. _pubkey/cmce/key_gen: + + +Key Generation +-------------- + +Classic McEliece key generation follows Section 8.3 of [CMCE-ISO]_ and is +implemented within the ``Classic_McEliece_KeyPair_Internal`` class. It works as +follows: + +.. admonition:: Classic McEliece Key Generation + + **Input:** + + - ``rng``: random number generator + + **Output:** + + - ``SK``, ``PK``: private and public key + + **Steps:** + + 1. Generate a random value ``seed`` using ``rng`` + 2. ``s, ordering_bits, irreducible_bits, next_seed = PRF(seed)`` + 3. | Create a field ordering ``field_ordering`` using ``ordering_bits`` + | On failure, set ``seed = next_seed`` and go to step 2 + + 4. | Create a monic irreducible polynomial ``g`` using ``irreducible_bits`` + | On failure, set ``seed = next_seed`` and go to step 2 + + 5. | Create a parity check matrix in systematic form ``H = (I_mt | T)`` using ``field_ordering`` and ``g``. Meanwhile, compute the column selection ``c`` + | On failure, set ``seed = next_seed`` and go to step 2 + + 6. ``SK = {seed, c, g, field_ordering, s}, PK = {T}`` + + **Notes:** + + - ``PRG`` is an application of ``SHAKE256`` with an input prefix byte 64. + The output length is ``n/8 + 4q + 2t + 32`` bytes. It is defined + in Section 9.1 of [CMCE-ISO]_. + - Only the first ``n`` elements of the field ordering are used to + create the parity check matrix. + - For instances with the suffix ``f``, the semi-systematic transformation + strategy is employed. In this case, ``field_ordering`` is updated to + reflect the column selection. + - To store the private and public keys as bytes, the respective entries are + serialized following the specifications of Section 9.2 of [CMCE-ISO]_. + + +.. _pubkey/cmce/encapsulation: + +Key Encapsulation +----------------- + +The Classic McEliece encapsulation procedure of Botan follows Section 8.5 of +[CMCE-ISO]_ and works as follows: + +.. admonition:: Classic McEliece Encapsulation + + **Input:** + + - ``PK = {T}``: public key + - ``rng``: random number generator + + **Output:** + + - ``encap_key``: ciphertext of shared key + - ``shared_key``: plaintext shared key + + **Steps:** + + 1. Generate a random error vector ``e`` of weight ``t`` using ``rng`` + 2. ``c0 = (I_mt | T) * e`` to encode ``e`` + 3. Depending on whether the parameter set includes plaintext confirmation (suffix ``pc``): + + a. **Without pc:** ``encap_key = c0`` + b. **With pc:** ``c1 = Hash(2, e)``, ``encap_key = c0 || c1`` + + 4. ``shared_key = Hash(1, e, encap_key)`` + + **Notes:** + + - ``Hash`` is an application of ``SHAKE256`` with 32 output bytes as defined + in Section 9.1 of [CMCE-ISO]_. + + +.. _pubkey/cmce/decapsulation: + +Key Decapsulation +----------------- + +The Classic McEliece decapsulation procedure of Botan follows Section 8.6 of +[CMCE-ISO]_ and works as follows: + +.. admonition:: Classic McEliece Decapsulation + + **Input:** + + - ``SK = {seed, c, g, field_ordering, s}``: secret key + - ``encap_key``: encapsulated key bytes + + **Output:** + + - ``shared_key``: shared key + + **Steps:** + + 1. Depending on whether the parameter set includes plaintext confirmation (suffix ``pc``): + + a. **Without pc:** ``c0 = encap_key`` + b. **With pc:** ``c0, c1 = encap_key``, split after ``ceil(m*t/8)`` bytes + + 2. | Decode ``c0`` to obtain ``e`` using Berlekamp's algorithm and set ``b = 1`` + | On failure set ``e = s`` and ``b = 0`` + + 3. | **Only for pc instances:** ``c1_p = Hash(2, e)`` + | If ``c1_p != c1`` set ``e = s`` and ``b = 0`` + + 4. ``shared_key = Hash(b, e, encap_key)`` + + **Notes:** + + - ``Hash`` is an application of ``SHAKE256`` with 32 output bytes as defined + in Section 9.1 of [CMCE-ISO]_. + - The assignments of ``e`` and ``b`` in steps 2 and 3 are implemented using + Botan's constant-time helper functions to ensure constant-time execution. diff --git a/docs/cryptodoc/src/90_bibliographie.rst b/docs/cryptodoc/src/90_bibliographie.rst index 56ca0d36..549a4d05 100644 --- a/docs/cryptodoc/src/90_bibliographie.rst +++ b/docs/cryptodoc/src/90_bibliographie.rst @@ -26,10 +26,23 @@ "Message verification and transmission error detection by block chaining", US Patent 4074066, 1976 +.. [CBits] Daniel J. Bernstein: + "Verified fast formulas for control bits for permutation networks", + 2020 + .. [CCM] U.S. DEPARTMENT OF COMMERCE/National Institute of Standards and Technology: "Recommendation for Block Cipher Modes of Operation: The CCM Mode for Authentication and Confidentiality", July 2007 +.. [CMCE-ISO] ISO Draft (2023): + Information security — Encryption algorithms — Part 1978: + Classic McEliece + +.. [CMCE-R4] Martin R. Albrecht, Daniel J. Bernstein, Tung Chou, Carlos Cid, Jan Gilcher, Tanja Lange, Varun Maram, Ingo von Maurich, Rafael Misoczki, Ruben Niederhagen, Kenneth G. Paterson, Edoardo Persichetti, Christiane Peters, Peter Schwabe, Nicolas Sendrier, Jakub Szefer, Cen Jung Tjhai, Martin Tomlinson, Wen Wang: + "Classic McEliece: Conservative Code-Based Cryptography: Cryptosystem Specification", + NIST PQC Challenge Round 4 Submission, 2022, + https://classic.mceliece.org/mceliece-spec-20221023.pdf + .. [Dilithium-R3] S. Bai, L. Ducas, E. Kiltz, T. Lepoint, V. Lyubashevsky, P. Schwabe, G. Seiler, D. Stehlé: "CRYSTALS-Dilithium Algorithm Specifications and Supporting Documentation (Version 3.1)", NIST PQC Challenge Round 3 Submission, 2021, @@ -125,6 +138,10 @@ A Chosen Ciphertext Attack on RSA Optimal Asymmetric Encryption Padding (OAEP) as Standardized in PKCS#1 v2.0. Crypto 2001 +.. [McBits] Daniel J. Bernstein, Tung Chou, Peter Schwabe: + "McBits: fast constant-time code-based cryptography", + 2015 + .. [NIST-OMAC] National Institute of Standards and Technology. OMAC: One-Key CBC MAC — Addendum. http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/omac/omac-ad.pdf From 8e3c58d96181ce2c9c2c3fa24cb9b9357800afef Mon Sep 17 00:00:00 2001 From: Fabian Albert Date: Wed, 6 Mar 2024 09:48:31 +0100 Subject: [PATCH 2/6] Apply review suggestions --- docs/cryptodoc/src/05_10_cmce.rst | 157 +++++++++++++----------- docs/cryptodoc/src/90_bibliographie.rst | 16 ++- 2 files changed, 98 insertions(+), 75 deletions(-) diff --git a/docs/cryptodoc/src/05_10_cmce.rst b/docs/cryptodoc/src/05_10_cmce.rst index d0249a80..d05cd664 100644 --- a/docs/cryptodoc/src/05_10_cmce.rst +++ b/docs/cryptodoc/src/05_10_cmce.rst @@ -6,7 +6,7 @@ Classic McEliece Botan implements the Classic McEliece Key Encapsulation Mechanism (KEM) as defined in the Round 4 NIST submission [CMCE-R4]_ and the ClassicMcEliece ISO Draft [CMCE-ISO]_. It supports all parameter sets defined in both documents, listed -in Table :ref:`Supported Classic McEliece Parameter Sets `. +in Table :ref:`Supported Classic McEliece parameter sets `. .. _pubkey/cmce/parameter_table: @@ -65,11 +65,11 @@ in the following sections. +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ | :ref:`Matrix Operations ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_matrix.h` | Binary matrix data structure, creation, and systematic form transformation | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ - | :ref:`Key Pair ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_keys_internal.h` | Key pair container and key generation | + | :ref:`Key Pair ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_keys_internal.h` | Internal key pair container and key generation | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ | :ref:`Key Encapsulation ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_encaps.h` | Encapsulation logic | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ - | :ref:`Key Decapsulation ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_decaps.h` | Decapsulation logic, including Berlekamp's algorithm | + | :ref:`Key Decapsulation ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_decaps.h` | Decapsulation and decoding | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ | :ref:`Parameter Set ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_parameter_set.h` | Parameter set enum, parsing, and serialization | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ @@ -91,7 +91,7 @@ Classic McEliece, such as multiple types of seeds, random byte sequences for dif algorithms, and bit-vectors with different semantic contexts. Specific integers, like raw Galois Field elements and their modulus, are also represented as strong types. This reliance on strong types is similar to using them -in :ref:`SPHINCS+ ` for +in other PQC algorithms for similar reasons. The Classic McEliece implementation enhances readability, clarity, and reliability by employing strong types. @@ -102,20 +102,22 @@ Galois Field Arithmetic ^^^^^^^^^^^^^^^^^^^^^^^ The Goppa code is based on the Galois field (GF) :math:`\mathbb{F}_{q}`, where :math:`q=2^m`. -To represent GF elements, we utilize the class ``Classic_McEliece_GF``. Each +Corresponding GF elements are represented by :math:`\mathbb{F}_{2}[z]/f(z)`, +which in Botan's implementation is realized via the class ``Classic_McEliece_GF``. Each element is defined by two polynomials: one defines its value, and the other -defines the modulus of the field. These values are represented as unsigned -integers. For example, the element :math:`z^3+z+1` is represented by the unsigned -integer ``0b1011``. +defines the modulus of the field (:math:`f` in [CMCE-ISO]_). These values are +represented as unsigned integers where the bit on position :math:`i` is set if the +:math:`i`-th coefficient is 1. For example, the element :math:`z^3+z+1` is represented by +the unsigned integer ``0b1011``. The GF elements support various operations such as addition, multiplication, and inversion. These operations are implemented in constant time for operands within the same field. Multiplication is performed using a constant-time -schoolbook multiplication algorithm with a consecutive constant-time reduction. -Inversion is achieved using Fermat's little theorem: :math:`a^{-1} = a^{q-2}`. +long multiplication algorithm with a consecutive constant-time reduction. +Inversion of an element :math:`a` is achieved using Fermat's little theorem: +:math:`a^{-1} = a^{q-2}`. For that, exponentiation is implemented using a simple square-and-multiply -algorithm. It is worth noting that square-and-multiply has no timing -side-channel vulnerabilities since the exponent remains constant for each field. +algorithm. .. _pubkey/cmce/field_ordering: @@ -130,14 +132,18 @@ code. Botan's ``Classic_McEliece_Field_Ordering`` serves as a container for the field ordering and includes the algorithm to generate it. To sort the pairs :math:`(a_i, i)` (as described in Step 3 of Section 8.2 in [CMCE-ISO]_), a constant-time bitonic sort implementation is utilized. This sorting algorithm is -particularly suitable for sets with a power of two elements. +particularly suitable for sets with a power of two elements. The sorted +:math:`a_i` are then transformed into elements from :math:`\mathbb{F}_{q}` as +described in the final Steps 4-6 of Section 8.2 in [CMCE-ISO]_. The class +stores the resulting elements :math:`\alpha_0,...,\alpha_{q-1}` and provides +accessors. Another vital role of the field ordering class is managing the Beneš network. As Section 9.2.10 of [CMCE-ISO]_ outlines, the Beneš network stores the field ordering as control bits in a compact form. Botan employs a constant-time implementation of the ``controlbits`` algorithm presented in -Fig. 7.1 of [CBits]_ to create control bits, and the ``permutation`` algorithm -to reconstruct the field ordering from the control bits. The creation +Fig. 7.1 of [CBits]_ to create control bits and the ``permutation`` algorithm +to reconstruct the field ordering from given control bits. The creation algorithm also utilizes constant-time bitonic sorting. @@ -146,29 +152,34 @@ algorithm also utilizes constant-time bitonic sorting. Polynomial Arithmetic ^^^^^^^^^^^^^^^^^^^^^ -The Classic McEliece algorithm uses elements in the polynomial ring -:math:`\mathbb{F}_q [y]` in multiple places. The monic irreducible -polynomial defines the Goppa code, and performing decapsulation requires an -error locator polynomial. Botan's ``Classic_McEliece_Poly`` class is designed -to represent these polynomials. It consists of a vector of GF elements, which -serve as the polynomial coefficients. Additionally, this class provides -the necessary logic to evaluate the polynomial at a given point in -:math:`\mathbb{F}_q`. +The Classic McEliece algorithm uses elements of the polynomial ring +:math:`\mathbb{F}_q [y]` in multiple places, which are represented as +elements in :math:`\mathbb{F}_q [y] / F(y)`. Botan's +``Classic_McEliece_Polynomial`` class is used for this purpose. +One key application of this class is creating and representing +the irreducible polynomial :math:`g` for the Goppa code. Additionally, it is +used to represent the error locator polynomial used in the decapsulation process. + +Internally, the polynomial class is composed of a vector of +``Classic_McEliece_GF`` elements, which act as the polynomial coefficients. +Also, the necessary functionality is provided to evaluate a +polynomial at a given point in :math:`\mathbb{F}_q`. Polynomial arithmetic is required to obtain the monic irreducible polynomial -:math:`g` from a random element :math:`\beta \in \mathbb{F}_{q} [y]/F(y)`, as +:math:`g` from a random seed, as described in Step 3 of Section 8.1 in [CMCE-ISO]_. This arithmetic is implemented in the ``Classic_McEliece_Polynomial_Ring`` class, representing the polynomial ring :math:`\mathbb{F}_{q} [y]/F(y)` and supporting the -multiplication of two polynomials. +multiplication of two ``Classic_McEliece_Poly`` polynomials. -Following the recommendation in the implementors' guide Section 6.1 that -accompanies [CMCE-R4]_, the minimal polynomial is computed by finding a unique +Following the recommendation of [CMCE-IMPL]_ Section 6.1, +the minimal polynomial is computed by finding a unique solution to the equation :math:`g_0\beta^0 + ... + g_{t-1}\beta^{t-1} = \beta^t`. -A constant-time Gauss elimination algorithm is used to solve this equation. +A constant-time Gaussian elimination algorithm is used to solve this equation. The algorithm aborts if the solution is non-unique. The minimal polynomial is then represented as a ``Classic_McEliece_Minimal_Polynomial`` object, which -includes logic for serialization and deserialization as described in +is a corresponding `Classic_McEliece_Polynomial` with additional logic +for serialization and deserialization as described in Section 9.2.9 of [CMCE-ISO]_. @@ -178,9 +189,11 @@ Bit Vector Arithmetic ^^^^^^^^^^^^^^^^^^^^^ Botan's ``bitvector`` class is a versatile tool for working with bits. -One such application is the Classic McEliece algorithm, where it handles -binary matrices, error vectors, code words, and the column selections in the private -key. The ``bitvector`` class provides a range of useful methods for these tasks. +It is intended to be a general component for handling bit vectors in various +cryptographic contexts. +In the context of Classic McEliece, it was introduced to handle +binary matrices, error vectors, code words, and column selections. +The ``bitvector`` class provides a range of useful methods for these tasks. A ``bitvector`` can be dynamically initialized with any length. It can be created from a vector of bytes and serialized back to it, as described in Section 9.2.1 @@ -193,12 +206,12 @@ Furthermore, the ``bitvector`` class supports binary operations between two vect of the same length, including AND, OR, and XOR. These operations are optimized for performance, especially in the context of Classic McEliece. -The design of the ``bitvector`` class prioritizes constant times, particularly -for Classic McEliece. The time taken for bit accesses and manipulations depends +The design of the ``bitvector`` class supports many side-channel resistant +operations. The time taken for bit accesses and manipulations depends only on the bit's position, not its value. Operations between two vectors -are also constant-time when the operands have the same length. The timing of -helper functions, such as the Hamming weight, is also implemented with -constant time in mind. +are also constant-time when the operands have the same length. Other helper +functions used in Classic McEliece, such as Hamming weight computation, are +also available with side-channel protection. .. _pubkey/cmce/matrix: @@ -223,22 +236,22 @@ the public key specified in Section 9.2.7 of [CMCE-ISO]_. Classic McEliece instances with the suffix ``f`` employ a semi-systematic transformation strategy, utilizing the parameters :math:`(\mu, \nu) = (32, 64)`, as described -in Section 7.2.3 of [CMCE-ISO]_. Following the recommendation in Section 6.1 of -the implementation guide accompanying [CMCE-R4]_, a Gauss algorithm is executed +in Section 7.2.3 of [CMCE-ISO]_. Following the recommendation of [CMCE-IMPL]_ +Section 6.1, a Gauss algorithm is executed to create an identity matrix for the first :math:`mt-\mu` rows. Subsequently, a modified Gauss algorithm achieves a reduced row-echelon form for the :math:`\mu \times \nu` submatrix at position :math:`(\mu, \mu)`. This process determines the column selection, i.e., the indices of the non-zero -columns. As Section 7.2.3 Step 5 of [CMCE-ISO]_ outlines, the matrix's +columns. As Section 7.2.3 Step 5 of [CMCE-ISO]_ outlines, the matrix columns and the field ordering are permuted according to the pivots. The main Gauss algorithm concludes at this point, leaving the matrix in its modified and systematic form. -For encapsulation, the matrix :math:`H` is multiplied by an error vector -:math:`e`. This multiplication is performed by computing the parity of the -Hamming weight of :math:`e\ \textrm{XOR}\ r` for each row :math:`r` of :math:`H`. -Matrix creation and multiplication are implemented in constant time for matrices -with fixed dimensions. +For encoding, the matrix :math:`H` is multiplied by an error vector +:math:`e` as specified in Section 7.3 of [CMCE-ISO]_. This multiplication is +performed by computing the parity of the +Hamming weight of :math:`e\ \oplus\ r` for each row :math:`r` of :math:`H`. +Matrix creation and multiplication are implemented in constant time. .. _pubkey/cmce/keys_internal: @@ -250,12 +263,12 @@ Botan's key pair for Classic McEliece consists of two classes: ``Classic_McEliece_PrivateKeyInternal`` and ``Classic_McEliece_PublicKeyInternal``. As defined in Section 9.2.12, the private key stores the key generation seed, column selection, monic irreducible polynomial, field ordering control bits, -and the seed for implicit rejection. On the other hand, the public key +and the seed for implicit rejection. The public key contains the sub-matrix :math:`T` of the binary parity check matrix :math:`H = (I_{mt}|T)`. The class ``Classic_McEliece_KeyPair_Internal`` holds both the private and public -keys and contains key generation method. Details are discussed in Section +keys and contains the key generation method. Details are discussed in Section :ref:`Key Generation `. @@ -271,15 +284,11 @@ Fixed weight vector creation and error vector encoding. The algorithm described in Section 8.4 of [CMCE-ISO]_ is followed to create a fixed weight error vector. Random elements :math:`d_0,...,d_{\tau-1}` are generated, where the first :math:`t` elements smaller than :math:`n` are selected as -:math:`a_0,...,a_{t-1}`. It is important to note that selecting -:math:`d_i` elements for :math:`a_j` elements may leak through timing -side-channels. However, the content of these elements remains undisclosed, -preventing attackers from gaining helpful information from this side channel. - -Next, all possible pairs are compared to ensure that all elements of -:math:`a_0,...,a_{t-1}` are distinct. Finally, a binary error vector :math:`e` -is created with set bits at the locations of :math:`a_0,...,a_{t-1}`. This -creation process also considers constant times. +:math:`a_0,...,a_{t-1}`. Note that side-channels may leak the information about which +:math:`d_i` element is assigned to which :math:`a_j` element. However, this information +is insensitive since the contents of :math:`a_i` elements are not disclosed. +The selected values are translated to an error vector :math:`e` in constant time, +as described in Section 8.4 Step 5 of [CMCE-ISO]_. For encoding, the parity check matrix :math:`H` is multiplied with :math:`e` as Section :ref:`Matrix Operations ` describes. The @@ -296,34 +305,35 @@ The class ``Classic_McEliece_Decryptor`` in Botan is responsible for key decapsulation. One of the crucial steps in the decapsulation algorithm of Classic McEliece is the decoding subroutine described in Section 7.4 of [CMCE-ISO]_. This subroutine is implemented based on the recommendations -provided in [McBits]_. The decoding process utilizes Berlekamp's algorithm for -Goppa decoding. +provided in Section 6 of [McBits]_. It utilizes Berlekamp's +algorithm for Goppa decoding. To begin with, the code word :math:`C` that needs to be decoded is extended by -appending zeros. This results in a binary vector :math:`\nu = (C,0,\dots,0) \in \mathbb{F}_2^{n}`, -as Section 7.2 Step 1 of [CMCE-ISO]_ defines. Subsequently, the syndrome for -Berlekamp's method is computed from :math:`\nu`. The syndrome is a vector given by -:math:`\left( \sum\nolimits_{i} \frac{\nu_i\alpha_i^0}{g(\alpha_i)^2},\dots,\sum\nolimits_{i} \frac{\nu_i\alpha_i^{n-1}}{g(\alpha_i)^2} \right)`, +appending zeros. This results in a binary vector :math:`v = (C,0,\dots,0) \in \mathbb{F}_2^{n}`, +as Step 1 of Section 7.2 of [CMCE-ISO]_ defines. Subsequently, the syndrome for +Berlekamp's method is computed from :math:`v`. The syndrome is a vector given by +:math:`\left( \sum\nolimits_{i} \frac{v_i\alpha_i^0}{g(\alpha_i)^2},\dots,\sum\nolimits_{i} \frac{v_i\alpha_i^{n-1}}{g(\alpha_i)^2} \right)`, where :math:`\alpha_i` are the first :math:`n` field ordering elements and :math:`g` is the Goppa polynomial. -Next, the error locator polynomial :math:`\sigma` is computed using the +Next, an error locator polynomial :math:`\sigma` is computed using the Berlekamp-Massey algorithm on the syndrome. The resulting polynomial has a -particular property concerning the error vector :math:`e` we search for. +particular property that allows deriving the error vector :math:`e`. Specifically, :math:`\sigma(\alpha_i) = 0` if and only if :math:`e_i = 1`. By evaluating :math:`\sigma` at :math:`\alpha_0,\dots,\alpha_{n-1}`, we can reconstruct the error vector :math:`e`. -To ensure accurate decoding, Botan follows the recommendation in Section 6.3 of -the implementation guide of [CMCE-R4]_. It computes the syndrome for the error -vector :math:`e` and compares it with the syndrome for :math:`\nu`. If the +To ensure accurate decoding, Botan follows the recommendation of [CMCE-IMPL]_ Section 6.3. +It computes the syndrome for the error +vector :math:`e` and compares it with the syndrome for :math:`v`. If the comparison holds and the weight of :math:`e` is equal to :math:`t`, we consider the decoding successful. Otherwise, it is flagged as a failure. It is worth noting that the syndrome computation, Berlekamp-Massey algorithm, and locator polynomial evaluation are implemented in constant time. Additionally, the checks for the weight of :math:`e` and the syndrome comparison are designed -to avoid early abortion if any check fails. +to avoid early abortion if any check fails. This ensures that no information about +the decoding success leaks. .. _pubkey/cmce/params: @@ -371,7 +381,7 @@ follows: 4. | Create a monic irreducible polynomial ``g`` using ``irreducible_bits`` | On failure, set ``seed = next_seed`` and go to step 2 - 5. | Create a parity check matrix in systematic form ``H = (I_mt | T)`` using ``field_ordering`` and ``g``. Meanwhile, compute the column selection ``c`` + 5. | Create a parity check matrix in systematic form ``H = (I_mt | T)`` using ``field_ordering`` and ``g``. During this process, the column selection ``c`` is also computed. | On failure, set ``seed = next_seed`` and go to step 2 6. ``SK = {seed, c, g, field_ordering, s}, PK = {T}`` @@ -413,7 +423,7 @@ The Classic McEliece encapsulation procedure of Botan follows Section 8.5 of **Steps:** 1. Generate a random error vector ``e`` of weight ``t`` using ``rng`` - 2. ``c0 = (I_mt | T) * e`` to encode ``e`` + 2. ``c0 = H * e`` to encode ``e`` where ``H`` is a ``Classic_McEliece_Matrix`` object 3. Depending on whether the parameter set includes plaintext confirmation (suffix ``pc``): a. **Without pc:** ``encap_key = c0`` @@ -425,6 +435,11 @@ The Classic McEliece encapsulation procedure of Botan follows Section 8.5 of - ``Hash`` is an application of ``SHAKE256`` with 32 output bytes as defined in Section 9.1 of [CMCE-ISO]_. + - The creation of error vectors is a rejection sampling algorithm. For each + iteration, the success probability is greater than 24%. To prevent a + broken RNG leading to an endless loop, the algorithm is aborted after 203 + iterations. This value is chosen to ensure that the probability of + aborting with a correct RNG is less than :math:`2^{-80}`. .. _pubkey/cmce/decapsulation: @@ -465,5 +480,5 @@ The Classic McEliece decapsulation procedure of Botan follows Section 8.6 of - ``Hash`` is an application of ``SHAKE256`` with 32 output bytes as defined in Section 9.1 of [CMCE-ISO]_. - - The assignments of ``e`` and ``b`` in steps 2 and 3 are implemented using + - The failure comparisons and assignments in steps 2 and 3 are implemented using Botan's constant-time helper functions to ensure constant-time execution. diff --git a/docs/cryptodoc/src/90_bibliographie.rst b/docs/cryptodoc/src/90_bibliographie.rst index 549a4d05..54856c1a 100644 --- a/docs/cryptodoc/src/90_bibliographie.rst +++ b/docs/cryptodoc/src/90_bibliographie.rst @@ -28,21 +28,28 @@ .. [CBits] Daniel J. Bernstein: "Verified fast formulas for control bits for permutation networks", + Cryptology ePrint Archive, Paper 2020/1493, 2020 .. [CCM] U.S. DEPARTMENT OF COMMERCE/National Institute of Standards and Technology: "Recommendation for Block Cipher Modes of Operation: The CCM Mode for Authentication and Confidentiality", July 2007 -.. [CMCE-ISO] ISO Draft (2023): - Information security — Encryption algorithms — Part 1978: - Classic McEliece +.. [CMCE-ISO] Martin R. Albrecht, Daniel J. Bernstein, Tung Chou, Carlos Cid, Jan Gilcher, Tanja Lange, Varun Maram, Ingo von Maurich, Rafael Misoczki, Ruben Niederhagen, Kenneth G. Paterson, Edoardo Persichetti, Christiane Peters, Peter Schwabe, Nicolas Sendrier, Jakub Szefer, Cen Jung Tjhai, Martin Tomlinson, Wen Wang: + Information security — Encryption algorithms — Part 1978", + Preliminary Standardization Proposal submitted to ISO, 2023, + https://classic.mceliece.org/iso-mceliece-20230419.pdf .. [CMCE-R4] Martin R. Albrecht, Daniel J. Bernstein, Tung Chou, Carlos Cid, Jan Gilcher, Tanja Lange, Varun Maram, Ingo von Maurich, Rafael Misoczki, Ruben Niederhagen, Kenneth G. Paterson, Edoardo Persichetti, Christiane Peters, Peter Schwabe, Nicolas Sendrier, Jakub Szefer, Cen Jung Tjhai, Martin Tomlinson, Wen Wang: "Classic McEliece: Conservative Code-Based Cryptography: Cryptosystem Specification", NIST PQC Challenge Round 4 Submission, 2022, https://classic.mceliece.org/mceliece-spec-20221023.pdf +.. [CMCE-IMPL] Martin R. Albrecht, Daniel J. Bernstein, Tung Chou, Carlos Cid, Jan Gilcher, Tanja Lange, Varun Maram, Ingo von Maurich, Rafael Misoczki, Ruben Niederhagen, Kenneth G. Paterson, Edoardo Persichetti, Christiane Peters, Peter Schwabe, Nicolas Sendrier, Jakub Szefer, Cen Jung Tjhai, Martin Tomlinson, Wen Wang: + "Classic McEliece: Conservative Code-Based Cryptography: Guide for Implementors", + NIST PQC Challenge Round 4 Submission, 2022, + https://classic.mceliece.org/mceliece-impl-20221023.pdf + .. [Dilithium-R3] S. Bai, L. Ducas, E. Kiltz, T. Lepoint, V. Lyubashevsky, P. Schwabe, G. Seiler, D. Stehlé: "CRYSTALS-Dilithium Algorithm Specifications and Supporting Documentation (Version 3.1)", NIST PQC Challenge Round 3 Submission, 2021, @@ -140,7 +147,8 @@ .. [McBits] Daniel J. Bernstein, Tung Chou, Peter Schwabe: "McBits: fast constant-time code-based cryptography", - 2015 + Cryptology ePrint Archive, Paper 2015/610, + CHES 2013 .. [NIST-OMAC] National Institute of Standards and Technology. OMAC: One-Key CBC MAC — Addendum. From bbcec6aed699a6d3ab0d6d1002f76d38b876d131 Mon Sep 17 00:00:00 2001 From: Fabian Albert <126883116+FAlbertDev@users.noreply.github.com> Date: Mon, 18 Mar 2024 09:33:54 +0100 Subject: [PATCH 3/6] Bitvector with Classic McEliece descr Co-authored-by: Amos Treiber <40764707+atreiber94@users.noreply.github.com> --- docs/cryptodoc/src/05_10_cmce.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/cryptodoc/src/05_10_cmce.rst b/docs/cryptodoc/src/05_10_cmce.rst index d05cd664..ad0c78a4 100644 --- a/docs/cryptodoc/src/05_10_cmce.rst +++ b/docs/cryptodoc/src/05_10_cmce.rst @@ -212,6 +212,7 @@ only on the bit's position, not its value. Operations between two vectors are also constant-time when the operands have the same length. Other helper functions used in Classic McEliece, such as Hamming weight computation, are also available with side-channel protection. +Botan's Classic McEliece implementation only uses the constant-time functionalities of ``bitvector``. .. _pubkey/cmce/matrix: From 056fefe11f553791c265b4c9ed8d7460683ec38d Mon Sep 17 00:00:00 2001 From: Fabian Albert Date: Mon, 18 Mar 2024 09:40:17 +0100 Subject: [PATCH 4/6] control bits use bitvectors --- docs/cryptodoc/src/05_10_cmce.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cryptodoc/src/05_10_cmce.rst b/docs/cryptodoc/src/05_10_cmce.rst index ad0c78a4..067b03dd 100644 --- a/docs/cryptodoc/src/05_10_cmce.rst +++ b/docs/cryptodoc/src/05_10_cmce.rst @@ -192,7 +192,7 @@ Botan's ``bitvector`` class is a versatile tool for working with bits. It is intended to be a general component for handling bit vectors in various cryptographic contexts. In the context of Classic McEliece, it was introduced to handle -binary matrices, error vectors, code words, and column selections. +binary matrices, error vectors, code words, control bits, and column selections. The ``bitvector`` class provides a range of useful methods for these tasks. A ``bitvector`` can be dynamically initialized with any length. It can be created From 4cb4c0adc08db47d967a70c84e02fd60c436b323 Mon Sep 17 00:00:00 2001 From: Amos Treiber <40764707+atreiber94@users.noreply.github.com> Date: Thu, 2 May 2024 11:01:22 +0200 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: weitkaemper-bsi <157401255+weitkaemper-bsi@users.noreply.github.com> --- docs/cryptodoc/src/05_10_cmce.rst | 99 +++++++++++++++---------------- 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/docs/cryptodoc/src/05_10_cmce.rst b/docs/cryptodoc/src/05_10_cmce.rst index 067b03dd..10031b31 100644 --- a/docs/cryptodoc/src/05_10_cmce.rst +++ b/docs/cryptodoc/src/05_10_cmce.rst @@ -11,7 +11,7 @@ in Table :ref:`Supported Classic McEliece parameter sets `` and ```` indicate that sets with and without f and pc are supported. +.. table:: Supported Classic McEliece parameter sets (see [CMCE-ISO]_ Section 10 and [CMCE-R4]_ Section 7). ```` and ```` indicate that sets of the "fast" variant (f) and with or without plaintext confirmation (pc) are supported. +----------------------------+-----------+-----------+-----------+----------------------------+---------------------------------+ | Parameter Set | :math:`m` | :math:`n` | :math:`t` | :math:`f(z)` | :math:`F(y)` | @@ -39,7 +39,7 @@ their corresponding file locations. Classic McEliece, like all Key Encapsulation Mechanisms (KEMs), consists of three main algorithms: Key generation, key encapsulation, and key decapsulation. In the case of Classic McEliece, the key generation process involves creating a field ordering and an irreducible -polynomial. These two components define the randomly chosen Goppa code, the +polynomial. These two components define a randomly chosen Goppa code which is the secret information stored in the private key. A parity check matrix in systematic form is derived from the Goppa code to generate the public key used for encapsulation. More detailed information about these processes can be found @@ -47,7 +47,7 @@ in the following sections. .. _pubkey/cmce/component_table: -.. table:: Classic McEliece components and file locations. Its files are located at :srcref:`src/lib/pubkey/classic_mceliece/`. +.. table:: Classic McEliece components and file locations. The files are located at :srcref:`src/lib/pubkey/classic_mceliece/`. :widths: 21 29 40 +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ @@ -61,7 +61,7 @@ in the following sections. +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ | :ref:`Polynomial Arithmetic ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_poly.h` | Polynomial data structure, logic, and minimal polynomial creation | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ - | :ref:`Bit Vector Arithmetic ` | :srcref:`src/lib/utils/bitvector.h` | Representation of bit-vectors and bit-vector arithmetic | + | :ref:`Bit Vector Arithmetic ` | :srcref:`src/lib/utils/bitvector.h` | Representation of bit vectors and bit vector arithmetic | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ | :ref:`Matrix Operations ` | :srcref:`[src/lib/pubkey/classic_mceliece]/cmce_matrix.h` | Binary matrix data structure, creation, and systematic form transformation | +--------------------------------------------------------+------------------------------------------------------------------+----------------------------------------------------------------------------+ @@ -86,11 +86,11 @@ Types In implementing Botan's Classic McEliece, strong types are utilized to ensure the correct data usage within the code. These strong types are -fundamental to separate the domain of the various byte sequences involved in +fundamental to separate the domains of the various byte sequences involved in Classic McEliece, such as multiple types of seeds, random byte sequences for different -algorithms, and bit-vectors with different semantic contexts. Specific integers, +algorithms, and bit vectors with different semantic contexts. Specific integers, like raw Galois Field elements and their modulus, are -also represented as strong types. This reliance on strong types is similar to using them +also represented as strong types. This reliance on strong types is analogous to using them in other PQC algorithms for similar reasons. The Classic McEliece implementation enhances readability, clarity, and reliability by employing strong types. @@ -101,9 +101,9 @@ clarity, and reliability by employing strong types. Galois Field Arithmetic ^^^^^^^^^^^^^^^^^^^^^^^ -The Goppa code is based on the Galois field (GF) :math:`\mathbb{F}_{q}`, where :math:`q=2^m`. -Corresponding GF elements are represented by :math:`\mathbb{F}_{2}[z]/f(z)`, -which in Botan's implementation is realized via the class ``Classic_McEliece_GF``. Each +The Goppa code is based on the Galois field (GF) :math:`\mathbb{F}_{q}` where :math:`q=2^m` for some positive integer :math:`m`. +Corresponding GF elements are represented by elements in :math:`\mathbb{F}_{2}[z]/f(z)`. +In Botan's implementation, this is realized via the class ``Classic_McEliece_GF``. Each element is defined by two polynomials: one defines its value, and the other defines the modulus of the field (:math:`f` in [CMCE-ISO]_). These values are represented as unsigned integers where the bit on position :math:`i` is set if the @@ -114,10 +114,10 @@ The GF elements support various operations such as addition, multiplication, and inversion. These operations are implemented in constant time for operands within the same field. Multiplication is performed using a constant-time long multiplication algorithm with a consecutive constant-time reduction. -Inversion of an element :math:`a` is achieved using Fermat's little theorem: -:math:`a^{-1} = a^{q-2}`. -For that, exponentiation is implemented using a simple square-and-multiply -algorithm. +Inversion of an element :math:`a` is achieved using Lagrange's theorem, +which implies that :math:`a^(q-1) = 1` for every non-zero GF element :math:`a`. +Hence, :math:`a^{-1} = a^{q-2}`. The exponentiation :math:`a^{q-2}` +is implemented using a simple square-and-multiply algorithm. .. _pubkey/cmce/field_ordering: @@ -127,19 +127,19 @@ Field Ordering Section 8.2 of [CMCE-ISO]_ defines the field ordering as a permutation of elements in the Galois field :math:`\mathbb{F}_{q}`. This ordering is required for generating a random sequence :math:`\alpha_0,...,\alpha_{n-1}` of distinct -:math:`\mathbb{F}_{q}` elements, which is necessary for creating the Goppa +:math:`\mathbb{F}_{q}` elements which is necessary for instantiating the Goppa code. Botan's ``Classic_McEliece_Field_Ordering`` serves as a container for the field ordering and includes the algorithm to generate it. To sort the pairs :math:`(a_i, i)` (as described in Step 3 of Section 8.2 in [CMCE-ISO]_), a constant-time bitonic sort implementation is utilized. This sorting algorithm is -particularly suitable for sets with a power of two elements. The sorted -:math:`a_i` are then transformed into elements from :math:`\mathbb{F}_{q}` as -described in the final Steps 4-6 of Section 8.2 in [CMCE-ISO]_. The class +particularly suitable for sets of cardinality a power of two. The sorted +:math:`a_i` are then transformed into elements of :math:`\mathbb{F}_{q}` as +described in Steps 4-6 of Section 8.2 in [CMCE-ISO]_. The class stores the resulting elements :math:`\alpha_0,...,\alpha_{q-1}` and provides accessors. Another vital role of the field ordering class is managing the Beneš network. -As Section 9.2.10 of [CMCE-ISO]_ outlines, the Beneš network stores the field +As outlined in Section 9.2.10 of [CMCE-ISO]_, the Beneš network stores the field ordering as control bits in a compact form. Botan employs a constant-time implementation of the ``controlbits`` algorithm presented in Fig. 7.1 of [CBits]_ to create control bits and the ``permutation`` algorithm @@ -153,32 +153,31 @@ Polynomial Arithmetic ^^^^^^^^^^^^^^^^^^^^^ The Classic McEliece algorithm uses elements of the polynomial ring -:math:`\mathbb{F}_q [y]` in multiple places, which are represented as +:math:`\mathbb{F}_q [y]` in multiple places, and these are represented by elements in :math:`\mathbb{F}_q [y] / F(y)`. Botan's ``Classic_McEliece_Polynomial`` class is used for this purpose. One key application of this class is creating and representing -the irreducible polynomial :math:`g` for the Goppa code. Additionally, it is +the irreducible polynomial :math:`g` defining the Goppa code. Additionally, it is used to represent the error locator polynomial used in the decapsulation process. Internally, the polynomial class is composed of a vector of -``Classic_McEliece_GF`` elements, which act as the polynomial coefficients. +``Classic_McEliece_GF`` elements which act as the polynomial coefficients. Also, the necessary functionality is provided to evaluate a polynomial at a given point in :math:`\mathbb{F}_q`. Polynomial arithmetic is required to obtain the monic irreducible polynomial :math:`g` from a random seed, as -described in Step 3 of Section 8.1 in [CMCE-ISO]_. This arithmetic -is implemented in the ``Classic_McEliece_Polynomial_Ring`` class, representing -the polynomial ring :math:`\mathbb{F}_{q} [y]/F(y)` and supporting the -multiplication of two ``Classic_McEliece_Poly`` polynomials. +described in Step 3 of Section 8.1 in [CMCE-ISO]_. This arithmetic, including the representation of +the polynomial ring :math:`\mathbb{F}_{q} [y]/F(y)` and the +multiplication of two ``Classic_McEliece_Poly`` polynomials, is implemented in the ``Classic_McEliece_Polynomial_Ring`` class. Following the recommendation of [CMCE-IMPL]_ Section 6.1, the minimal polynomial is computed by finding a unique solution to the equation :math:`g_0\beta^0 + ... + g_{t-1}\beta^{t-1} = \beta^t`. A constant-time Gaussian elimination algorithm is used to solve this equation. The algorithm aborts if the solution is non-unique. The minimal polynomial -is then represented as a ``Classic_McEliece_Minimal_Polynomial`` object, which -is a corresponding `Classic_McEliece_Polynomial` with additional logic +is then represented as a ``Classic_McEliece_Minimal_Polynomial`` object, +a corresponding `Classic_McEliece_Polynomial` with additional logic for serialization and deserialization as described in Section 9.2.9 of [CMCE-ISO]_. @@ -228,11 +227,11 @@ check matrix :math:`H` in systematic form. This matrix is represented by the The class follows the process outlined in Section 7.2 of [CMCE-ISO]_ for matrix creation. Initially, a binary :math:`mt \times n` matrix is created as described in Steps 1 and 2 of Section 7.2.2. Each row of the matrix is -represented as a ``bitvector`` object. Subsequently, a constant-time Gauss +represented as a ``bitvector`` object. Subsequently, a constant-time Gaussian elimination algorithm is applied to reduce the matrix to the systematic form :math:`H=(I_{mt}|T)`. The algorithm achieves this by systematically applying XOR operations on pairs of matrix rows, resulting in the identity matrix on the left. Finally, the -submatrix `T` is stored in the matrix object, mirroring its representation in +submatrix `T` is stored as a matrix object, analogous to its representation in the public key specified in Section 9.2.7 of [CMCE-ISO]_. Classic McEliece instances with the suffix ``f`` employ a semi-systematic transformation @@ -241,7 +240,7 @@ in Section 7.2.3 of [CMCE-ISO]_. Following the recommendation of [CMCE-IMPL]_ Section 6.1, a Gauss algorithm is executed to create an identity matrix for the first :math:`mt-\mu` rows. Subsequently, a modified Gauss algorithm achieves a reduced row-echelon form for -the :math:`\mu \times \nu` submatrix at position :math:`(\mu, \mu)`. +the :math:`\mu \times \nu` submatrix beginning at position :math:`(\mu, \mu)`. This process determines the column selection, i.e., the indices of the non-zero columns. As Section 7.2.3 Step 5 of [CMCE-ISO]_ outlines, the matrix columns and the field ordering are permuted according to the pivots. The main @@ -262,7 +261,7 @@ Key Pair Botan's key pair for Classic McEliece consists of two classes: ``Classic_McEliece_PrivateKeyInternal`` and ``Classic_McEliece_PublicKeyInternal``. -As defined in Section 9.2.12, the private key stores the key generation seed, +As defined in Section 9.2.12 of [CMCE-ISO]_, the private key stores the key generation seed, column selection, monic irreducible polynomial, field ordering control bits, and the seed for implicit rejection. The public key contains the sub-matrix :math:`T` of the binary parity check matrix @@ -280,16 +279,16 @@ Encapsulation Internals The class ``Classic_McEliece_Encryptor`` implements Botan's key encapsulation interface. Performing encapsulation requires two building blocks: -Fixed weight vector creation and error vector encoding. +Fixed-weight vector creation and error vector encoding. -The algorithm described in Section 8.4 of [CMCE-ISO]_ is followed to create a -fixed weight error vector. Random elements :math:`d_0,...,d_{\tau-1}` are +An error vector of fixed weight is created following the algorithm described in Section 8.4 of [CMCE-ISO]_. +Random elements :math:`d_0,...,d_{\tau-1}` are generated, where the first :math:`t` elements smaller than :math:`n` are selected as :math:`a_0,...,a_{t-1}`. Note that side-channels may leak the information about which :math:`d_i` element is assigned to which :math:`a_j` element. However, this information -is insensitive since the contents of :math:`a_i` elements are not disclosed. +is insensitive since the values of the :math:`a_i` cannot be extracted. The selected values are translated to an error vector :math:`e` in constant time, -as described in Section 8.4 Step 5 of [CMCE-ISO]_. +as described in Section 8.4, Step 5 of [CMCE-ISO]_. For encoding, the parity check matrix :math:`H` is multiplied with :math:`e` as Section :ref:`Matrix Operations ` describes. The @@ -302,7 +301,7 @@ encapsulation algorithm used in Botan is outlined in Section Decapsulation Internals ^^^^^^^^^^^^^^^^^^^^^^^ -The class ``Classic_McEliece_Decryptor`` in Botan is responsible for +The class ``Classic_McEliece_Decryptor`` in Botan handles key decapsulation. One of the crucial steps in the decapsulation algorithm of Classic McEliece is the decoding subroutine described in Section 7.4 of [CMCE-ISO]_. This subroutine is implemented based on the recommendations @@ -311,30 +310,30 @@ algorithm for Goppa decoding. To begin with, the code word :math:`C` that needs to be decoded is extended by appending zeros. This results in a binary vector :math:`v = (C,0,\dots,0) \in \mathbb{F}_2^{n}`, -as Step 1 of Section 7.2 of [CMCE-ISO]_ defines. Subsequently, the syndrome for +as Step 1 of Section 7.4 of [CMCE-ISO]_ describes. Subsequently, the syndrome for Berlekamp's method is computed from :math:`v`. The syndrome is a vector given by :math:`\left( \sum\nolimits_{i} \frac{v_i\alpha_i^0}{g(\alpha_i)^2},\dots,\sum\nolimits_{i} \frac{v_i\alpha_i^{n-1}}{g(\alpha_i)^2} \right)`, -where :math:`\alpha_i` are the first :math:`n` field ordering elements and +where the :math:`\alpha_i` are the first :math:`n` field ordering elements and :math:`g` is the Goppa polynomial. Next, an error locator polynomial :math:`\sigma` is computed using the Berlekamp-Massey algorithm on the syndrome. The resulting polynomial has a -particular property that allows deriving the error vector :math:`e`. +particular property that allows the derivation of the error vector :math:`e`. Specifically, :math:`\sigma(\alpha_i) = 0` if and only if :math:`e_i = 1`. By evaluating :math:`\sigma` at :math:`\alpha_0,\dots,\alpha_{n-1}`, we can reconstruct the error vector :math:`e`. To ensure accurate decoding, Botan follows the recommendation of [CMCE-IMPL]_ Section 6.3. It computes the syndrome for the error -vector :math:`e` and compares it with the syndrome for :math:`v`. If the -comparison holds and the weight of :math:`e` is equal to :math:`t`, we consider +vector :math:`e` and compares it with the syndrome for :math:`v`. If both +syndromes are the same and the weight of :math:`e` is equal to :math:`t`, we consider the decoding successful. Otherwise, it is flagged as a failure. It is worth noting that the syndrome computation, Berlekamp-Massey algorithm, and locator polynomial evaluation are implemented in constant time. Additionally, the checks for the weight of :math:`e` and the syndrome comparison are designed to avoid early abortion if any check fails. This ensures that no information about -the decoding success leaks. +the decoding success is leaked. .. _pubkey/cmce/params: @@ -377,13 +376,13 @@ follows: 1. Generate a random value ``seed`` using ``rng`` 2. ``s, ordering_bits, irreducible_bits, next_seed = PRF(seed)`` 3. | Create a field ordering ``field_ordering`` using ``ordering_bits`` - | On failure, set ``seed = next_seed`` and go to step 2 + | Upon failure, set ``seed = next_seed`` and go to Step 2 4. | Create a monic irreducible polynomial ``g`` using ``irreducible_bits`` - | On failure, set ``seed = next_seed`` and go to step 2 + | Upon failure, set ``seed = next_seed`` and go to Step 2 5. | Create a parity check matrix in systematic form ``H = (I_mt | T)`` using ``field_ordering`` and ``g``. During this process, the column selection ``c`` is also computed. - | On failure, set ``seed = next_seed`` and go to step 2 + | Upon failure, set ``seed = next_seed`` and go to Step 2 6. ``SK = {seed, c, g, field_ordering, s}, PK = {T}`` @@ -467,10 +466,10 @@ The Classic McEliece decapsulation procedure of Botan follows Section 8.6 of 1. Depending on whether the parameter set includes plaintext confirmation (suffix ``pc``): a. **Without pc:** ``c0 = encap_key`` - b. **With pc:** ``c0, c1 = encap_key``, split after ``ceil(m*t/8)`` bytes + b. **With pc:** ``c0, c1 = encap_key``, split after :math:`\lceil \frac{mt}{8} \rceil` bytes 2. | Decode ``c0`` to obtain ``e`` using Berlekamp's algorithm and set ``b = 1`` - | On failure set ``e = s`` and ``b = 0`` + | Upon failure set ``e = s`` and ``b = 0`` 3. | **Only for pc instances:** ``c1_p = Hash(2, e)`` | If ``c1_p != c1`` set ``e = s`` and ``b = 0`` @@ -481,5 +480,5 @@ The Classic McEliece decapsulation procedure of Botan follows Section 8.6 of - ``Hash`` is an application of ``SHAKE256`` with 32 output bytes as defined in Section 9.1 of [CMCE-ISO]_. - - The failure comparisons and assignments in steps 2 and 3 are implemented using + - The failure comparisons and assignments in Steps 2 and 3 are implemented using Botan's constant-time helper functions to ensure constant-time execution. From 3a66b49e9618febf6e4f7a6dda4ae9af268667d5 Mon Sep 17 00:00:00 2001 From: Amos Treiber Date: Fri, 3 May 2024 13:54:25 +0200 Subject: [PATCH 6/6] Add explicit mode/parameter input to CMCE keygen --- docs/cryptodoc/src/05_10_cmce.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/cryptodoc/src/05_10_cmce.rst b/docs/cryptodoc/src/05_10_cmce.rst index 10031b31..1a68a83e 100644 --- a/docs/cryptodoc/src/05_10_cmce.rst +++ b/docs/cryptodoc/src/05_10_cmce.rst @@ -366,6 +366,7 @@ follows: **Input:** - ``rng``: random number generator + - ``param_set``: Classic McEliece parameter set **Output:**