KpqC-0.1.0: cbits/third_party/SMAUG-T/src/cbd.c
// SPDX-License-Identifier: MIT
#include "cbd.h"
#if SMAUGT_MODE == SMAUGT_MODE1 || SMAUGT_MODE == SMAUGT_MODET
#define load24_littleendian SMAUGT_NAMESPACE(load24_littleendian)
static uint32_t load24_littleendian(const uint8_t x[3]) {
uint32_t r;
r = (uint32_t)x[0];
r |= (uint32_t)x[1] << 8;
r |= (uint32_t)x[2] << 16;
return r;
}
/*************************************************
* Name: sp_cbd1
*
* Description: Given an array of uniformly random bytes, compute
* polynomial with coefficients distributed according to
* a modified centered binomial distribution with parameter eta=2
* (p(0)=3/4, p(1)=p(-1)=1/8)
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
* array
*
* Specification: Implements @[KS X 123456, Algorithm 7, spCBD1]
**************************************************/
#define sp_cbd1 SMAUGT_NAMESPACE(sp_cbd1)
static void sp_cbd1(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
unsigned int i, j;
uint32_t t, d, s;
int16_t a;
for (i = 0; i < SMAUGT_N / 8; i++) {
t = load24_littleendian(buf + 3 * i);
d = t & 0x00249249;
d &= (t >> 1) & 0x00249249;
s = (t >> 2) & 0x00249249;
for (j = 0; j < 8; j++) {
a = (d >> (3 * j)) & 0x1;
r->coeffs[8 * i + j] =
a * (((((s >> (3 * j)) & 0x1) - 1) ^ -2) | 1);
}
}
}
#endif
#if SMAUGT_MODE == SMAUGT_MODE3 || SMAUGT_MODE == SMAUGT_MODE5
/*************************************************
* Name: load32_littleendian
*
* Description: load 4 bytes into a 32-bit integer
* in little-endian order
*
* Arguments: - const uint8_t x[4]: pointer to input byte array
*
* Return: 32-bit unsigned integer loaded from x
**************************************************/
#define load32_littleendian SMAUGT_NAMESPACE(load32_littleendian)
static uint32_t load32_littleendian(const uint8_t x[4]) {
uint32_t r;
r = (uint32_t)x[0];
r |= (uint32_t)x[1] << 8;
r |= (uint32_t)x[2] << 16;
r |= (uint32_t)x[3] << 24;
return r;
}
#endif
#if SMAUGT_MODE == SMAUGT_MODE3
/*************************************************
* Name: cbd
*
* Description: Given an array of uniformly random bytes, compute
* polynomial with coefficients distributed according to
* a centered binomial distribution with parameter eta=1
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
* array
*
* Specification: Implements @[KS X 123456, Algorithm 9, CBD]
**************************************************/
#define cbd SMAUGT_NAMESPACE(cbd)
static void cbd(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
unsigned int i, j;
uint32_t t;
int16_t a, b;
for (i = 0; i < SMAUGT_N / 16; i++) {
t = load32_littleendian(buf + 4 * i);
for (j = 0; j < 16; j++) {
a = (t >> (2 * j + 0)) & 0x01;
b = (t >> (2 * j + 1)) & 0x01;
r->coeffs[16 * i + j] = a - b;
}
}
}
#endif
#if SMAUGT_MODE == SMAUGT_MODE5
/*************************************************
* Name: sp_cbd2
*
* Description: Given an array of uniformly random bytes, compute
* polynomial with coefficients distributed according to
* a modified centered binomial distribution with parameter eta=2
* (p(0)=5/8, p(1)=p(-1)=3/16)
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
* array
*
* Specification: Implements @[KS X 123456, Algorithm 8, spCBD2]
**************************************************/
#define sp_cbd2 SMAUGT_NAMESPACE(sp_cbd2)
static void sp_cbd2(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
unsigned int i, j;
uint32_t t, s, d;
int16_t a;
for (i = 0; i < SMAUGT_N / 8; i++) {
t = load32_littleendian(buf + 4 * i);
d = t & 0x11111111;
d |= (t >> 1) & 0x11111111;
d &= (t >> 2) & 0x11111111;
s = (t >> 3) & 0x11111111;
for (j = 0; j < 8; j++) {
a = (d >> (4 * j)) & 0x1;
r->coeffs[8 * i + j] =
a * (((((s >> (4 * j)) & 0x1) - 1) ^ -2) | 1);
}
}
}
#endif
/*************************************************
* Name: sp_cbd
*
* Description: Given an array of uniformly random bytes, compute
* polynomial with coefficients
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t buf[SMAUGT_CBDSEED_BYTES]: pointer to input byte
* array
*
* Specification: Implements @[KS X 123456, Algorithm 6, spCBD]
**************************************************/
void sp_cbd(poly *r, const uint8_t buf[SMAUGT_CBDSEED_BYTES]) {
#if SMAUGT_MODE == SMAUGT_MODE1 || SMAUGT_MODE == SMAUGT_MODET
sp_cbd1(r, buf);
#elif SMAUGT_MODE == SMAUGT_MODE3
cbd(r, buf);
#elif SMAUGT_MODE == SMAUGT_MODE5
sp_cbd2(r, buf);
#endif
}