packages feed

KpqC-0.1.0: cbits/third_party/HAETAE/src/reduce.c

// SPDX-License-Identifier: MIT

#include "reduce.h"
#include "params.h"

#include <stdint.h>

/*************************************************
 * Name:        montgomery_reduce
 *
 * Description: For finite field element a with -2^{31}Q <= a <= HAETAE_Q*2^31,
 *              compute r \equiv a*2^{-32} (mod HAETAE_Q) such that -HAETAE_Q <
 *              r < HAETAE_Q.
 *
 * Arguments:   - int64_t: finite field element a
 *
 * Returns r.
 *
 * Specification: Implements @[Algorithm 1, MontgomeryReduce]
 **************************************************/
int32_t montgomery_reduce(int64_t a) {
  int32_t t;

  t = (int64_t)(int32_t)a * QINV;
  t = (a - (int64_t)t * HAETAE_Q) >> 32;
  return t;
}

/*************************************************
 * Name:        caddq
 *
 * Description: Add HAETAE_Q if input coefficient is negative.
 *
 * Arguments:   - int32_t: finite field element a
 *
 * Returns r.
 **************************************************/
int32_t caddq(int32_t a) {
  a += (a >> 31) & HAETAE_Q;
  return a;
}

/*************************************************
 * Name:        freeze
 *
 * Description: For finite field element a, compute standard
 *              representative r = a mod^+ HAETAE_Q.
 *
 * Arguments:   - int32_t: finite field element a
 *
 * Returns r.
 **************************************************/
int32_t freeze(int32_t a) {
  int64_t t = (int64_t)a * QREC;
  t = t >> 32;
  t = a - t * HAETAE_Q;                    // -2Q <  t < 2Q
  t += (t >> 31) & HAETAE_DQ;              //   0 <= t < 2Q
  t -= ~((t - HAETAE_Q) >> 31) & HAETAE_Q; //   0 <= t < HAETAE_Q
  return t;
}

/*************************************************
 * Name:        reduce32_2q
 *
 * Description: compute reduction with 2Q
 *
 * Arguments:   - int32_t: finite field element a
 *
 * Returns r.
 **************************************************/
int32_t reduce32_2q(int32_t a) {
  int64_t t = (int64_t)a * DQREC;
  t >>= 32;
  t = a - t * HAETAE_DQ;                     // -4Q <  t < 4Q
  t += (t >> 31) & (HAETAE_DQ * 2);          //   0 <= t < 4Q
  t -= ~((t - HAETAE_DQ) >> 31) & HAETAE_DQ; //   0 <= t < HAETAE_Q
  t -= ~((t - HAETAE_Q) >> 31) & HAETAE_DQ;  // centered representation
  return (int32_t)t;
}

/*************************************************
 * Name:        freeze2q
 *
 * Description: For finite field element a, compute standard
 *              representative r = a mod^+ 2Q.
 *
 * Arguments:   - int32_t: finite field element a
 *
 * Returns r.
 **************************************************/
int32_t freeze2q(int32_t a) {
  int64_t t = (int64_t)a * DQREC;
  t >>= 32;
  t = a - t * HAETAE_DQ;                     // -4Q <  t < 4Q
  t += (t >> 31) & (HAETAE_DQ * 2);          //   0 <= t < 4Q
  t -= ~((t - HAETAE_DQ) >> 31) & HAETAE_DQ; //   0 <= t < HAETAE_Q
  return (int32_t)t;
}