Chapter 10. PBC Internals

Algebraic structures are represented in the field_t data type, which mostly contains pointers to functions written to perform operations such as addition and multiplication on elements of that particular group, ring or field:

struct field_s {
  ...
  void (*init)(element_ptr);
  void (*clear)(element_ptr);
  ...
  void (*add)(element_ptr, element_ptr, element_ptr);
  void (*sub)(element_ptr, element_ptr, element_ptr);
  void (*mul)(element_ptr, element_ptr, element_ptr);
  ...
};
typedef struct field_s *field_ptr;
typedef struct field_s field_t[1];

The name algebraic_structure_t is arguably more accurate, but far too cumbersome. It may help if one views groups and rings as handicapped fields.

The last two lines of the above code excerpt show how GMP and PBC define data types: they are arrays of length one so that when a variable is declared, space is automatically allocated for it. Yet when used as a argument to a function, a pointer is passed, thus there is no need to explicitly allocate and deallocate memory, nor reference and dereference variables.

Each element_t contains a field named field to such a field_t variable. The only other field is data, which stores any data needed for the implementation of the particular algebraic structure the element resides in.

struct element_s {
  struct field_s *field;
  void *data;
};

When an element_t variable is initialized, field is set appropriately, and then the initialization specific to that field is called to complete the initialization. Here, a line of code is worth a thousand words:

void element_init(element_t e, field_ptr f) {
  e->field = f;
  f->init(e);
}

Thus during a call to one of the element_ functions, the field pointer is followed then the appropriate routine is executed. For example, modular addition results when the input element is an element of a finite field, while polynomial addition is performed for elements of a polynomial ring and so on.

void element_add(element_t n, element_t a, element_t b) {
  n->field->add(n, a, b);
}