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