Botan 3.4.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 <string>
15
16namespace Botan {
17
18const size_t MAX_EXT_DEG = 16;
19
20namespace {
21
22const gf2m prim_poly[MAX_EXT_DEG + 1] = {
23 01, /* extension degree 0 (!) never used */
24 03, /* extension degree 1 (!) never used */
25 07, /* extension degree 2 */
26 013, /* extension degree 3 */
27 023, /* extension degree 4 */
28 045, /* extension degree 5 */
29 0103, /* extension degree 6 */
30 0203, /* extension degree 7 */
31 0435, /* extension degree 8 */
32 01041, /* extension degree 9 */
33 02011, /* extension degree 10 */
34 04005, /* extension degree 11 */
35 010123, /* extension degree 12 */
36 020033, /* extension degree 13 */
37 042103, /* extension degree 14 */
38 0100003, /* extension degree 15 */
39};
40
41std::vector<gf2m> gf_exp_table(size_t deg, gf2m prime_poly) {
42 // construct the table gf_exp[i]=alpha^i
43
44 std::vector<gf2m> tab((static_cast<size_t>(1) << deg) + 1);
45
46 tab[0] = 1;
47 for(size_t i = 1; i < tab.size(); ++i) {
48 const gf2m overflow = tab[i - 1] >> (deg - 1);
49 tab[i] = (tab[i - 1] << 1) ^ (overflow * prime_poly);
50 }
51
52 return tab;
53}
54
55const std::vector<gf2m>& exp_table(size_t deg) {
56 static std::vector<gf2m> tabs[MAX_EXT_DEG + 1];
57
58 if(deg < 2 || deg > MAX_EXT_DEG) {
59 throw Invalid_Argument("GF2m_Field does not support degree " + std::to_string(deg));
60 }
61
62 if(tabs[deg].empty()) {
63 tabs[deg] = gf_exp_table(deg, prim_poly[deg]);
64 }
65
66 return tabs[deg];
67}
68
69std::vector<gf2m> gf_log_table(size_t deg, const std::vector<gf2m>& exp) {
70 std::vector<gf2m> tab(static_cast<size_t>(1) << deg);
71
72 tab[0] = static_cast<gf2m>((static_cast<gf2m>(1) << deg) - 1); // log of 0 is the order by convention
73 for(size_t i = 0; i < tab.size(); ++i) {
74 tab[exp[i]] = static_cast<gf2m>(i);
75 }
76 return tab;
77}
78
79const std::vector<gf2m>& log_table(size_t deg) {
80 static std::vector<gf2m> tabs[MAX_EXT_DEG + 1];
81
82 if(deg < 2 || deg > MAX_EXT_DEG) {
83 throw Invalid_Argument("GF2m_Field does not support degree " + std::to_string(deg));
84 }
85
86 if(tabs[deg].empty()) {
87 tabs[deg] = gf_log_table(deg, exp_table(deg));
88 }
89
90 return tabs[deg];
91}
92
93} // namespace
94
95uint32_t encode_gf2m(gf2m to_enc, uint8_t* mem) {
96 mem[0] = to_enc >> 8;
97 mem[1] = to_enc & 0xFF;
98 return sizeof(to_enc);
99}
100
101gf2m decode_gf2m(const uint8_t* mem) {
102 gf2m result;
103 result = mem[0] << 8;
104 result |= mem[1];
105 return result;
106}
107
109 m_gf_extension_degree(extdeg),
110 m_gf_multiplicative_order((1 << extdeg) - 1),
111 m_gf_log_table(log_table(m_gf_extension_degree)),
112 m_gf_exp_table(exp_table(m_gf_extension_degree)) {}
113
115 const int32_t sub_res = static_cast<int32_t>(gf_log(x) - static_cast<int32_t>(gf_log(y)));
116 const gf2m modq_res = _gf_modq_1(sub_res);
117 const int32_t div_res = static_cast<int32_t>(x) ? static_cast<int32_t>(gf_exp(modq_res)) : 0;
118 return static_cast<gf2m>(div_res);
119}
120
121} // namespace Botan
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