25 typedef unsigned char GF28_Element;
27 typedef uint16_t GF216_Element;
30 static const unsigned char GF28_Generator = 0x1b;
32 extern const GF28_Element GF28_mult_table[256][256];
34 extern const GF28_Element GF28_inv_table[256];
36 extern const GF216_Element GF216_exp_table[131070];
38 extern const GF216_Element GF216_log_table[65536];
43 inline E multiply_GF2E(E x, E y);
46 inline GF28_Element multiply_GF2E<GF28_Element>(GF28_Element x, GF28_Element y) {
47 return GF28_mult_table[x][y];
51 inline GF216_Element multiply_GF2E<GF216_Element>(GF216_Element x, GF216_Element y) {
52 if(x == 0 || y == 0)
return 0;
54 GF216_Element log_x = GF216_log_table[x];
55 GF216_Element log_y = GF216_log_table[y];
57 return GF216_exp_table[log_x+log_y];
63 inline E inverse_GF2E(E x);
66 inline GF28_Element inverse_GF2E<GF28_Element>(GF28_Element x) {
67 return GF28_inv_table[x];
71 inline GF216_Element inverse_GF2E<GF216_Element>(GF216_Element x) {
73 GF216_Element log_x = GF216_log_table[x];
74 return GF216_exp_table[65535-log_x];
79 E evalpoly_GF2E(E *coeffs,
unsigned short degree,
88 res = multiply_GF2E<E>(res, index);
98 E interpolate_GF2E(
const E *indices,
const E *values,
99 unsigned short numpoints,
const E alpha) {
102 E *lagrange =
new E[numpoints];
105 for (i=0;i<numpoints;++i) {
106 E numer = 1, denom = 1;
107 for (j=0;j<numpoints;++j) {
109 E numerdiff = indices[j] ^ alpha;
110 E denomdiff = indices[j] ^ indices[i];
111 numer = multiply_GF2E<E>(numer, numerdiff);
112 denom = multiply_GF2E<E>(denom, denomdiff);
114 lagrange[i] = multiply_GF2E<E>(numer, inverse_GF2E<E>(denom));
118 for (i=0;i<numpoints;++i) {
119 res ^= multiply_GF2E<E>(lagrange[i], values[i]);
137 template <
typename E>
138 inline void multpoly_GF2E(E *result,
const E *in1,
unsigned short deg1,
139 const E *in2,
unsigned short deg2)
141 unsigned short resdeg = deg1 + deg2;
143 for (
unsigned short d=0; d<=resdeg; ++d) {
147 unsigned short lower = 0;
148 if (d > deg2) lower = d-deg2;
151 unsigned short upper = d;
152 if (deg1 < d) upper = deg1;
154 for (
unsigned short i=lower; i<=upper; ++i) {
155 result[d] ^= multiply_GF2E<E>(in1[i],in2[d-i]);
163 template <
typename E>
164 inline void polyfromroots_GF2E(E *result,
const E *roots,
165 unsigned short numroots)
167 result[numroots] = 1;
168 for (
unsigned short r=0; r<numroots; ++r) {
169 result[numroots-r-1] = 0;
170 for (
unsigned short i=0; i<=r; ++i) {
171 result[numroots-r+i-1] ^=
172 multiply_GF2E<E>(result[numroots-r+i],roots[r]);