2
* Copyright (c) 2014, James S. Plank and Kevin Greenan
5
* Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
8
* Revision 2.0: Galois Field backend now links to GF-Complete
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
14
* - Redistributions of source code must retain the above copyright
15
* notice, this list of conditions and the following disclaimer.
17
* - Redistributions in binary form must reproduce the above copyright
18
* notice, this list of conditions and the following disclaimer in
19
* the documentation and/or other materials provided with the
22
* - Neither the name of the University of Tennessee nor the names of its
23
* contributors may be used to endorse or promote products derived
24
* from this software without specific prior written permission.
26
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
33
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
34
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
36
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
* POSSIBILITY OF SUCH DAMAGE.
40
/* Jerasure's authors:
42
Revision 2.x - 2014: James S. Plank and Kevin M. Greenan
43
Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
44
Revision 1.0 - 2007: James S. Plank
53
#define MAX_GF_INSTANCES 64
54
gf_t *gfp_array[MAX_GF_INSTANCES] = { 0 };
55
int gfp_is_composite[MAX_GF_INSTANCES] = { 0 };
57
gf_t *galois_get_field_ptr(int w)
59
if (gfp_array[w] != NULL) {
66
gf_t* galois_init_field(int w,
78
if (w <= 0 || w > 32) {
79
fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
83
gfp = (gf_t *) malloc(sizeof(gf_t));
85
fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w);
89
scratch_size = gf_scratch_size(w, mult_type, region_type, divide_type, arg1, arg2);
91
fprintf(stderr, "ERROR -- cannot get scratch size for base field w=%d\n", w);
95
scratch_memory = malloc(scratch_size);
96
if (!scratch_memory) {
97
fprintf(stderr, "ERROR -- cannot get scratch memory for base field w=%d\n", w);
101
if(!gf_init_hard(gfp,
112
fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
116
gfp_is_composite[w] = 0;
120
gf_t* galois_init_composite_field(int w,
127
void *scratch_memory;
130
if (w <= 0 || w > 32) {
131
fprintf(stderr, "ERROR -- cannot init composite field for w=%d\n", w);
135
gfp = (gf_t *) malloc(sizeof(gf_t));
137
fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w);
141
scratch_size = gf_scratch_size(w, GF_MULT_COMPOSITE, region_type, divide_type, degree, 0);
143
fprintf(stderr, "ERROR -- cannot get scratch size for composite field w=%d\n", w);
147
scratch_memory = malloc(scratch_size);
148
if (!scratch_memory) {
149
fprintf(stderr, "ERROR -- cannot get scratch memory for composite field w=%d\n", w);
153
if(!gf_init_hard(gfp,
164
fprintf(stderr, "ERROR -- cannot init default composite field for w=%d\n", w);
167
gfp_is_composite[w] = 1;
171
static void galois_init_default_field(int w)
173
if (w <= 0 || w > 32) {
174
fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
178
if (gfp_array[w] == NULL) {
179
gfp_array[w] = (gf_t*)malloc(sizeof(gf_t));
180
if (gfp_array[w] == NULL) {
181
fprintf(stderr, "ERROR -- cannot allocate memory for Galois field w=%d\n", w);
186
if (!gf_init_easy(gfp_array[w], w)) {
187
fprintf(stderr, "ERROR -- cannot init default Galois field for w=%d\n", w);
193
static int is_valid_gf(gf_t *gf, int w)
195
// TODO: I assume we may eventually
196
// want to do w=64 and 128, so w
197
// will be needed to perform this check
203
if (gf->multiply.w32 == NULL) {
206
if (gf->multiply_region.w32 == NULL) {
209
if (gf->divide.w32 == NULL) {
212
if (gf->inverse.w32 == NULL) {
215
if (gf->extract_word.w32 == NULL) {
222
void galois_change_technique(gf_t *gf, int w)
224
if (w <= 0 || w > 32) {
225
fprintf(stderr, "ERROR -- cannot support Galois field for w=%d\n", w);
229
if (!is_valid_gf(gf, w)) {
230
fprintf(stderr, "ERROR -- overriding with invalid Galois field for w=%d\n", w);
234
if (gfp_array[w] != NULL) {
235
gf_free(gfp_array[w], gfp_is_composite[w]);
241
int galois_single_multiply(int x, int y, int w)
243
if (x == 0 || y == 0) return 0;
245
if (gfp_array[w] == NULL) {
246
galois_init_default_field(w);
250
return gfp_array[w]->multiply.w32(gfp_array[w], x, y);
252
fprintf(stderr, "ERROR -- Galois field not implemented for w=%d\n", w);
257
int galois_single_divide(int x, int y, int w)
259
if (x == 0) return 0;
260
if (y == 0) return -1;
262
if (gfp_array[w] == NULL) {
263
galois_init_default_field(w);
267
return gfp_array[w]->divide.w32(gfp_array[w], x, y);
269
fprintf(stderr, "ERROR -- Galois field not implemented for w=%d\n", w);
274
void galois_w08_region_multiply(char *region, /* Region to multiply */
275
int multby, /* Number to multiply by */
276
int nbytes, /* Number of bytes in region */
277
char *r2, /* If r2 != NULL, products go here */
280
if (gfp_array[8] == NULL) {
281
galois_init_default_field(8);
283
gfp_array[8]->multiply_region.w32(gfp_array[8], region, r2, multby, nbytes, add);
286
void galois_w16_region_multiply(char *region, /* Region to multiply */
287
int multby, /* Number to multiply by */
288
int nbytes, /* Number of bytes in region */
289
char *r2, /* If r2 != NULL, products go here */
292
if (gfp_array[16] == NULL) {
293
galois_init_default_field(16);
295
gfp_array[16]->multiply_region.w32(gfp_array[16], region, r2, multby, nbytes, add);
299
void galois_w32_region_multiply(char *region, /* Region to multiply */
300
int multby, /* Number to multiply by */
301
int nbytes, /* Number of bytes in region */
302
char *r2, /* If r2 != NULL, products go here */
305
if (gfp_array[32] == NULL) {
306
galois_init_default_field(32);
308
gfp_array[32]->multiply_region.w32(gfp_array[32], region, r2, multby, nbytes, add);
311
void galois_w8_region_xor(void *src, void *dest, int nbytes)
313
if (gfp_array[8] == NULL) {
314
galois_init_default_field(8);
316
gfp_array[8]->multiply_region.w32(gfp_array[32], src, dest, 1, nbytes, 1);
319
void galois_w16_region_xor(void *src, void *dest, int nbytes)
321
if (gfp_array[16] == NULL) {
322
galois_init_default_field(16);
324
gfp_array[16]->multiply_region.w32(gfp_array[16], src, dest, 1, nbytes, 1);
327
void galois_w32_region_xor(void *src, void *dest, int nbytes)
329
if (gfp_array[32] == NULL) {
330
galois_init_default_field(32);
332
gfp_array[32]->multiply_region.w32(gfp_array[32], src, dest, 1, nbytes, 1);
335
void galois_region_xor(char *src, char *dest, int nbytes)
338
galois_w32_region_xor(src, dest, nbytes);
341
for (i = 0; i < nbytes; i++) {
349
int galois_inverse(int y, int w)
351
if (y == 0) return -1;
352
return galois_single_divide(1, y, w);