1 #include "api.h"
2 
3 #include "aes256ctr.h"
4 #include "controlbits.h"
5 #include "crypto_hash.h"
6 #include "decrypt.h"
7 #include "encrypt.h"
8 #include "params.h"
9 #include "pk_gen.h"
10 #include "randombytes.h"
11 #include "sk_gen.h"
12 #include "util.h"
13 
14 #include <stdint.h>
15 #include <string.h>
16 
PQCLEAN_MCELIECE348864_AVX_crypto_kem_enc(uint8_t * c,uint8_t * key,const uint8_t * pk)17 int PQCLEAN_MCELIECE348864_AVX_crypto_kem_enc(
18     uint8_t *c,
19     uint8_t *key,
20     const uint8_t *pk
21 ) {
22     uint8_t two_e[ 1 + SYS_N / 8 ] = {2};
23     uint8_t *e = two_e + 1;
24     uint8_t one_ec[ 1 + SYS_N / 8 + (SYND_BYTES + 32) ] = {1};
25 
26     PQCLEAN_MCELIECE348864_AVX_encrypt(c, e, pk);
27 
28     crypto_hash_32b(c + SYND_BYTES, two_e, sizeof(two_e));
29 
30     memcpy(one_ec + 1, e, SYS_N / 8);
31     memcpy(one_ec + 1 + SYS_N / 8, c, SYND_BYTES + 32);
32 
33     crypto_hash_32b(key, one_ec, sizeof(one_ec));
34 
35     return 0;
36 }
37 
PQCLEAN_MCELIECE348864_AVX_crypto_kem_dec(uint8_t * key,const uint8_t * c,const uint8_t * sk)38 int PQCLEAN_MCELIECE348864_AVX_crypto_kem_dec(
39     uint8_t *key,
40     const uint8_t *c,
41     const uint8_t *sk
42 ) {
43     int i;
44 
45     uint8_t ret_confirm = 0;
46     uint8_t ret_decrypt = 0;
47 
48     uint16_t m;
49 
50     uint8_t conf[32];
51     uint8_t two_e[ 1 + SYS_N / 8 ] = {2};
52     uint8_t *e = two_e + 1;
53     uint8_t preimage[ 1 + SYS_N / 8 + (SYND_BYTES + 32) ];
54     uint8_t *x = preimage;
55 
56     //
57 
58     ret_decrypt = (uint8_t)PQCLEAN_MCELIECE348864_AVX_decrypt(e, sk + SYS_N / 8, c);
59 
60     crypto_hash_32b(conf, two_e, sizeof(two_e));
61 
62     for (i = 0; i < 32; i++) {
63         ret_confirm |= conf[i] ^ c[SYND_BYTES + i];
64     }
65 
66     m = ret_decrypt | ret_confirm;
67     m -= 1;
68     m >>= 8;
69 
70     *x++ = (~m &     0) | (m &    1);
71     for (i = 0; i < SYS_N / 8;         i++) {
72         *x++ = (~m & sk[i]) | (m & e[i]);
73     }
74     for (i = 0; i < SYND_BYTES + 32; i++) {
75         *x++ = c[i];
76     }
77 
78     crypto_hash_32b(key, preimage, sizeof(preimage));
79 
80     return 0;
81 }
82 
PQCLEAN_MCELIECE348864_AVX_crypto_kem_keypair(uint8_t * pk,uint8_t * sk)83 int PQCLEAN_MCELIECE348864_AVX_crypto_kem_keypair
84 (
85     uint8_t *pk,
86     uint8_t *sk
87 ) {
88     int i;
89     uint8_t seed[ 32 ];
90     uint8_t r[ SYS_T * 2 + (1 << GFBITS)*sizeof(uint32_t) + SYS_N / 8 + 32 ];
91     uint8_t nonce[ 16 ] = {0};
92     uint8_t *rp;
93 
94     gf f[ SYS_T ]; // element in GF(2^mt)
95     gf irr[ SYS_T ]; // Goppa polynomial
96     uint32_t perm[ 1 << GFBITS ]; // random permutation
97 
98     randombytes(seed, sizeof(seed));
99 
100     while (1) {
101         rp = r;
102         PQCLEAN_MCELIECE348864_AVX_aes256ctr(r, sizeof(r), nonce, seed);
103         memcpy(seed, &r[ sizeof(r) - 32 ], 32);
104 
105         for (i = 0; i < SYS_T; i++) {
106             f[i] = PQCLEAN_MCELIECE348864_AVX_load2(rp + i * 2);
107         }
108         rp += sizeof(f);
109         if (PQCLEAN_MCELIECE348864_AVX_genpoly_gen(irr, f)) {
110             continue;
111         }
112 
113         for (i = 0; i < (1 << GFBITS); i++) {
114             perm[i] = PQCLEAN_MCELIECE348864_AVX_load4(rp + i * 4);
115         }
116         rp += sizeof(perm);
117         if (PQCLEAN_MCELIECE348864_AVX_perm_check(perm)) {
118             continue;
119         }
120 
121         for (i = 0; i < SYS_T;   i++) {
122             PQCLEAN_MCELIECE348864_AVX_store2(sk + SYS_N / 8 + i * 2, irr[i]);
123         }
124         if (PQCLEAN_MCELIECE348864_AVX_pk_gen(pk, perm, sk + SYS_N / 8)) {
125             continue;
126         }
127 
128         memcpy(sk, rp, SYS_N / 8);
129         PQCLEAN_MCELIECE348864_AVX_controlbits(sk + SYS_N / 8 + IRR_BYTES, perm);
130 
131         break;
132     }
133 
134     return 0;
135 }
136 
137