move implementations of functions to .c files
Este cometimento está contido em:
ascendente
9e3f973f56
cometimento
6811a40527
@ -18,13 +18,13 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[],
|
||||
int iteration = 0;
|
||||
|
||||
do {
|
||||
gf2x_copy(currSyndrome, privateSyndrome);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_copy(currSyndrome, privateSyndrome);
|
||||
memset(unsatParityChecks, 0x00, N0 * P * sizeof(uint8_t));
|
||||
for (int i = 0; i < N0; i++) {
|
||||
for (int valueIdx = 0; valueIdx < P; valueIdx++) {
|
||||
for (int HtrOneIdx = 0; HtrOneIdx < DV; HtrOneIdx++) {
|
||||
POSITION_T tmp = (HtrPosOnes[i][HtrOneIdx] + valueIdx) >= P ? (HtrPosOnes[i][HtrOneIdx] + valueIdx) - P : (HtrPosOnes[i][HtrOneIdx] + valueIdx);
|
||||
if (gf2x_get_coeff(currSyndrome, tmp)) {
|
||||
if (PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_get_coeff(currSyndrome, tmp)) {
|
||||
unsatParityChecks[i * P + valueIdx]++;
|
||||
}
|
||||
}
|
||||
@ -54,13 +54,13 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[],
|
||||
}
|
||||
/* Correlation based flipping */
|
||||
if (correlation >= corrt_syndrome_based) {
|
||||
gf2x_toggle_coeff(err + NUM_DIGITS_GF2X_ELEMENT * i, j);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_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++) {
|
||||
syndromePosToFlip = (HtrPosOnes[currQBlkPos[v]][HtrOneIdx] + currQBitPos[v] );
|
||||
syndromePosToFlip = syndromePosToFlip >= P ? syndromePosToFlip - P : syndromePosToFlip;
|
||||
gf2x_toggle_coeff(privateSyndrome, syndromePosToFlip);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_toggle_coeff(privateSyndrome, syndromePosToFlip);
|
||||
}
|
||||
} // end for v
|
||||
} // end if
|
||||
|
@ -38,7 +38,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) {
|
||||
LSparse_loc[i][j] = (P - LSparse[i][j]);
|
||||
}
|
||||
}
|
||||
quicksort_sparse(LSparse_loc[i]);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_quicksort_sparse(LSparse_loc[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < N0; i++ ) {
|
||||
@ -48,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_sparse(rotated_column);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_quicksort_sparse(rotated_column);
|
||||
/* compute the intersection amount */
|
||||
firstidx = 0, secondidx = 0;
|
||||
intersectionval = 0;
|
||||
|
@ -3,6 +3,12 @@
|
||||
#include <assert.h>
|
||||
#include <string.h> // memset(...)
|
||||
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr) {
|
||||
for (int i = 0; i < nr; i++) {
|
||||
Res[i] = A[i] ^ B[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* PRE: MAX ALLOWED ROTATION AMOUNT : DIGIT_SIZE_b */
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(int length, DIGIT in[], unsigned int amount) {
|
||||
assert(amount < DIGIT_SIZE_b);
|
||||
|
@ -50,12 +50,7 @@ typedef uint64_t DIGIT;
|
||||
|
||||
#define GF2X_MUL PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mul_comb
|
||||
|
||||
static inline void gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr) {
|
||||
for (int i = 0; i < nr; i++) {
|
||||
Res[i] = A[i] ^ B[i];
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(int length, DIGIT in[], unsigned int amount);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_left_bit_shift_n(int length, DIGIT in[], unsigned int amount);
|
||||
void GF2X_MUL(int nr, DIGIT Res[], int na, const DIGIT A[], int nb, const DIGIT B[]);
|
||||
|
@ -4,6 +4,103 @@
|
||||
#include <assert.h>
|
||||
#include <string.h> // memcpy(...), memset(...)
|
||||
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_copy(DIGIT dest[], const DIGIT in[]) {
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
dest[i] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the coefficient of the x^exponent term as the LSB of a digit */
|
||||
DIGIT PQCLEAN_LEDAKEMLT12_CLEAN_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;
|
||||
return (poly[digitIdx] >> (DIGIT_SIZE_b - 1 - inDigitIdx)) & ((DIGIT) 1) ;
|
||||
}
|
||||
|
||||
/* sets the coefficient of the x^exponent term as the LSB of a digit */
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_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 */
|
||||
DIGIT mask = ~( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] & mask;
|
||||
poly[digitIdx] = poly[digitIdx] | (( value & ((DIGIT) 1)) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
}
|
||||
|
||||
/* toggles (flips) the coefficient of the x^exponent term as the LSB of a digit */
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_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 */
|
||||
DIGIT mask = ( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] ^ mask;
|
||||
}
|
||||
|
||||
/* population count for an unsigned 64-bit integer
|
||||
Source: Hacker's delight, p.66 */
|
||||
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 */
|
||||
int PQCLEAN_LEDAKEMLT12_CLEAN_population_count(DIGIT *poly) {
|
||||
int ret = 0;
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
ret += popcount_uint64t(poly[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) {
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_add(Res, A, B, NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
static int partition(POSITION_T arr[], int lo, int hi) {
|
||||
POSITION_T x = arr[hi];
|
||||
POSITION_T tmp;
|
||||
int i = (lo - 1);
|
||||
for (int j = lo; j <= hi - 1; j++) {
|
||||
if (arr[j] <= x) {
|
||||
i++;
|
||||
tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
}
|
||||
tmp = arr[i + 1];
|
||||
arr[i + 1] = arr[hi];
|
||||
arr[hi] = tmp;
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_quicksort_sparse(POSITION_T Res[]) {
|
||||
int stack[DV * M];
|
||||
int hi, lo, pivot, tos = -1;
|
||||
stack[++tos] = 0;
|
||||
stack[++tos] = (DV * M) - 1;
|
||||
while (tos >= 0 ) {
|
||||
hi = stack[tos--];
|
||||
lo = stack[tos--];
|
||||
pivot = partition(Res, lo, hi);
|
||||
if ( (pivot - 1) > lo) {
|
||||
stack[++tos] = lo;
|
||||
stack[++tos] = pivot - 1;
|
||||
}
|
||||
if ( (pivot + 1) < hi) {
|
||||
stack[++tos] = pivot + 1;
|
||||
stack[++tos] = hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gf2x_mod(DIGIT out[], const DIGIT in[]) {
|
||||
|
||||
@ -65,7 +162,7 @@ static void right_bit_shift(unsigned int length, DIGIT in[]) {
|
||||
|
||||
|
||||
/* shifts by whole digits */
|
||||
static inline void left_DIGIT_shift_n(unsigned int length, DIGIT in[], unsigned int amount) {
|
||||
static 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];
|
||||
@ -75,7 +172,6 @@ static inline void left_DIGIT_shift_n(unsigned int length, DIGIT in[], unsigned
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* may shift by an arbitrary 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);
|
||||
@ -115,7 +211,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place(DIGIT A[]) {
|
||||
A[NUM_DIGITS_GF2X_ELEMENT - 1 - i] = rev1;
|
||||
}
|
||||
|
||||
A[NUM_DIGITS_GF2X_ELEMENT / 2] = reverse_digit(A[NUM_DIGITS_GF2X_ELEMENT / 2]); // reverse middle digit
|
||||
A[NUM_DIGITS_GF2X_ELEMENT / 2] = reverse_digit(A[NUM_DIGITS_GF2X_ELEMENT / 2]);
|
||||
|
||||
if (slack_bits_amount) {
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_right_bit_shift_n(NUM_DIGITS_GF2X_ELEMENT, A, slack_bits_amount);
|
||||
@ -143,9 +239,7 @@ static void rotate_bit_right(DIGIT in[]) { /* x^{-1} * in(x) mod x^P+1 */
|
||||
in[0] |= rotated_bit;
|
||||
}
|
||||
|
||||
static void gf2x_swap(const int length,
|
||||
DIGIT f[],
|
||||
DIGIT s[]) {
|
||||
static void gf2x_swap(const int length, DIGIT f[], DIGIT s[]) {
|
||||
DIGIT t;
|
||||
for (int i = length - 1; i >= 0; i--) {
|
||||
t = f[i];
|
||||
@ -174,7 +268,7 @@ static void gf2x_swap(const int length,
|
||||
int PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]) { /* in^{-1} mod x^P-1 */
|
||||
|
||||
int i;
|
||||
long int delta = 0;
|
||||
int delta = 0;
|
||||
DIGIT u[NUM_DIGITS_GF2X_ELEMENT] = {0};
|
||||
DIGIT v[NUM_DIGITS_GF2X_ELEMENT] = {0};
|
||||
DIGIT s[NUM_DIGITS_GF2X_MODULUS] = {0};
|
||||
@ -205,8 +299,8 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]) {
|
||||
delta += 1;
|
||||
} else {
|
||||
if ( (s[0] & mask) != 0) {
|
||||
gf2x_add(s, s, f, NUM_DIGITS_GF2X_MODULUS);
|
||||
gf2x_mod_add(v, v, u);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_add(s, s, f, NUM_DIGITS_GF2X_MODULUS);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add(v, v, u);
|
||||
}
|
||||
left_bit_shift(NUM_DIGITS_GF2X_MODULUS, s);
|
||||
if ( delta == 0 ) {
|
||||
@ -258,7 +352,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_dense_to_sparse(
|
||||
for (unsigned int i = 1; i < nPos; i++) {
|
||||
if (sparse[i] != INVALID_POS_VALUE) {
|
||||
left_bit_shift_wide_n(2 * NUM_DIGITS_GF2X_ELEMENT, aux, (sparse[i] - sparse[i - 1]) );
|
||||
gf2x_add(resDouble, aux, resDouble, 2 * NUM_DIGITS_GF2X_ELEMENT);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_add(resDouble, aux, resDouble, 2 * NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,7 +406,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[
|
||||
Res[lastFilledPos] = INVALID_POS_VALUE;
|
||||
lastFilledPos++;
|
||||
}
|
||||
quicksort_sparse(Res);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_quicksort_sparse(Res);
|
||||
/* eliminate duplicates */
|
||||
POSITION_T lastReadPos = Res[0];
|
||||
int duplicateCount;
|
||||
@ -438,8 +532,9 @@ 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],
|
||||
AES_XOF_struct *seed_expander_ctx) {
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence(
|
||||
DIGIT sequence[N0 * NUM_DIGITS_GF2X_ELEMENT],
|
||||
AES_XOF_struct *seed_expander_ctx) {
|
||||
|
||||
int rndPos[NUM_ERRORS_T], duplicated, counter = 0;
|
||||
int p, polyIndex, exponent;
|
||||
@ -463,8 +558,8 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence(DIGIT sequence[N0
|
||||
for (int j = 0; j < counter; j++) {
|
||||
polyIndex = rndPos[j] / P;
|
||||
exponent = rndPos[j] % P;
|
||||
gf2x_set_coeff( sequence + NUM_DIGITS_GF2X_ELEMENT * polyIndex, exponent,
|
||||
( (DIGIT) 1));
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_set_coeff( sequence + NUM_DIGITS_GF2X_ELEMENT * polyIndex, exponent,
|
||||
( (DIGIT) 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,105 +15,13 @@
|
||||
#define INVALID_POS_VALUE (P)
|
||||
#define P_BITS (16) // log_2(p) = 15.6703
|
||||
|
||||
|
||||
static inline void gf2x_copy(DIGIT dest[], const DIGIT in[]) {
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
dest[i] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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;
|
||||
return (poly[digitIdx] >> (DIGIT_SIZE_b - 1 - inDigitIdx)) & ((DIGIT) 1) ;
|
||||
}
|
||||
|
||||
/* sets the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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 */
|
||||
DIGIT mask = ~( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] & mask;
|
||||
poly[digitIdx] = poly[digitIdx] | (( value & ((DIGIT) 1)) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
}
|
||||
|
||||
/* toggles (flips) the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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 */
|
||||
DIGIT mask = ( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] ^ mask;
|
||||
}
|
||||
|
||||
/* population count for an unsigned 64-bit integer
|
||||
Source: Hacker's delight, p.66 */
|
||||
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 *poly) {
|
||||
int ret = 0;
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
ret += popcount_uint64t(poly[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) {
|
||||
gf2x_add(Res, A, B, NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
static inline int partition(POSITION_T arr[], int lo, int hi) {
|
||||
POSITION_T x = arr[hi];
|
||||
POSITION_T tmp;
|
||||
int i = (lo - 1);
|
||||
for (int j = lo; j <= hi - 1; j++) {
|
||||
if (arr[j] <= x) {
|
||||
i++;
|
||||
tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
}
|
||||
tmp = arr[i + 1];
|
||||
arr[i + 1] = arr[hi];
|
||||
arr[hi] = tmp;
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
static inline void quicksort_sparse(POSITION_T Res[]) {
|
||||
int stack[DV * M];
|
||||
int hi, lo, pivot, tos = -1;
|
||||
stack[++tos] = 0;
|
||||
stack[++tos] = (DV * M) - 1;
|
||||
while (tos >= 0 ) {
|
||||
hi = stack[tos--];
|
||||
lo = stack[tos--];
|
||||
pivot = partition(Res, lo, hi);
|
||||
if ( (pivot - 1) > lo) {
|
||||
stack[++tos] = lo;
|
||||
stack[++tos] = pivot - 1;
|
||||
}
|
||||
if ( (pivot + 1) < hi) {
|
||||
stack[++tos] = pivot + 1;
|
||||
stack[++tos] = hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_copy(DIGIT dest[], const DIGIT in[]);
|
||||
DIGIT PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_get_coeff(const DIGIT poly[], unsigned int exponent);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_set_coeff(DIGIT poly[], unsigned int exponent, DIGIT value);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_toggle_coeff(DIGIT poly[], unsigned int exponent);
|
||||
int PQCLEAN_LEDAKEMLT12_CLEAN_population_count(DIGIT *poly);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_quicksort_sparse(POSITION_T Res[]);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul(DIGIT Res[], const DIGIT A[], const DIGIT B[]);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place(DIGIT A[]);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, int countOnes, AES_XOF_struct *seed_expander_ctx);
|
||||
@ -123,7 +31,6 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place_sparse(int sizeA, POSITIO
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[], size_t sizeA, const POSITION_T A[], size_t sizeB, const POSITION_T B[]);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul_dense_to_sparse(DIGIT Res[], const DIGIT dense[], POSITION_T sparse[], unsigned int nPos);
|
||||
void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_tobytes(uint8_t *bytes, const DIGIT *poly);
|
||||
|
||||
int PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]);
|
||||
|
||||
#endif
|
||||
|
@ -58,7 +58,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk,
|
||||
memset(Ln0dense, 0x00, sizeof(Ln0dense));
|
||||
for (int j = 0; j < DV * M; j++) {
|
||||
if (LPosOnes[N0 - 1][j] != INVALID_POS_VALUE) {
|
||||
gf2x_set_coeff(Ln0dense, LPosOnes[N0 - 1][j], 1);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_set_coeff(Ln0dense, LPosOnes[N0 - 1][j], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,9 +86,9 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_encrypt(DIGIT *syndrome, const publi
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_mul(saux,
|
||||
pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT,
|
||||
err + i * NUM_DIGITS_GF2X_ELEMENT);
|
||||
gf2x_mod_add(syndrome, syndrome, saux);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add(syndrome, syndrome, saux);
|
||||
}
|
||||
gf2x_mod_add(syndrome, syndrome, err + (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT);
|
||||
PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add(syndrome, syndrome, err + (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
|
||||
@ -180,7 +180,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(DIGIT *err, const privateKeyN
|
||||
|
||||
err_weight = 0;
|
||||
for (int i = 0 ; i < N0; i++) {
|
||||
err_weight += population_count(err + (NUM_DIGITS_GF2X_ELEMENT * i));
|
||||
err_weight += PQCLEAN_LEDAKEMLT12_CLEAN_population_count(err + (NUM_DIGITS_GF2X_ELEMENT * i));
|
||||
}
|
||||
decryptOk = decryptOk && (err_weight == NUM_ERRORS_T);
|
||||
|
||||
|
@ -18,13 +18,13 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(DIGIT err[],
|
||||
int iteration = 0;
|
||||
|
||||
do {
|
||||
gf2x_copy(currSyndrome, privateSyndrome);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_copy(currSyndrome, privateSyndrome);
|
||||
memset(unsatParityChecks, 0x00, N0 * P * sizeof(uint8_t));
|
||||
for (int i = 0; i < N0; i++) {
|
||||
for (int valueIdx = 0; valueIdx < P; valueIdx++) {
|
||||
for (int HtrOneIdx = 0; HtrOneIdx < DV; HtrOneIdx++) {
|
||||
POSITION_T tmp = (HtrPosOnes[i][HtrOneIdx] + valueIdx) >= P ? (HtrPosOnes[i][HtrOneIdx] + valueIdx) - P : (HtrPosOnes[i][HtrOneIdx] + valueIdx);
|
||||
if (gf2x_get_coeff(currSyndrome, tmp)) {
|
||||
if (PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_get_coeff(currSyndrome, tmp)) {
|
||||
unsatParityChecks[i * P + valueIdx]++;
|
||||
}
|
||||
}
|
||||
@ -54,13 +54,13 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(DIGIT err[],
|
||||
}
|
||||
/* Correlation based flipping */
|
||||
if (correlation >= corrt_syndrome_based) {
|
||||
gf2x_toggle_coeff(err + NUM_DIGITS_GF2X_ELEMENT * i, j);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_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++) {
|
||||
syndromePosToFlip = (HtrPosOnes[currQBlkPos[v]][HtrOneIdx] + currQBitPos[v] );
|
||||
syndromePosToFlip = syndromePosToFlip >= P ? syndromePosToFlip - P : syndromePosToFlip;
|
||||
gf2x_toggle_coeff(privateSyndrome, syndromePosToFlip);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_toggle_coeff(privateSyndrome, syndromePosToFlip);
|
||||
}
|
||||
} // end for v
|
||||
} // end if
|
||||
|
@ -38,7 +38,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) {
|
||||
LSparse_loc[i][j] = (P - LSparse[i][j]);
|
||||
}
|
||||
}
|
||||
quicksort_sparse(LSparse_loc[i]);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_quicksort_sparse(LSparse_loc[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < N0; i++ ) {
|
||||
@ -48,7 +48,7 @@ int PQCLEAN_LEDAKEMLT32_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_sparse(rotated_column);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_quicksort_sparse(rotated_column);
|
||||
/* compute the intersection amount */
|
||||
firstidx = 0, secondidx = 0;
|
||||
intersectionval = 0;
|
||||
|
@ -3,6 +3,12 @@
|
||||
#include <assert.h>
|
||||
#include <string.h> // memset(...)
|
||||
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr) {
|
||||
for (int i = 0; i < nr; i++) {
|
||||
Res[i] = A[i] ^ B[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* PRE: MAX ALLOWED ROTATION AMOUNT : DIGIT_SIZE_b */
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_right_bit_shift_n(int length, DIGIT in[], unsigned int amount) {
|
||||
assert(amount < DIGIT_SIZE_b);
|
||||
|
@ -50,12 +50,7 @@ typedef uint64_t DIGIT;
|
||||
|
||||
#define GF2X_MUL PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mul_comb
|
||||
|
||||
static inline void gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr) {
|
||||
for (int i = 0; i < nr; i++) {
|
||||
Res[i] = A[i] ^ B[i];
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_right_bit_shift_n(int length, DIGIT in[], unsigned int amount);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_left_bit_shift_n(int length, DIGIT in[], unsigned int amount);
|
||||
void GF2X_MUL(int nr, DIGIT Res[], int na, const DIGIT A[], int nb, const DIGIT B[]);
|
||||
|
@ -4,6 +4,103 @@
|
||||
#include <assert.h>
|
||||
#include <string.h> // memcpy(...), memset(...)
|
||||
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_copy(DIGIT dest[], const DIGIT in[]) {
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
dest[i] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the coefficient of the x^exponent term as the LSB of a digit */
|
||||
DIGIT PQCLEAN_LEDAKEMLT32_CLEAN_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;
|
||||
return (poly[digitIdx] >> (DIGIT_SIZE_b - 1 - inDigitIdx)) & ((DIGIT) 1) ;
|
||||
}
|
||||
|
||||
/* sets the coefficient of the x^exponent term as the LSB of a digit */
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_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 */
|
||||
DIGIT mask = ~( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] & mask;
|
||||
poly[digitIdx] = poly[digitIdx] | (( value & ((DIGIT) 1)) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
}
|
||||
|
||||
/* toggles (flips) the coefficient of the x^exponent term as the LSB of a digit */
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_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 */
|
||||
DIGIT mask = ( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] ^ mask;
|
||||
}
|
||||
|
||||
/* population count for an unsigned 64-bit integer
|
||||
Source: Hacker's delight, p.66 */
|
||||
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 */
|
||||
int PQCLEAN_LEDAKEMLT32_CLEAN_population_count(DIGIT *poly) {
|
||||
int ret = 0;
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
ret += popcount_uint64t(poly[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) {
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_add(Res, A, B, NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
static int partition(POSITION_T arr[], int lo, int hi) {
|
||||
POSITION_T x = arr[hi];
|
||||
POSITION_T tmp;
|
||||
int i = (lo - 1);
|
||||
for (int j = lo; j <= hi - 1; j++) {
|
||||
if (arr[j] <= x) {
|
||||
i++;
|
||||
tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
}
|
||||
tmp = arr[i + 1];
|
||||
arr[i + 1] = arr[hi];
|
||||
arr[hi] = tmp;
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_quicksort_sparse(POSITION_T Res[]) {
|
||||
int stack[DV * M];
|
||||
int hi, lo, pivot, tos = -1;
|
||||
stack[++tos] = 0;
|
||||
stack[++tos] = (DV * M) - 1;
|
||||
while (tos >= 0 ) {
|
||||
hi = stack[tos--];
|
||||
lo = stack[tos--];
|
||||
pivot = partition(Res, lo, hi);
|
||||
if ( (pivot - 1) > lo) {
|
||||
stack[++tos] = lo;
|
||||
stack[++tos] = pivot - 1;
|
||||
}
|
||||
if ( (pivot + 1) < hi) {
|
||||
stack[++tos] = pivot + 1;
|
||||
stack[++tos] = hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gf2x_mod(DIGIT out[], const DIGIT in[]) {
|
||||
|
||||
@ -65,7 +162,7 @@ static void right_bit_shift(unsigned int length, DIGIT in[]) {
|
||||
|
||||
|
||||
/* shifts by whole digits */
|
||||
static inline void left_DIGIT_shift_n(unsigned int length, DIGIT in[], unsigned int amount) {
|
||||
static 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];
|
||||
@ -75,7 +172,6 @@ static inline void left_DIGIT_shift_n(unsigned int length, DIGIT in[], unsigned
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* may shift by an arbitrary 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);
|
||||
@ -115,7 +211,7 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_transpose_in_place(DIGIT A[]) {
|
||||
A[NUM_DIGITS_GF2X_ELEMENT - 1 - i] = rev1;
|
||||
}
|
||||
|
||||
// A[NUM_DIGITS_GF2X_ELEMENT / 2] = reverse_digit(A[NUM_DIGITS_GF2X_ELEMENT / 2]); // reverse middle digit
|
||||
// A[NUM_DIGITS_GF2X_ELEMENT / 2] = reverse_digit(A[NUM_DIGITS_GF2X_ELEMENT / 2]); // no middle digit
|
||||
|
||||
if (slack_bits_amount) {
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_right_bit_shift_n(NUM_DIGITS_GF2X_ELEMENT, A, slack_bits_amount);
|
||||
@ -143,9 +239,7 @@ static void rotate_bit_right(DIGIT in[]) { /* x^{-1} * in(x) mod x^P+1 */
|
||||
in[0] |= rotated_bit;
|
||||
}
|
||||
|
||||
static void gf2x_swap(const int length,
|
||||
DIGIT f[],
|
||||
DIGIT s[]) {
|
||||
static void gf2x_swap(const int length, DIGIT f[], DIGIT s[]) {
|
||||
DIGIT t;
|
||||
for (int i = length - 1; i >= 0; i--) {
|
||||
t = f[i];
|
||||
@ -174,7 +268,7 @@ static void gf2x_swap(const int length,
|
||||
int PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]) { /* in^{-1} mod x^P-1 */
|
||||
|
||||
int i;
|
||||
long int delta = 0;
|
||||
int delta = 0;
|
||||
DIGIT u[NUM_DIGITS_GF2X_ELEMENT] = {0};
|
||||
DIGIT v[NUM_DIGITS_GF2X_ELEMENT] = {0};
|
||||
DIGIT s[NUM_DIGITS_GF2X_MODULUS] = {0};
|
||||
@ -205,8 +299,8 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]) {
|
||||
delta += 1;
|
||||
} else {
|
||||
if ( (s[0] & mask) != 0) {
|
||||
gf2x_add(s, s, f, NUM_DIGITS_GF2X_MODULUS);
|
||||
gf2x_mod_add(v, v, u);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_add(s, s, f, NUM_DIGITS_GF2X_MODULUS);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_add(v, v, u);
|
||||
}
|
||||
left_bit_shift(NUM_DIGITS_GF2X_MODULUS, s);
|
||||
if ( delta == 0 ) {
|
||||
@ -258,7 +352,7 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_mul_dense_to_sparse(
|
||||
for (unsigned int i = 1; i < nPos; i++) {
|
||||
if (sparse[i] != INVALID_POS_VALUE) {
|
||||
left_bit_shift_wide_n(2 * NUM_DIGITS_GF2X_ELEMENT, aux, (sparse[i] - sparse[i - 1]) );
|
||||
gf2x_add(resDouble, aux, resDouble, 2 * NUM_DIGITS_GF2X_ELEMENT);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_add(resDouble, aux, resDouble, 2 * NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,7 +406,7 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[
|
||||
Res[lastFilledPos] = INVALID_POS_VALUE;
|
||||
lastFilledPos++;
|
||||
}
|
||||
quicksort_sparse(Res);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_quicksort_sparse(Res);
|
||||
/* eliminate duplicates */
|
||||
POSITION_T lastReadPos = Res[0];
|
||||
int duplicateCount;
|
||||
@ -464,8 +558,8 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_rand_circulant_blocks_sequence(
|
||||
for (int j = 0; j < counter; j++) {
|
||||
polyIndex = rndPos[j] / P;
|
||||
exponent = rndPos[j] % P;
|
||||
gf2x_set_coeff( sequence + NUM_DIGITS_GF2X_ELEMENT * polyIndex, exponent,
|
||||
( (DIGIT) 1));
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_set_coeff( sequence + NUM_DIGITS_GF2X_ELEMENT * polyIndex, exponent,
|
||||
( (DIGIT) 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,105 +15,13 @@
|
||||
#define INVALID_POS_VALUE (P)
|
||||
#define P_BITS (17) // log_2(p) = 16.55406417
|
||||
|
||||
|
||||
static inline void gf2x_copy(DIGIT dest[], const DIGIT in[]) {
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
dest[i] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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;
|
||||
return (poly[digitIdx] >> (DIGIT_SIZE_b - 1 - inDigitIdx)) & ((DIGIT) 1) ;
|
||||
}
|
||||
|
||||
/* sets the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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 */
|
||||
DIGIT mask = ~( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] & mask;
|
||||
poly[digitIdx] = poly[digitIdx] | (( value & ((DIGIT) 1)) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
}
|
||||
|
||||
/* toggles (flips) the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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 */
|
||||
DIGIT mask = ( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] ^ mask;
|
||||
}
|
||||
|
||||
/* population count for an unsigned 64-bit integer
|
||||
Source: Hacker's delight, p.66 */
|
||||
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 *poly) {
|
||||
int ret = 0;
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
ret += popcount_uint64t(poly[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) {
|
||||
gf2x_add(Res, A, B, NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
static inline int partition(POSITION_T arr[], int lo, int hi) {
|
||||
POSITION_T x = arr[hi];
|
||||
POSITION_T tmp;
|
||||
int i = (lo - 1);
|
||||
for (int j = lo; j <= hi - 1; j++) {
|
||||
if (arr[j] <= x) {
|
||||
i++;
|
||||
tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
}
|
||||
tmp = arr[i + 1];
|
||||
arr[i + 1] = arr[hi];
|
||||
arr[hi] = tmp;
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
static inline void quicksort_sparse(POSITION_T Res[]) {
|
||||
int stack[DV * M];
|
||||
int hi, lo, pivot, tos = -1;
|
||||
stack[++tos] = 0;
|
||||
stack[++tos] = (DV * M) - 1;
|
||||
while (tos >= 0 ) {
|
||||
hi = stack[tos--];
|
||||
lo = stack[tos--];
|
||||
pivot = partition(Res, lo, hi);
|
||||
if ( (pivot - 1) > lo) {
|
||||
stack[++tos] = lo;
|
||||
stack[++tos] = pivot - 1;
|
||||
}
|
||||
if ( (pivot + 1) < hi) {
|
||||
stack[++tos] = pivot + 1;
|
||||
stack[++tos] = hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_copy(DIGIT dest[], const DIGIT in[]);
|
||||
DIGIT PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_get_coeff(const DIGIT poly[], unsigned int exponent);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_set_coeff(DIGIT poly[], unsigned int exponent, DIGIT value);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_toggle_coeff(DIGIT poly[], unsigned int exponent);
|
||||
int PQCLEAN_LEDAKEMLT32_CLEAN_population_count(DIGIT *poly);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_quicksort_sparse(POSITION_T Res[]);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_mul(DIGIT Res[], const DIGIT A[], const DIGIT B[]);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_transpose_in_place(DIGIT A[]);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, int countOnes, AES_XOF_struct *seed_expander_ctx);
|
||||
@ -123,7 +31,6 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_transpose_in_place_sparse(int sizeA, POSITIO
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[], size_t sizeA, const POSITION_T A[], size_t sizeB, const POSITION_T B[]);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_mul_dense_to_sparse(DIGIT Res[], const DIGIT dense[], POSITION_T sparse[], unsigned int nPos);
|
||||
void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_tobytes(uint8_t *bytes, const DIGIT *poly);
|
||||
|
||||
int PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]);
|
||||
|
||||
#endif
|
||||
|
@ -58,7 +58,7 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk,
|
||||
memset(Ln0dense, 0x00, sizeof(Ln0dense));
|
||||
for (int j = 0; j < DV * M; j++) {
|
||||
if (LPosOnes[N0 - 1][j] != INVALID_POS_VALUE) {
|
||||
gf2x_set_coeff(Ln0dense, LPosOnes[N0 - 1][j], 1);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_set_coeff(Ln0dense, LPosOnes[N0 - 1][j], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,9 +86,9 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_encrypt(DIGIT *syndrome, const publi
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_mul(saux,
|
||||
pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT,
|
||||
err + i * NUM_DIGITS_GF2X_ELEMENT);
|
||||
gf2x_mod_add(syndrome, syndrome, saux);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_add(syndrome, syndrome, saux);
|
||||
}
|
||||
gf2x_mod_add(syndrome, syndrome, err + (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT);
|
||||
PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_add(syndrome, syndrome, err + (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
|
||||
@ -180,7 +180,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_decrypt(DIGIT *err, const privateKeyN
|
||||
|
||||
err_weight = 0;
|
||||
for (int i = 0 ; i < N0; i++) {
|
||||
err_weight += population_count(err + (NUM_DIGITS_GF2X_ELEMENT * i));
|
||||
err_weight += PQCLEAN_LEDAKEMLT32_CLEAN_population_count(err + (NUM_DIGITS_GF2X_ELEMENT * i));
|
||||
}
|
||||
decryptOk = decryptOk && (err_weight == NUM_ERRORS_T);
|
||||
|
||||
|
@ -18,13 +18,13 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(DIGIT err[],
|
||||
int iteration = 0;
|
||||
|
||||
do {
|
||||
gf2x_copy(currSyndrome, privateSyndrome);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_copy(currSyndrome, privateSyndrome);
|
||||
memset(unsatParityChecks, 0x00, N0 * P * sizeof(uint8_t));
|
||||
for (int i = 0; i < N0; i++) {
|
||||
for (int valueIdx = 0; valueIdx < P; valueIdx++) {
|
||||
for (int HtrOneIdx = 0; HtrOneIdx < DV; HtrOneIdx++) {
|
||||
POSITION_T tmp = (HtrPosOnes[i][HtrOneIdx] + valueIdx) >= P ? (HtrPosOnes[i][HtrOneIdx] + valueIdx) - P : (HtrPosOnes[i][HtrOneIdx] + valueIdx);
|
||||
if (gf2x_get_coeff(currSyndrome, tmp)) {
|
||||
if (PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_get_coeff(currSyndrome, tmp)) {
|
||||
unsatParityChecks[i * P + valueIdx]++;
|
||||
}
|
||||
}
|
||||
@ -54,13 +54,13 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(DIGIT err[],
|
||||
}
|
||||
/* Correlation based flipping */
|
||||
if (correlation >= corrt_syndrome_based) {
|
||||
gf2x_toggle_coeff(err + NUM_DIGITS_GF2X_ELEMENT * i, j);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_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++) {
|
||||
syndromePosToFlip = (HtrPosOnes[currQBlkPos[v]][HtrOneIdx] + currQBitPos[v] );
|
||||
syndromePosToFlip = syndromePosToFlip >= P ? syndromePosToFlip - P : syndromePosToFlip;
|
||||
gf2x_toggle_coeff(privateSyndrome, syndromePosToFlip);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_toggle_coeff(privateSyndrome, syndromePosToFlip);
|
||||
}
|
||||
} // end for v
|
||||
} // end if
|
||||
|
@ -38,7 +38,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) {
|
||||
LSparse_loc[i][j] = (P - LSparse[i][j]);
|
||||
}
|
||||
}
|
||||
quicksort_sparse(LSparse_loc[i]);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_quicksort_sparse(LSparse_loc[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < N0; i++ ) {
|
||||
@ -48,7 +48,7 @@ int PQCLEAN_LEDAKEMLT52_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_sparse(rotated_column);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_quicksort_sparse(rotated_column);
|
||||
/* compute the intersection amount */
|
||||
firstidx = 0, secondidx = 0;
|
||||
intersectionval = 0;
|
||||
|
@ -3,6 +3,12 @@
|
||||
#include <assert.h>
|
||||
#include <string.h> // memset(...)
|
||||
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr) {
|
||||
for (int i = 0; i < nr; i++) {
|
||||
Res[i] = A[i] ^ B[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* PRE: MAX ALLOWED ROTATION AMOUNT : DIGIT_SIZE_b */
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_right_bit_shift_n(int length, DIGIT in[], unsigned int amount) {
|
||||
assert(amount < DIGIT_SIZE_b);
|
||||
|
@ -50,12 +50,7 @@ typedef uint64_t DIGIT;
|
||||
|
||||
#define GF2X_MUL PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mul_comb
|
||||
|
||||
static inline void gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr) {
|
||||
for (int i = 0; i < nr; i++) {
|
||||
Res[i] = A[i] ^ B[i];
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_add(DIGIT Res[], const DIGIT A[], const DIGIT B[], int nr);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_right_bit_shift_n(int length, DIGIT in[], unsigned int amount);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_left_bit_shift_n(int length, DIGIT in[], unsigned int amount);
|
||||
void GF2X_MUL(int nr, DIGIT Res[], int na, const DIGIT A[], int nb, const DIGIT B[]);
|
||||
|
@ -5,6 +5,104 @@
|
||||
#include <string.h> // memcpy(...), memset(...)
|
||||
|
||||
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_copy(DIGIT dest[], const DIGIT in[]) {
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
dest[i] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the coefficient of the x^exponent term as the LSB of a digit */
|
||||
DIGIT PQCLEAN_LEDAKEMLT52_CLEAN_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;
|
||||
return (poly[digitIdx] >> (DIGIT_SIZE_b - 1 - inDigitIdx)) & ((DIGIT) 1) ;
|
||||
}
|
||||
|
||||
/* sets the coefficient of the x^exponent term as the LSB of a digit */
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_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 */
|
||||
DIGIT mask = ~( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] & mask;
|
||||
poly[digitIdx] = poly[digitIdx] | (( value & ((DIGIT) 1)) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
}
|
||||
|
||||
/* toggles (flips) the coefficient of the x^exponent term as the LSB of a digit */
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_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 */
|
||||
DIGIT mask = ( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] ^ mask;
|
||||
}
|
||||
|
||||
/* population count for an unsigned 64-bit integer
|
||||
Source: Hacker's delight, p.66 */
|
||||
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 */
|
||||
int PQCLEAN_LEDAKEMLT52_CLEAN_population_count(DIGIT *poly) {
|
||||
int ret = 0;
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
ret += popcount_uint64t(poly[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) {
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_add(Res, A, B, NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
static int partition(POSITION_T arr[], int lo, int hi) {
|
||||
POSITION_T x = arr[hi];
|
||||
POSITION_T tmp;
|
||||
int i = (lo - 1);
|
||||
for (int j = lo; j <= hi - 1; j++) {
|
||||
if (arr[j] <= x) {
|
||||
i++;
|
||||
tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
}
|
||||
tmp = arr[i + 1];
|
||||
arr[i + 1] = arr[hi];
|
||||
arr[hi] = tmp;
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_quicksort_sparse(POSITION_T Res[]) {
|
||||
int stack[DV * M];
|
||||
int hi, lo, pivot, tos = -1;
|
||||
stack[++tos] = 0;
|
||||
stack[++tos] = (DV * M) - 1;
|
||||
while (tos >= 0 ) {
|
||||
hi = stack[tos--];
|
||||
lo = stack[tos--];
|
||||
pivot = partition(Res, lo, hi);
|
||||
if ( (pivot - 1) > lo) {
|
||||
stack[++tos] = lo;
|
||||
stack[++tos] = pivot - 1;
|
||||
}
|
||||
if ( (pivot + 1) < hi) {
|
||||
stack[++tos] = pivot + 1;
|
||||
stack[++tos] = hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void gf2x_mod(DIGIT out[], const DIGIT in[]) {
|
||||
|
||||
int i, j, posTrailingBit, maskOffset;
|
||||
@ -65,7 +163,7 @@ static void right_bit_shift(unsigned int length, DIGIT in[]) {
|
||||
|
||||
|
||||
/* shifts by whole digits */
|
||||
static inline void left_DIGIT_shift_n(unsigned int length, DIGIT in[], unsigned int amount) {
|
||||
static 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];
|
||||
@ -75,7 +173,6 @@ static inline void left_DIGIT_shift_n(unsigned int length, DIGIT in[], unsigned
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* may shift by an arbitrary 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);
|
||||
@ -143,9 +240,7 @@ static void rotate_bit_right(DIGIT in[]) { /* x^{-1} * in(x) mod x^P+1 */
|
||||
in[0] |= rotated_bit;
|
||||
}
|
||||
|
||||
static void gf2x_swap(const int length,
|
||||
DIGIT f[],
|
||||
DIGIT s[]) {
|
||||
static void gf2x_swap(const int length, DIGIT f[], DIGIT s[]) {
|
||||
DIGIT t;
|
||||
for (int i = length - 1; i >= 0; i--) {
|
||||
t = f[i];
|
||||
@ -174,7 +269,7 @@ static void gf2x_swap(const int length,
|
||||
int PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]) { /* in^{-1} mod x^P-1 */
|
||||
|
||||
int i;
|
||||
long int delta = 0;
|
||||
int delta = 0;
|
||||
DIGIT u[NUM_DIGITS_GF2X_ELEMENT] = {0};
|
||||
DIGIT v[NUM_DIGITS_GF2X_ELEMENT] = {0};
|
||||
DIGIT s[NUM_DIGITS_GF2X_MODULUS] = {0};
|
||||
@ -205,8 +300,8 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]) {
|
||||
delta += 1;
|
||||
} else {
|
||||
if ( (s[0] & mask) != 0) {
|
||||
gf2x_add(s, s, f, NUM_DIGITS_GF2X_MODULUS);
|
||||
gf2x_mod_add(v, v, u);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_add(s, s, f, NUM_DIGITS_GF2X_MODULUS);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_add(v, v, u);
|
||||
}
|
||||
left_bit_shift(NUM_DIGITS_GF2X_MODULUS, s);
|
||||
if ( delta == 0 ) {
|
||||
@ -258,7 +353,7 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_mul_dense_to_sparse(
|
||||
for (unsigned int i = 1; i < nPos; i++) {
|
||||
if (sparse[i] != INVALID_POS_VALUE) {
|
||||
left_bit_shift_wide_n(2 * NUM_DIGITS_GF2X_ELEMENT, aux, (sparse[i] - sparse[i - 1]) );
|
||||
gf2x_add(resDouble, aux, resDouble, 2 * NUM_DIGITS_GF2X_ELEMENT);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_add(resDouble, aux, resDouble, 2 * NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -312,7 +407,7 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[
|
||||
Res[lastFilledPos] = INVALID_POS_VALUE;
|
||||
lastFilledPos++;
|
||||
}
|
||||
quicksort_sparse(Res);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_quicksort_sparse(Res);
|
||||
/* eliminate duplicates */
|
||||
POSITION_T lastReadPos = Res[0];
|
||||
int duplicateCount;
|
||||
@ -464,8 +559,8 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_rand_circulant_blocks_sequence(
|
||||
for (int j = 0; j < counter; j++) {
|
||||
polyIndex = rndPos[j] / P;
|
||||
exponent = rndPos[j] % P;
|
||||
gf2x_set_coeff( sequence + NUM_DIGITS_GF2X_ELEMENT * polyIndex, exponent,
|
||||
( (DIGIT) 1));
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_set_coeff( sequence + NUM_DIGITS_GF2X_ELEMENT * polyIndex, exponent,
|
||||
( (DIGIT) 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,105 +15,13 @@
|
||||
#define INVALID_POS_VALUE (P)
|
||||
#define P_BITS (18) // log_2(p) = 17.216243783
|
||||
|
||||
|
||||
static inline void gf2x_copy(DIGIT dest[], const DIGIT in[]) {
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
dest[i] = in[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* returns the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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;
|
||||
return (poly[digitIdx] >> (DIGIT_SIZE_b - 1 - inDigitIdx)) & ((DIGIT) 1) ;
|
||||
}
|
||||
|
||||
/* sets the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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 */
|
||||
DIGIT mask = ~( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] & mask;
|
||||
poly[digitIdx] = poly[digitIdx] | (( value & ((DIGIT) 1)) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
}
|
||||
|
||||
/* toggles (flips) the coefficient of the x^exponent term as the LSB of a digit */
|
||||
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 */
|
||||
DIGIT mask = ( ((DIGIT) 1) << (DIGIT_SIZE_b - 1 - inDigitIdx));
|
||||
poly[digitIdx] = poly[digitIdx] ^ mask;
|
||||
}
|
||||
|
||||
/* population count for an unsigned 64-bit integer
|
||||
Source: Hacker's delight, p.66 */
|
||||
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 *poly) {
|
||||
int ret = 0;
|
||||
for (int i = NUM_DIGITS_GF2X_ELEMENT - 1; i >= 0; i--) {
|
||||
ret += popcount_uint64t(poly[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]) {
|
||||
gf2x_add(Res, A, B, NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
static inline int partition(POSITION_T arr[], int lo, int hi) {
|
||||
POSITION_T x = arr[hi];
|
||||
POSITION_T tmp;
|
||||
int i = (lo - 1);
|
||||
for (int j = lo; j <= hi - 1; j++) {
|
||||
if (arr[j] <= x) {
|
||||
i++;
|
||||
tmp = arr[i];
|
||||
arr[i] = arr[j];
|
||||
arr[j] = tmp;
|
||||
}
|
||||
}
|
||||
tmp = arr[i + 1];
|
||||
arr[i + 1] = arr[hi];
|
||||
arr[hi] = tmp;
|
||||
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
static inline void quicksort_sparse(POSITION_T Res[]) {
|
||||
int stack[DV * M];
|
||||
int hi, lo, pivot, tos = -1;
|
||||
stack[++tos] = 0;
|
||||
stack[++tos] = (DV * M) - 1;
|
||||
while (tos >= 0 ) {
|
||||
hi = stack[tos--];
|
||||
lo = stack[tos--];
|
||||
pivot = partition(Res, lo, hi);
|
||||
if ( (pivot - 1) > lo) {
|
||||
stack[++tos] = lo;
|
||||
stack[++tos] = pivot - 1;
|
||||
}
|
||||
if ( (pivot + 1) < hi) {
|
||||
stack[++tos] = pivot + 1;
|
||||
stack[++tos] = hi;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_copy(DIGIT dest[], const DIGIT in[]);
|
||||
DIGIT PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_get_coeff(const DIGIT poly[], unsigned int exponent);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_set_coeff(DIGIT poly[], unsigned int exponent, DIGIT value);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_toggle_coeff(DIGIT poly[], unsigned int exponent);
|
||||
int PQCLEAN_LEDAKEMLT52_CLEAN_population_count(DIGIT *poly);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_add(DIGIT Res[], const DIGIT A[], const DIGIT B[]);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_quicksort_sparse(POSITION_T Res[]);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_mul(DIGIT Res[], const DIGIT A[], const DIGIT B[]);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_transpose_in_place(DIGIT A[]);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, int countOnes, AES_XOF_struct *seed_expander_ctx);
|
||||
@ -123,7 +31,6 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_transpose_in_place_sparse(int sizeA, POSITIO
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_mul_sparse(size_t sizeR, POSITION_T Res[], size_t sizeA, const POSITION_T A[], size_t sizeB, const POSITION_T B[]);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_mul_dense_to_sparse(DIGIT Res[], const DIGIT dense[], POSITION_T sparse[], unsigned int nPos);
|
||||
void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_tobytes(uint8_t *bytes, const DIGIT *poly);
|
||||
|
||||
int PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]);
|
||||
|
||||
#endif
|
||||
|
@ -58,7 +58,7 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk,
|
||||
memset(Ln0dense, 0x00, sizeof(Ln0dense));
|
||||
for (int j = 0; j < DV * M; j++) {
|
||||
if (LPosOnes[N0 - 1][j] != INVALID_POS_VALUE) {
|
||||
gf2x_set_coeff(Ln0dense, LPosOnes[N0 - 1][j], 1);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_set_coeff(Ln0dense, LPosOnes[N0 - 1][j], 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,9 +86,9 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_encrypt(DIGIT *syndrome, const publi
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_mul(saux,
|
||||
pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT,
|
||||
err + i * NUM_DIGITS_GF2X_ELEMENT);
|
||||
gf2x_mod_add(syndrome, syndrome, saux);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_add(syndrome, syndrome, saux);
|
||||
}
|
||||
gf2x_mod_add(syndrome, syndrome, err + (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT);
|
||||
PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_add(syndrome, syndrome, err + (N0 - 1)*NUM_DIGITS_GF2X_ELEMENT);
|
||||
}
|
||||
|
||||
|
||||
@ -180,7 +180,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_decrypt(DIGIT *err, const privateKeyN
|
||||
|
||||
err_weight = 0;
|
||||
for (int i = 0 ; i < N0; i++) {
|
||||
err_weight += population_count(err + (NUM_DIGITS_GF2X_ELEMENT * i));
|
||||
err_weight += PQCLEAN_LEDAKEMLT52_CLEAN_population_count(err + (NUM_DIGITS_GF2X_ELEMENT * i));
|
||||
}
|
||||
decryptOk = decryptOk && (err_weight == NUM_ERRORS_T);
|
||||
|
||||
|
Carregando…
Criar uma nova questão referindo esta
Bloquear um utilizador