1 #include "cbd.h"
2 #include "params.h"
3 
4 #include <stddef.h>
5 #include <stdint.h>
6 
7 /*************************************************
8 * Name:        load32_littleendian
9 *
10 * Description: load bytes into a 32-bit integer
11 *              in little-endian order
12 *
13 * Arguments:   - const uint8_t *x: pointer to input byte array
14 *
15 * Returns 32-bit unsigned integer loaded from x
16 **************************************************/
load32_littleendian(const uint8_t * x)17 static uint32_t load32_littleendian(const uint8_t *x) {
18     uint32_t r;
19     r  = (uint32_t)x[0];
20     r |= (uint32_t)x[1] << 8;
21     r |= (uint32_t)x[2] << 16;
22     r |= (uint32_t)x[3] << 24;
23     return r;
24 }
25 
26 /*************************************************
27 * Name:        cbd
28 *
29 * Description: Given an array of uniformly random bytes, compute
30 *              polynomial with coefficients distributed according to
31 *              a centered binomial distribution with parameter KYBER_ETA
32 *              specialized for KYBER_ETA=2
33 *
34 * Arguments:   - poly *r:                  pointer to output polynomial
35 *              - const uint8_t *buf: pointer to input byte array
36 **************************************************/
PQCLEAN_KYBER51290S_CLEAN_cbd(poly * r,const uint8_t * buf)37 void PQCLEAN_KYBER51290S_CLEAN_cbd(poly *r, const uint8_t *buf) {
38     int16_t a, b;
39 
40     for (size_t i = 0; i < KYBER_N / 8; i++) {
41         uint32_t t = load32_littleendian(buf + 4 * i);
42         uint32_t d  = t & 0x55555555;
43         d += (t >> 1) & 0x55555555;
44 
45         for (size_t j = 0; j < 8; j++) {
46             a = (d >>  4 * j)      & 0x3;
47             b = (d >> (4 * j + 2)) & 0x3;
48             r->coeffs[8 * i + j] = a - b;
49         }
50     }
51 }
52