CECCO: Prime Fields
CECCO supports prime fields, their arithmetic, and their properties. To work with a prime field, it is convenient to define a shortcut for it (here for the binary field consisting of 0 and 1 together with addition/XOR and multiplication/AND):
using F2 = Fp<2>;
Using this shortcut, field elements can be instantiated using either of the following syntaxes:
F2 a(1);
F2 b = 0;
auto c = F2(1);
All three variants are equivalent, but the third one is preferred.
Information about a particular field can be obtained through the static get_info() member:
std::cout << "Show textual info about the field:" << std::endl;
std::cout << F2::get_info() << std::endl;
Show textual info about the field: prime field with 2 elements
All operators are overloaded for prime fields, so we can work with them very conveniently:
c = a + b;
auto d = c * c;
auto e = -d / F2(1);
e *= c;
Random field elements with a uniform distribution can be obtained as follows:
F2 f;
f.randomize();
auto g = F2().randomize();
Here, the second variant is preferred.
Field elements can be output using the overloaded << operator:
std::cout << "(Random) value of g is " << g << std::endl;
(Random) value of g is 1
Field elements know
their basic properties (a full list is available in the documentation):
std::cout << "Additive order of g: " << g.get_additive_order() << std::endl;
if (!g.is_zero()) std::cout << "Multiplicative order of g: " << g.get_multiplicative_order() << std::endl;
Additive order of g: 2 Multiplicative order of g: 1
If erasure support is enabled (by defining CECCO_ERASURE_SUPPORT before including cecco.hpp), elements can be erased
, that is, set to an out-of-field value represented by X:
g.erase();
std::cout << "Value of erased g is " << g << std::endl;
if (g.is_erased()) std::cout << "g is now erased" << std::endl;
Value of erased g is X g is now erased
Arithmetic with erased field elements is not defined, and it is the user's responsibility to avoid it. Previously erased field elements can be reset to an in-field value by un-erasing
them:
g.unerase();
std::cout << "Value of unerased g is " << g << std::endl;
if (!g.is_erased()) std::cout << "g is not erased any more" << std::endl;
Value of unerased g is 0 g is not erased any more
Prime fields can be defined for any prime greater than one, so we can have using F3 = Fp<3>;, using F5 = Fp<5>;, using F7 = Fp<7>;, and so on.
A complete, compilable demo is shown below:
#include <iostream>
#define CECCO_ERASURE_SUPPORT
#include "cecco.hpp"
using namespace CECCO;
using F2 = Fp<2>;
int main(void) {
F2 a(1);
F2 b = 0;
auto c = F2(1);
std::cout << "Show textual info about the field:" << std::endl;
std::cout << F2::get_info() << std::endl;
c = a + b;
auto d = c * c;
auto e = -d / F2(1);
e *= c;
F2 f;
f.randomize();
auto g = F2().randomize();
std::cout << "(Random) value of g is " << g << std::endl;
std::cout << "Additive order of g: " << g.get_additive_order() << std::endl;
if (!g.is_zero()) std::cout << "Multiplicative order of g: " << g.get_multiplicative_order() << std::endl;
g.erase();
std::cout << "Value of erased g is " << g << std::endl;
if (g.is_erased()) std::cout << "g is now erased" << std::endl;
g.unerase();
std::cout << "Value of unerased g is " << g << std::endl;
if (!g.is_erased()) std::cout << "g is not erased any more" << std::endl;
return 0;
}
