2 * GF-Complete: A Comprehensive Open Source Library for Galois Field Arithmetic
3 * James S. Plank, Ethan L. Miller, Kevin M. Greenan,
4 * Benjamin A. Arnold, John A. Burnum, Adam W. Disney, Allen C. McBride.
8 * Routines for Galois fields for general w < 32. For specific w,
9 like 4, 8, 16, 32, 64 and 128, see the other files.
16 struct gf_wgen_table_w8_data
{
22 struct gf_wgen_table_w16_data
{
28 struct gf_wgen_log_w8_data
{
35 struct gf_wgen_log_w16_data
{
42 struct gf_wgen_log_w32_data
{
49 struct gf_wgen_group_data
{
60 gf_val_32_t
gf_wgen_inverse_from_divide (gf_t
*gf
, gf_val_32_t a
)
62 return gf
->divide
.w32(gf
, 1, a
);
67 gf_val_32_t
gf_wgen_divide_from_inverse (gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
69 b
= gf
->inverse
.w32(gf
, b
);
70 return gf
->multiply
.w32(gf
, a
, b
);
75 gf_val_32_t
gf_wgen_euclid (gf_t
*gf
, gf_val_32_t b
)
78 gf_val_32_t e_i
, e_im1
, e_ip1
;
79 gf_val_32_t d_i
, d_im1
, d_ip1
;
80 gf_val_32_t y_i
, y_im1
, y_ip1
;
83 if (b
== 0) return -1;
84 e_im1
= ((gf_internal_t
*) (gf
->scratch
))->prim_poly
;
86 d_im1
= ((gf_internal_t
*) (gf
->scratch
))->w
;
87 for (d_i
= d_im1
; ((1 << d_i
) & e_i
) == 0; d_i
--) ;
97 while (d_ip1
>= d_i
) {
98 c_i
^= (1 << (d_ip1
- d_i
));
99 e_ip1
^= (e_i
<< (d_ip1
- d_i
));
100 if (e_ip1
== 0) return 0;
101 while ((e_ip1
& (1 << d_ip1
)) == 0) d_ip1
--;
104 y_ip1
= y_im1
^ gf
->multiply
.w32(gf
, c_i
, y_i
);
117 gf_val_32_t
gf_wgen_extract_word(gf_t
*gf
, void *start
, int bytes
, int index
)
125 h
= (gf_internal_t
*) gf
->scratch
;
130 ptr
= (uint8_t *) start
;
136 for (i
= 0; i
< h
->w
; i
++) {
138 if ((*ptr
) & (1 << bit
)) rv
|= 1;
147 gf_val_32_t
gf_wgen_matrix (gf_t
*gf
, gf_val_32_t b
)
149 return gf_bitmatrix_inverse(b
, ((gf_internal_t
*) (gf
->scratch
))->w
,
150 ((gf_internal_t
*) (gf
->scratch
))->prim_poly
);
156 gf_wgen_shift_multiply (gf_t
*gf
, uint32_t a32
, uint32_t b32
)
158 uint64_t product
, i
, pp
, a
, b
, one
;
163 h
= (gf_internal_t
*) gf
->scratch
;
165 pp
= h
->prim_poly
| (one
<< h
->w
);
169 for (i
= 0; i
< (uint64_t)h
->w
; i
++) {
170 if (a
& (one
<< i
)) product
^= (b
<< i
);
172 for (i
= h
->w
*2-1; i
>= (uint64_t)h
->w
; i
--) {
173 if (product
& (one
<< i
)) product
^= (pp
<< (i
-h
->w
));
179 int gf_wgen_shift_init(gf_t
*gf
)
181 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_shift_multiply
)
182 SET_FUNCTION(gf
,inverse
,w32
,gf_wgen_euclid
)
188 gf_wgen_bytwo_b_multiply (gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
190 uint32_t prod
, pp
, bmask
;
193 h
= (gf_internal_t
*) gf
->scratch
;
197 bmask
= (1 << (h
->w
-1));
200 if (a
& 1) prod
^= b
;
202 if (a
== 0) return prod
;
212 int gf_wgen_bytwo_b_init(gf_t
*gf
)
214 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_bytwo_b_multiply
)
215 SET_FUNCTION(gf
,inverse
,w32
,gf_wgen_euclid
)
222 gf_wgen_bytwo_p_multiply (gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
224 uint32_t prod
, pp
, pmask
, amask
;
227 h
= (gf_internal_t
*) gf
->scratch
;
231 pmask
= (1 << ((h
->w
)-1)); /*Ben: Had an operator precedence warning here*/
236 prod
= ((prod
<< 1) ^ pp
);
240 if (a
& amask
) prod
^= b
;
248 int gf_wgen_bytwo_p_init(gf_t
*gf
)
250 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_bytwo_p_multiply
)
251 SET_FUNCTION(gf
,inverse
,w32
,gf_wgen_euclid
)
257 gf_wgen_group_set_shift_tables(uint32_t *shift
, uint32_t val
, gf_internal_t
*h
)
263 if (h
->mult_type
== GF_MULT_DEFAULT
) {
271 for (i
= 1; i
< ((uint32_t)1 << g_s
); i
<<= 1) {
272 for (j
= 0; j
< i
; j
++) shift
[i
|j
] = shift
[j
]^val
;
273 if (val
& (1 << (h
->w
-1))) {
285 gf_wgen_group_s_equals_r_multiply(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
288 uint32_t p
, l
, ind
, a32
;
293 struct gf_wgen_group_data
*gd
;
294 gf_internal_t
*h
= (gf_internal_t
*) gf
->scratch
;
298 gd
= (struct gf_wgen_group_data
*) h
->private;
299 gf_wgen_group_set_shift_tables(gd
->shift
, b
, h
);
302 if (leftover
== 0) leftover
= g_s
;
314 while (bits_left
> 0) {
320 p
= (gd
->shift
[ind
] ^ gd
->reduce
[l
] ^ (p
<< g_s
)) & gd
->mask
;
325 char *bits(uint32_t v
)
332 for (i
= 27; i
>= 0; i
--) {
333 rv
[j
] = '0' + ((v
& (1 << i
)) ? 1 : 0);
339 char *bits_56(uint64_t v
)
349 for (i
= 55; i
>= 0; i
--) {
350 rv
[j
] = '0' + ((v
& (one
<< i
)) ? 1 : 0);
360 gf_wgen_group_multiply(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
367 struct gf_wgen_group_data
*gd
;
370 gf_internal_t
*h
= (gf_internal_t
*) gf
->scratch
;
371 if (h
->mult_type
== GF_MULT_DEFAULT
) {
379 gd
= (struct gf_wgen_group_data
*) h
->private;
380 gf_wgen_group_set_shift_tables(gd
->shift
, b
, h
);
383 if (leftover
== 0) leftover
= g_s
;
386 ind
= a32
>> (w
- leftover
);
394 ind
= a32
>> (w
-g_s
);
402 ind
= a32
>> (h
->w
-g_s
);
405 for (i
= gd
->tshift
; i
>= 0; i
-= g_r
) {
406 l
= p
& (gd
->rmask
<< i
);
407 r
= gd
->reduce
[l
>> (i
+w
)];
415 int gf_wgen_group_init(gf_t
*gf
)
417 uint32_t i
, j
, p
, index
;
418 struct gf_wgen_group_data
*gd
;
419 gf_internal_t
*h
= (gf_internal_t
*) gf
->scratch
;
422 if (h
->mult_type
== GF_MULT_DEFAULT
) {
429 gd
= (struct gf_wgen_group_data
*) h
->private;
430 gd
->shift
= &(gd
->memory
);
431 gd
->reduce
= gd
->shift
+ (1 << g_s
);
432 gd
->mask
= (h
->w
!= 31) ? ((1 << h
->w
)-1) : 0x7fffffff;
434 gd
->rmask
= (1 << g_r
) - 1;
437 gd
->tshift
= h
->w
% g_s
;
438 if (gd
->tshift
== 0) gd
->tshift
= g_s
;
439 gd
->tshift
= (h
->w
- gd
->tshift
);
440 gd
->tshift
= ((gd
->tshift
-1)/g_r
) * g_r
;
443 for (i
= 0; i
< ((uint32_t)1 << g_r
); i
++) {
446 for (j
= 0; j
< g_r
; j
++) {
448 p
^= (h
->prim_poly
<< j
);
449 index
^= (h
->prim_poly
>> (h
->w
-j
));
452 gd
->reduce
[index
] = (p
& gd
->mask
);
456 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_group_s_equals_r_multiply
)
458 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_group_multiply
)
460 SET_FUNCTION(gf
,divide
,w32
,NULL
)
461 SET_FUNCTION(gf
,divide
,w32
,NULL
)
468 gf_wgen_table_8_multiply(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
471 struct gf_wgen_table_w8_data
*std
;
473 h
= (gf_internal_t
*) gf
->scratch
;
474 std
= (struct gf_wgen_table_w8_data
*) h
->private;
476 return (std
->mult
[(a
<<h
->w
)+b
]);
481 gf_wgen_table_8_divide(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
484 struct gf_wgen_table_w8_data
*std
;
486 h
= (gf_internal_t
*) gf
->scratch
;
487 std
= (struct gf_wgen_table_w8_data
*) h
->private;
489 return (std
->div
[(a
<<h
->w
)+b
]);
493 int gf_wgen_table_8_init(gf_t
*gf
)
497 struct gf_wgen_table_w8_data
*std
;
500 h
= (gf_internal_t
*) gf
->scratch
;
502 std
= (struct gf_wgen_table_w8_data
*) h
->private;
504 std
->mult
= &(std
->base
);
505 std
->div
= std
->mult
+ ((1<<h
->w
)*(1<<h
->w
));
507 for (a
= 0; a
< ((uint32_t)1 << w
); a
++) {
514 for (a
= 1; a
< ((uint32_t)1 << w
); a
++) {
515 for (b
= 1; b
< ((uint32_t)1 << w
); b
++) {
516 p
= gf_wgen_shift_multiply(gf
, a
, b
);
517 std
->mult
[(a
<<w
)|b
] = p
;
518 std
->div
[(p
<<w
)|a
] = b
;
522 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_table_8_multiply
)
523 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_table_8_divide
)
529 gf_wgen_table_16_multiply(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
532 struct gf_wgen_table_w16_data
*std
;
534 h
= (gf_internal_t
*) gf
->scratch
;
535 std
= (struct gf_wgen_table_w16_data
*) h
->private;
537 return (std
->mult
[(a
<<h
->w
)+b
]);
542 gf_wgen_table_16_divide(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
545 struct gf_wgen_table_w16_data
*std
;
547 h
= (gf_internal_t
*) gf
->scratch
;
548 std
= (struct gf_wgen_table_w16_data
*) h
->private;
550 return (std
->div
[(a
<<h
->w
)+b
]);
554 int gf_wgen_table_16_init(gf_t
*gf
)
558 struct gf_wgen_table_w16_data
*std
;
561 h
= (gf_internal_t
*) gf
->scratch
;
563 std
= (struct gf_wgen_table_w16_data
*) h
->private;
565 std
->mult
= &(std
->base
);
566 std
->div
= std
->mult
+ ((1<<h
->w
)*(1<<h
->w
));
568 for (a
= 0; a
< ((uint32_t)1 << w
); a
++) {
575 for (a
= 1; a
< ((uint32_t)1 << w
); a
++) {
576 for (b
= 1; b
< ((uint32_t)1 << w
); b
++) {
577 p
= gf_wgen_shift_multiply(gf
, a
, b
);
578 std
->mult
[(a
<<w
)|b
] = p
;
579 std
->div
[(p
<<w
)|a
] = b
;
583 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_table_16_multiply
)
584 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_table_16_divide
)
589 int gf_wgen_table_init(gf_t
*gf
)
593 h
= (gf_internal_t
*) gf
->scratch
;
594 if (h
->w
<= 8) return gf_wgen_table_8_init(gf
);
595 if (h
->w
<= 14) return gf_wgen_table_16_init(gf
);
597 /* Returning zero to make the compiler happy, but this won't get
598 executed, because it is tested in _scratch_space. */
605 gf_wgen_log_8_multiply(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
608 struct gf_wgen_log_w8_data
*std
;
610 h
= (gf_internal_t
*) gf
->scratch
;
611 std
= (struct gf_wgen_log_w8_data
*) h
->private;
613 if (a
== 0 || b
== 0) return 0;
614 return (std
->anti
[std
->log
[a
]+std
->log
[b
]]);
619 gf_wgen_log_8_divide(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
622 struct gf_wgen_log_w8_data
*std
;
625 h
= (gf_internal_t
*) gf
->scratch
;
626 std
= (struct gf_wgen_log_w8_data
*) h
->private;
628 if (a
== 0 || b
== 0) return 0;
630 index
-= std
->log
[b
];
632 return (std
->danti
[index
]);
636 int gf_wgen_log_8_init(gf_t
*gf
)
639 struct gf_wgen_log_w8_data
*std
;
644 h
= (gf_internal_t
*) gf
->scratch
;
646 std
= (struct gf_wgen_log_w8_data
*) h
->private;
648 std
->log
= &(std
->base
);
649 std
->anti
= std
->log
+ (1<<h
->w
);
650 std
->danti
= std
->anti
+ (1<<h
->w
)-1;
652 for (i
= 0; i
< ((uint32_t)1 << w
); i
++)
656 for(i
=0; i
< ((uint32_t)1<<w
)-1; i
++)
658 if (std
->log
[a
] != 0) check
= 1;
669 _gf_errno
= GF_E_LOGPOLY
;
673 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_log_8_multiply
)
674 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_log_8_divide
)
680 gf_wgen_log_16_multiply(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
683 struct gf_wgen_log_w16_data
*std
;
685 h
= (gf_internal_t
*) gf
->scratch
;
686 std
= (struct gf_wgen_log_w16_data
*) h
->private;
688 if (a
== 0 || b
== 0) return 0;
689 return (std
->anti
[std
->log
[a
]+std
->log
[b
]]);
694 gf_wgen_log_16_divide(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
697 struct gf_wgen_log_w16_data
*std
;
700 h
= (gf_internal_t
*) gf
->scratch
;
701 std
= (struct gf_wgen_log_w16_data
*) h
->private;
703 if (a
== 0 || b
== 0) return 0;
705 index
-= std
->log
[b
];
707 return (std
->danti
[index
]);
711 int gf_wgen_log_16_init(gf_t
*gf
)
714 struct gf_wgen_log_w16_data
*std
;
719 h
= (gf_internal_t
*) gf
->scratch
;
721 std
= (struct gf_wgen_log_w16_data
*) h
->private;
723 std
->log
= &(std
->base
);
724 std
->anti
= std
->log
+ (1<<h
->w
);
725 std
->danti
= std
->anti
+ (1<<h
->w
)-1;
727 for (i
= 0; i
< ((uint32_t)1 << w
); i
++)
731 for(i
=0; i
< ((uint32_t)1<<w
)-1; i
++)
733 if (std
->log
[a
] != 0) check
= 1;
744 if (h
->mult_type
!= GF_MULT_LOG_TABLE
) return gf_wgen_shift_init(gf
);
745 _gf_errno
= GF_E_LOGPOLY
;
749 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_log_16_multiply
)
750 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_log_16_divide
)
756 gf_wgen_log_32_multiply(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
759 struct gf_wgen_log_w32_data
*std
;
761 h
= (gf_internal_t
*) gf
->scratch
;
762 std
= (struct gf_wgen_log_w32_data
*) h
->private;
764 if (a
== 0 || b
== 0) return 0;
765 return (std
->anti
[std
->log
[a
]+std
->log
[b
]]);
770 gf_wgen_log_32_divide(gf_t
*gf
, gf_val_32_t a
, gf_val_32_t b
)
773 struct gf_wgen_log_w32_data
*std
;
776 h
= (gf_internal_t
*) gf
->scratch
;
777 std
= (struct gf_wgen_log_w32_data
*) h
->private;
779 if (a
== 0 || b
== 0) return 0;
781 index
-= std
->log
[b
];
783 return (std
->danti
[index
]);
787 int gf_wgen_log_32_init(gf_t
*gf
)
790 struct gf_wgen_log_w32_data
*std
;
795 h
= (gf_internal_t
*) gf
->scratch
;
797 std
= (struct gf_wgen_log_w32_data
*) h
->private;
799 std
->log
= &(std
->base
);
800 std
->anti
= std
->log
+ (1<<h
->w
);
801 std
->danti
= std
->anti
+ (1<<h
->w
)-1;
803 for (i
= 0; i
< ((uint32_t)1 << w
); i
++)
807 for(i
=0; i
< ((uint32_t)1<<w
)-1; i
++)
809 if (std
->log
[a
] != 0) check
= 1;
820 _gf_errno
= GF_E_LOGPOLY
;
824 SET_FUNCTION(gf
,multiply
,w32
,gf_wgen_log_32_multiply
)
825 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_log_32_divide
)
830 int gf_wgen_log_init(gf_t
*gf
)
834 h
= (gf_internal_t
*) gf
->scratch
;
835 if (h
->w
<= 8) return gf_wgen_log_8_init(gf
);
836 if (h
->w
<= 16) return gf_wgen_log_16_init(gf
);
837 if (h
->w
<= 32) return gf_wgen_log_32_init(gf
);
839 /* Returning zero to make the compiler happy, but this won't get
840 executed, because it is tested in _scratch_space. */
845 int gf_wgen_scratch_size(int w
, int mult_type
, int region_type
, int divide_type
, int arg1
, int arg2
)
850 case GF_MULT_DEFAULT
:
852 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_table_w8_data
) +
853 sizeof(uint8_t)*(1 << w
)*(1<<w
)*2 + 64;
854 } else if (w
<= 16) {
855 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_log_w16_data
) +
856 sizeof(uint16_t)*(1 << w
)*3;
858 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_group_data
) +
859 sizeof(uint32_t) * (1 << 2) +
860 sizeof(uint32_t) * (1 << 8) + 64;
863 case GF_MULT_BYTWO_b
:
864 case GF_MULT_BYTWO_p
:
865 return sizeof(gf_internal_t
);
868 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_group_data
) +
869 sizeof(uint32_t) * (1 << arg1
) +
870 sizeof(uint32_t) * (1 << arg2
) + 64;
875 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_table_w8_data
) +
876 sizeof(uint8_t)*(1 << w
)*(1<<w
)*2 + 64;
878 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_table_w16_data
) +
879 sizeof(uint16_t)*(1 << w
)*(1<<w
)*2 + 64;
882 case GF_MULT_LOG_TABLE
:
884 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_log_w8_data
) +
885 sizeof(uint8_t)*(1 << w
)*3;
886 } else if (w
<= 16) {
887 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_log_w16_data
) +
888 sizeof(uint16_t)*(1 << w
)*3;
889 } else if (w
<= 27) {
890 return sizeof(gf_internal_t
) + sizeof(struct gf_wgen_log_w32_data
) +
891 sizeof(uint32_t)*(1 << w
)*3;
900 gf_wgen_cauchy_region(gf_t
*gf
, void *src
, void *dest
, gf_val_32_t val
, int bytes
, int xor)
907 gf_set_region_data(&rd
, gf
, src
, dest
, bytes
, val
, xor, -1);
909 if (val
== 0) { gf_multby_zero(dest
, bytes
, xor); return; }
910 if (val
== 1) { gf_multby_one(src
, dest
, bytes
, xor); return; }
912 h
= (gf_internal_t
*) gf
->scratch
;
915 written
= (xor) ? 0xffffffff : 0;
916 for (i
= 0; i
< h
->w
; i
++) {
917 for (j
= 0; j
< h
->w
; j
++) {
918 if (val
& (1 << j
)) {
919 gf_multby_one(src
, ((uint8_t *)dest
) + j
*rs
, rs
, (written
& (1 << j
)));
923 src
= (uint8_t *)src
+ rs
;
924 val
= gf
->multiply
.w32(gf
, val
, 2);
928 int gf_wgen_init(gf_t
*gf
)
932 h
= (gf_internal_t
*) gf
->scratch
;
933 if (h
->prim_poly
== 0) {
935 case 1: h
->prim_poly
= 1; break;
936 case 2: h
->prim_poly
= 7; break;
937 case 3: h
->prim_poly
= 013; break;
938 case 4: h
->prim_poly
= 023; break;
939 case 5: h
->prim_poly
= 045; break;
940 case 6: h
->prim_poly
= 0103; break;
941 case 7: h
->prim_poly
= 0211; break;
942 case 8: h
->prim_poly
= 0435; break;
943 case 9: h
->prim_poly
= 01021; break;
944 case 10: h
->prim_poly
= 02011; break;
945 case 11: h
->prim_poly
= 04005; break;
946 case 12: h
->prim_poly
= 010123; break;
947 case 13: h
->prim_poly
= 020033; break;
948 case 14: h
->prim_poly
= 042103; break;
949 case 15: h
->prim_poly
= 0100003; break;
950 case 16: h
->prim_poly
= 0210013; break;
951 case 17: h
->prim_poly
= 0400011; break;
952 case 18: h
->prim_poly
= 01000201; break;
953 case 19: h
->prim_poly
= 02000047; break;
954 case 20: h
->prim_poly
= 04000011; break;
955 case 21: h
->prim_poly
= 010000005; break;
956 case 22: h
->prim_poly
= 020000003; break;
957 case 23: h
->prim_poly
= 040000041; break;
958 case 24: h
->prim_poly
= 0100000207; break;
959 case 25: h
->prim_poly
= 0200000011; break;
960 case 26: h
->prim_poly
= 0400000107; break;
961 case 27: h
->prim_poly
= 01000000047; break;
962 case 28: h
->prim_poly
= 02000000011; break;
963 case 29: h
->prim_poly
= 04000000005; break;
964 case 30: h
->prim_poly
= 010040000007; break;
965 case 31: h
->prim_poly
= 020000000011; break;
966 case 32: h
->prim_poly
= 00020000007; break;
967 default: fprintf(stderr
, "gf_wgen_init: w not defined yet\n"); exit(1);
971 h
->prim_poly
&= 0xffffffff;
973 h
->prim_poly
|= (1 << h
->w
);
974 if (h
->prim_poly
& ~((1ULL<<(h
->w
+1))-1)) return 0;
978 SET_FUNCTION(gf
,multiply
,w32
,NULL
)
979 SET_FUNCTION(gf
,divide
,w32
,NULL
)
980 SET_FUNCTION(gf
,inverse
,w32
,NULL
)
981 SET_FUNCTION(gf
,multiply_region
,w32
,gf_wgen_cauchy_region
)
982 SET_FUNCTION(gf
,extract_word
,w32
,gf_wgen_extract_word
)
984 switch(h
->mult_type
) {
985 case GF_MULT_DEFAULT
:
987 if (gf_wgen_table_init(gf
) == 0) return 0;
988 } else if (h
->w
<= 16) {
989 if (gf_wgen_log_init(gf
) == 0) return 0;
991 if (gf_wgen_bytwo_p_init(gf
) == 0) return 0;
994 case GF_MULT_SHIFT
: if (gf_wgen_shift_init(gf
) == 0) return 0; break;
995 case GF_MULT_BYTWO_b
: if (gf_wgen_bytwo_b_init(gf
) == 0) return 0; break;
996 case GF_MULT_BYTWO_p
: if (gf_wgen_bytwo_p_init(gf
) == 0) return 0; break;
997 case GF_MULT_GROUP
: if (gf_wgen_group_init(gf
) == 0) return 0; break;
998 case GF_MULT_TABLE
: if (gf_wgen_table_init(gf
) == 0) return 0; break;
999 case GF_MULT_LOG_TABLE
: if (gf_wgen_log_init(gf
) == 0) return 0; break;
1002 if (h
->divide_type
== GF_DIVIDE_EUCLID
) {
1003 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_divide_from_inverse
)
1004 SET_FUNCTION(gf
,inverse
,w32
,gf_wgen_euclid
)
1005 } else if (h
->divide_type
== GF_DIVIDE_MATRIX
) {
1006 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_divide_from_inverse
)
1007 SET_FUNCTION(gf
,inverse
,w32
,gf_wgen_matrix
)
1010 if (gf
->inverse
.w32
== NULL
&& gf
->divide
.w32
== NULL
) SET_FUNCTION(gf
,inverse
,w32
,gf_wgen_euclid
)
1012 if (gf
->inverse
.w32
!= NULL
&& gf
->divide
.w32
== NULL
) {
1013 SET_FUNCTION(gf
,divide
,w32
,gf_wgen_divide_from_inverse
)
1015 if (gf
->inverse
.w32
== NULL
&& gf
->divide
.w32
!= NULL
) {
1016 SET_FUNCTION(gf
,inverse
,w32
,gf_wgen_inverse_from_divide
)