Coverage Report

Created: 2025-04-11 06:34

/src/botan/build/include/internal/botan/internal/dilithium_polynomial.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Crystals Dilithium Polynomial Adapter
3
 *
4
 * (C) 2022-2023 Jack Lloyd
5
 * (C) 2022      Manuel Glaser - Rohde & Schwarz Cybersecurity
6
 * (C) 2022-2023 Michael Boric, René Meusel - Rohde & Schwarz Cybersecurity
7
 * (C) 2024 René Meusel, Rohde & Schwarz Cybersecurity
8
 *
9
 * Botan is released under the Simplified BSD License (see license.txt)
10
 */
11
12
#ifndef BOTAN_DILITHIUM_POLYNOMIAL_H_
13
#define BOTAN_DILITHIUM_POLYNOMIAL_H_
14
15
#include <botan/mem_ops.h>
16
#include <botan/internal/dilithium_constants.h>
17
#include <botan/internal/pqcrystals.h>
18
#include <botan/internal/pqcrystals_helpers.h>
19
20
namespace Botan {
21
22
class DilithiumPolyTraits final : public CRYSTALS::Trait_Base<DilithiumConstants, DilithiumPolyTraits> {
23
   private:
24
      friend class CRYSTALS::Trait_Base<DilithiumConstants, DilithiumPolyTraits>;
25
26
0
      static constexpr T montgomery_reduce_coefficient(T2 a) {
27
0
         const T2 t = static_cast<T>(static_cast<T2>(static_cast<T>(a)) * Q_inverse);
28
0
         return (a - static_cast<T2>(t) * Q) >> (sizeof(T) * 8);
29
0
      }
30
31
0
      static constexpr T barrett_reduce_coefficient(T a) {
32
         // 2**22 is roughly Q/2 and 2**23 is roughly Q
33
0
         const T t = (a + (1 << 22)) >> 23;
34
0
         a = a - t * Q;
35
0
         return a;
36
0
      }
37
38
   public:
39
      /**
40
       * NIST FIPS 204, Algorithm 41 (NTT)
41
       *
42
       * Note: ntt(), inverse_ntt() and operator* have side effects on the
43
       *       montgomery factor of the involved coefficients!
44
       *       It is assumed that EXACTLY ONE vector or matrix multiplication
45
       *       is performed between transforming in and out of NTT domain.
46
       *
47
       * Produces the result of the NTT transformation without any montgomery
48
       * factors in the coefficients.
49
       */
50
0
      static constexpr void ntt(std::span<T, N> coeffs) {
51
0
         size_t j;
52
0
         size_t k = 0;
53
54
0
         for(size_t len = N / 2; len > 0; len >>= 1) {
55
0
            for(size_t start = 0; start < N; start = j + len) {
56
0
               const T zeta = zetas[++k];
57
0
               for(j = start; j < start + len; ++j) {
58
                  // Zetas contain the montgomery parameter 2^32 mod q
59
0
                  T t = fqmul(zeta, coeffs[j + len]);
60
0
                  coeffs[j + len] = coeffs[j] - t;
61
0
                  coeffs[j] = coeffs[j] + t;
62
0
               }
63
0
            }
64
0
         }
65
0
      }
66
67
      /**
68
       * NIST FIPS 204, Algorithm 42 (NTT^-1).
69
       *
70
       * The output is effectively multiplied by the montgomery parameter 2^32
71
       * mod q so that the input factors 2^(-32) mod q are eliminated. Note
72
       * that factors 2^(-32) mod q are introduced by multiplication and
73
       * reduction of values not in montgomery domain.
74
       *
75
       * Produces the result of the inverse NTT transformation with a montgomery
76
       * factor of (2^32 mod q) added (!). See above.
77
       */
78
0
      static constexpr void inverse_ntt(std::span<T, N> coeffs) {
79
0
         size_t j;
80
0
         size_t k = N;
81
0
         for(size_t len = 1; len < N; len <<= 1) {
82
0
            for(size_t start = 0; start < N; start = j + len) {
83
0
               const T zeta = -zetas[--k];
84
0
               for(j = start; j < start + len; ++j) {
85
0
                  T t = coeffs[j];
86
0
                  coeffs[j] = t + coeffs[j + len];
87
0
                  coeffs[j + len] = t - coeffs[j + len];
88
                  // Zetas contain the montgomery parameter 2^32 mod q
89
0
                  coeffs[j + len] = fqmul(zeta, coeffs[j + len]);
90
0
               }
91
0
            }
92
0
         }
93
94
0
         for(auto& coeff : coeffs) {
95
0
            coeff = fqmul(coeff, F_WITH_MONTY_SQUARED);
96
0
         }
97
0
      }
98
99
      /**
100
       * Multiplication of two polynomials @p lhs and @p rhs in NTT domain.
101
       *
102
       * Produces the result of the multiplication in NTT domain, with a factor
103
       * of (2^-32 mod q) in each element due to montgomery reduction.
104
       */
105
      static constexpr void poly_pointwise_montgomery(std::span<T, N> result,
106
                                                      std::span<const T, N> lhs,
107
0
                                                      std::span<const T, N> rhs) {
108
0
         for(size_t i = 0; i < N; ++i) {
109
0
            result[i] = fqmul(lhs[i], rhs[i]);
110
0
         }
111
0
      }
112
};
113
114
}  // namespace Botan
115
116
#endif