Botan 3.7.1
Crypto and TLS for C&
cmce_gf.cpp
Go to the documentation of this file.
1/*
2* Classic McEliece GF arithmetic
3* Based on the public domain reference implementation by the designers
4* (https://classic.mceliece.org/impl.html - released in Oct 2022 for NISTPQC-R4)
5*
6* (C) 2023 Jack Lloyd
7* 2023,2024 Fabian Albert, Amos Treiber - Rohde & Schwarz Cybersecurity
8*
9* Botan is released under the Simplified BSD License (see license.txt)
10**/
11
12#include <botan/internal/cmce_gf.h>
13
14namespace Botan {
15
16namespace {
17// Only for moduli 0b0010000000011011 and 0b0001000000001001
18inline CmceGfElem internal_reduce(uint32_t x, CmceGfMod mod) {
19 // Optimization for the specific moduli used in Classic McEliece
20 // Taken from the reference implementation
21 if(mod == 0b0010000000011011) {
22 uint32_t t = x & 0x1FF0000;
23 x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
24
25 t = x & 0x000E000;
26 x ^= (t >> 9) ^ (t >> 10) ^ (t >> 12) ^ (t >> 13);
27
28 return CmceGfElem(x & 0x1fff);
29 } else if(mod == 0b0001000000001001) {
30 uint32_t t = x & 0x7FC000;
31 x ^= t >> 9;
32 x ^= t >> 12;
33
34 t = x & 0x3000;
35 x ^= t >> 9;
36 x ^= t >> 12;
37
38 x &= 0xfff;
39
40 return CmceGfElem(static_cast<uint16_t>(x & 0xfff));
41 }
43}
44
45} // namespace
46
48 BOTAN_ASSERT_NOMSG(m_modulus == other.m_modulus);
49
50 uint32_t a = m_elem.get();
51 uint32_t b = other.m_elem.get();
52
53 uint32_t acc = a * (b & CT::value_barrier<uint32_t>(1));
54
55 for(size_t i = 1; i < log_q(); i++) {
56 acc ^= (a * (b & (1 << i)));
57 }
58
59 return Classic_McEliece_GF(internal_reduce(acc, m_modulus), m_modulus);
60}
61
63 // Compute the inverse using fermat's little theorem: a^(q-1) = 1 => a^(q-2) = a^-1
64
65 // exponent = (q-2). This is public information, therefore the workflow is constant time.
66 size_t exponent = (size_t(1) << log_q()) - 2;
67 Classic_McEliece_GF base = *this;
68
69 // Compute base^exponent using the square-and-multiply algorithm
70 Classic_McEliece_GF result = {CmceGfElem(1), m_modulus};
71 while(exponent > 0) {
72 if(exponent % 2 == 1) {
73 // multiply
74 result = (result * base);
75 }
76 // square
77 base = base.square();
78 exponent /= 2;
79 }
80
81 return result;
82}
83
84} // namespace Botan
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:59
#define BOTAN_ASSERT_UNREACHABLE()
Definition assert.h:137
Represents an element of the finite field GF(q) for q = 2^m.
Definition cmce_gf.h:30
Classic_McEliece_GF inv() const
Invert the element. Constant time.
Definition cmce_gf.cpp:62
Classic_McEliece_GF(CmceGfElem elem, CmceGfMod modulus)
Creates an element of GF(q) from a uint16_t.
Definition cmce_gf.h:41
Classic_McEliece_GF operator*(Classic_McEliece_GF other) const
Multiply the element by other in GF(q). Constant time.
Definition cmce_gf.cpp:47
size_t log_q() const
Get m, the degree of the element's modulus.
Definition cmce_gf.h:61
Classic_McEliece_GF square() const
Square the element. Constant time.
Definition cmce_gf.h:132
constexpr T & get() &
Definition strong_type.h:50
constexpr T value_barrier(T x)
Definition ct_utils.h:272
Strong< uint16_t, struct CmceGfMod_ > CmceGfMod
Represents a GF(q) modulus.
Definition cmce_types.h:22
Strong< uint16_t, struct CmceGfElem_ > CmceGfElem
Represents a GF(q) element.
Definition cmce_types.h:19
const SIMD_8x32 & b