Botan 3.13.0
Crypto and TLS for C&
gf2m_small_m.cpp
Go to the documentation of this file.
1/*
2* (C) Copyright Projet SECRET, INRIA, Rocquencourt
3* (C) Bhaskar Biswas and Nicolas Sendrier
4*
5* (C) 2014 cryptosource GmbH
6* (C) 2014 Falko Strenzke fstrenzke@cryptosource.de
7*
8* Botan is released under the Simplified BSD License (see license.txt)
9*/
10
11#include <botan/internal/gf2m_small_m.h>
12
13#include <botan/exceptn.h>
14#include <botan/internal/ct_utils.h>
15#include <array>
16#include <string>
17
18namespace Botan {
19
20const size_t MAX_EXT_DEG = 15;
21
22namespace {
23
24using GF2m_Tables = std::array<std::vector<gf2m>, MAX_EXT_DEG + 1>;
25
26const gf2m prim_poly[MAX_EXT_DEG + 1] = {
27 01, /* extension degree 0 (!) never used */
28 03, /* extension degree 1 (!) never used */
29 07, /* extension degree 2 */
30 013, /* extension degree 3 */
31 023, /* extension degree 4 */
32 045, /* extension degree 5 */
33 0103, /* extension degree 6 */
34 0203, /* extension degree 7 */
35 0435, /* extension degree 8 */
36 01041, /* extension degree 9 */
37 02011, /* extension degree 10 */
38 04005, /* extension degree 11 */
39 010123, /* extension degree 12 */
40 020033, /* extension degree 13 */
41 042103, /* extension degree 14 */
42 0100003, /* extension degree 15 */
43};
44
45std::vector<gf2m> gf_exp_table(size_t deg, gf2m prime_poly) {
46 // construct the table gf_exp[i]=alpha^i
47
48 std::vector<gf2m> tab((static_cast<size_t>(1) << deg) + 1);
49
50 tab[0] = 1;
51 for(size_t i = 1; i < tab.size(); ++i) {
52 const gf2m overflow = tab[i - 1] >> (deg - 1);
53 tab[i] = (tab[i - 1] << 1) ^ (overflow * prime_poly);
54 }
55
56 return tab;
57}
58
59const GF2m_Tables& exp_tables() {
60 static const GF2m_Tables tables = [] {
61 GF2m_Tables result;
62 for(size_t degree = 2; degree <= MAX_EXT_DEG; ++degree) {
63 result[degree] = gf_exp_table(degree, prim_poly[degree]);
64 }
65 return result;
66 }();
67 return tables;
68}
69
70const std::vector<gf2m>& exp_table(size_t deg) {
71 if(deg < 2 || deg > MAX_EXT_DEG) {
72 throw Invalid_Argument("GF2m_Field does not support degree " + std::to_string(deg));
73 }
74 return exp_tables()[deg];
75}
76
77std::vector<gf2m> gf_log_table(size_t deg, const std::vector<gf2m>& exp) {
78 std::vector<gf2m> tab(static_cast<size_t>(1) << deg);
79
80 tab[0] = static_cast<gf2m>((static_cast<gf2m>(1) << deg) - 1); // log of 0 is the order by convention
81 for(size_t i = 0; i < tab.size(); ++i) {
82 tab[exp[i]] = static_cast<gf2m>(i);
83 }
84 return tab;
85}
86
87const GF2m_Tables& log_tables() {
88 static const GF2m_Tables tables = [] {
89 GF2m_Tables result;
90 for(size_t degree = 2; degree <= MAX_EXT_DEG; ++degree) {
91 result[degree] = gf_log_table(degree, exp_table(degree));
92 }
93 return result;
94 }();
95 return tables;
96}
97
98const std::vector<gf2m>& log_table(size_t deg) {
99 if(deg < 2 || deg > MAX_EXT_DEG) {
100 throw Invalid_Argument("GF2m_Field does not support degree " + std::to_string(deg));
101 }
102 return log_tables()[deg];
103}
104
105} // namespace
106
107uint32_t encode_gf2m(gf2m to_enc, uint8_t* mem) {
108 mem[0] = to_enc >> 8;
109 mem[1] = to_enc & 0xFF;
110 return sizeof(to_enc);
111}
112
113gf2m decode_gf2m(const uint8_t* mem) {
114 gf2m result = mem[0] << 8;
115 result |= mem[1];
116 return result;
117}
118
120 m_gf_extension_degree(extdeg),
121 m_gf_multiplicative_order((1 << extdeg) - 1),
122 m_gf_log_table(log_table(m_gf_extension_degree)),
123 m_gf_exp_table(exp_table(m_gf_extension_degree)) {}
124
126 const int32_t sub_res = static_cast<int32_t>(gf_log(x) - static_cast<int32_t>(gf_log(y)));
127 const gf2m modq_res = _gf_modq_1(sub_res);
128 const gf2m div = gf_exp(modq_res);
129 return (~CT::Mask<gf2m>::is_zero(x)).if_set_return(div);
130}
131
132} // namespace Botan
static constexpr Mask< T > is_zero(T x)
Definition ct_utils.h:437
gf2m gf_div(gf2m x, gf2m y) const
GF2m_Field(size_t extdeg)
gf2m gf_exp(gf2m i) const
gf2m gf_log(gf2m i) const
const size_t MAX_EXT_DEG
gf2m decode_gf2m(const uint8_t *mem)
uint32_t encode_gf2m(gf2m to_enc, uint8_t *mem)
uint16_t gf2m