CALIB provides the GFpkx
domain, representing the ring
GF(p^k)[x], the univariate polynomials having coefficients that
are in the Galois Field GF(p^k).
The “values” of this domain are represented by the following object:
struct calib_GFpkx_obj { int degree; /* Degree of polynomial */ int size; /* Size of coeff buffer (degree < size) */ const struct calib_GFpkx_dom * dom; /* Domain of polynomial */ struct calib_GFpk_obj * coeff; /* Coefficients of polynomial. */ };
The following additional object is used to represent linked-lists of factors produced by various GFpkx factorization algorithms:
struct calib_GFpkx_factor { int multiplicity; struct calib_GFpkx_obj * factor; struct calib_GFpkx_factor * next; };
CALIB GFpkx
domains are constructed by specifying a GFpk
domain used to represent the coefficients of the corresponding GFpkx
polynomials.
One may access CALIB’s GFpkx
domain as follows:
#include "calib/GFpkx.h" ... struct calib_Zpx_obj * gpoly; struct calib_GFpk_dom * GFpk; struct calib_GFpkx_dom * GFpkx; struct calib_GFpkx_obj poly1, poly2; ... gpoly = /* Make generator polynomial in Zp[x]. */ GFpk = calib_make_GFpk_dom (gpoly); GFpkx = calib_make_GFpkx_dom (GFpk); ... GFpkx -> init (&poly1); GFpkx -> init (&poly2); ... GFpkx -> mul (GFpkx, &poly1, &poly1, &poly2); ... GFpkx -> clear (&poly2); GFpkx -> clear (&poly1); calib_free_GFpkx_dom (GFpkx); calib_free_GFPk_dom (GFpk); ...
The struct calib_GFpkx_dom
object contains the following members
(pointers to functions) that provide operations of the domain:
void (*init) (const struct calib_GFpkx_dom * K_of_x, struct calib_GFpkx_obj * x);
Initialize the given GFpkx polynomial x
, where:
K_of_x | is the GFpkx ring/domain the polynomial belongs to; and |
x | is the polynomial to initialize. |
void (*init_degree) (const struct calib_GFpkx_dom * K_of_x, struct calib_GFpkx_obj * x, int degree);
Initialize the given GFpkx polynomial x
(while assuring that
internal buffers are sufficiently large to hold a polynomial of up to
the given degree
without further allocation), where:
K_of_x | is the GFpkx ring/domain the polynomial belongs to; |
x | is the polynomial to initialize; and |
degree | is the guaranteed minimimum degree polynomial that x
will be able to hold (without further buffer allocation) upon
successful completion of this operation. |
void (*alloc) (struct calib_GFpkx_obj * rop, int degree);
Force the given (already initialized) polynomial rop
to have
buffer space sufficient to hold a polynomial of at least the given
degree
, where:
rop | is the polynomial whose allocation is to be adjusted; and |
degree | is the guaranteed minimum degree polynomial that rop will
be able to hold (without further buffer allocation) upon successful
completion of this operation. |
void (*clear) (struct calib_GFpkx_obj * x);
Clear out the given polynomial x
(freeing all memory it might
hold and returning it to the constant value of zero), where:
x | is the polynomial to be cleared. |
void (*set) (struct calib_GFpkx_obj * rop, const struct calib_GFpkx_obj * op);
Set rop
to op
in GFpkx, where:
rop | is the polynomial receiving the result; |
rop | is the polynomial to copy. |
void (*set_si) (struct calib_GFpkx_obj * rop, calib_si_t op);
Set rop
to op
in GFpkx, where:
rop | is the polynomial receiving the result; |
op | is the integer value to set. |
void (*set_z) (struct calib_GFpkx_obj * rop, mpz_srcptr op);
Set rop
to op
in GFpkx, where:
rop | is the polynomial receiving the result; |
op | is the GMP integer value to set. |
void (*set_q) (struct calib_GFpkx_obj * rop, mpq_srcptr op);
Set rop
to op
in GFpkx, where:
rop | is the polynomial receiving the result; |
op | is the GMP rational value to set. |
void (*set_var_power) (struct calib_GFpkx_obj * rop, int power);
Set rop
to x ** power
in GFpkx, where:
rop | is the Zpx polynomial receiving the result; |
power | is the power to set (must be non-negative). |
void (*add) (struct calib_GFpkx_obj * rop, const struct calib_GFpkx_obj * op1, const struct calib_GFpkx_obj * op2);
Set rop
to op1 + op2
in GFpkx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*sub) (struct calib_GFpkx_obj * rop, const struct calib_GFpkx_obj * op1, const struct calib_GFpkx_obj * op2);
Set rop
to op1 - op2
in GFpkx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*neg) (struct calib_GFpkx_obj * rop, const struct calib_GFpkx_obj * op);
Set rop
to - op
in GFpkx, where:
rop | is the GFpkx polynomial receiving the result; and |
op | is the GFpkx polynomial being negated. |
void (*mul) (struct calib_GFpkx_obj * rop, const struct calib_GFpkx_obj * op1, const struct calib_GFpkx_obj * op2);
Set rop
to op1 * op2
in GFpkx, where:
rop | is the polynomial receiving the result; |
op1 | is the first operand; and |
op2 | is the second operand. |
void (*mul_z) (struct calib_GFpkx_obj * rop, const struct calib_GFpkx_obj * op1, mpz_srcptr op2);
Set rop
to op1 * op2
in GFpkx, where:
rop | is the polynomial receiving the result; |
op1 | is the first (polynomial) operand; and |
op2 | is the second (GMP integer) operand. |
void (*ipow) (struct calib_GFpkx_obj * rop, const struct calib_GFpkx_obj * op, int power);
Set rop
to op ** power
in GFpkx, where:
rop | is the polynomial receiving the result; |
op | is the polynomial to exponentiate; and |
power | is the power to take (must be >= 0). |
struct calib_GFpkx_obj * (*dup) (const struct calib_GFpkx_obj * op);
Return a dynamically-allocated GFpkx polynomial that is a copy of
op
, where:
op | is the polynomial to be duplicated. |
void (*free) (struct calib_GFpkx_obj * poly);
Free the given dynamically-allocated polynomial poly
, where:
poly | is the polynomial to be freed. |
This is equivalent to performing GFpkx -> clear (poly);
, followed
by free (poly);
.
void (*eval) (struct calib_GFpk_obj * rop, const struct calib_GFpkx_obj * poly, const struct calib_GFpk_obj * value);
Evaluate polynomial poly
at the given value
, storing the
result in rop
, where:
rop | is the GFpk value object receiving the result; |
op | is the polynomial to be evaluated; and |
value | is the GFpk value at which to evaluate the polynomial. |
void (*div) (struct calib_GFpkx_obj * quotient, struct calib_GFpkx_obj * remainder, const struct calib_GFpkx_obj * a, const struct calib_GFpkx_obj * b);
Polynomial division in GF(p^k)[x], where:
quotient | receives the quotient polynomial (may be NULL); |
remainder | receives the remainder polynomial (may be NULL); |
a | is the dividend polynomial; and |
b | is the divisor polynomial (may not be zero). |
Division in GF(p^k)[x] has the following properties:
void (*gcd) (struct calib_GFpkx_obj * gcd, const struct calib_GFpkx_obj * a, const struct calib_GFpkx_obj * b);
Compute the greatest common divisor (GCD) of a
and b
,
storing the result in gcd
, where:
gcd | receives the resulting GCD polynomial (always monic); |
a | is the first operand polynomial; and |
b | is the second operand polynomial. |
The GCD is always monic unless a = b = 0.
void (*extgcd) (struct calib_GFpkx_obj * gcd, struct calib_GFpkx_obj * xa, struct calib_GFpkx_obj * xb, const struct calib_GFpkx_obj * a, const struct calib_GFpkx_obj * b);
The extended Euclidean algorithm.
Compute polynomials gcd
, xa
and xb
such that
gcd = a * xa + b * xb, where:
K_of_x | is the GFpkx ring/domain performing this operation; |
gcd | receives the resulting GCD polynomial (always monic); |
xa | receives the multiplier polynomial for a ; |
xb | receives the multiplier polynomial for b ; |
a | is the first operand polynomial; and |
b | is the second operand polynomial. |
The result satisfies the following properties:
struct calib_GFpkx_obj * (*cvZax) (const struct calib_GFpkx_dom * K_of_x, const struct calib_Zax_obj * op);
Return a dynamically-allocated GFpkx polynomial that is copied from the
given Zax polynomial op
, where:
K_of_x | is the destination GFpkx ring/domain; |
poly | is the Zax polynomial to be copied into GFpkx form. |
Note: this function requires that K_of_x
and the Zax domain of
op
have the same generator polynomial — it is a fatal
error if they do not.
struct calib_GFpkx_factor * (*factor) (const struct calib_GFpkx_obj * poly);
Factor the given polynomial poly
into its irreducible
factors, returning a linked list of these factors, where:
poly | is the GFpkx polynomial to be factored. |
Except for an optional leading constant factor, all other factors are monic and irreducible.
void (*free_factors) (struct calib_GFpkx_factor * factors);
Free up the given list of GFpkx factors, where:
factors | is a linked-list factors to be freed. |
void (*set_random) (struct calib_GFpkx_obj * rop, int d, struct calib_Random * randp);
Set rop
to be a randomly chosen GFpkx polynomial of degree
d
, using random numbers from randp
, where:
rop | receives the GFpkx polynomial result; |
d | is the degree of polynomial to generate; and |
randp | is the random number generator to use. |
calib_bool (*zerop) (const struct calib_GFpkx_obj * op);
Return 1 if-and-only-if the given GFpkx polynomial is identically zero and 0 otherwise, where:
op | is the GFpkx polynomial to test for zero. |
calib_bool (*onep) (const struct calib_GFpkx_obj * op);
Return 1 if-and-only-if the given GFpkx polynomial is identically one and 0 otherwise, where:
op | is the GFpkx polynomial to test for one. |
void (*set_genrep) (struct calib_GFpkx_obj * rop, const struct calib_genrep * op, const char * xvar, const char * avar);
Compute a GFpkx polynomial obtained from the given
genrep op
, interpreting xvar
to be the name of the
variable used by the GFpkx polynomial and avar
to be the name
of the variable used by the GFpk coefficients, storing the result in
rop
, where:
rop | receives the GFpkx polynomial result; |
op | is the genrep to convert into GFpkx polynomial form; |
xvar | is the variable name (appearing within genrep op ) that is
to be interpreted as the polynomial variable in GFpkx; and |
avar | is the variable name (appearing within genrep op ) that is
to be interpreted as the variable used by the GFpk coefficients. |
struct calib_genrep * (*to_genrep) (const struct calib_GFpkx_obj * op, const char * xvar, const char * avar);
Return a dynamically-allocated genrep corresponding to the given GFpkx
polynomial op
, using xvar
as the name of the GFpkx
polynomial variable and avar
as the name of the GFpk
coefficient variable within the returned genrep, where:
op | is the GFpkx polynomial to convert into genrep form; |
xvar | is the variable name to use in the genrep for the polynomial variable of GFpkx; and |
avar | is the variable name to use in the genrep for the GFpk coefficients. |
struct calib_genrep * (*factors_to_genrep) (const struct calib_GFpkx_factor * factors, const char * xvar, const char * avar);
Return a dynamically-allocated genrep corresponding to the given list
of GFpkx factors
, using xvar
as the name of the GFpkx
polynomial variable and avar
as the name of the GFpk
coefficient variable within the returned genrep, where:
factors | is the list of GFpkx polynomial factors to convert into genrep form; and |
xvar | is the variable name to use in the genrep for the polynomial variable of GFpkx; |
avar | is the variable name to use in the genrep for the GFpk coefficients. |