1 /*
2   This file is for secret-key generation
3 */
4 
5 #include "sk_gen.h"
6 
7 #include "controlbits.h"
8 #include "gf.h"
9 #include "params.h"
10 #include "util.h"
11 
12 /* input: f, element in GF((2^m)^t) */
13 /* output: out, minimal polynomial of f */
14 /* return: 0 for success and -1 for failure */
PQCLEAN_MCELIECE460896F_AVX_genpoly_gen(gf * out,gf * f)15 int PQCLEAN_MCELIECE460896F_AVX_genpoly_gen(gf *out, gf *f) {
16     int i, j, k, c;
17 
18     gf mat[ SYS_T + 1 ][ SYS_T ];
19     gf mask, inv, t;
20 
21     // fill matrix
22 
23     mat[0][0] = 1;
24 
25     for (i = 1; i < SYS_T; i++) {
26         mat[0][i] = 0;
27     }
28 
29     for (i = 0; i < SYS_T; i++) {
30         mat[1][i] = f[i];
31     }
32 
33     for (j = 2; j <= SYS_T; j++) {
34         PQCLEAN_MCELIECE460896F_AVX_GF_mul(mat[j], mat[j - 1], f);
35     }
36 
37     // gaussian
38 
39     for (j = 0; j < SYS_T; j++) {
40         for (k = j + 1; k < SYS_T; k++) {
41             mask = PQCLEAN_MCELIECE460896F_AVX_gf_iszero(mat[ j ][ j ]);
42 
43             for (c = j; c < SYS_T + 1; c++) {
44                 mat[ c ][ j ] ^= mat[ c ][ k ] & mask;
45             }
46 
47         }
48 
49         if ( mat[ j ][ j ] == 0 ) { // return if not systematic
50             return -1;
51         }
52 
53         inv = PQCLEAN_MCELIECE460896F_AVX_gf_inv(mat[j][j]);
54 
55         for (c = j; c < SYS_T + 1; c++) {
56             mat[ c ][ j ] = PQCLEAN_MCELIECE460896F_AVX_gf_mul(mat[ c ][ j ], inv) ;
57         }
58 
59         for (k = 0; k < SYS_T; k++) {
60             if (k != j) {
61                 t = mat[ j ][ k ];
62 
63                 for (c = j; c < SYS_T + 1; c++) {
64                     mat[ c ][ k ] ^= PQCLEAN_MCELIECE460896F_AVX_gf_mul(mat[ c ][ j ], t);
65                 }
66             }
67         }
68     }
69 
70     for (i = 0; i < SYS_T; i++) {
71         out[i] = mat[ SYS_T ][ i ];
72     }
73 
74     return 0;
75 }
76 
77 /* input: permutation p represented as a list of 32-bit intergers */
78 /* output: -1 if some interger repeats in p */
79 /*          0 otherwise */
PQCLEAN_MCELIECE460896F_AVX_perm_check(const uint32_t * p)80 int PQCLEAN_MCELIECE460896F_AVX_perm_check(const uint32_t *p) {
81     int i;
82     uint64_t list[1 << GFBITS];
83 
84     for (i = 0; i < (1 << GFBITS); i++) {
85         list[i] = p[i];
86     }
87 
88     PQCLEAN_MCELIECE460896F_AVX_sort_63b(1 << GFBITS, list);
89 
90     for (i = 1; i < (1 << GFBITS); i++) {
91         if (list[i - 1] == list[i]) {
92             return -1;
93         }
94     }
95 
96     return 0;
97 }
98 
99