1 /*
2   This file is for Niederreiter encryption
3 */
4 
5 #include "encrypt.h"
6 
7 #include "int32_sort.h"
8 #include "params.h"
9 #include "randombytes.h"
10 #include "util.h"
11 
12 #include <assert.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <string.h>
16 
17 #include "gf.h"
18 
19 /* input: public key pk, error vector e */
20 /* output: syndrome s */
21 extern void PQCLEAN_MCELIECE6688128F_AVX_syndrome_asm(unsigned char *s, const unsigned char *pk, unsigned char *e);
22 
23 /* output: e, an error vector of weight t */
24 static void gen_e(unsigned char *e) {
25     int i, j, eq, count;
26 
27     uint16_t ind[ SYS_T * 2 ];
28     int32_t ind32[ SYS_T * 2 ];
29     uint64_t e_int[ (SYS_N + 63) / 64 ];
30     uint64_t one = 1;
31     uint64_t mask;
32     uint64_t val[ SYS_T ];
33 
34     while (1) {
35         randombytes((unsigned char *) ind, sizeof(ind));
36 
37         for (i = 0; i < SYS_T * 2; i++) {
38             ind[i] &= GFMASK;
39         }
40 
41         // moving and counting indices in the correct range
42 
43         count = 0;
44         for (i = 0; i < SYS_T * 2; i++) {
45             if (ind[i] < SYS_N) {
46                 ind32[ count++ ] = ind[i];
47             }
48         }
49 
50         if (count < SYS_T) {
51             continue;
52         }
53 
54         // check for repetition
55 
56         PQCLEAN_MCELIECE6688128F_AVX_int32_sort(ind32, SYS_T);
57 
58         eq = 0;
59         for (i = 1; i < SYS_T; i++) {
60             if (ind32[i - 1] == ind32[i]) {
61                 eq = 1;
62             }
63         }
64 
65         if (eq == 0) {
66             break;
67         }
68     }
69 
70     for (j = 0; j < SYS_T; j++) {
71         val[j] = one << (ind32[j] & 63);
72     }
73 
74     for (i = 0; i < (SYS_N + 63) / 64; i++) {
75         e_int[i] = 0;
76 
77         for (j = 0; j < SYS_T; j++) {
78             mask = i ^ (ind32[j] >> 6);
79             mask -= 1;
80             mask >>= 63;
81             mask = -mask;
82 
83             e_int[i] |= val[j] & mask;
84         }
85     }
86 
87     for (i = 0; i < (SYS_N + 63) / 64 - 1; i++) {
88         PQCLEAN_MCELIECE6688128F_AVX_store8(e, e_int[i]);
89         e += 8;
90     }
91 
92     for (j = 0; j < (SYS_N % 64); j += 8) {
93         e[ j / 8 ] = (e_int[i] >> j) & 0xFF;
94     }
95 }
96 
97 /* input: public key pk */
98 /* output: error vector e, syndrome s */
99 void PQCLEAN_MCELIECE6688128F_AVX_encrypt(unsigned char *s, unsigned char *e, const unsigned char *pk) {
100     gen_e(e);
101 
102     PQCLEAN_MCELIECE6688128F_AVX_syndrome_asm(s, pk, e);
103 }
104 
105