From bf0aca644ec61256322106a75d8791d3e1dfa85d Mon Sep 17 00:00:00 2001 From: Leon Date: Fri, 14 Jun 2019 14:23:58 +0200 Subject: [PATCH] avoid global state by including 2nd round threshold in secret key --- crypto_kem/ledakemlt12/META.yml | 6 ++--- crypto_kem/ledakemlt12/clean/api.h | 2 +- crypto_kem/ledakemlt12/clean/bf_decoding.c | 12 +++++----- crypto_kem/ledakemlt12/clean/bf_decoding.h | 3 ++- crypto_kem/ledakemlt12/clean/dfr_test.c | 26 +++++++-------------- crypto_kem/ledakemlt12/clean/dfr_test.h | 4 +++- crypto_kem/ledakemlt12/clean/kem.c | 2 +- crypto_kem/ledakemlt12/clean/niederreiter.c | 10 ++++---- crypto_kem/ledakemlt12/clean/niederreiter.h | 1 + crypto_kem/ledakemlt32/META.yml | 6 ++--- crypto_kem/ledakemlt32/clean/api.h | 2 +- crypto_kem/ledakemlt32/clean/bf_decoding.c | 12 +++++----- crypto_kem/ledakemlt32/clean/bf_decoding.h | 3 ++- crypto_kem/ledakemlt32/clean/dfr_test.c | 26 +++++++-------------- crypto_kem/ledakemlt32/clean/dfr_test.h | 4 +++- crypto_kem/ledakemlt32/clean/kem.c | 2 +- crypto_kem/ledakemlt32/clean/niederreiter.c | 10 ++++---- crypto_kem/ledakemlt32/clean/niederreiter.h | 1 + crypto_kem/ledakemlt52/META.yml | 6 ++--- crypto_kem/ledakemlt52/clean/api.h | 2 +- crypto_kem/ledakemlt52/clean/bf_decoding.c | 12 +++++----- crypto_kem/ledakemlt52/clean/bf_decoding.h | 3 ++- crypto_kem/ledakemlt52/clean/dfr_test.c | 26 +++++++-------------- crypto_kem/ledakemlt52/clean/dfr_test.h | 4 +++- crypto_kem/ledakemlt52/clean/kem.c | 2 +- crypto_kem/ledakemlt52/clean/niederreiter.c | 10 ++++---- crypto_kem/ledakemlt52/clean/niederreiter.h | 1 + 27 files changed, 93 insertions(+), 105 deletions(-) diff --git a/crypto_kem/ledakemlt12/META.yml b/crypto_kem/ledakemlt12/META.yml index a213611a..9eda0152 100644 --- a/crypto_kem/ledakemlt12/META.yml +++ b/crypto_kem/ledakemlt12/META.yml @@ -3,10 +3,10 @@ type: kem claimed-nist-level: 1 claimed-security: IND-CCA2 length-public-key: 6520 -length-secret-key: 25 +length-secret-key: 26 length-ciphertext: 6520 length-shared-secret: 32 -nistkat-sha256: 3bb5945e0aea26f121e1d56946760e506bdfbebb07e2fb018ce737b90b1eee2b +nistkat-sha256: c49a3f0ff5f3e7d6b41995649d7003daf7c06d9539fc28cb3b93ed02dcbe09d4 principal-submitter: Marco Baldi auxiliary-submitters: - Alessandro Barenghi @@ -15,4 +15,4 @@ auxiliary-submitters: - Paolo Santini implementations: - name: clean - version: 2.0 + version: 2.? diff --git a/crypto_kem/ledakemlt12/clean/api.h b/crypto_kem/ledakemlt12/clean/api.h index 170022d3..d37a6323 100644 --- a/crypto_kem/ledakemlt12/clean/api.h +++ b/crypto_kem/ledakemlt12/clean/api.h @@ -3,7 +3,7 @@ #include -#define PQCLEAN_LEDAKEMLT12_CLEAN_CRYPTO_SECRETKEYBYTES 25 +#define PQCLEAN_LEDAKEMLT12_CLEAN_CRYPTO_SECRETKEYBYTES 26 #define PQCLEAN_LEDAKEMLT12_CLEAN_CRYPTO_PUBLICKEYBYTES 6520 #define PQCLEAN_LEDAKEMLT12_CLEAN_CRYPTO_CIPHERTEXTBYTES 6520 #define PQCLEAN_LEDAKEMLT12_CLEAN_CRYPTO_BYTES 32 diff --git a/crypto_kem/ledakemlt12/clean/bf_decoding.c b/crypto_kem/ledakemlt12/clean/bf_decoding.c index 070771dd..d4dca821 100644 --- a/crypto_kem/ledakemlt12/clean/bf_decoding.c +++ b/crypto_kem/ledakemlt12/clean/bf_decoding.c @@ -4,18 +4,18 @@ #include #include -unsigned int PQCLEAN_LEDAKEMLT12_CLEAN_thresholds[2] = {B0, (DV * M) / 2 + 1}; - int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[], const POSITION_T HtrPosOnes[N0][DV], const POSITION_T QtrPosOnes[N0][M], - DIGIT privateSyndrome[]) { + DIGIT privateSyndrome[], + uint8_t threshold) { uint8_t unsatParityChecks[N0 * P]; POSITION_T currQBlkPos[M], currQBitPos[M]; DIGIT currSyndrome[NUM_DIGITS_GF2X_ELEMENT]; int check; int iteration = 0; + unsigned int corrt_syndrome_based; do { PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_copy(currSyndrome, privateSyndrome); @@ -32,7 +32,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[], } /* iteration based threshold determination*/ - unsigned int corrt_syndrome_based = PQCLEAN_LEDAKEMLT12_CLEAN_thresholds[iteration]; + corrt_syndrome_based = iteration ? (unsigned int) threshold : B0; //Computation of correlation with a full Q matrix for (int i = 0; i < N0; i++) { @@ -45,7 +45,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[], endQblockIdx += qBlockWeights[blockIdx][i]; int currblockoffset = blockIdx * P; for (; currQoneIdx < endQblockIdx; currQoneIdx++) { - uint32_t tmp = QtrPosOnes[i][currQoneIdx] + j; + POSITION_T tmp = QtrPosOnes[i][currQoneIdx] + j; tmp = tmp >= P ? tmp - P : tmp; currQBitPos[currQoneIdx] = tmp; currQBlkPos[currQoneIdx] = blockIdx; @@ -56,7 +56,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[], if (correlation >= corrt_syndrome_based) { PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_toggle_coeff(err + NUM_DIGITS_GF2X_ELEMENT * i, j); for (int v = 0; v < M; v++) { - unsigned syndromePosToFlip; + POSITION_T syndromePosToFlip; for (int HtrOneIdx = 0; HtrOneIdx < DV; HtrOneIdx++) { syndromePosToFlip = (HtrPosOnes[currQBlkPos[v]][HtrOneIdx] + currQBitPos[v] ); syndromePosToFlip = syndromePosToFlip >= P ? syndromePosToFlip - P : syndromePosToFlip; diff --git a/crypto_kem/ledakemlt12/clean/bf_decoding.h b/crypto_kem/ledakemlt12/clean/bf_decoding.h index 18a7dd8b..3da62547 100644 --- a/crypto_kem/ledakemlt12/clean/bf_decoding.h +++ b/crypto_kem/ledakemlt12/clean/bf_decoding.h @@ -12,6 +12,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(DIGIT err[], const POSITION_T HtrPosOnes[N0][DV], const POSITION_T QtrPosOnes[N0][M], - DIGIT privateSyndrome[]); + DIGIT privateSyndrome[], + uint8_t threshold); // B2 #endif diff --git a/crypto_kem/ledakemlt12/clean/dfr_test.c b/crypto_kem/ledakemlt12/clean/dfr_test.c index 522a98f3..b36861fa 100644 --- a/crypto_kem/ledakemlt12/clean/dfr_test.c +++ b/crypto_kem/ledakemlt12/clean/dfr_test.c @@ -6,29 +6,22 @@ #include /* Tests if the current code attains the desired DFR. If that is the case, - * computes the threshold for the second iteration of the decoder and stores - * it in the globally accessible vector */ + * computes the threshold for the second iteration of the decoder and returns this values + * (max DV * M), on failure it returns 255 >> DV * M */ -extern unsigned int PQCLEAN_LEDAKEMLT12_CLEAN_thresholds[2]; - -int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { +uint8_t PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { POSITION_T LSparse_loc[N0][DV * M]; - + POSITION_T rotated_column[DV * M]; /* Gamma matrix: an N0 x N0 block circulant matrix with block size p * 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 */ + * 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 */ 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}}; - unsigned int maxMut[N0], maxMutMinusOne[N0]; + unsigned int firstidx, secondidx, intersectionval; unsigned int allBlockMaxSumst, allBlockMaxSumstMinusOne; - unsigned int toAdd, histIdx; /*transpose blocks of L, we need its columns */ @@ -113,8 +106,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { allBlockMaxSumstMinusOne; } if (DV * M > (allBlockMaxSumstMinusOne + allBlockMaxSumst)) { - PQCLEAN_LEDAKEMLT12_CLEAN_thresholds[1] = allBlockMaxSumst + 1; - return 1; + return allBlockMaxSumst + 1; } - return 0; + return DFR_TEST_FAIL; } diff --git a/crypto_kem/ledakemlt12/clean/dfr_test.h b/crypto_kem/ledakemlt12/clean/dfr_test.h index da98b2f2..cbbcbd8a 100644 --- a/crypto_kem/ledakemlt12/clean/dfr_test.h +++ b/crypto_kem/ledakemlt12/clean/dfr_test.h @@ -1,6 +1,8 @@ #ifndef DFR_TEST_H #define DFR_TEST_H -int PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]); +#define DFR_TEST_FAIL (255) + +uint8_t PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]); #endif diff --git a/crypto_kem/ledakemlt12/clean/kem.c b/crypto_kem/ledakemlt12/clean/kem.c index f8c72798..89f47145 100644 --- a/crypto_kem/ledakemlt12/clean/kem.c +++ b/crypto_kem/ledakemlt12/clean/kem.c @@ -13,7 +13,7 @@ static void pack_pk(uint8_t *pk_bytes, publicKeyNiederreiter_t *pk) { } } -static void unpack_pk(publicKeyNiederreiter_t *pk, const uint8_t *pk_bytes) { +static void unpack_pk(publicKeyNiederreiter_t *pk, const uint8_t *pk_bytes) { size_t i; for (i = 0; i < N0 - 1; i++) { PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_frombytes(pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT, diff --git a/crypto_kem/ledakemlt12/clean/niederreiter.c b/crypto_kem/ledakemlt12/clean/niederreiter.c index 1cb3ea51..e78ef814 100644 --- a/crypto_kem/ledakemlt12/clean/niederreiter.c +++ b/crypto_kem/ledakemlt12/clean/niederreiter.c @@ -10,7 +10,6 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, privateKeyNiederreiter_t *sk, AES_XOF_struct *keys_expander) { - POSITION_T HPosOnes[N0][DV]; // sequence of N0 circ block matrices (p x p): Hi POSITION_T HtrPosOnes[N0][DV]; // Sparse tranposed circulant H POSITION_T QPosOnes[N0][M]; // Sparse Q, Each row contains the position of the ones of all the blocks of a row of Q as exponent+P*block_position @@ -20,7 +19,7 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, DIGIT Ln0dense[NUM_DIGITS_GF2X_ELEMENT]; DIGIT Ln0Inv[NUM_DIGITS_GF2X_ELEMENT]; int is_L_full = 0; - int isDFRok = 0; + uint8_t threshold; // threshold for round 2 sk->rejections = (int8_t) 0; do { @@ -50,10 +49,11 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, } sk->rejections = sk->rejections + 1; if (is_L_full) { - isDFRok = PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(LPosOnes); + threshold = PQCLEAN_LEDAKEMLT12_CLEAN_DFR_test(LPosOnes); } - } while (!is_L_full || !isDFRok); + } while (!is_L_full || threshold == DFR_TEST_FAIL); sk->rejections = sk->rejections - 1; + sk->threshold = threshold; memset(Ln0dense, 0x00, sizeof(Ln0dense)); for (int j = 0; j < DV * M; j++) { @@ -176,7 +176,7 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(DIGIT *err, const privateKeyN memset(err, 0x00, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); decryptOk = PQCLEAN_LEDAKEMLT12_CLEAN_bf_decoding(err, (const POSITION_T (*)[DV]) HtrPosOnes, - (const POSITION_T (*)[M]) QtrPosOnes, privateSyndrome); + (const POSITION_T (*)[M]) QtrPosOnes, privateSyndrome, sk->threshold); err_weight = 0; for (int i = 0 ; i < N0; i++) { diff --git a/crypto_kem/ledakemlt12/clean/niederreiter.h b/crypto_kem/ledakemlt12/clean/niederreiter.h index 0692581b..428726cf 100644 --- a/crypto_kem/ledakemlt12/clean/niederreiter.h +++ b/crypto_kem/ledakemlt12/clean/niederreiter.h @@ -10,6 +10,7 @@ typedef struct { * H and Q during decryption */ unsigned char prng_seed[TRNG_BYTE_LENGTH]; int8_t rejections; + uint8_t threshold; // for round 2 } privateKeyNiederreiter_t; typedef struct { diff --git a/crypto_kem/ledakemlt32/META.yml b/crypto_kem/ledakemlt32/META.yml index fffc304a..ed52b88d 100644 --- a/crypto_kem/ledakemlt32/META.yml +++ b/crypto_kem/ledakemlt32/META.yml @@ -3,10 +3,10 @@ type: kem claimed-nist-level: 3 claimed-security: IND-CCA2 length-public-key: 12032 -length-secret-key: 33 +length-secret-key: 34 length-ciphertext: 12032 length-shared-secret: 48 -nistkat-sha256: 5f4e10c91755d87722bc16e13c6bc5d8bcd6190589cb8924aedb8639d9f1f244 +nistkat-sha256: 455dc69ee95196fe0526c3289fe46792acd55ac380b3c66be48eb3e3e10ad4e6 principal-submitter: Marco Baldi auxiliary-submitters: - Alessandro Barenghi @@ -15,4 +15,4 @@ auxiliary-submitters: - Paolo Santini implementations: - name: clean - version: 2.0 + version: 2.? diff --git a/crypto_kem/ledakemlt32/clean/api.h b/crypto_kem/ledakemlt32/clean/api.h index 509108d8..0d54b775 100644 --- a/crypto_kem/ledakemlt32/clean/api.h +++ b/crypto_kem/ledakemlt32/clean/api.h @@ -3,7 +3,7 @@ #include -#define PQCLEAN_LEDAKEMLT32_CLEAN_CRYPTO_SECRETKEYBYTES 33 +#define PQCLEAN_LEDAKEMLT32_CLEAN_CRYPTO_SECRETKEYBYTES 34 #define PQCLEAN_LEDAKEMLT32_CLEAN_CRYPTO_PUBLICKEYBYTES 12032 #define PQCLEAN_LEDAKEMLT32_CLEAN_CRYPTO_CIPHERTEXTBYTES 12032 #define PQCLEAN_LEDAKEMLT32_CLEAN_CRYPTO_BYTES 48 diff --git a/crypto_kem/ledakemlt32/clean/bf_decoding.c b/crypto_kem/ledakemlt32/clean/bf_decoding.c index f2eb85aa..f740dbc2 100644 --- a/crypto_kem/ledakemlt32/clean/bf_decoding.c +++ b/crypto_kem/ledakemlt32/clean/bf_decoding.c @@ -4,18 +4,18 @@ #include #include -unsigned int PQCLEAN_LEDAKEMLT32_CLEAN_thresholds[2] = {B0, (DV * M) / 2 + 1}; - int PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(DIGIT err[], const POSITION_T HtrPosOnes[N0][DV], const POSITION_T QtrPosOnes[N0][M], - DIGIT privateSyndrome[]) { + DIGIT privateSyndrome[], + uint8_t threshold) { uint8_t unsatParityChecks[N0 * P]; POSITION_T currQBlkPos[M], currQBitPos[M]; DIGIT currSyndrome[NUM_DIGITS_GF2X_ELEMENT]; int check; int iteration = 0; + unsigned int corrt_syndrome_based; do { PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_copy(currSyndrome, privateSyndrome); @@ -32,7 +32,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(DIGIT err[], } /* iteration based threshold determination*/ - unsigned int corrt_syndrome_based = PQCLEAN_LEDAKEMLT32_CLEAN_thresholds[iteration]; + corrt_syndrome_based = iteration ? (unsigned int) threshold : B0; //Computation of correlation with a full Q matrix for (int i = 0; i < N0; i++) { @@ -45,7 +45,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(DIGIT err[], endQblockIdx += qBlockWeights[blockIdx][i]; int currblockoffset = blockIdx * P; for (; currQoneIdx < endQblockIdx; currQoneIdx++) { - uint32_t tmp = QtrPosOnes[i][currQoneIdx] + j; + POSITION_T tmp = QtrPosOnes[i][currQoneIdx] + j; tmp = tmp >= P ? tmp - P : tmp; currQBitPos[currQoneIdx] = tmp; currQBlkPos[currQoneIdx] = blockIdx; @@ -56,7 +56,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(DIGIT err[], if (correlation >= corrt_syndrome_based) { PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_toggle_coeff(err + NUM_DIGITS_GF2X_ELEMENT * i, j); for (int v = 0; v < M; v++) { - unsigned syndromePosToFlip; + POSITION_T syndromePosToFlip; for (int HtrOneIdx = 0; HtrOneIdx < DV; HtrOneIdx++) { syndromePosToFlip = (HtrPosOnes[currQBlkPos[v]][HtrOneIdx] + currQBitPos[v] ); syndromePosToFlip = syndromePosToFlip >= P ? syndromePosToFlip - P : syndromePosToFlip; diff --git a/crypto_kem/ledakemlt32/clean/bf_decoding.h b/crypto_kem/ledakemlt32/clean/bf_decoding.h index 672e65a3..31cc369a 100644 --- a/crypto_kem/ledakemlt32/clean/bf_decoding.h +++ b/crypto_kem/ledakemlt32/clean/bf_decoding.h @@ -12,6 +12,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(DIGIT err[], const POSITION_T HtrPosOnes[N0][DV], const POSITION_T QtrPosOnes[N0][M], - DIGIT privateSyndrome[]); + DIGIT privateSyndrome[], + uint8_t threshold); #endif diff --git a/crypto_kem/ledakemlt32/clean/dfr_test.c b/crypto_kem/ledakemlt32/clean/dfr_test.c index 99571cf5..c9e6fb1c 100644 --- a/crypto_kem/ledakemlt32/clean/dfr_test.c +++ b/crypto_kem/ledakemlt32/clean/dfr_test.c @@ -6,29 +6,22 @@ #include /* Tests if the current code attains the desired DFR. If that is the case, - * computes the threshold for the second iteration of the decoder and stores - * it in the globally accessible vector */ + * computes the threshold for the second iteration of the decoder and returns this values + * (max DV * M), on failure it returns 255 >> DV * M */ -extern unsigned int PQCLEAN_LEDAKEMLT32_CLEAN_thresholds[2]; - -int PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { +uint8_t PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { POSITION_T LSparse_loc[N0][DV * M]; - + POSITION_T rotated_column[DV * M]; /* Gamma matrix: an N0 x N0 block circulant matrix with block size p * 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 */ + * 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 */ 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}}; - unsigned int maxMut[N0], maxMutMinusOne[N0]; + unsigned int firstidx, secondidx, intersectionval; unsigned int allBlockMaxSumst, allBlockMaxSumstMinusOne; - unsigned int toAdd, histIdx; /*transpose blocks of L, we need its columns */ @@ -113,8 +106,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { allBlockMaxSumstMinusOne; } if (DV * M > (allBlockMaxSumstMinusOne + allBlockMaxSumst)) { - PQCLEAN_LEDAKEMLT32_CLEAN_thresholds[1] = allBlockMaxSumst + 1; - return 1; + return allBlockMaxSumst + 1; } - return 0; + return DFR_TEST_FAIL; } diff --git a/crypto_kem/ledakemlt32/clean/dfr_test.h b/crypto_kem/ledakemlt32/clean/dfr_test.h index 72d2297b..1dd40cd2 100644 --- a/crypto_kem/ledakemlt32/clean/dfr_test.h +++ b/crypto_kem/ledakemlt32/clean/dfr_test.h @@ -1,6 +1,8 @@ #ifndef DFR_TEST_H #define DFR_TEST_H -int PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]); +#define DFR_TEST_FAIL (255) + +uint8_t PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]); #endif diff --git a/crypto_kem/ledakemlt32/clean/kem.c b/crypto_kem/ledakemlt32/clean/kem.c index 23b08cbd..647f4326 100644 --- a/crypto_kem/ledakemlt32/clean/kem.c +++ b/crypto_kem/ledakemlt32/clean/kem.c @@ -13,7 +13,7 @@ static void pack_pk(uint8_t *pk_bytes, publicKeyNiederreiter_t *pk) { } } -static void unpack_pk(publicKeyNiederreiter_t *pk, const uint8_t *pk_bytes) { +static void unpack_pk(publicKeyNiederreiter_t *pk, const uint8_t *pk_bytes) { size_t i; for (i = 0; i < N0 - 1; i++) { PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_frombytes(pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT, diff --git a/crypto_kem/ledakemlt32/clean/niederreiter.c b/crypto_kem/ledakemlt32/clean/niederreiter.c index 3d524800..540151f7 100644 --- a/crypto_kem/ledakemlt32/clean/niederreiter.c +++ b/crypto_kem/ledakemlt32/clean/niederreiter.c @@ -10,7 +10,6 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, privateKeyNiederreiter_t *sk, AES_XOF_struct *keys_expander) { - POSITION_T HPosOnes[N0][DV]; // sequence of N0 circ block matrices (p x p): Hi POSITION_T HtrPosOnes[N0][DV]; // Sparse tranposed circulant H POSITION_T QPosOnes[N0][M]; // Sparse Q, Each row contains the position of the ones of all the blocks of a row of Q as exponent+P*block_position @@ -20,7 +19,7 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, DIGIT Ln0dense[NUM_DIGITS_GF2X_ELEMENT]; DIGIT Ln0Inv[NUM_DIGITS_GF2X_ELEMENT]; int is_L_full = 0; - int isDFRok = 0; + uint8_t threshold; // threshold for round 2 sk->rejections = (int8_t) 0; do { @@ -50,10 +49,11 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, } sk->rejections = sk->rejections + 1; if (is_L_full) { - isDFRok = PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(LPosOnes); + threshold = PQCLEAN_LEDAKEMLT32_CLEAN_DFR_test(LPosOnes); } - } while (!is_L_full || !isDFRok); + } while (!is_L_full || threshold == DFR_TEST_FAIL); sk->rejections = sk->rejections - 1; + sk->threshold = threshold; memset(Ln0dense, 0x00, sizeof(Ln0dense)); for (int j = 0; j < DV * M; j++) { @@ -176,7 +176,7 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_decrypt(DIGIT *err, const privateKeyN memset(err, 0x00, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); decryptOk = PQCLEAN_LEDAKEMLT32_CLEAN_bf_decoding(err, (const POSITION_T (*)[DV]) HtrPosOnes, - (const POSITION_T (*)[M]) QtrPosOnes, privateSyndrome); + (const POSITION_T (*)[M]) QtrPosOnes, privateSyndrome, sk->threshold); err_weight = 0; for (int i = 0 ; i < N0; i++) { diff --git a/crypto_kem/ledakemlt32/clean/niederreiter.h b/crypto_kem/ledakemlt32/clean/niederreiter.h index abea8a9a..c2e09ffa 100644 --- a/crypto_kem/ledakemlt32/clean/niederreiter.h +++ b/crypto_kem/ledakemlt32/clean/niederreiter.h @@ -10,6 +10,7 @@ typedef struct { * H and Q during decryption */ unsigned char prng_seed[TRNG_BYTE_LENGTH]; int8_t rejections; + uint8_t threshold; } privateKeyNiederreiter_t; typedef struct { diff --git a/crypto_kem/ledakemlt52/META.yml b/crypto_kem/ledakemlt52/META.yml index 5751adc4..0dcac3f0 100644 --- a/crypto_kem/ledakemlt52/META.yml +++ b/crypto_kem/ledakemlt52/META.yml @@ -3,10 +3,10 @@ type: kem claimed-nist-level: 5 claimed-security: IND-CCA2 length-public-key: 19040 -length-secret-key: 41 +length-secret-key: 42 length-ciphertext: 19040 length-shared-secret: 64 -nistkat-sha256: c53eaa3c3573a4db989671994e9501dbbc080b9c86106787f438960848c71326 +nistkat-sha256: 9cd9299d20a1c8c242730d3795683a9e87c6bcd0e691dc1fd54cd6a418266c36 principal-submitter: Marco Baldi auxiliary-submitters: - Alessandro Barenghi @@ -15,4 +15,4 @@ auxiliary-submitters: - Paolo Santini implementations: - name: clean - version: 2.0 + version: 2.? diff --git a/crypto_kem/ledakemlt52/clean/api.h b/crypto_kem/ledakemlt52/clean/api.h index 9d23bb79..2ac2f10c 100644 --- a/crypto_kem/ledakemlt52/clean/api.h +++ b/crypto_kem/ledakemlt52/clean/api.h @@ -3,7 +3,7 @@ #include -#define PQCLEAN_LEDAKEMLT52_CLEAN_CRYPTO_SECRETKEYBYTES 41 +#define PQCLEAN_LEDAKEMLT52_CLEAN_CRYPTO_SECRETKEYBYTES 42 #define PQCLEAN_LEDAKEMLT52_CLEAN_CRYPTO_PUBLICKEYBYTES 19040 #define PQCLEAN_LEDAKEMLT52_CLEAN_CRYPTO_CIPHERTEXTBYTES 19040 #define PQCLEAN_LEDAKEMLT52_CLEAN_CRYPTO_BYTES 64 diff --git a/crypto_kem/ledakemlt52/clean/bf_decoding.c b/crypto_kem/ledakemlt52/clean/bf_decoding.c index 2b90c00a..5e209aa9 100644 --- a/crypto_kem/ledakemlt52/clean/bf_decoding.c +++ b/crypto_kem/ledakemlt52/clean/bf_decoding.c @@ -4,18 +4,18 @@ #include #include -unsigned int PQCLEAN_LEDAKEMLT52_CLEAN_thresholds[2] = {B0, (DV * M) / 2 + 1}; - int PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(DIGIT err[], const POSITION_T HtrPosOnes[N0][DV], const POSITION_T QtrPosOnes[N0][M], - DIGIT privateSyndrome[]) { + DIGIT privateSyndrome[], + uint8_t threshold) { uint8_t unsatParityChecks[N0 * P]; POSITION_T currQBlkPos[M], currQBitPos[M]; DIGIT currSyndrome[NUM_DIGITS_GF2X_ELEMENT]; int check; int iteration = 0; + unsigned int corrt_syndrome_based; do { PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_copy(currSyndrome, privateSyndrome); @@ -32,7 +32,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(DIGIT err[], } /* iteration based threshold determination*/ - unsigned int corrt_syndrome_based = PQCLEAN_LEDAKEMLT52_CLEAN_thresholds[iteration]; + corrt_syndrome_based = iteration ? (unsigned int) threshold : B0; //Computation of correlation with a full Q matrix for (int i = 0; i < N0; i++) { @@ -45,7 +45,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(DIGIT err[], endQblockIdx += qBlockWeights[blockIdx][i]; int currblockoffset = blockIdx * P; for (; currQoneIdx < endQblockIdx; currQoneIdx++) { - uint32_t tmp = QtrPosOnes[i][currQoneIdx] + j; + POSITION_T tmp = QtrPosOnes[i][currQoneIdx] + j; tmp = tmp >= P ? tmp - P : tmp; currQBitPos[currQoneIdx] = tmp; currQBlkPos[currQoneIdx] = blockIdx; @@ -56,7 +56,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(DIGIT err[], if (correlation >= corrt_syndrome_based) { PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_toggle_coeff(err + NUM_DIGITS_GF2X_ELEMENT * i, j); for (int v = 0; v < M; v++) { - unsigned syndromePosToFlip; + POSITION_T syndromePosToFlip; for (int HtrOneIdx = 0; HtrOneIdx < DV; HtrOneIdx++) { syndromePosToFlip = (HtrPosOnes[currQBlkPos[v]][HtrOneIdx] + currQBitPos[v] ); syndromePosToFlip = syndromePosToFlip >= P ? syndromePosToFlip - P : syndromePosToFlip; diff --git a/crypto_kem/ledakemlt52/clean/bf_decoding.h b/crypto_kem/ledakemlt52/clean/bf_decoding.h index af006f04..e3b8bb90 100644 --- a/crypto_kem/ledakemlt52/clean/bf_decoding.h +++ b/crypto_kem/ledakemlt52/clean/bf_decoding.h @@ -12,6 +12,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(DIGIT err[], const POSITION_T HtrPosOnes[N0][DV], const POSITION_T QtrPosOnes[N0][M], - DIGIT privateSyndrome[]); + DIGIT privateSyndrome[], + uint8_t threshold); #endif diff --git a/crypto_kem/ledakemlt52/clean/dfr_test.c b/crypto_kem/ledakemlt52/clean/dfr_test.c index e8de098e..d82b3388 100644 --- a/crypto_kem/ledakemlt52/clean/dfr_test.c +++ b/crypto_kem/ledakemlt52/clean/dfr_test.c @@ -6,29 +6,22 @@ #include /* Tests if the current code attains the desired DFR. If that is the case, - * computes the threshold for the second iteration of the decoder and stores - * it in the globally accessible vector */ + * computes the threshold for the second iteration of the decoder and returns this values + * (max DV * M), on failure it returns 255 >> DV * M */ -extern unsigned int PQCLEAN_LEDAKEMLT52_CLEAN_thresholds[2]; - -int PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { +uint8_t PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { POSITION_T LSparse_loc[N0][DV * M]; - + POSITION_T rotated_column[DV * M]; /* Gamma matrix: an N0 x N0 block circulant matrix with block size p * 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 */ + * 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 */ 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}}; - unsigned int maxMut[N0], maxMutMinusOne[N0]; + unsigned int firstidx, secondidx, intersectionval; unsigned int allBlockMaxSumst, allBlockMaxSumstMinusOne; - unsigned int toAdd, histIdx; /*transpose blocks of L, we need its columns */ @@ -113,8 +106,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]) { allBlockMaxSumstMinusOne; } if (DV * M > (allBlockMaxSumstMinusOne + allBlockMaxSumst)) { - PQCLEAN_LEDAKEMLT52_CLEAN_thresholds[1] = allBlockMaxSumst + 1; - return 1; + return allBlockMaxSumst + 1; } - return 0; + return DFR_TEST_FAIL; } diff --git a/crypto_kem/ledakemlt52/clean/dfr_test.h b/crypto_kem/ledakemlt52/clean/dfr_test.h index 8a74e5a3..577dd3fa 100644 --- a/crypto_kem/ledakemlt52/clean/dfr_test.h +++ b/crypto_kem/ledakemlt52/clean/dfr_test.h @@ -1,6 +1,8 @@ #ifndef DFR_TEST_H #define DFR_TEST_H -int PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]); +#define DFR_TEST_FAIL (255) + +uint8_t PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(POSITION_T LSparse[N0][DV * M]); #endif diff --git a/crypto_kem/ledakemlt52/clean/kem.c b/crypto_kem/ledakemlt52/clean/kem.c index f7869550..d571c73e 100644 --- a/crypto_kem/ledakemlt52/clean/kem.c +++ b/crypto_kem/ledakemlt52/clean/kem.c @@ -13,7 +13,7 @@ static void pack_pk(uint8_t *pk_bytes, publicKeyNiederreiter_t *pk) { } } -static void unpack_pk(publicKeyNiederreiter_t *pk, const uint8_t *pk_bytes) { +static void unpack_pk(publicKeyNiederreiter_t *pk, const uint8_t *pk_bytes) { size_t i; for (i = 0; i < N0 - 1; i++) { PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_frombytes(pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT, diff --git a/crypto_kem/ledakemlt52/clean/niederreiter.c b/crypto_kem/ledakemlt52/clean/niederreiter.c index e811f1e2..03d5d84b 100644 --- a/crypto_kem/ledakemlt52/clean/niederreiter.c +++ b/crypto_kem/ledakemlt52/clean/niederreiter.c @@ -10,7 +10,6 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, privateKeyNiederreiter_t *sk, AES_XOF_struct *keys_expander) { - POSITION_T HPosOnes[N0][DV]; // sequence of N0 circ block matrices (p x p): Hi POSITION_T HtrPosOnes[N0][DV]; // Sparse tranposed circulant H POSITION_T QPosOnes[N0][M]; // Sparse Q, Each row contains the position of the ones of all the blocks of a row of Q as exponent+P*block_position @@ -20,7 +19,7 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, DIGIT Ln0dense[NUM_DIGITS_GF2X_ELEMENT]; DIGIT Ln0Inv[NUM_DIGITS_GF2X_ELEMENT]; int is_L_full = 0; - int isDFRok = 0; + uint8_t threshold; // threshold for round 2 sk->rejections = (int8_t) 0; do { @@ -50,10 +49,11 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_keygen(publicKeyNiederreiter_t *pk, } sk->rejections = sk->rejections + 1; if (is_L_full) { - isDFRok = PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(LPosOnes); + threshold = PQCLEAN_LEDAKEMLT52_CLEAN_DFR_test(LPosOnes); } - } while (!is_L_full || !isDFRok); + } while (!is_L_full || threshold == DFR_TEST_FAIL); sk->rejections = sk->rejections - 1; + sk->threshold = threshold; memset(Ln0dense, 0x00, sizeof(Ln0dense)); for (int j = 0; j < DV * M; j++) { @@ -176,7 +176,7 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_decrypt(DIGIT *err, const privateKeyN memset(err, 0x00, N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); decryptOk = PQCLEAN_LEDAKEMLT52_CLEAN_bf_decoding(err, (const POSITION_T (*)[DV]) HtrPosOnes, - (const POSITION_T (*)[M]) QtrPosOnes, privateSyndrome); + (const POSITION_T (*)[M]) QtrPosOnes, privateSyndrome, sk->threshold); err_weight = 0; for (int i = 0 ; i < N0; i++) { diff --git a/crypto_kem/ledakemlt52/clean/niederreiter.h b/crypto_kem/ledakemlt52/clean/niederreiter.h index eb1d69b9..e6c33ecd 100644 --- a/crypto_kem/ledakemlt52/clean/niederreiter.h +++ b/crypto_kem/ledakemlt52/clean/niederreiter.h @@ -10,6 +10,7 @@ typedef struct { * H and Q during decryption */ unsigned char prng_seed[TRNG_BYTE_LENGTH]; int8_t rejections; + uint8_t threshold; } privateKeyNiederreiter_t; typedef struct {