From 5a4b7f24a3b9e53c1c26c775284f5ee83f586fd0 Mon Sep 17 00:00:00 2001 From: Leon Date: Wed, 12 Jun 2019 15:33:20 +0200 Subject: [PATCH] (de)serialization instead of pointer casts --- .../clean/gf2x_arith_mod_xPplusOne.c | 10 ++++ .../clean/gf2x_arith_mod_xPplusOne.h | 4 +- crypto_kem/ledakemlt12/clean/kem.c | 56 +++++++++++++++---- .../clean/gf2x_arith_mod_xPplusOne.c | 10 ++++ .../clean/gf2x_arith_mod_xPplusOne.h | 4 +- crypto_kem/ledakemlt32/clean/kem.c | 56 +++++++++++++++---- .../clean/gf2x_arith_mod_xPplusOne.c | 10 ++++ .../clean/gf2x_arith_mod_xPplusOne.h | 3 +- crypto_kem/ledakemlt52/clean/kem.c | 56 +++++++++++++++---- 9 files changed, 176 insertions(+), 33 deletions(-) diff --git a/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.c b/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.c index d56b18a0..30dca0f9 100644 --- a/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.c +++ b/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.c @@ -572,3 +572,13 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_tobytes(uint8_t *bytes, const DIGIT *poly) { } } } + +void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_frombytes(DIGIT *poly, const uint8_t *poly_bytes) { + size_t i, j; + for (i = 0; i < NUM_DIGITS_GF2X_ELEMENT; i++) { + poly[i] = (DIGIT) 0; + for (j = 0; j < DIGIT_SIZE_B; j++) { + poly[i] |= (DIGIT) poly_bytes[i * DIGIT_SIZE_B + j] << 8 * j; + } + } +} diff --git a/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.h b/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.h index cfae3dc6..05695f67 100644 --- a/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.h +++ b/crypto_kem/ledakemlt12/clean/gf2x_arith_mod_xPplusOne.h @@ -28,9 +28,11 @@ void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, void PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence(DIGIT *sequence, AES_XOF_struct *seed_expander_ctx); void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_add_sparse(int sizeR, POSITION_T Res[], int sizeA, const POSITION_T A[], int sizeB, const POSITION_T B[]); void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_transpose_in_place_sparse(int sizeA, POSITION_T A[]); +int PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]); 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[]); +void PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_frombytes(DIGIT *poly, const uint8_t *poly_bytes); + #endif diff --git a/crypto_kem/ledakemlt12/clean/kem.c b/crypto_kem/ledakemlt12/clean/kem.c index 8a2d1dc4..f8c72798 100644 --- a/crypto_kem/ledakemlt12/clean/kem.c +++ b/crypto_kem/ledakemlt12/clean/kem.c @@ -5,24 +5,52 @@ #include +static void pack_pk(uint8_t *pk_bytes, publicKeyNiederreiter_t *pk) { + size_t i; + for (i = 0; i < N0 - 1; i++) { + PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_tobytes(pk_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, + pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT); + } +} + +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, + pk_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); + } +} + +static void pack_ct(uint8_t *sk_bytes, DIGIT *ct) { + PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_tobytes(sk_bytes, ct); +} + +static void unpack_ct(DIGIT *ct, const uint8_t *ct_bytes) { + PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_frombytes(ct, ct_bytes); +} + +static void pack_error(uint8_t *error_bytes, DIGIT *error_digits) { + size_t i; + for (i = 0; i < N0; i++) { + PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_tobytes(error_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, + error_digits + i * NUM_DIGITS_GF2X_ELEMENT); + } +} + /* Generates a keypair - pk is the public key and sk is the secret key. */ int PQCLEAN_LEDAKEMLT12_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk) { AES_XOF_struct niederreiter_keys_expander; + publicKeyNiederreiter_t pk_nie; randombytes(((privateKeyNiederreiter_t *)sk)->prng_seed, TRNG_BYTE_LENGTH); PQCLEAN_LEDAKEMLT12_CLEAN_seedexpander_from_trng(&niederreiter_keys_expander, ((privateKeyNiederreiter_t *)sk)->prng_seed); - PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen((publicKeyNiederreiter_t *) pk, (privateKeyNiederreiter_t *) sk, &niederreiter_keys_expander); + PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_keygen(&pk_nie, (privateKeyNiederreiter_t *) sk, &niederreiter_keys_expander); + + pack_pk(pk, &pk_nie); return 0; } -static void pack_error(uint8_t *error_bytes, const DIGIT *error_digits) { - size_t i; - for (i = 0; i < N0; i++) { - PQCLEAN_LEDAKEMLT12_CLEAN_gf2x_tobytes(error_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, error_digits + i * NUM_DIGITS_GF2X_ELEMENT); - } -} - /* Encrypt - pk is the public key, ct is a key encapsulation message (ciphertext), ss is the shared secret.*/ int PQCLEAN_LEDAKEMLT12_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk) { @@ -30,13 +58,19 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *s unsigned char encapsulated_key_seed[TRNG_BYTE_LENGTH]; DIGIT error_vector[N0 * NUM_DIGITS_GF2X_ELEMENT]; uint8_t error_bytes[N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B]; + DIGIT syndrome[NUM_DIGITS_GF2X_ELEMENT]; + publicKeyNiederreiter_t pk_nie; randombytes(encapsulated_key_seed, TRNG_BYTE_LENGTH); + unpack_pk(&pk_nie, pk); + PQCLEAN_LEDAKEMLT12_CLEAN_seedexpander_from_trng(&niederreiter_encap_key_expander, encapsulated_key_seed); PQCLEAN_LEDAKEMLT12_CLEAN_rand_circulant_blocks_sequence(error_vector, &niederreiter_encap_key_expander); pack_error(error_bytes, error_vector); HASH_FUNCTION(ss, error_bytes, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); - PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_encrypt((DIGIT *) ct, (publicKeyNiederreiter_t *) pk, error_vector); + PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_encrypt(syndrome, &pk_nie, error_vector); + + pack_ct(ct, syndrome); return 0; } @@ -47,8 +81,10 @@ int PQCLEAN_LEDAKEMLT12_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *s int PQCLEAN_LEDAKEMLT12_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk) { DIGIT decoded_error_vector[N0 * NUM_DIGITS_GF2X_ELEMENT]; uint8_t decoded_error_bytes[N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B]; + DIGIT syndrome[NUM_DIGITS_GF2X_ELEMENT]; - PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(decoded_error_vector, (privateKeyNiederreiter_t *)sk, (DIGIT *)ct); + unpack_ct(syndrome, ct); + PQCLEAN_LEDAKEMLT12_CLEAN_niederreiter_decrypt(decoded_error_vector, (privateKeyNiederreiter_t *)sk, syndrome); pack_error(decoded_error_bytes, decoded_error_vector); HASH_FUNCTION(ss, decoded_error_bytes, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); diff --git a/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.c b/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.c index 39067248..0d69e00e 100644 --- a/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.c +++ b/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.c @@ -572,3 +572,13 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_tobytes(uint8_t *bytes, const DIGIT *poly) { } } } + +void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_frombytes(DIGIT *poly, const uint8_t *poly_bytes) { + size_t i, j; + for (i = 0; i < NUM_DIGITS_GF2X_ELEMENT; i++) { + poly[i] = (DIGIT) 0; + for (j = 0; j < DIGIT_SIZE_B; j++) { + poly[i] |= (DIGIT) poly_bytes[i * DIGIT_SIZE_B + j] << 8 * j; + } + } +} diff --git a/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.h b/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.h index 8f7a1f53..371ae170 100644 --- a/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.h +++ b/crypto_kem/ledakemlt32/clean/gf2x_arith_mod_xPplusOne.h @@ -28,9 +28,11 @@ void PQCLEAN_LEDAKEMLT32_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, void PQCLEAN_LEDAKEMLT32_CLEAN_rand_circulant_blocks_sequence(DIGIT *sequence, AES_XOF_struct *seed_expander_ctx); void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_add_sparse(int sizeR, POSITION_T Res[], int sizeA, const POSITION_T A[], int sizeB, const POSITION_T B[]); void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_transpose_in_place_sparse(int sizeA, POSITION_T A[]); +int PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]); 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[]); +void PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_frombytes(DIGIT *poly, const uint8_t *poly_bytes); + #endif diff --git a/crypto_kem/ledakemlt32/clean/kem.c b/crypto_kem/ledakemlt32/clean/kem.c index fb67f865..23b08cbd 100644 --- a/crypto_kem/ledakemlt32/clean/kem.c +++ b/crypto_kem/ledakemlt32/clean/kem.c @@ -5,24 +5,52 @@ #include +static void pack_pk(uint8_t *pk_bytes, publicKeyNiederreiter_t *pk) { + size_t i; + for (i = 0; i < N0 - 1; i++) { + PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_tobytes(pk_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, + pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT); + } +} + +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, + pk_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); + } +} + +static void pack_ct(uint8_t *sk_bytes, DIGIT *ct) { + PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_tobytes(sk_bytes, ct); +} + +static void unpack_ct(DIGIT *ct, const uint8_t *ct_bytes) { + PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_frombytes(ct, ct_bytes); +} + +static void pack_error(uint8_t *error_bytes, DIGIT *error_digits) { + size_t i; + for (i = 0; i < N0; i++) { + PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_tobytes(error_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, + error_digits + i * NUM_DIGITS_GF2X_ELEMENT); + } +} + /* Generates a keypair - pk is the public key and sk is the secret key. */ int PQCLEAN_LEDAKEMLT32_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk) { AES_XOF_struct niederreiter_keys_expander; + publicKeyNiederreiter_t pk_nie; randombytes(((privateKeyNiederreiter_t *)sk)->prng_seed, TRNG_BYTE_LENGTH); PQCLEAN_LEDAKEMLT32_CLEAN_seedexpander_from_trng(&niederreiter_keys_expander, ((privateKeyNiederreiter_t *)sk)->prng_seed); - PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_keygen((publicKeyNiederreiter_t *) pk, (privateKeyNiederreiter_t *) sk, &niederreiter_keys_expander); + PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_keygen(&pk_nie, (privateKeyNiederreiter_t *) sk, &niederreiter_keys_expander); + + pack_pk(pk, &pk_nie); return 0; } -static void pack_error(uint8_t *error_bytes, const DIGIT *error_digits) { - size_t i; - for (i = 0; i < N0; i++) { - PQCLEAN_LEDAKEMLT32_CLEAN_gf2x_tobytes(error_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, error_digits + i * NUM_DIGITS_GF2X_ELEMENT); - } -} - /* Encrypt - pk is the public key, ct is a key encapsulation message (ciphertext), ss is the shared secret.*/ int PQCLEAN_LEDAKEMLT32_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk) { @@ -30,13 +58,19 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *s unsigned char encapsulated_key_seed[TRNG_BYTE_LENGTH]; DIGIT error_vector[N0 * NUM_DIGITS_GF2X_ELEMENT]; uint8_t error_bytes[N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B]; + DIGIT syndrome[NUM_DIGITS_GF2X_ELEMENT]; + publicKeyNiederreiter_t pk_nie; randombytes(encapsulated_key_seed, TRNG_BYTE_LENGTH); + unpack_pk(&pk_nie, pk); + PQCLEAN_LEDAKEMLT32_CLEAN_seedexpander_from_trng(&niederreiter_encap_key_expander, encapsulated_key_seed); PQCLEAN_LEDAKEMLT32_CLEAN_rand_circulant_blocks_sequence(error_vector, &niederreiter_encap_key_expander); pack_error(error_bytes, error_vector); HASH_FUNCTION(ss, error_bytes, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); - PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_encrypt((DIGIT *) ct, (publicKeyNiederreiter_t *) pk, error_vector); + PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_encrypt(syndrome, &pk_nie, error_vector); + + pack_ct(ct, syndrome); return 0; } @@ -47,8 +81,10 @@ int PQCLEAN_LEDAKEMLT32_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *s int PQCLEAN_LEDAKEMLT32_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk) { DIGIT decoded_error_vector[N0 * NUM_DIGITS_GF2X_ELEMENT]; uint8_t decoded_error_bytes[N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B]; + DIGIT syndrome[NUM_DIGITS_GF2X_ELEMENT]; - PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_decrypt(decoded_error_vector, (privateKeyNiederreiter_t *)sk, (DIGIT *)ct); + unpack_ct(syndrome, ct); + PQCLEAN_LEDAKEMLT32_CLEAN_niederreiter_decrypt(decoded_error_vector, (privateKeyNiederreiter_t *)sk, syndrome); pack_error(decoded_error_bytes, decoded_error_vector); HASH_FUNCTION(ss, decoded_error_bytes, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); diff --git a/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.c b/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.c index d48c804d..7aac95c7 100644 --- a/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.c +++ b/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.c @@ -573,3 +573,13 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_tobytes(uint8_t *bytes, const DIGIT *poly) { } } } + +void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_frombytes(DIGIT *poly, const uint8_t *poly_bytes) { + size_t i, j; + for (i = 0; i < NUM_DIGITS_GF2X_ELEMENT; i++) { + poly[i] = (DIGIT) 0; + for (j = 0; j < DIGIT_SIZE_B; j++) { + poly[i] |= (DIGIT) poly_bytes[i * DIGIT_SIZE_B + j] << 8 * j; + } + } +} diff --git a/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.h b/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.h index f730ed41..959c645a 100644 --- a/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.h +++ b/crypto_kem/ledakemlt52/clean/gf2x_arith_mod_xPplusOne.h @@ -28,9 +28,10 @@ void PQCLEAN_LEDAKEMLT52_CLEAN_rand_circulant_sparse_block(POSITION_T *pos_ones, void PQCLEAN_LEDAKEMLT52_CLEAN_rand_circulant_blocks_sequence(DIGIT *sequence, AES_XOF_struct *seed_expander_ctx); void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_add_sparse(int sizeR, POSITION_T Res[], int sizeA, const POSITION_T A[], int sizeB, const POSITION_T B[]); void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_transpose_in_place_sparse(int sizeA, POSITION_T A[]); +int PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_mod_inverse(DIGIT out[], const DIGIT in[]); 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[]); +void PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_frombytes(DIGIT *poly, const uint8_t *poly_bytes); #endif diff --git a/crypto_kem/ledakemlt52/clean/kem.c b/crypto_kem/ledakemlt52/clean/kem.c index 40ac222b..f7869550 100644 --- a/crypto_kem/ledakemlt52/clean/kem.c +++ b/crypto_kem/ledakemlt52/clean/kem.c @@ -5,24 +5,52 @@ #include +static void pack_pk(uint8_t *pk_bytes, publicKeyNiederreiter_t *pk) { + size_t i; + for (i = 0; i < N0 - 1; i++) { + PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_tobytes(pk_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, + pk->Mtr + i * NUM_DIGITS_GF2X_ELEMENT); + } +} + +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, + pk_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B); + } +} + +static void pack_ct(uint8_t *sk_bytes, DIGIT *ct) { + PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_tobytes(sk_bytes, ct); +} + +static void unpack_ct(DIGIT *ct, const uint8_t *ct_bytes) { + PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_frombytes(ct, ct_bytes); +} + +static void pack_error(uint8_t *error_bytes, DIGIT *error_digits) { + size_t i; + for (i = 0; i < N0; i++) { + PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_tobytes(error_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, + error_digits + i * NUM_DIGITS_GF2X_ELEMENT); + } +} + /* Generates a keypair - pk is the public key and sk is the secret key. */ int PQCLEAN_LEDAKEMLT52_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigned char *sk) { AES_XOF_struct niederreiter_keys_expander; + publicKeyNiederreiter_t pk_nie; randombytes(((privateKeyNiederreiter_t *)sk)->prng_seed, TRNG_BYTE_LENGTH); PQCLEAN_LEDAKEMLT52_CLEAN_seedexpander_from_trng(&niederreiter_keys_expander, ((privateKeyNiederreiter_t *)sk)->prng_seed); - PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_keygen((publicKeyNiederreiter_t *) pk, (privateKeyNiederreiter_t *) sk, &niederreiter_keys_expander); + PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_keygen(&pk_nie, (privateKeyNiederreiter_t *) sk, &niederreiter_keys_expander); + + pack_pk(pk, &pk_nie); return 0; } -static void pack_error(uint8_t *error_bytes, const DIGIT *error_digits) { - size_t i; - for (i = 0; i < N0; i++) { - PQCLEAN_LEDAKEMLT52_CLEAN_gf2x_tobytes(error_bytes + i * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B, error_digits + i * NUM_DIGITS_GF2X_ELEMENT); - } -} - /* Encrypt - pk is the public key, ct is a key encapsulation message (ciphertext), ss is the shared secret.*/ int PQCLEAN_LEDAKEMLT52_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk) { @@ -30,13 +58,19 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *s unsigned char encapsulated_key_seed[TRNG_BYTE_LENGTH]; DIGIT error_vector[N0 * NUM_DIGITS_GF2X_ELEMENT]; uint8_t error_bytes[N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B]; + DIGIT syndrome[NUM_DIGITS_GF2X_ELEMENT]; + publicKeyNiederreiter_t pk_nie; randombytes(encapsulated_key_seed, TRNG_BYTE_LENGTH); + unpack_pk(&pk_nie, pk); + PQCLEAN_LEDAKEMLT52_CLEAN_seedexpander_from_trng(&niederreiter_encap_key_expander, encapsulated_key_seed); PQCLEAN_LEDAKEMLT52_CLEAN_rand_circulant_blocks_sequence(error_vector, &niederreiter_encap_key_expander); pack_error(error_bytes, error_vector); HASH_FUNCTION(ss, error_bytes, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B)); - PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_encrypt((DIGIT *) ct, (publicKeyNiederreiter_t *) pk, error_vector); + PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_encrypt(syndrome, &pk_nie, error_vector); + + pack_ct(ct, syndrome); return 0; } @@ -47,8 +81,10 @@ int PQCLEAN_LEDAKEMLT52_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned char *s int PQCLEAN_LEDAKEMLT52_CLEAN_crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk) { DIGIT decoded_error_vector[N0 * NUM_DIGITS_GF2X_ELEMENT]; uint8_t decoded_error_bytes[N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B]; + DIGIT syndrome[NUM_DIGITS_GF2X_ELEMENT]; - PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_decrypt(decoded_error_vector, (privateKeyNiederreiter_t *)sk, (DIGIT *)ct); + unpack_ct(syndrome, ct); + PQCLEAN_LEDAKEMLT52_CLEAN_niederreiter_decrypt(decoded_error_vector, (privateKeyNiederreiter_t *)sk, syndrome); pack_error(decoded_error_bytes, decoded_error_vector); HASH_FUNCTION(ss, decoded_error_bytes, (N0 * NUM_DIGITS_GF2X_ELEMENT * DIGIT_SIZE_B));