@@ -1,8 +1,8 @@ | |||
#ifndef H_Q_MATRICES_GENERATION_H | |||
#define H_Q_MATRICES_GENERATION_H | |||
#include "qc_ldpc_parameters.h" | |||
#include "gf2x_limbs.h" | |||
#include "qc_ldpc_parameters.h" | |||
#include "rng.h" | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_generateHPosOnes_HtrPosOnes( | |||
@@ -8,11 +8,9 @@ HEADERS=api.h bf_decoding.h dfr_test.h gf2x_arith_mod_xPplusOne.h \ | |||
OBJECTS=bf_decoding.o dfr_test.o gf2x_arith_mod_xPplusOne.o \ | |||
gf2x_arith.o H_Q_matrices_generation.o kem.o niederreiter.o rng.o | |||
CFLAGS=-O3 -Wall -Wextra -Wpedantic -Wmissing-prototypes -std=c99 \ | |||
CFLAGS=-O3 -Wall -Werror -Wextra -Wvla -Wpedantic -Wmissing-prototypes -std=c99 \ | |||
-I../../../common $(EXTRAFLAGS) | |||
# TODO: -Werror -Wvla | |||
all: $(LIB) | |||
%.o: %.c $(HEADERS) | |||
@@ -1,15 +1,15 @@ | |||
#include "bf_decoding.h" | |||
#include "gf2x_arith_mod_xPplusOne.h" | |||
#include <string.h> | |||
#include <assert.h> | |||
#include <string.h> | |||
#define ROTBYTE(a) ( (a << 8) | (a >> (DIGIT_SIZE_b - 8)) ) | |||
#define ROTUPC(a) ( (a >> 8) | (a << (DIGIT_SIZE_b - 8)) ) | |||
#define ROTBYTE(a) ( ((a) << 8) | ((a) >> (DIGIT_SIZE_b - 8)) ) | |||
#define ROTUPC(a) ( ((a) >> 8) | ((a) << (DIGIT_SIZE_b - 8)) ) | |||
int thresholds[2] = {B0, (DV * M) / 2 + 1}; | |||
unsigned int thresholds[2] = {B0, (DV * M) / 2 + 1}; | |||
int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT out[], // N0 polynomials | |||
int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[], | |||
const POSITION_T HtrPosOnes[N0][DV], | |||
const POSITION_T QtrPosOnes[N0][M], | |||
DIGIT privateSyndrome[]) { | |||
@@ -35,20 +35,20 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT out[], // N0 polynomials | |||
} | |||
/* iteration based threshold determination*/ | |||
int corrt_syndrome_based = thresholds[iteration]; | |||
unsigned int corrt_syndrome_based = thresholds[iteration]; | |||
//Computation of correlation with a full Q matrix | |||
for (int i = 0; i < N0; i++) { | |||
for (int j = 0; j < P; j++) { | |||
int currQoneIdx = 0; // position in the column of QtrPosOnes[][...] | |||
int endQblockIdx = 0; | |||
int correlation = 0; | |||
unsigned int correlation = 0; | |||
for (int blockIdx = 0; blockIdx < N0; blockIdx++) { | |||
endQblockIdx += qBlockWeights[blockIdx][i]; | |||
int currblockoffset = blockIdx * P; | |||
for (; currQoneIdx < endQblockIdx; currQoneIdx++) { | |||
int tmp = QtrPosOnes[i][currQoneIdx] + j; | |||
uint32_t tmp = QtrPosOnes[i][currQoneIdx] + j; | |||
tmp = tmp >= P ? tmp - P : tmp; | |||
currQBitPos[currQoneIdx] = tmp; | |||
currQBlkPos[currQoneIdx] = blockIdx; | |||
@@ -57,7 +57,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT out[], // N0 polynomials | |||
} | |||
/* Correlation based flipping */ | |||
if (correlation >= corrt_syndrome_based) { | |||
gf2x_toggle_coeff(out + NUM_DIGITS_GF2X_ELEMENT * i, j); | |||
gf2x_toggle_coeff(err + NUM_DIGITS_GF2X_ELEMENT * i, j); | |||
for (int v = 0; v < M; v++) { | |||
unsigned syndromePosToFlip; | |||
for (int HtrOneIdx = 0; HtrOneIdx < DV; HtrOneIdx++) { | |||
@@ -72,7 +72,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT out[], // N0 polynomials | |||
iteration = iteration + 1; | |||
check = 0; | |||
while (check < NUM_DIGITS_GF2X_ELEMENT && privateSyndrome[check++] == 0); | |||
while (check < NUM_DIGITS_GF2X_ELEMENT && privateSyndrome[check++] == 0) {}; | |||
} while (iteration < ITERATIONS_MAX && check < NUM_DIGITS_GF2X_ELEMENT); | |||
@@ -1,8 +1,8 @@ | |||
#ifndef BF_DECODING_H | |||
#define BF_DECODING_H | |||
#include "qc_ldpc_parameters.h" | |||
#include "gf2x_limbs.h" | |||
#include "qc_ldpc_parameters.h" | |||
/* Definitions for DFR level 2^-SL with SL=128 */ | |||
#define ITERATIONS_MAX (2) | |||
@@ -9,7 +9,7 @@ | |||
* computes the threshold for the second iteration of the decoder and stores | |||
* it in the globally accessible vector */ | |||
extern int thresholds[2]; | |||
extern unsigned int thresholds[2]; | |||
int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { | |||
@@ -19,14 +19,15 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { | |||
* gamma[a][b][c] stores the intersection of the first column of the a-th | |||
* block of L with the c-th column of the b-th block of L */ | |||
/* Gamma computation can be accelerated employing symmetry and QC properties */ | |||
int gamma[N0][N0][P] = {{{0}}}; | |||
uint32_t rotated_column[DV * M]; | |||
int firstidx, secondidx, intersectionval; | |||
unsigned int gamma[N0][N0][P] = {{{0}}}; | |||
unsigned int rotated_column[DV * M]; | |||
unsigned int firstidx, secondidx, intersectionval; | |||
unsigned int gammaHist[N0][DV * M + 1] = {{0}}; | |||
int maxMut[N0], maxMutMinusOne[N0]; | |||
int allBlockMaxSumst, allBlockMaxSumstMinusOne; | |||
unsigned int maxMut[N0], maxMutMinusOne[N0]; | |||
unsigned int allBlockMaxSumst, allBlockMaxSumstMinusOne; | |||
unsigned int toAdd, histIdx; | |||
@@ -34,10 +35,10 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { | |||
for (int i = 0; i < N0; i++) { | |||
for (int j = 0; j < DV * M; j++) { | |||
if (LSparse[i][j] != 0) { | |||
LSparse_loc[i][j] = (P - LSparse[i][j]) ; | |||
LSparse_loc[i][j] = (P - LSparse[i][j]); | |||
} | |||
} | |||
quicksort(LSparse_loc[i], DV * M); | |||
quicksort_sparse(LSparse_loc[i]); | |||
} | |||
for (int i = 0; i < N0; i++ ) { | |||
@@ -47,7 +48,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { | |||
for (int idxToRotate = 0; idxToRotate < (DV * M); idxToRotate++) { | |||
rotated_column[idxToRotate] = (LSparse_loc[j][idxToRotate] + k) % P; | |||
} | |||
quicksort(rotated_column, DV * M); | |||
quicksort_sparse(rotated_column); | |||
/* compute the intersection amount */ | |||
firstidx = 0, secondidx = 0; | |||
intersectionval = 0; | |||
@@ -1,6 +1,7 @@ | |||
#include "gf2x_arith.h" | |||
#include <string.h> // memset(...) | |||
#include <assert.h> | |||
#include <string.h> // memset(...) | |||
/* allows the second operand to be shorter than the first */ | |||
/* the result should be as large as the first operand*/ | |||
@@ -19,12 +20,12 @@ static inline void gf2x_add_asymm(const size_t nr, DIGIT Res[], | |||
} | |||
/* PRE: MAX ALLOWED ROTATION AMOUNT : DIGIT_SIZE_b */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(const int length, DIGIT in[], const int amount) { | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(size_t length, DIGIT in[], unsigned int amount) { | |||
assert(amount < DIGIT_SIZE_b); | |||
if ( amount == 0 ) { | |||
return; | |||
} | |||
int j; | |||
unsigned int j; | |||
DIGIT mask; | |||
mask = ((DIGIT)0x01 << amount) - 1; | |||
for (j = length - 1; j > 0 ; j--) { | |||
@@ -35,12 +36,12 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(const int length, DIGIT in[], c | |||
} | |||
/* PRE: MAX ALLOWED ROTATION AMOUNT : DIGIT_SIZE_b */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(const int length, DIGIT in[], const int amount) { | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(size_t length, DIGIT in[], unsigned int amount) { | |||
assert(amount < DIGIT_SIZE_b); | |||
if ( amount == 0 ) { | |||
return; | |||
} | |||
int j; | |||
size_t j; | |||
DIGIT mask; | |||
mask = ~(((DIGIT)0x01 << (DIGIT_SIZE_b - amount)) - 1); | |||
for (j = 0 ; j < length - 1 ; j++) { | |||
@@ -50,22 +51,22 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(const int length, DIGIT in[], co | |||
in[j] <<= amount; | |||
} | |||
static void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_comb(const int nr, DIGIT Res[], | |||
const int na, const DIGIT A[], | |||
const int nb, const DIGIT B[]) { | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_comb(int nr, DIGIT Res[], | |||
int na, const DIGIT A[], | |||
int nb, const DIGIT B[]) { | |||
int i, j, k; | |||
DIGIT u, h; | |||
memset(Res, 0x00, nr * sizeof(DIGIT)); | |||
for (k = DIGIT_SIZE_b - 1; k > 0; k--) { | |||
for (i = na - 1; i >= 0; i--) | |||
if ( A[i] & (((DIGIT)0x1) << k) ) | |||
for (i = na - 1; i >= 0; i--) { | |||
if ( A[i] & (((DIGIT)0x1) << k) ) { | |||
for (j = nb - 1; j >= 0; j--) { | |||
Res[i + j + 1] ^= B[j]; | |||
} | |||
} | |||
} | |||
u = Res[na + nb - 1]; | |||
Res[na + nb - 1] = u << 0x1; | |||
@@ -75,11 +76,13 @@ static void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_comb(const int nr, DIGIT Res[], | |||
Res[na + nb - 1 - j] = h ^ (u << 0x1); | |||
} | |||
} | |||
for (i = na - 1; i >= 0; i--) | |||
if ( A[i] & ((DIGIT)0x1) ) | |||
for (i = na - 1; i >= 0; i--) { | |||
if ( A[i] & ((DIGIT)0x1) ) { | |||
for (j = nb - 1; j >= 0; j--) { | |||
Res[i + j + 1] ^= B[j]; | |||
} | |||
} | |||
} | |||
} | |||
static inline void gf2x_exact_div_x_plus_one(const int na, DIGIT A[]) { | |||
@@ -96,258 +99,258 @@ static inline void gf2x_exact_div_x_plus_one(const int na, DIGIT A[]) { | |||
} | |||
} | |||
#define MIN_KAR_DIGITS 20 | |||
static void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(const int nr, DIGIT Res[], | |||
const int na, const DIGIT A[], | |||
const int nb, const DIGIT B[]) { | |||
if (na < MIN_KAR_DIGITS || nb < MIN_KAR_DIGITS) { | |||
/* fall back to schoolbook */ | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_comb(nr, Res, na, A, nb, B); | |||
return; | |||
} | |||
if (na % 2 == 0) { | |||
unsigned bih = na / 2; | |||
DIGIT middle[2 * bih], sumA[bih], sumB[bih]; | |||
gf2x_add(sumA, A, A + bih, bih); | |||
gf2x_add(sumB, B, B + bih, bih); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, middle, | |||
bih, sumA, | |||
bih, sumB); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, Res + 2 * bih, | |||
bih, A + bih, | |||
bih, B + bih); | |||
gf2x_add(middle, middle, Res + 2 * bih, 2 * bih); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, Res, | |||
bih, A, | |||
bih, B); | |||
gf2x_add(middle, middle, Res, 2 * bih); | |||
gf2x_add(Res + bih, Res + bih, middle, 2 * bih); | |||
} else { | |||
unsigned bih = na / 2 + 1; | |||
DIGIT middle[2 * bih], sumA[bih], sumB[bih]; | |||
gf2x_add_asymm(bih, sumA, | |||
bih, A + bih - 1, | |||
bih - 1, A); | |||
gf2x_add_asymm(bih, sumB, | |||
bih, B + bih - 1, | |||
bih - 1, B); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, middle, | |||
bih, sumA, | |||
bih, sumB); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, Res + 2 * (bih - 1), | |||
bih, A + bih - 1, | |||
bih, B + bih - 1); | |||
gf2x_add(middle, middle, Res + 2 * (bih - 1), 2 * bih); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * (bih - 1), Res, | |||
(bih - 1), A, | |||
(bih - 1), B); | |||
gf2x_add_asymm(2 * bih, middle, | |||
2 * bih, middle, | |||
2 * (bih - 1), Res); | |||
gf2x_add(Res + bih - 2, Res + bih - 2, middle, 2 * bih); | |||
} | |||
} | |||
#define MIN_TOOM_DIGITS 35 | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(const int nr, DIGIT Res[], | |||
const int na, const DIGIT A[], | |||
const int nb, const DIGIT B[]) { | |||
if (na < MIN_TOOM_DIGITS || nb < MIN_TOOM_DIGITS) { | |||
/* fall back to Karatsuba */ | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(nr, Res, na, A, nb, B); | |||
return; | |||
} | |||
unsigned int bih; //number of limbs for each part. | |||
if (na % 3 == 0) { | |||
bih = na / 3; | |||
} else { | |||
bih = na / 3 + 1; | |||
} | |||
DIGIT u2[bih], u1[bih], u0[bih]; | |||
unsigned int leading_slack = (3 - (na) % 3) % 3; | |||
// printf("leading slack %d",leading_slack); | |||
unsigned int i; | |||
for (i = 0; i < leading_slack ; i++) { | |||
u2[i] = 0; | |||
} | |||
for (; i < bih; ++i) { | |||
u2[i] = A[i - leading_slack]; | |||
} | |||
/* note: only u2 needs to be a copy, refactor */ | |||
for (; i < 2 * bih; ++i) { | |||
u1[i - bih] = A[i - leading_slack]; | |||
} | |||
for (; i < 3 * bih; ++i) { | |||
u0[i - 2 * bih] = A[i - leading_slack]; | |||
} | |||
DIGIT v2[bih], v1[bih], v0[bih]; /* partitioned inputs */ | |||
/* note: only v2 needs to be a copy, refactor */ | |||
for (i = 0; i < leading_slack ; i++) { | |||
v2[i] = 0; | |||
} | |||
for (; i < bih; ++i) { | |||
v2[i] = B[i - leading_slack]; | |||
} | |||
/* note , only v2 needs to be a copy */ | |||
for (; i < 2 * bih; ++i) { | |||
v1[i - bih] = B[i - leading_slack]; | |||
} | |||
for (; i < 3 * bih; ++i) { | |||
v0[i - 2 * bih] = B[i - leading_slack]; | |||
} | |||
DIGIT sum_u[bih]; /*bih digit wide*/ | |||
gf2x_add(sum_u, u0, u1, bih); | |||
gf2x_add(sum_u, sum_u, u2, bih); | |||
DIGIT sum_v[bih]; /*bih digit wide*/ | |||
gf2x_add(sum_v, v0, v1, bih); | |||
gf2x_add(sum_v, sum_v, v2, bih); | |||
DIGIT w1[2 * bih]; | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih, w1, | |||
bih, sum_u, | |||
bih, sum_v); | |||
DIGIT u2_x2[bih + 1]; | |||
u2_x2[0] = 0; | |||
memcpy(u2_x2 + 1, u2, bih * DIGIT_SIZE_B); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, u2_x2, 2); | |||
DIGIT u1_x[bih + 1]; | |||
u1_x[0] = 0; | |||
memcpy(u1_x + 1, u1, bih * DIGIT_SIZE_B); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, u1_x, 1); | |||
DIGIT u1_x1_u2_x2[bih + 1]; | |||
gf2x_add(u1_x1_u2_x2, u1_x, u2_x2, bih + 1); | |||
DIGIT temp_u_components[bih + 1]; | |||
gf2x_add_asymm(bih + 1, temp_u_components, | |||
bih + 1, u1_x1_u2_x2, | |||
bih, sum_u); | |||
DIGIT v2_x2[bih + 1]; | |||
v2_x2[0] = 0; | |||
memcpy(v2_x2 + 1, v2, bih * DIGIT_SIZE_B); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, v2_x2, 2); | |||
DIGIT v1_x[bih + 1]; | |||
v1_x[0] = 0; | |||
memcpy(v1_x + 1, v1, bih * DIGIT_SIZE_B); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, v1_x, 1); | |||
DIGIT v1_x1_v2_x2[bih + 1]; | |||
gf2x_add(v1_x1_v2_x2, v1_x, v2_x2, bih + 1); | |||
DIGIT temp_v_components[bih + 1]; | |||
gf2x_add_asymm(bih + 1, temp_v_components, | |||
bih + 1, v1_x1_v2_x2, | |||
bih, sum_v); | |||
DIGIT w3[2 * bih + 2]; | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih + 2, w3, | |||
bih + 1, temp_u_components, | |||
bih + 1, temp_v_components); | |||
gf2x_add_asymm(bih + 1, u1_x1_u2_x2, | |||
bih + 1, u1_x1_u2_x2, | |||
bih, u0); | |||
gf2x_add_asymm(bih + 1, v1_x1_v2_x2, | |||
bih + 1, v1_x1_v2_x2, | |||
bih, v0); | |||
DIGIT w2[2 * bih + 2]; | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih + 2, w2, | |||
bih + 1, u1_x1_u2_x2, | |||
bih + 1, v1_x1_v2_x2); | |||
DIGIT w4[2 * bih]; | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih, w4, | |||
bih, u2, | |||
bih, v2); | |||
DIGIT w0[2 * bih]; | |||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih, w0, | |||
bih, u0, | |||
bih, v0); | |||
// Interpolation starts | |||
gf2x_add(w3, w2, w3, 2 * bih + 2); | |||
gf2x_add_asymm(2 * bih + 2, w2, | |||
2 * bih + 2, w2, | |||
2 * bih, w0); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(2 * bih + 2, w2, 1); | |||
gf2x_add(w2, w2, w3, 2 * bih + 2); | |||
// w2 + (w4 * x^3+1) = w2 + w4 + w4 << 3 | |||
DIGIT w4_x3_plus_1[2 * bih + 1]; | |||
w4_x3_plus_1[0] = 0; | |||
memcpy(w4_x3_plus_1 + 1, w4, 2 * bih * DIGIT_SIZE_B); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(2 * bih + 1, w4_x3_plus_1, 3); | |||
gf2x_add_asymm(2 * bih + 2, w2, | |||
2 * bih + 2, w2, | |||
2 * bih, w4); | |||
gf2x_add_asymm(2 * bih + 2, w2, | |||
2 * bih + 2, w2, | |||
2 * bih + 1, w4_x3_plus_1); | |||
gf2x_exact_div_x_plus_one(2 * bih + 2, w2); | |||
gf2x_add(w1, w1, w0, 2 * bih); | |||
gf2x_add_asymm(2 * bih + 2, w3, | |||
2 * bih + 2, w3, | |||
2 * bih, w1); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(2 * bih + 2, w3, 1); | |||
gf2x_exact_div_x_plus_one(2 * bih + 2, w3); | |||
gf2x_add(w1, w1, w4, 2 * bih); | |||
DIGIT w1_final[2 * bih + 2]; | |||
gf2x_add_asymm(2 * bih + 2, w1_final, | |||
2 * bih + 2, w2, | |||
2 * bih, w1); | |||
gf2x_add(w2, w2, w3, 2 * bih + 2); | |||
// Result recombination starts here | |||
memset(Res, 0, nr * DIGIT_SIZE_B); | |||
/* optimization: topmost slack digits should be computed, and not addedd, | |||
* zeroization can be avoided altogether with a proper merge of the | |||
* results */ | |||
int leastSignifDigitIdx = nr - 1; | |||
for (int i = 0; i < 2 * bih; i++) { | |||
Res[leastSignifDigitIdx - i] ^= w0[2 * bih - 1 - i]; | |||
} | |||
leastSignifDigitIdx -= bih; | |||
for (int i = 0; i < 2 * bih + 2; i++) { | |||
Res[leastSignifDigitIdx - i] ^= w1_final[2 * bih + 2 - 1 - i]; | |||
} | |||
leastSignifDigitIdx -= bih; | |||
for (int i = 0; i < 2 * bih + 2; i++) { | |||
Res[leastSignifDigitIdx - i] ^= w2[2 * bih + 2 - 1 - i]; | |||
} | |||
leastSignifDigitIdx -= bih; | |||
for (int i = 0; i < 2 * bih + 2 ; i++) { | |||
Res[leastSignifDigitIdx - i] ^= w3[2 * bih + 2 - 1 - i]; | |||
} | |||
leastSignifDigitIdx -= bih; | |||
for (int i = 0; i < 2 * bih && (leastSignifDigitIdx - i >= 0) ; i++) { | |||
Res[leastSignifDigitIdx - i] ^= w4[2 * bih - 1 - i]; | |||
} | |||
} | |||
// #define MIN_KAR_DIGITS 20 | |||
// | |||
// static void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(const int nr, DIGIT Res[], | |||
// const int na, const DIGIT A[], | |||
// const int nb, const DIGIT B[]) { | |||
// | |||
// if (na < MIN_KAR_DIGITS || nb < MIN_KAR_DIGITS) { | |||
// /* fall back to schoolbook */ | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_comb(nr, Res, na, A, nb, B); | |||
// return; | |||
// } | |||
// | |||
// if (na % 2 == 0) { | |||
// unsigned bih = na / 2; | |||
// DIGIT middle[2 * bih], sumA[bih], sumB[bih]; | |||
// gf2x_add(sumA, A, A + bih, bih); | |||
// gf2x_add(sumB, B, B + bih, bih); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, middle, | |||
// bih, sumA, | |||
// bih, sumB); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, Res + 2 * bih, | |||
// bih, A + bih, | |||
// bih, B + bih); | |||
// gf2x_add(middle, middle, Res + 2 * bih, 2 * bih); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, Res, | |||
// bih, A, | |||
// bih, B); | |||
// gf2x_add(middle, middle, Res, 2 * bih); | |||
// gf2x_add(Res + bih, Res + bih, middle, 2 * bih); | |||
// } else { | |||
// unsigned bih = na / 2 + 1; | |||
// DIGIT middle[2 * bih], sumA[bih], sumB[bih]; | |||
// gf2x_add_asymm(bih, sumA, | |||
// bih, A + bih - 1, | |||
// bih - 1, A); | |||
// gf2x_add_asymm(bih, sumB, | |||
// bih, B + bih - 1, | |||
// bih - 1, B); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, middle, | |||
// bih, sumA, | |||
// bih, sumB); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * bih, Res + 2 * (bih - 1), | |||
// bih, A + bih - 1, | |||
// bih, B + bih - 1); | |||
// gf2x_add(middle, middle, Res + 2 * (bih - 1), 2 * bih); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(2 * (bih - 1), Res, | |||
// (bih - 1), A, | |||
// (bih - 1), B); | |||
// gf2x_add_asymm(2 * bih, middle, | |||
// 2 * bih, middle, | |||
// 2 * (bih - 1), Res); | |||
// gf2x_add(Res + bih - 2, Res + bih - 2, middle, 2 * bih); | |||
// } | |||
// } | |||
// | |||
// #define MIN_TOOM_DIGITS 35 | |||
// | |||
// void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(const int nr, DIGIT Res[], | |||
// const int na, const DIGIT A[], | |||
// const int nb, const DIGIT B[]) { | |||
// | |||
// if (na < MIN_TOOM_DIGITS || nb < MIN_TOOM_DIGITS) { | |||
// /* fall back to Karatsuba */ | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_Kar(nr, Res, na, A, nb, B); | |||
// return; | |||
// } | |||
// | |||
// int bih; //number of limbs for each part. | |||
// if (na % 3 == 0) { | |||
// bih = na / 3; | |||
// } else { | |||
// bih = na / 3 + 1; | |||
// } | |||
// | |||
// DIGIT u2[bih], u1[bih], u0[bih]; | |||
// | |||
// int leading_slack = (3 - (na) % 3) % 3; | |||
// // printf("leading slack %d",leading_slack); | |||
// int i; | |||
// for (i = 0; i < leading_slack ; i++) { | |||
// u2[i] = 0; | |||
// } | |||
// for (; i < bih; ++i) { | |||
// u2[i] = A[i - leading_slack]; | |||
// } | |||
// /* note: only u2 needs to be a copy, refactor */ | |||
// for (; i < 2 * bih; ++i) { | |||
// u1[i - bih] = A[i - leading_slack]; | |||
// } | |||
// for (; i < 3 * bih; ++i) { | |||
// u0[i - 2 * bih] = A[i - leading_slack]; | |||
// } | |||
// | |||
// DIGIT v2[bih], v1[bih], v0[bih]; /* partitioned inputs */ | |||
// /* note: only v2 needs to be a copy, refactor */ | |||
// for (i = 0; i < leading_slack ; i++) { | |||
// v2[i] = 0; | |||
// } | |||
// for (; i < bih; ++i) { | |||
// v2[i] = B[i - leading_slack]; | |||
// } | |||
// /* note , only v2 needs to be a copy */ | |||
// for (; i < 2 * bih; ++i) { | |||
// v1[i - bih] = B[i - leading_slack]; | |||
// } | |||
// for (; i < 3 * bih; ++i) { | |||
// v0[i - 2 * bih] = B[i - leading_slack]; | |||
// } | |||
// | |||
// DIGIT sum_u[bih]; /*bih digit wide*/ | |||
// gf2x_add(sum_u, u0, u1, bih); | |||
// gf2x_add(sum_u, sum_u, u2, bih); | |||
// | |||
// DIGIT sum_v[bih]; /*bih digit wide*/ | |||
// gf2x_add(sum_v, v0, v1, bih); | |||
// gf2x_add(sum_v, sum_v, v2, bih); | |||
// | |||
// | |||
// DIGIT w1[2 * bih]; | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih, w1, | |||
// bih, sum_u, | |||
// bih, sum_v); | |||
// | |||
// | |||
// DIGIT u2_x2[bih + 1]; | |||
// u2_x2[0] = 0; | |||
// memcpy(u2_x2 + 1, u2, bih * DIGIT_SIZE_B); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, u2_x2, 2); | |||
// | |||
// DIGIT u1_x[bih + 1]; | |||
// u1_x[0] = 0; | |||
// memcpy(u1_x + 1, u1, bih * DIGIT_SIZE_B); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, u1_x, 1); | |||
// | |||
// DIGIT u1_x1_u2_x2[bih + 1]; | |||
// gf2x_add(u1_x1_u2_x2, u1_x, u2_x2, bih + 1); | |||
// | |||
// DIGIT temp_u_components[bih + 1]; | |||
// gf2x_add_asymm(bih + 1, temp_u_components, | |||
// bih + 1, u1_x1_u2_x2, | |||
// bih, sum_u); | |||
// | |||
// DIGIT v2_x2[bih + 1]; | |||
// v2_x2[0] = 0; | |||
// memcpy(v2_x2 + 1, v2, bih * DIGIT_SIZE_B); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, v2_x2, 2); | |||
// | |||
// DIGIT v1_x[bih + 1]; | |||
// v1_x[0] = 0; | |||
// memcpy(v1_x + 1, v1, bih * DIGIT_SIZE_B); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(bih + 1, v1_x, 1); | |||
// | |||
// DIGIT v1_x1_v2_x2[bih + 1]; | |||
// gf2x_add(v1_x1_v2_x2, v1_x, v2_x2, bih + 1); | |||
// | |||
// DIGIT temp_v_components[bih + 1]; | |||
// gf2x_add_asymm(bih + 1, temp_v_components, | |||
// bih + 1, v1_x1_v2_x2, | |||
// bih, sum_v); | |||
// | |||
// DIGIT w3[2 * bih + 2]; | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih + 2, w3, | |||
// bih + 1, temp_u_components, | |||
// bih + 1, temp_v_components); | |||
// | |||
// gf2x_add_asymm(bih + 1, u1_x1_u2_x2, | |||
// bih + 1, u1_x1_u2_x2, | |||
// bih, u0); | |||
// gf2x_add_asymm(bih + 1, v1_x1_v2_x2, | |||
// bih + 1, v1_x1_v2_x2, | |||
// bih, v0); | |||
// | |||
// DIGIT w2[2 * bih + 2]; | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih + 2, w2, | |||
// bih + 1, u1_x1_u2_x2, | |||
// bih + 1, v1_x1_v2_x2); | |||
// | |||
// DIGIT w4[2 * bih]; | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih, w4, | |||
// bih, u2, | |||
// bih, v2); | |||
// DIGIT w0[2 * bih]; | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3(2 * bih, w0, | |||
// bih, u0, | |||
// bih, v0); | |||
// | |||
// // Interpolation starts | |||
// gf2x_add(w3, w2, w3, 2 * bih + 2); | |||
// gf2x_add_asymm(2 * bih + 2, w2, | |||
// 2 * bih + 2, w2, | |||
// 2 * bih, w0); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(2 * bih + 2, w2, 1); | |||
// gf2x_add(w2, w2, w3, 2 * bih + 2); | |||
// | |||
// // w2 + (w4 * x^3+1) = w2 + w4 + w4 << 3 | |||
// DIGIT w4_x3_plus_1[2 * bih + 1]; | |||
// w4_x3_plus_1[0] = 0; | |||
// memcpy(w4_x3_plus_1 + 1, w4, 2 * bih * DIGIT_SIZE_B); | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(2 * bih + 1, w4_x3_plus_1, 3); | |||
// gf2x_add_asymm(2 * bih + 2, w2, | |||
// 2 * bih + 2, w2, | |||
// 2 * bih, w4); | |||
// gf2x_add_asymm(2 * bih + 2, w2, | |||
// 2 * bih + 2, w2, | |||
// 2 * bih + 1, w4_x3_plus_1); | |||
// | |||
// gf2x_exact_div_x_plus_one(2 * bih + 2, w2); | |||
// | |||
// gf2x_add(w1, w1, w0, 2 * bih); | |||
// gf2x_add_asymm(2 * bih + 2, w3, | |||
// 2 * bih + 2, w3, | |||
// 2 * bih, w1); | |||
// | |||
// PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(2 * bih + 2, w3, 1); | |||
// gf2x_exact_div_x_plus_one(2 * bih + 2, w3); | |||
// | |||
// gf2x_add(w1, w1, w4, 2 * bih); | |||
// | |||
// DIGIT w1_final[2 * bih + 2]; | |||
// gf2x_add_asymm(2 * bih + 2, w1_final, | |||
// 2 * bih + 2, w2, | |||
// 2 * bih, w1); | |||
// gf2x_add(w2, w2, w3, 2 * bih + 2); | |||
// | |||
// // Result recombination starts here | |||
// | |||
// memset(Res, 0, nr * DIGIT_SIZE_B); | |||
// /* optimization: topmost slack digits should be computed, and not addedd, | |||
// * zeroization can be avoided altogether with a proper merge of the | |||
// * results */ | |||
// | |||
// int leastSignifDigitIdx = nr - 1; | |||
// for (int i = 0; i < 2 * bih; i++) { | |||
// Res[leastSignifDigitIdx - i] ^= w0[2 * bih - 1 - i]; | |||
// } | |||
// leastSignifDigitIdx -= bih; | |||
// for (int i = 0; i < 2 * bih + 2; i++) { | |||
// Res[leastSignifDigitIdx - i] ^= w1_final[2 * bih + 2 - 1 - i]; | |||
// } | |||
// leastSignifDigitIdx -= bih; | |||
// for (int i = 0; i < 2 * bih + 2; i++) { | |||
// Res[leastSignifDigitIdx - i] ^= w2[2 * bih + 2 - 1 - i]; | |||
// } | |||
// leastSignifDigitIdx -= bih; | |||
// for (int i = 0; i < 2 * bih + 2 ; i++) { | |||
// Res[leastSignifDigitIdx - i] ^= w3[2 * bih + 2 - 1 - i]; | |||
// } | |||
// leastSignifDigitIdx -= bih; | |||
// for (int i = 0; i < 2 * bih && (leastSignifDigitIdx - i >= 0) ; i++) { | |||
// Res[leastSignifDigitIdx - i] ^= w4[2 * bih - 1 - i]; | |||
// } | |||
// } | |||
// // Unused | |||
// static int gf2x_cmp(const unsigned lenA, const DIGIT A[], | |||
// const unsigned lenB, const DIGIT B[]) { | |||
@@ -43,27 +43,22 @@ | |||
*/ | |||
#define GF2X_MUL PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_TC3 | |||
#define GF2X_MUL PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_comb | |||
// #define GF2X_MUL gf2x_mul_comb | |||
static inline void gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], const unsigned int nr) { | |||
unsigned int i; | |||
for (i = 0; i < nr; i++) { | |||
static inline void gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], size_t nr) { | |||
for (size_t i = 0; i < nr; i++) { | |||
Res[i] = A[i] ^ B[i]; | |||
} | |||
} | |||
void GF2X_MUL(const int nr, DIGIT Res[], | |||
const int na, const DIGIT A[], | |||
const int nb, const DIGIT B[]); | |||
/* PRE: MAX ALLOWED ROTATION AMOUNT : DIGIT_SIZE_b */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(const int length, DIGIT in[], const int amount); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(size_t length, DIGIT in[], unsigned int amount); | |||
/* PRE: MAX ALLOWED ROTATION AMOUNT : DIGIT_SIZE_b */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(const int length, DIGIT in[], const int amount); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(size_t length, DIGIT in[], unsigned int amount); | |||
void GF2X_MUL(int nr, DIGIT Res[], int na, const DIGIT A[], int nb, const DIGIT B[]); | |||
#endif |
@@ -1,25 +1,25 @@ | |||
#include "gf2x_arith_mod_xPplusOne.h" | |||
#include "rng.h" | |||
#include <string.h> // memcpy(...), memset(...) | |||
#include <assert.h> | |||
#include <string.h> // memcpy(...), memset(...) | |||
static void gf2x_mod(DIGIT out[], | |||
const int nin, const DIGIT in[]) { | |||
static void gf2x_mod(DIGIT out[], const DIGIT in[]) { | |||
long int i, j, posTrailingBit, maskOffset; | |||
DIGIT mask, aux[nin]; | |||
int i, j, posTrailingBit, maskOffset; | |||
DIGIT mask, aux[2 * NUM_DIGITS_GF2X_ELEMENT]; | |||
memcpy(aux, in, nin * DIGIT_SIZE_B); | |||
memcpy(aux, in, 2 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); | |||
memset(out, 0x00, NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); | |||
if (nin < NUM_DIGITS_GF2X_MODULUS) { | |||
for (i = 0; i < nin; i++) { | |||
out[NUM_DIGITS_GF2X_ELEMENT - 1 - i] = in[nin - 1 - i]; | |||
if (2 * NUM_DIGITS_GF2X_ELEMENT < NUM_DIGITS_GF2X_MODULUS) { | |||
for (i = 0; i < 2 * NUM_DIGITS_GF2X_ELEMENT; i++) { | |||
out[NUM_DIGITS_GF2X_ELEMENT - 1 - i] = in[2 * NUM_DIGITS_GF2X_ELEMENT - 1 - i]; | |||
} | |||
return; | |||
} | |||
for (i = 0; i < nin - NUM_DIGITS_GF2X_MODULUS; i += 1) { | |||
for (i = 0; i < (2 * NUM_DIGITS_GF2X_ELEMENT) - NUM_DIGITS_GF2X_MODULUS; i += 1) { | |||
for (j = DIGIT_SIZE_b - 1; j >= 0; j--) { | |||
mask = ((DIGIT)0x1) << j; | |||
if (aux[i] & mask) { | |||
@@ -43,10 +43,10 @@ static void gf2x_mod(DIGIT out[], | |||
} | |||
} | |||
int to_copy = (nin > NUM_DIGITS_GF2X_ELEMENT) ? NUM_DIGITS_GF2X_ELEMENT : nin; | |||
int to_copy = (2 * NUM_DIGITS_GF2X_ELEMENT > NUM_DIGITS_GF2X_ELEMENT) ? NUM_DIGITS_GF2X_ELEMENT : 2 * NUM_DIGITS_GF2X_ELEMENT; | |||
for (i = 0; i < to_copy; i++) { | |||
out[NUM_DIGITS_GF2X_ELEMENT - 1 - i] = aux[nin - 1 - i]; | |||
out[NUM_DIGITS_GF2X_ELEMENT - 1 - i] = aux[2 * NUM_DIGITS_GF2X_ELEMENT - 1 - i]; | |||
} | |||
} | |||
@@ -61,9 +61,9 @@ static void left_bit_shift(const int length, DIGIT in[]) { | |||
in[j] <<= 1; | |||
} | |||
static void right_bit_shift(const int length, DIGIT in[]) { | |||
static void right_bit_shift(unsigned int length, DIGIT in[]) { | |||
int j; | |||
unsigned int j; | |||
for (j = length - 1; j > 0 ; j--) { | |||
in[j] >>= 1; | |||
in[j] |= (in[j - 1] & (DIGIT)0x01) << (DIGIT_SIZE_b - 1); | |||
@@ -73,8 +73,8 @@ static void right_bit_shift(const int length, DIGIT in[]) { | |||
/* shifts by whole digits */ | |||
static inline void left_DIGIT_shift_n(const int length, DIGIT in[], int amount) { | |||
int j; | |||
static inline void left_DIGIT_shift_n(unsigned int length, DIGIT in[], unsigned int amount) { | |||
unsigned int j; | |||
for (j = 0; (j + amount) < length; j++) { | |||
in[j] = in[j + amount]; | |||
} | |||
@@ -85,39 +85,15 @@ static inline void left_DIGIT_shift_n(const int length, DIGIT in[], int amount) | |||
/* may shift by an arbitrary amount*/ | |||
static void left_bit_shift_wide_n(const int length, DIGIT in[], int amount) { | |||
static void left_bit_shift_wide_n(const int length, DIGIT in[], unsigned int amount) { | |||
left_DIGIT_shift_n(length, in, amount / DIGIT_SIZE_b); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(length, in, amount % DIGIT_SIZE_b); | |||
} | |||
#if (defined(DIGIT_IS_UINT8) || defined(DIGIT_IS_UINT16)) | |||
static uint8_t byte_reverse_with_less32bitDIGIT(uint8_t b) { | |||
uint8_t r = b; | |||
int s = (sizeof(b) << 3) - 1; | |||
for (b >>= 1; b; b >>= 1) { | |||
r <<= 1; | |||
r |= b & 1; | |||
s--; | |||
} | |||
r <<= s; | |||
return r; | |||
} | |||
#endif | |||
#if defined(DIGIT_IS_UINT32) | |||
static uint8_t byte_reverse_with_32bitDIGIT(uint8_t b) { | |||
b = ( (b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU) | |||
) * 0x10101LU >> 16; | |||
return b; | |||
} | |||
#endif | |||
#if defined(DIGIT_IS_UINT64) | |||
static uint8_t byte_reverse_with_64bitDIGIT(uint8_t b) { | |||
b = (b * 0x0202020202ULL & 0x010884422010ULL) % 1023; | |||
return b; | |||
} | |||
#endif | |||
static DIGIT reverse_digit(const DIGIT b) { | |||
int i; | |||
@@ -127,28 +103,11 @@ static DIGIT reverse_digit(const DIGIT b) { | |||
} toReverse; | |||
toReverse.digitValue = b; | |||
#if defined(DIGIT_IS_UINT64) | |||
for (i = 0; i < DIGIT_SIZE_B; i++) { | |||
toReverse.inByte[i] = byte_reverse_with_64bitDIGIT(toReverse.inByte[i]); | |||
} | |||
return __builtin_bswap64(toReverse.digitValue); | |||
#elif defined(DIGIT_IS_UINT32) | |||
for (i = 0; i < DIGIT_SIZE_B; i++) { | |||
toReverse.inByte[i] = byte_reverse_with_32bitDIGIT(toReverse.inByte[i]); | |||
} | |||
return __builtin_bswap32(toReverse.digitValue); | |||
#elif defined(DIGIT_IS_UINT16) | |||
for (i = 0; i < DIGIT_SIZE_B; i++) { | |||
toReverse.inByte[i] = byte_reverse_with_less32bitDIGIT(toReverse.inByte[i]); | |||
} | |||
reversed = __builtin_bswap16(toReverse.digitValue); | |||
#elif defined(DIGIT_IS_UINT8) | |||
return byte_reverse_with_less32bitDIGIT(toReverse.inByte[0]); | |||
#else | |||
#error "Missing implementation for reverse_digit(...) \ | |||
with this CPU word bitsize !!! " | |||
#endif | |||
return toReverse.digitValue; | |||
} | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place(DIGIT A[]) { | |||
@@ -159,17 +118,6 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place(DIGIT A[]) { | |||
DIGIT rev1, rev2, a00; | |||
int i, slack_bits_amount = NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_b - P; | |||
if (NUM_DIGITS_GF2X_ELEMENT == 1) { | |||
a00 = A[0] & mask; | |||
right_bit_shift(1, A); | |||
rev1 = reverse_digit(A[0]); | |||
#if (NUM_DIGITS_GF2X_MOD_P_ELEMENT*DIGIT_SIZE_b - P) | |||
rev1 >>= (DIGIT_SIZE_b - (P % DIGIT_SIZE_b)); | |||
#endif | |||
A[0] = (rev1 & (~mask)) | a00; | |||
return; | |||
} | |||
a00 = A[NUM_DIGITS_GF2X_ELEMENT - 1] & mask; | |||
right_bit_shift(NUM_DIGITS_GF2X_ELEMENT, A); | |||
@@ -280,18 +228,20 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]) { | |||
} | |||
s[0] |= mask; | |||
for (i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0 && in[i] == 0; i--); | |||
for (i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0 && in[i] == 0; i--) { }; | |||
if (i < 0) { | |||
return 0; | |||
} | |||
if (NUM_DIGITS_GF2X_MODULUS == 1 + NUM_DIGITS_GF2X_ELEMENT) | |||
if (NUM_DIGITS_GF2X_MODULUS == 1 + NUM_DIGITS_GF2X_ELEMENT) { | |||
for (i = NUM_DIGITS_GF2X_MODULUS - 1; i >= 1 ; i--) { | |||
f[i] = in[i - 1]; | |||
} else /* they are equal */ | |||
} | |||
} else { /* they are equal */ | |||
for (i = NUM_DIGITS_GF2X_MODULUS - 1; i >= 0 ; i--) { | |||
f[i] = in[i]; | |||
} | |||
} | |||
for (i = 1; i <= 2 * P; i++) { | |||
if ( (f[0] & mask) == 0 ) { | |||
@@ -329,7 +279,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul(DIGIT Res[], const DIGIT A[], const | |||
GF2X_MUL(2 * NUM_DIGITS_GF2X_ELEMENT, aux, | |||
NUM_DIGITS_GF2X_ELEMENT, A, | |||
NUM_DIGITS_GF2X_ELEMENT, B); | |||
gf2x_mod(Res, 2 * NUM_DIGITS_GF2X_ELEMENT, aux); | |||
gf2x_mod(Res, aux); | |||
} | |||
@@ -358,7 +308,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_dense_to_sparse( | |||
} | |||
} | |||
gf2x_mod(Res, 2 * NUM_DIGITS_GF2X_ELEMENT, resDouble); | |||
gf2x_mod(Res, resDouble); | |||
} | |||
@@ -392,7 +342,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[ | |||
size_t lastFilledPos = 0; | |||
for (size_t i = 0 ; i < sizeA ; i++) { | |||
for (size_t j = 0 ; j < sizeB ; j++) { | |||
uint32_t prod = ((uint32_t) A[i]) + ((uint32_t) B[j]); | |||
uint32_t prod = A[i] + B[j]; | |||
prod = ( (prod >= P) ? prod - P : prod); | |||
if ((A[i] != INVALID_POS_VALUE) && | |||
(B[j] != INVALID_POS_VALUE)) { | |||
@@ -407,7 +357,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[ | |||
Res[lastFilledPos] = INVALID_POS_VALUE; | |||
lastFilledPos++; | |||
} | |||
quicksort(Res, sizeR); | |||
quicksort_sparse(Res); | |||
/* eliminate duplicates */ | |||
POSITION_T lastReadPos = Res[0]; | |||
int duplicateCount; | |||
@@ -436,10 +386,10 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[ | |||
/* PRE: A and B should be sorted and have INVALID_POS_VALUE at the end */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add_sparse( | |||
int sizeR, POSITION_T Res[], | |||
int sizeA, POSITION_T A[], | |||
int sizeB, POSITION_T B[]) { | |||
int sizeA, const POSITION_T A[], | |||
int sizeB, const POSITION_T B[]) { | |||
POSITION_T tmpRes[sizeR]; | |||
POSITION_T tmpRes[DV * M]; // TODO: now function only works for adding (disjunct) DV and M positions | |||
int idxA = 0, idxB = 0, idxR = 0; | |||
while ( idxA < sizeA && | |||
idxB < sizeB && | |||
@@ -509,7 +459,7 @@ static uint32_t rand_range(const unsigned int n, const int logn, AES_XOF_struct | |||
/* Obtains fresh randomness and seed-expands it until all the required positions | |||
* for the '1's in the circulant block are obtained */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, | |||
const int countOnes, | |||
int countOnes, | |||
AES_XOF_struct *seed_expander_ctx) { | |||
int duplicated, placedOnes = 0; | |||
@@ -520,9 +470,11 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, | |||
BITS_TO_REPRESENT(P), | |||
seed_expander_ctx); | |||
duplicated = 0; | |||
for (int j = 0; j < placedOnes; j++) if (pos_ones[j] == p) { | |||
for (int j = 0; j < placedOnes; j++) { | |||
if (pos_ones[j] == p) { | |||
duplicated = 1; | |||
} | |||
} | |||
if (duplicated == 0) { | |||
pos_ones[placedOnes] = p; | |||
placedOnes++; | |||
@@ -530,21 +482,23 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, | |||
} | |||
} | |||
/* Returns random weight-t circulant block */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence(DIGIT sequence[N0 * NUM_DIGITS_GF2X_ELEMENT], | |||
const int countOnes, | |||
AES_XOF_struct *seed_expander_ctx) { | |||
int rndPos[countOnes], duplicated, counter = 0; | |||
int rndPos[NUM_ERRORS_T], duplicated, counter = 0; | |||
memset(sequence, 0x00, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); | |||
while (counter < countOnes) { | |||
while (counter < NUM_ERRORS_T) { | |||
int p = rand_range(N0 * NUM_BITS_GF2X_ELEMENT, BITS_TO_REPRESENT(P), | |||
seed_expander_ctx); | |||
duplicated = 0; | |||
for (int j = 0; j < counter; j++) if (rndPos[j] == p) { | |||
for (int j = 0; j < counter; j++) { | |||
if (rndPos[j] == p) { | |||
duplicated = 1; | |||
} | |||
} | |||
if (duplicated == 0) { | |||
rndPos[counter] = p; | |||
counter++; | |||
@@ -18,43 +18,43 @@ | |||
#define INVALID_POS_VALUE (P) | |||
#define IS_REPRESENTABLE_IN_D_BITS(D, N) \ | |||
(((unsigned long) N >= (1UL << (D - 1)) && (unsigned long) N < (1UL << D)) ? D : -1) | |||
(((unsigned long) (N) >= (1UL << ((D) - 1)) && (unsigned long) (N) < (1UL << (D))) ? (D) : -1) | |||
#define BITS_TO_REPRESENT(N) \ | |||
(N == 0 ? 1 : (31 \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 1, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 2, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 3, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 4, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 5, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 6, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 7, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 8, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 9, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(10, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(11, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(12, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(13, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(14, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(15, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(16, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(17, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(18, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(19, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(20, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(21, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(22, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(23, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(24, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(25, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(26, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(27, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(28, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(29, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(30, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(31, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(32, N) \ | |||
) \ | |||
((N) == 0 ? 1 : (31 \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 1, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 2, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 3, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 4, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 5, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 6, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 7, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 8, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS( 9, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(10, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(11, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(12, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(13, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(14, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(15, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(16, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(17, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(18, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(19, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(20, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(21, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(22, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(23, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(24, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(25, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(26, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(27, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(28, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(29, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(30, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(31, N) \ | |||
+ IS_REPRESENTABLE_IN_D_BITS(32, N) \ | |||
) \ | |||
) | |||
@@ -65,7 +65,7 @@ static inline void gf2x_copy(DIGIT dest[], const DIGIT in[]) { | |||
} | |||
/* returns the coefficient of the x^exponent term as the LSB of a digit */ | |||
static inline DIGIT gf2x_get_coeff(const DIGIT poly[], const unsigned int exponent) { | |||
static inline DIGIT gf2x_get_coeff(const DIGIT poly[], unsigned int exponent) { | |||
unsigned int straightIdx = (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_b - 1) - exponent; | |||
unsigned int digitIdx = straightIdx / DIGIT_SIZE_b; | |||
unsigned int inDigitIdx = straightIdx % DIGIT_SIZE_b; | |||
@@ -73,10 +73,9 @@ static inline DIGIT gf2x_get_coeff(const DIGIT poly[], const unsigned int expone | |||
} | |||
/* sets the coefficient of the x^exponent term as the LSB of a digit */ | |||
static inline void gf2x_set_coeff(DIGIT poly[], const unsigned int exponent, DIGIT value) { | |||
int straightIdx = (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_b - 1) - exponent; | |||
int digitIdx = straightIdx / DIGIT_SIZE_b; | |||
static inline void gf2x_set_coeff(DIGIT poly[], unsigned int exponent, DIGIT value) { | |||
unsigned int straightIdx = (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_b - 1) - exponent; | |||
unsigned int digitIdx = straightIdx / DIGIT_SIZE_b; | |||
unsigned int inDigitIdx = straightIdx % DIGIT_SIZE_b; | |||
/* clear given coefficient */ | |||
@@ -87,9 +86,9 @@ static inline void gf2x_set_coeff(DIGIT poly[], const unsigned int exponent, DIG | |||
} | |||
/* toggles (flips) the coefficient of the x^exponent term as the LSB of a digit */ | |||
static inline void gf2x_toggle_coeff(DIGIT poly[], const unsigned int exponent) { | |||
int straightIdx = (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_b - 1) - exponent; | |||
int digitIdx = straightIdx / DIGIT_SIZE_b; | |||
static inline void gf2x_toggle_coeff(DIGIT poly[], unsigned int exponent) { | |||
unsigned int straightIdx = (NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_b - 1) - exponent; | |||
unsigned int digitIdx = straightIdx / DIGIT_SIZE_b; | |||
unsigned int inDigitIdx = straightIdx % DIGIT_SIZE_b; | |||
/* clear given coefficient */ | |||
@@ -97,28 +96,23 @@ static inline void gf2x_toggle_coeff(DIGIT poly[], const unsigned int exponent) | |||
poly[digitIdx] = poly[digitIdx] ^ mask; | |||
} | |||
/* population count for an unsigned 64-bit integer */ | |||
static int popcount_uint64t(uint64_t x) { | |||
x -= (x >> 1) & 0x5555555555555555; | |||
x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333); | |||
x = (x + (x >> 4)) & 0x0f0f0f0f0f0f0f0f; | |||
return (int)((x * 0x0101010101010101) >> 56); | |||
} | |||
/* population count for a single polynomial */ | |||
static inline int population_count(DIGIT upc[]) { | |||
static inline int population_count(DIGIT *poly) { | |||
int ret = 0; | |||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) { | |||
#if defined(DIGIT_IS_ULLONG) | |||
ret += __builtin_popcountll((unsigned long long int) (upc[i])); | |||
#elif defined(DIGIT_IS_ULONG) | |||
ret += __builtin_popcountl((unsigned long int) (upc[i])); | |||
#elif defined(DIGIT_IS_UINT) | |||
ret += __builtin_popcount((unsigned int) (upc[i])); | |||
#elif defined(DIGIT_IS_UCHAR) | |||
const unsigned char split_lookup[] = { | |||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 | |||
}; | |||
ret += split_lookup[upc[i] & 0xF] + split_lookup[upc[i] >> 4]; | |||
#else | |||
#error "Missing implementation for population_count(...) \ | |||
with this CPU word bitsize !!! " | |||
#endif | |||
ret += popcount_uint64t(poly[i]); | |||
} | |||
return ret; | |||
} // end population_count | |||
} | |||
static inline void gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) { | |||
gf2x_add(Res, A, B, NUM_DIGITS_GF2X_ELEMENT); | |||
@@ -126,25 +120,24 @@ static inline void gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) { | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul(DIGIT Res[], const DIGIT A[], const DIGIT B[]); | |||
int PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]);/* ret. 1 if inv. exists */ | |||
int PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]); | |||
/* in place bit-transp. of a(x) % x^P+1, e.g.: a3 a2 a1 a0 --> a1 a2 a3 a0 */ | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place(DIGIT A[]); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_sparse_block( | |||
POSITION_T *pos_ones, | |||
const int countOnes, | |||
int countOnes, | |||
AES_XOF_struct *seed_expander_ctx); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence( | |||
DIGIT sequence[N0 * NUM_DIGITS_GF2X_ELEMENT], | |||
const int countOnes, | |||
AES_XOF_struct *seed_expander_ctx); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add_sparse( | |||
int sizeR, POSITION_T Res[], | |||
int sizeA, POSITION_T A[], | |||
int sizeB, POSITION_T B[]); | |||
int sizeA, const POSITION_T A[], | |||
int sizeB, const POSITION_T B[]); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place_sparse( | |||
int sizeA, | |||
@@ -180,12 +173,11 @@ static inline int partition(POSITION_T arr[], int lo, int hi) { | |||
return i + 1; | |||
} | |||
static inline void quicksort(POSITION_T Res[], unsigned int sizeR) { | |||
/* sort the result */ | |||
int stack[sizeR]; | |||
static inline void quicksort_sparse(POSITION_T Res[]) { | |||
int stack[DV * M]; | |||
int hi, lo, pivot, tos = -1; | |||
stack[++tos] = 0; | |||
stack[++tos] = sizeR - 1; | |||
stack[++tos] = (DV * M) - 1; | |||
while (tos >= 0 ) { | |||
hi = stack[tos--]; | |||
lo = stack[tos--]; | |||
@@ -1,58 +1,11 @@ | |||
#ifndef GF2X_LIMBS_H | |||
#define GF2X_LIMBS_H | |||
#include "qc_ldpc_parameters.h" | |||
#include <inttypes.h> | |||
#include <limits.h> | |||
#include <stddef.h> | |||
#include "qc_ldpc_parameters.h" | |||
/*----------------------------------------------------------------------------*/ | |||
/* limb size definitions for the multi-precision GF(2^x) library */ | |||
/*----------------------------------------------------------------------------*/ | |||
// #ifndef CPU_WORD_BITS | |||
// typedef size_t DIGIT; | |||
// #define DIGIT_MAX SIZE_MAX | |||
// #else | |||
// // gcc -DCPU_WORD_BITS=64 ... | |||
// #define CAT(a, b, c) PRIMITIVE_CAT(a, b, c) | |||
// #define PRIMITIVE_CAT(a, b, c) a ## b ## c | |||
// | |||
// typedef CAT( uint, CPU_WORD_BITS, _t ) DIGIT; | |||
// #define DIGIT_MAX (CAT(UINT, CPU_WORD_BITS, _MAX)) | |||
// #endif | |||
// | |||
// #if (DIGIT_MAX == ULLONG_MAX) | |||
// #define DIGIT_IS_ULLONG | |||
// #elif (DIGIT_MAX == ULONG_MAX) | |||
// #define DIGIT_IS_ULONG | |||
// #elif (DIGIT_MAX == UINT_MAX) | |||
// #define DIGIT_IS_UINT | |||
// #elif (DIGIT_MAX == UCHAR_MAX) | |||
// #define DIGIT_IS_UCHAR | |||
// #else | |||
// #error "unable to find the type of CPU_WORD_BITS" | |||
// #endif | |||
// | |||
// #if (DIGIT_MAX == UINT64_MAX) | |||
// #define DIGIT_IS_UINT64 | |||
// #define DIGIT_SIZE_B 8 | |||
// #elif (DIGIT_MAX == UINT32_MAX) | |||
// #define DIGIT_IS_UINT32 | |||
// #define DIGIT_SIZE_B 4 | |||
// #elif (DIGIT_MAX == UINT16_MAX) | |||
// #define DIGIT_IS_UINT16 | |||
// #define DIGIT_SIZE_B 2 | |||
// #elif (DIGIT_MAX == UINT8_MAX) | |||
// #define DIGIT_IS_UINT8 | |||
// #define DIGIT_SIZE_B 1 | |||
// #else | |||
// #error "unable to find the bitsize of size_t" | |||
// #endif | |||
// #define LITTLE_ENDIAN | |||
typedef uint64_t DIGIT; | |||
#define DIGIT_IS_UINT64 | |||
@@ -27,12 +27,9 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_crypto_kem_enc( unsigned char *ct, unsigned char * | |||
randombytes(encapsulated_key_seed, TRNG_BYTE_LENGTH); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_seedexpander_from_trng(&niederreiter_encap_key_expander, encapsulated_key_seed); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence(error_vector, | |||
NUM_ERRORS_T, | |||
&niederreiter_encap_key_expander); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence(error_vector, &niederreiter_encap_key_expander); | |||
HASH_FUNCTION(ss, (const uint8_t *) error_vector, // input | |||
(N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); // input length | |||
HASH_FUNCTION(ss, (const uint8_t *) error_vector, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); | |||
PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_encrypt((DIGIT *) ct, (publicKeyNiederreiter_t *) pk, error_vector); | |||
return 0; | |||
@@ -46,13 +43,10 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_crypto_kem_dec(unsigned char *ss, | |||
const unsigned char *sk ) { | |||
DIGIT decoded_error_vector[N0 * NUM_DIGITS_GF2X_ELEMENT]; | |||
int decode_ok = PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(decoded_error_vector, | |||
(privateKeyNiederreiter_t *)sk, | |||
(DIGIT *)ct); | |||
HASH_FUNCTION(ss, (const unsigned char *) decoded_error_vector, | |||
(N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); | |||
if (decode_ok == 1) { | |||
return 0; | |||
} | |||
return -1; | |||
PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(decoded_error_vector, | |||
(privateKeyNiederreiter_t *)sk, | |||
(DIGIT *)ct); | |||
HASH_FUNCTION(ss, (const unsigned char *) decoded_error_vector, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); | |||
return 0; | |||
} |
@@ -1,14 +1,13 @@ | |||
#include "niederreiter.h" | |||
#include "H_Q_matrices_generation.h" | |||
#include "gf2x_arith_mod_xPplusOne.h" | |||
#include "rng.h" | |||
#include "dfr_test.h" | |||
#include "bf_decoding.h" | |||
#include "dfr_test.h" | |||
#include "gf2x_arith_mod_xPplusOne.h" | |||
#include "niederreiter.h" | |||
#include "qc_ldpc_parameters.h" | |||
#include "rng.h" | |||
#include <string.h> | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *const pk, | |||
privateKeyNiederreiter_t *const sk, | |||
AES_XOF_struct *keys_expander) { | |||
@@ -207,7 +206,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(DIGIT err[], // N0 | |||
} | |||
decryptOk = decryptOk && (err_weight == NUM_ERRORS_T); | |||
if (!decryptOk) { | |||
if (!decryptOk) { // TODO: not constant time | |||
memcpy(err, mockup_error_vector, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); | |||
} | |||
@@ -1,9 +1,9 @@ | |||
#ifndef NIEDERREITER_H | |||
#define NIEDERREITER_H | |||
#include "qc_ldpc_parameters.h" | |||
#include "gf2x_limbs.h" | |||
#include "gf2x_arith_mod_xPplusOne.h" | |||
#include "gf2x_limbs.h" | |||
#include "qc_ldpc_parameters.h" | |||
#include "rng.h" | |||
typedef struct { | |||
@@ -23,18 +23,21 @@ typedef struct { | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *const pk, | |||
privateKeyNiederreiter_t *const sk, | |||
AES_XOF_struct *keys_expander); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen( | |||
publicKeyNiederreiter_t *pk, | |||
privateKeyNiederreiter_t *sk, | |||
AES_XOF_struct *keys_expander); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_encrypt(DIGIT syndrome[], | |||
const publicKeyNiederreiter_t *const pk, | |||
const DIGIT err[]); | |||
void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_encrypt( | |||
DIGIT syndrome[], | |||
const publicKeyNiederreiter_t *pk, | |||
const DIGIT *err); | |||
// return 1 if everything is ok | |||
int PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(DIGIT err[], | |||
const privateKeyNiederreiter_t *const sk, | |||
const DIGIT syndrome[]); | |||
int PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt( | |||
DIGIT *err, | |||
const privateKeyNiederreiter_t *sk, | |||
const DIGIT *syndrome); | |||
#endif |
@@ -1,13 +1,13 @@ | |||
#ifndef RNG_H | |||
#define RNG_H | |||
#include <stdint.h> | |||
#include <stddef.h> | |||
#include <stdint.h> | |||
#define RNG_SUCCESS 0 | |||
#define RNG_BAD_MAXLEN -1 | |||
#define RNG_BAD_OUTBUF -2 | |||
#define RNG_BAD_REQ_LEN -3 | |||
#define RNG_SUCCESS ( 0) | |||
#define RNG_BAD_MAXLEN (-1) | |||
#define RNG_BAD_OUTBUF (-2) | |||
#define RNG_BAD_REQ_LEN (-3) | |||
typedef struct { | |||
unsigned char buffer[16]; | |||