packages feed

lol-cpp-0.2.0.0: Crypto/Lol/Cyclotomic/Tensor/CPP/zq.cpp

/*
Module      : zq.cpp
Description : Implementation of Z_q-specific functions.
Copyright   : (c) Eric Crockett, 2011-2017
                  Chris Peikert, 2011-2017
License     : GPL-3
Maintainer  : ecrockett0@email.com
Stability   : experimental
Portability : POSIX

Helper functions for modular arithmetic, including computing the inverse of a
mod-q value, and obtaining the canonical representative of a Z_q element.
*/

#include "types.h"
#include "common.h"

// Compute b^{-1} mod a (not necessarily in canonical form)
// Returns 0 if b is not invertible mod a.
hInt_t reciprocal (hInt_t a, hInt_t b)
{
  // extended Euclidean algorithm, matching description from wikipedia:
  // https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
  // In this implementation, a an b track the 'r' sequence, t0/t1 track
  // the t sequence, which computes the inverse of b.

  hInt_t fieldSize = a;

  // t0/t1 help compute the Bezout coefficient for b (i.e., b inverse mod a)
  hInt_t t0 = 0;
  hInt_t t1 = 1;

  // Euclid's algorithm is done when we get a remainder of 0
  while (b != 0) {
    // a = b*quotient + tmp
    hInt_t quotient = a / b;
    hInt_t tmp = a % b;
    // prepare for the next iteration
    a = b;
    b = tmp;
    // store the next 't' coefficient into t1, and move the old t1 into t0
    tmp = t1;
    t1 = t0 - quotient*t1;
    t0 = tmp;
  }
  // if a (the last non-zero remainder) !=1, then b is not invertible mod a
  if(a!=1) {
    return 0;
  }

  // this actually returns EITHER the reciprocal OR reciprocal + fieldSize
  hInt_t res = t0 + fieldSize;
  return res;
}

/* Put a Z_q coefficient in the range -q < x < q into the range 0 <= x < q*/
void canonicalizeZq (Zq* y, hDim_t totm, hInt_t q) {
  // canonicalize every coefficient with this modulus
  for(hDim_t j = 0; j < totm; j++) {
    if(y[j].x<0) {
      y[j].x+=q;
    }
  }
}