-
Notifications
You must be signed in to change notification settings - Fork 0
/
GFq.cpp
167 lines (140 loc) · 3.68 KB
/
GFq.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/*
* GFq.cpp
*
* Created on: 22 Dec, 2014
* Author: Mehrdad Tahernia
* User: mehrdad
*/
#include "Functions.h"
#include "GFq.h"
/************************************************************************
*
* GF(q)
*
************************************************************************/
// Static integers
int GFq::q = -1;
GFq GFq::alpha[MAX_Q];
int GFq::reverse_alpha[MAX_Q];
GFq GFq::inverse[MAX_Q];
bool GFq::IsPrimeQ = false;
bool GFq::IsModuloOperations = false;
// Forward declerations FIXME: Why do we need to forward declare static members?
int GFq::log_2_q;
int GFq::mask;
void GFq::Initialize(int p_q) {
if (p_q == GFq::q) // if already initialized with the same q
return;
if (p_q > MAX_Q) {
cout << "GFq::Initialize: p_q exceeds MAX_Q\n";
exit(1);
}
q = p_q;
//-----------------------------------------------------------------------
// Initialize
//-----------------------------------------------------------------------
if ((q > 2) && IsPowerOfTwo(q)) {
// Store for use by other utilities
log_2_q = Intlog2(q);
mask = 0; // Mask is used to select bits.
for (int i = 0; i < log_2_q; i++) {
mask <<= 1;
mask |= 1;
}
switch (q) {
case 4:
GenerateAlphas(2);
break;
case 8:
GenerateAlphas(3);
break;
case 16:
GenerateAlphas(4);
break;
case 32:
GenerateAlphas(5);
break;
case 64:
GenerateAlphas(6);
break;
case 256:
GenerateAlphas(8);
break;
default:
cout << "GFq::Initialize: Unsupported value of q\n";
exit(1);
}
IsPrimeQ = false;
IsModuloOperations = false;
} else {
if (q == 2) {
log_2_q = 1;
mask = 1;
}
IsModuloOperations = true;
IsPrimeQ = IsPrime(q);
}
//-----------------------------------------------------------------------
// Calc inverse table for elemets of GF(q)
//-----------------------------------------------------------------------
for (int i = 1; i < q; i++)
for (int j = 1; j < q; j++) {
GFq g1(i), g2(j);
if ((g1 * g2) == GFq::One())
inverse[i] = g2;
}
} // void GFq::Initialize
// Some predefined generator polynomials for extension fields of 2.
void GFq::GenerateAlphas(int m) {
int generator_polynomial;
int X0 = 1, X1 = 1 << 1, X2 = 1 << 2, X3 = 1 << 3, X4 = 1 << 4, X5 = 1 << 5, X6 = 1 << 6,/* X7 = 1 << 7,*/ X8 = 1 << 8; // X7 was not used
switch (m) {
case 2:
generator_polynomial = X0 ^ X1 ^ X2; // ^ is Bitwise XOR, it acts like modulo 2 adding here
break;
case 3:
generator_polynomial = X0 ^ X1 ^ X3;
break;
case 4:
generator_polynomial = X0 ^ X1 ^ X4;
break;
case 5:
generator_polynomial = X0 ^ X2 ^ X5;
break;
case 6:
generator_polynomial = X0 ^ X1 ^ X6;
break;
case 8:
generator_polynomial = X8 ^ X4 ^ X3 ^ X2 ^ X0;
break;
default:
cout << "GFq::GenerateAlphas: Unidentified Galois field\n";
exit(1);
break;
}
//------------------------------------------------
// Generate alphas
//------------------------------------------------
int x = 1;
int overflow = 1 << m;
for (int i = 0; i < (q - 1); i++) {
alpha[i].val = x;
x <<= 1; // multiply by alpha FIXME: What!!!!!!!!!!!! it looks like multiplication by 2
if (x & overflow) // if overflowed
x ^= generator_polynomial; // FIXME: I don't understand, why add the generator?
}
//------------------------------------------------
// Generate reverse alphas: inverse function
//------------------------------------------------
for (int i = 0; i < (q - 1); i++)
reverse_alpha[alpha[i].val] = i;
}
// static is only used once in decleration
GFq& GFq::One() {
if (IsModuloOperations) {
static GFq ConstOne(1);
return ConstOne;
} else
return alpha[0];
}
bool GFq::operator==(GFq g) { return val == g.val;}