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):

code.cpp Lines 6–6
using F2 = Fp<2>;

Using this shortcut, field elements can be instantiated using either of the following syntaxes:

code.cpp Lines 9–11
    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:

code.cpp Lines 13–14
    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:

code.cpp Lines 16–19
    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:

code.cpp Lines 21–23
    F2 f;
    f.randomize();
    auto g = F2().randomize();

Here, the second variant is preferred.

Field elements can be output using the overloaded << operator:

code.cpp Lines 25–25
    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):

code.cpp Lines 27–28
    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:

code.cpp Lines 30–32
    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:

code.cpp Lines 34–36
    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:

code.cpp
#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;
}