1 #include "poly.h"
2 
3 void PQCLEAN_NTRUHPS2048509_CLEAN_poly_Sq_tobytes(unsigned char *r, const poly *a) {
4     int i, j;
5     uint16_t t[8];
6 
7     for (i = 0; i < NTRU_PACK_DEG / 8; i++) {
8         for (j = 0; j < 8; j++) {
9             t[j] = MODQ(a->coeffs[8 * i + j]);
10         }
11 
12         r[11 * i + 0] = (unsigned char) ( t[0]        & 0xff);
13         r[11 * i + 1] = (unsigned char) ((t[0] >>  8) | ((t[1] & 0x1f) << 3));
14         r[11 * i + 2] = (unsigned char) ((t[1] >>  5) | ((t[2] & 0x03) << 6));
15         r[11 * i + 3] = (unsigned char) ((t[2] >>  2) & 0xff);
16         r[11 * i + 4] = (unsigned char) ((t[2] >> 10) | ((t[3] & 0x7f) << 1));
17         r[11 * i + 5] = (unsigned char) ((t[3] >>  7) | ((t[4] & 0x0f) << 4));
18         r[11 * i + 6] = (unsigned char) ((t[4] >>  4) | ((t[5] & 0x01) << 7));
19         r[11 * i + 7] = (unsigned char) ((t[5] >>  1) & 0xff);
20         r[11 * i + 8] = (unsigned char) ((t[5] >>  9) | ((t[6] & 0x3f) << 2));
21         r[11 * i + 9] = (unsigned char) ((t[6] >>  6) | ((t[7] & 0x07) << 5));
22         r[11 * i + 10] = (unsigned char) ((t[7] >>  3));
23     }
24 
25     for (j = 0; j < NTRU_PACK_DEG - 8 * i; j++) {
26         t[j] = MODQ(a->coeffs[8 * i + j]);
27     }
28     for (; j < 8; j++) {
29         t[j] = 0;
30     }
31 
32     switch (NTRU_PACK_DEG & 0x07) {
33     // cases 0 and 6 are impossible since 2 generates (Z/n)* and
34     // p mod 8 in {1, 7} implies that 2 is a quadratic residue.
35     case 4:
36         r[11 * i + 0] = (unsigned char) (t[0]        & 0xff);
37         r[11 * i + 1] = (unsigned char) (t[0] >>  8) | ((t[1] & 0x1f) << 3);
38         r[11 * i + 2] = (unsigned char) (t[1] >>  5) | ((t[2] & 0x03) << 6);
39         r[11 * i + 3] = (unsigned char) (t[2] >>  2) & 0xff;
40         r[11 * i + 4] = (unsigned char) (t[2] >> 10) | ((t[3] & 0x7f) << 1);
41         r[11 * i + 5] = (unsigned char) (t[3] >>  7) | ((t[4] & 0x0f) << 4);
42         break;
43     case 2:
44         r[11 * i + 0] = (unsigned char) (t[0]        & 0xff);
45         r[11 * i + 1] = (unsigned char) (t[0] >>  8) | ((t[1] & 0x1f) << 3);
46         r[11 * i + 2] = (unsigned char) (t[1] >>  5) | ((t[2] & 0x03) << 6);
47         break;
48     }
49 }
50 
51 void PQCLEAN_NTRUHPS2048509_CLEAN_poly_Sq_frombytes(poly *r, const unsigned char *a) {
52     int i;
53     for (i = 0; i < NTRU_PACK_DEG / 8; i++) {
54         r->coeffs[8 * i + 0] = (a[11 * i + 0] >> 0) | (((uint16_t)a[11 * i + 1] & 0x07) << 8);
55         r->coeffs[8 * i + 1] = (a[11 * i + 1] >> 3) | (((uint16_t)a[11 * i + 2] & 0x3f) << 5);
56         r->coeffs[8 * i + 2] = (a[11 * i + 2] >> 6) | (((uint16_t)a[11 * i + 3] & 0xff) << 2) | (((uint16_t)a[11 * i + 4] & 0x01) << 10);
57         r->coeffs[8 * i + 3] = (a[11 * i + 4] >> 1) | (((uint16_t)a[11 * i + 5] & 0x0f) << 7);
58         r->coeffs[8 * i + 4] = (a[11 * i + 5] >> 4) | (((uint16_t)a[11 * i + 6] & 0x7f) << 4);
59         r->coeffs[8 * i + 5] = (a[11 * i + 6] >> 7) | (((uint16_t)a[11 * i + 7] & 0xff) << 1) | (((uint16_t)a[11 * i + 8] & 0x03) <<  9);
60         r->coeffs[8 * i + 6] = (a[11 * i + 8] >> 2) | (((uint16_t)a[11 * i + 9] & 0x1f) << 6);
61         r->coeffs[8 * i + 7] = (a[11 * i + 9] >> 5) | (((uint16_t)a[11 * i + 10] & 0xff) << 3);
62     }
63     switch (NTRU_PACK_DEG & 0x07) {
64     // cases 0 and 6 are impossible since 2 generates (Z/n)* and
65     // p mod 8 in {1, 7} implies that 2 is a quadratic residue.
66     case 4:
67         r->coeffs[8 * i + 0] = (a[11 * i + 0] >> 0) | (((uint16_t)a[11 * i + 1] & 0x07) << 8);
68         r->coeffs[8 * i + 1] = (a[11 * i + 1] >> 3) | (((uint16_t)a[11 * i + 2] & 0x3f) << 5);
69         r->coeffs[8 * i + 2] = (a[11 * i + 2] >> 6) | (((uint16_t)a[11 * i + 3] & 0xff) << 2) | (((uint16_t)a[11 * i + 4] & 0x01) << 10);
70         r->coeffs[8 * i + 3] = (a[11 * i + 4] >> 1) | (((uint16_t)a[11 * i + 5] & 0x0f) << 7);
71         break;
72     case 2:
73         r->coeffs[8 * i + 0] = (a[11 * i + 0] >> 0) | (((uint16_t)a[11 * i + 1] & 0x07) << 8);
74         r->coeffs[8 * i + 1] = (a[11 * i + 1] >> 3) | (((uint16_t)a[11 * i + 2] & 0x3f) << 5);
75         break;
76     }
77     r->coeffs[NTRU_N - 1] = 0;
78 }
79 
80 void PQCLEAN_NTRUHPS2048509_CLEAN_poly_Rq_sum_zero_tobytes(unsigned char *r, const poly *a) {
81     PQCLEAN_NTRUHPS2048509_CLEAN_poly_Sq_tobytes(r, a);
82 }
83 
84 void PQCLEAN_NTRUHPS2048509_CLEAN_poly_Rq_sum_zero_frombytes(poly *r, const unsigned char *a) {
85     int i;
86     PQCLEAN_NTRUHPS2048509_CLEAN_poly_Sq_frombytes(r, a);
87 
88     /* Set r[n-1] so that the sum of coefficients is zero mod q */
89     r->coeffs[NTRU_N - 1] = 0;
90     for (i = 0; i < NTRU_PACK_DEG; i++) {
91         r->coeffs[NTRU_N - 1] -= r->coeffs[i];
92     }
93 }
94