123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195(** Base module signature for a finite field *)moduletypeBASE=sigexceptionNot_in_fieldofBytes.ttypet(** The order of the finite field *)valorder:Z.t(** Minimal number of bytes required to encode a value of the field *)valsize_in_bytes:int(** [check_bytes bs] returns [true] if [bs] is a correct byte representation
of a field element *)valcheck_bytes:Bytes.t->bool(** [copy x] creates a fresh copy of [x] *)valcopy:t->t(** The neutral element for the addition *)valzero:t(** The neutral element for the multiplication *)valone:t(** [is_zero x] returns [true] if [x] is the neutral element for the addition *)valis_zero:t->bool(** [is_one x] returns [true] if [x] is the neutral element for the
multiplication *)valis_one:t->bool(** {b Use carefully!}
[random ()] returns a random element of the field. A state for the PRNG
can be given to initialize the PRNG in the requested state. If no state is
given, no initialisation is performed.
To create a value of type [Random.State.t], you can use [Random.State.make
[|42|]]. *)valrandom:?state:Random.State.t->unit->t(** {b Use carefully!}
[non_null_random ()] returns a non null random element of the field. A
state for the PRNG can be given to initialize the PRNG in the requested
state. If no state is given, no initialisation is performed.
To create a value of type [Random.State.t], you can use [Random.State.make
[|42|]]. *)valnon_null_random:?state:Random.State.t->unit->t(** [add a b] returns [a + b mod order] *)valadd:t->t->t(** Infix operator for {!add} *)val(+):t->t->t(** [sub a b] returns [a - b mod order] *)valsub:t->t->t(** [mul a b] returns [a * b mod order] *)valmul:t->t->t(** Infix operator for {!mul} *)val(*):t->t->t(** [eq a b] returns [true] if [a = b mod order], else [false] *)valeq:t->t->bool(** Infix operator for {!eq} *)val(=):t->t->bool(** [negate x] returns [-x mod order]. Equivalently, [negate x] returns the
unique [y] such that [x + y mod order = 0] *)valnegate:t->t(** Infix operator for {!negate} *)val(-):t->t(** [inverse_exn x] returns [x^-1 mod order] if [x] is not [0], else raise
[Division_by_zero]. Equivalently, [inverse_exn x] returns the unique [y]
such that [x * y mod order = 1] *)valinverse_exn:t->t(** [inverse_opt x] returns [x^-1 mod order] as an option if [x] is not [0],
else returns [None]. Equivalently, [inverse_opt x] returns the unique [y]
such that [x * y mod order = 1] *)valinverse_opt:t->toption(** [div_exn a b] returns [a * b^-1]. Raise [Division_by_zero] if [b = zero].
Equivalently, [div_exn] returns the unique [y] such that [b * y mod order
= a] *)valdiv_exn:t->t->t(** [div_opt a b] returns [a * b^-1] as an option. Return [None] if [b =
zero]. Equivalently, [div_opt] returns the unique [y] such that [b * y mod
order = a] *)valdiv_opt:t->t->toption(** Infix operator for {!div_exn} *)val(/):t->t->t(** [square x] returns [x^2 mod order] *)valsquare:t->t(** [double x] returns [2x mod order] *)valdouble:t->t(** [pow x n] returns [x^n mod order] *)valpow:t->Z.t->t(** Infix operator for {!pow} *)val(**):t->Z.t->t(** Construct a value of type [t] from the bytes representation in little
endian of the field element. For non prime fields, the encoding starts
with the coefficient of the constant monomial. Raise {!Not_in_field} if
the bytes do not represent an element in the field. *)valof_bytes_exn:Bytes.t->t(** From a predefined little endian bytes representation, construct a value of
type [t]. The same representation than {!of_bytes_exn} is used. Return
[None] if the bytes do not represent an element in the field. *)valof_bytes_opt:Bytes.t->toption(** Convert the value [t] to a bytes representation. The number of bytes is
{!size_in_bytes} and the encoding must be in little endian. For instance,
the encoding of [1] in prime fields is always a bytes sequence of size
{!size_in_bytes} starting with the byte [0b00000001].
For non prime fields, the encoding starts with the coefficient of the
constant monomial. For instance, an element [a + b * X] in [GF(p^2)] will
be encoded as [to_bytes a || to_bytes b] where [||] is the concatenation
of bytes *)valto_bytes:t->Bytes.tend(** Module type for prime field of the form [GF(p)] where [p] is prime. The
order of GF(p) is [p] *)moduletypePRIME=sigincludeBASE(** Returns [s, q] such that [p - 1 = 2^s * q] *)valfactor_power_of_two:int*Z.t(** Create a value of type [t] from a predefined string representation. It is
not required that [to_string (of_string t) = t]. By default, decimal
representation of the number is used, modulo the order of the field *)valof_string:string->t(** String representation of a value of type [t]. It is not required that
[to_string (of_string t) = t]. By default, decimal representation of the
number is used. *)valto_string:t->string(** [of_z x] builds an element of type [t] from the Zarith element [x]. [mod
p] is applied if [x >= p] *)valof_z:Z.t->t(** [to_z x] builds a Zarith element, using the decimal representation.
Arithmetic on the result can be done using the modular functions on
integers *)valto_z:t->Z.t(** Returns the Legendre symbol of the parameter. Note it does not work for [p
= 2] *)vallegendre_symbol:t->Z.t(** [is_quadratic_residue x] returns [true] if [x] is a quadratic residue i.e.
if there exists [n] such that [n^2 mod p = x] *)valis_quadratic_residue:t->bool(** [sqrt_opt x] returns a square root of [x] as an option if it does exist.
If it does not exist, returns [None]. Equivalenty it returns a value [y]
such that [y^2 mod p = x]. *)valsqrt_opt:t->toption(** [of_int x] is equivalent to [of_z (Z.of_int x)] *)valof_int:int->tend(** Module type for prime field with additional functions to manipulate roots of
unity *)moduletypePRIME_WITH_ROOT_OF_UNITY=sigincludePRIME(** [get_nth_root_of_unity n] returns a [n]-th root of unity. Equivalently, it
returns a value [x] such that [x^n mod p = 1] *)valget_nth_root_of_unity:Z.t->t(** [is_nth_root_of_unity n x] returns [true] if [x] is a [n]-th root of
unity. Equivalenty it returns [true] if [x^n mod p = 1] *)valis_nth_root_of_unity:Z.t->t->boolend