Browse Source

fix gcc/clang-tidy warnings, remove preprocessor conditionals

tags/v0.0.1
Leon 5 years ago
parent
commit
a7b3aa73b2
14 changed files with 434 additions and 542 deletions
  1. +1
    -1
      crypto_kem/ledakemlt12/clean/H_Q_matrices_generation.h
  2. +1
    -3
      crypto_kem/ledakemlt12/clean/Makefile
  3. +10
    -10
      crypto_kem/ledakemlt12/clean/bf_decoding.c
  4. +1
    -1
      crypto_kem/ledakemlt12/clean/bf_decoding.h
  5. +10
    -9
      crypto_kem/ledakemlt12/clean/dfr_test.c
  6. +269
    -266
      crypto_kem/ledakemlt12/clean/gf2x_arith.c
  7. +7
    -12
      crypto_kem/ledakemlt12/clean/gf2x_arith.h
  8. +40
    -86
      crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.c
  9. +61
    -69
      crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.h
  10. +2
    -49
      crypto_kem/ledakemlt12/clean/gf2x_limbs.h
  11. +8
    -14
      crypto_kem/ledakemlt12/clean/kem.c
  12. +5
    -6
      crypto_kem/ledakemlt12/clean/niederreiter.c
  13. +14
    -11
      crypto_kem/ledakemlt12/clean/niederreiter.h
  14. +5
    -5
      crypto_kem/ledakemlt12/clean/rng.h

+ 1
- 1
crypto_kem/ledakemlt12/clean/H_Q_matrices_generation.h View File

@@ -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(


+ 1
- 3
crypto_kem/ledakemlt12/clean/Makefile View File

@@ -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)


+ 10
- 10
crypto_kem/ledakemlt12/clean/bf_decoding.c View File

@@ -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
- 1
crypto_kem/ledakemlt12/clean/bf_decoding.h View File

@@ -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)


+ 10
- 9
crypto_kem/ledakemlt12/clean/dfr_test.c View File

@@ -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;


+ 269
- 266
crypto_kem/ledakemlt12/clean/gf2x_arith.c View File

@@ -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[]) {


+ 7
- 12
crypto_kem/ledakemlt12/clean/gf2x_arith.h View File

@@ -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

+ 40
- 86
crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.c View File

@@ -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++;


+ 61
- 69
crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.h View File

@@ -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--];


+ 2
- 49
crypto_kem/ledakemlt12/clean/gf2x_limbs.h View File

@@ -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


+ 8
- 14
crypto_kem/ledakemlt12/clean/kem.c View File

@@ -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;
}

+ 5
- 6
crypto_kem/ledakemlt12/clean/niederreiter.c View File

@@ -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);
}



+ 14
- 11
crypto_kem/ledakemlt12/clean/niederreiter.h View File

@@ -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

+ 5
- 5
crypto_kem/ledakemlt12/clean/rng.h View File

@@ -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];


Loading…
Cancel
Save