avoid global state by including 2nd round threshold in secret key

Этот коммит содержится в:
Leon 2019-06-14 14:23:58 +02:00
родитель 5a4b7f24a3
Коммит bf0aca644e
27 изменённых файлов: 93 добавлений и 105 удалений

Просмотреть файл

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

Просмотреть файл

@ -3,7 +3,7 @@
#include <stdint.h>
#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

Просмотреть файл

@ -4,18 +4,18 @@
#include <assert.h>
#include <string.h>
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;

Просмотреть файл

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

Просмотреть файл

@ -6,29 +6,22 @@
#include <string.h>
/* 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;
}

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -3,7 +3,7 @@
#include <stdint.h>
#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

Просмотреть файл

@ -4,18 +4,18 @@
#include <assert.h>
#include <string.h>
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;

Просмотреть файл

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

Просмотреть файл

@ -6,29 +6,22 @@
#include <string.h>
/* 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;
}

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

@ -3,7 +3,7 @@
#include <stdint.h>
#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

Просмотреть файл

@ -4,18 +4,18 @@
#include <assert.h>
#include <string.h>
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;

Просмотреть файл

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

Просмотреть файл

@ -6,29 +6,22 @@
#include <string.h>
/* 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;
}

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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

Просмотреть файл

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