packages feed

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

// SPDX-License-Identifier: MIT

#include "decompose.h"
#include "params.h"

#include <stdint.h>

/*************************************************
 * Name:        decompose_z1
 *
 * Description: For finite field element r, compute high and lowbits
 *              hb, lb such that r = hb * b + lb with -b/2 <= lb < b/2,
 *              for b = alpha = 256.
 *
 * Arguments:   - int32_t r: input element
 *              - int32_t *lowbits: pointer to output element lb
 *              - int32_t *highbits: pointer to output element hb
 *
 * Specification: Implements @[Algorithm 20, HighBits] and
 *                @[Algorithm 21, LowBits] with alpha = 256
 **************************************************/
void decompose_z1(int32_t *highbits, int32_t *lowbits, const int32_t r) {
  const int alpha = 256; // TODO magic numbers!
  const int log_alpha = 8;

  int32_t lb, center;
  uint32_t alpha_mask = alpha - 1;

  lb = r & alpha_mask;
  center = ((alpha >> 1) - (lb + 1)) >> 31; // if lb >= HALF_ALPHA
  lb -= alpha & center;
  *lowbits = lb;
  *highbits = (r + (alpha >> 1)) >> log_alpha;
}

/*************************************************
 * Name:        decompose_hint
 *
 * Description: For finite field element r, compute highbits
 *              hb, lb such that r = hb * b + lb with -b/4 < lb <= b/4.
 *
 * Arguments:   - int32_t r: input element
 *              - int32_t *highbits: pointer to output element hb
 *
 * Specification: Implements @[Algorithm 22, DecomposeHint]
 **************************************************/

void decompose_hint(int32_t *highbits, const int32_t r) {
  int32_t hb, edgecase;

  hb = (r + HAETAE_HALF_ALPHA_HINT) >> HAETAE_LOG_ALPHA_HINT;
  edgecase = ((HAETAE_DQ - 2) / HAETAE_ALPHA_HINT - (hb + 1)) >>
             31; // if hb == (HAETAE_DQ-2)/ALPHA
  hb -= (HAETAE_DQ - 2) / HAETAE_ALPHA_HINT & edgecase; // hb = 0

  *highbits = hb;
}

/*************************************************
 * Name:        decompose_vk
 *
 * Description: For finite field element a, compute a0, a1 such that
 *              a mod^+ HAETAE_Q = a1*2^D + a0 with -2^{D-1} <= a0 < 2^{D-1}.
 *              Assumes a to be standard representative.
 *
 * Arguments:   - int32_t a: input element
 *              - int32_t *a0: pointer to output element a0
 *
 * Returns:     - a1
 *
 * Specification: Implements @[Algorithm 19, DecomposeVK]
 **************************************************/
int32_t decompose_vk(int32_t *a0, const int32_t a) {
  *a0 = a & 1;
  *a0 -= ((a >> 1) & *a0) << 1;
  return (a - *a0) >> 1;
}