diff --git a/Optimized_Implementation/neon/CMakeLists.txt b/Optimized_Implementation/neon/CMakeLists.txt index 9c39140..20a843f 100644 --- a/Optimized_Implementation/neon/CMakeLists.txt +++ b/Optimized_Implementation/neon/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.5) project(less_neon) enable_language(C ASM) set(CMAKE_C_STANDARD 99) @@ -28,7 +28,7 @@ if(CMAKE_EXPORT_COMPILE_COMMANDS) endif() set(ALLOWED_WARNINGS "-Wno-type-limits") -set(CMAKE_C_FLAGS_DEBUG "-g -DUSE_NEON -O0 -DDEBUG -march=native -flax-vector-conversions") +set(CMAKE_C_FLAGS_DEBUG "-g -DUSE_NEON -O0 -DDEBUG -Wall -Wextra -Wpedantic -fpermissive -march=native -flax-vector-conversions") set(CMAKE_C_FLAGS_RELEASE "-DUSE_NEON -O3 -DNDEBUG -Wall -Wextra -Wpedantic -fpermissive -march=native -flax-vector-conversions -ftree-vectorize -funroll-loops ${ALLOWED_WARNINGS}") set(SOURCES diff --git a/Optimized_Implementation/neon/include/fq_arith.h b/Optimized_Implementation/neon/include/fq_arith.h index 5dff830..cc47b99 100644 --- a/Optimized_Implementation/neon/include/fq_arith.h +++ b/Optimized_Implementation/neon/include/fq_arith.h @@ -30,6 +30,7 @@ #include "parameters.h" #include "rng.h" +#include "utils.h" // number of needed to represent q = 7 #define NUM_BITS_Q (BITS_TO_REPRESENT(Q)) @@ -137,10 +138,25 @@ static const uint8_t fq_inv_table[128] __attribute__((aligned(64))) = { /// \param x[in]: input value < 127 /// \return x^{-1} mod 127 static inline -FQ_ELEM fq_inv(FQ_ELEM x) { +FQ_ELEM fq_inv_non_ct(FQ_ELEM x) { return fq_inv_table[x]; } /* end fq_inv */ +/// NOTE: constant time +/// NOTE: input must be reduced. +/// \param x[in]: input value < 127 +/// \return x^{-1} mod 127 +static inline +FQ_ELEM fq_inv(const FQ_ELEM x) { + FQ_ELEM ret = 0; + for (uint64_t i = 0; i < 127; i++) { + const FQ_ELEM mask = COMPUTE_CT_MASK(i, x); + const FQ_ELEM val = fq_inv_table[i] & mask; + ret ^= val; + } + return ret; +} + /// Sampling functions from the global TRNG state DEF_RAND(fq_star_rnd_elements, FQ_ELEM, 1, Q-1) DEF_RAND(rand_range_q_elements, FQ_ELEM, 0, Q-1) diff --git a/Optimized_Implementation/neon/lib/codes.c b/Optimized_Implementation/neon/lib/codes.c index 81a93ab..924a9dd 100644 --- a/Optimized_Implementation/neon/lib/codes.c +++ b/Optimized_Implementation/neon/lib/codes.c @@ -55,11 +55,11 @@ void swap_rows(FQ_ELEM r[N_pad], /// else is 0 void generator_get_pivot_flags(const rref_generator_mat_t *const G, uint8_t pivot_flag [N]) { - for (int i = 0; i < N; i = i + 1) { + for (uint32_t i = 0; i < N; i = i + 1) { pivot_flag[i] = 1; } - for (int i = 0; i < K; i = i + 1) { + for (uint32_t i = 0; i < K; i = i + 1) { pivot_flag[G->column_pos[i]] = 0; } } /* end generator_get_pivot_flags */ @@ -97,7 +97,6 @@ void generator_monomial_mul(generator_mat_t *res, /// 1 on success int generator_RREF(generator_mat_t *G, uint8_t is_pivot_column[N_pad]) { - int i, j, pivc; uint8_t tmp, sc; vec256_t *gm[K] __attribute__((aligned(32))); @@ -106,14 +105,14 @@ int generator_RREF(generator_mat_t *G, vec256_t x, t, *rp, *rg; const uint8x16_t c7f = vdupq_n_u8(0x7F); - for (i = 0; i < K; i++) { + for (uint32_t i = 0; i < K; i++) { gm[i] = (vec256_t *) G->values[i]; } - for (i = 0; i < K; i++) { - j = i; + for (uint32_t i = 0; i < K; i++) { + uint32_t j = i; /*start by searching the pivot in the col = row*/ - pivc = i; + uint32_t pivc = i; while (pivc < N) { while (j < K) { @@ -207,7 +206,6 @@ int generator_RREF_pivot_reuse(generator_mat_t *G, uint8_t was_pivot_column[N], const int pvt_reuse_limit) { const uint8x16_t q = vdupq_n_u8(127); - int i, j, pivc; uint8_t sc; int pvt_reuse_cnt = 0; @@ -227,10 +225,10 @@ int generator_RREF_pivot_reuse(generator_mat_t *G, } } - for (i = 0; i < K; i++) { - j = i; + for (uint32_t i = 0; i < K; i++) { + uint32_t j = i; /*start by searching the pivot in the col = row*/ - pivc = i; + uint32_t pivc = i; while (pivc < N) { while (j < K) { @@ -409,8 +407,8 @@ void compress_rref(uint8_t *compressed, const generator_mat_t *const full, } } } - } /* end compress_rref */ -} + } +}/* end compress_rref */ /// Expands a compressed RREF generator matrix into a full one /// \param full[out]: output full matrix (K \times N) @@ -421,11 +419,11 @@ void expand_to_rref(generator_mat_t *full, const uint8_t *compressed, uint8_t is_pivot_column[N]) { // Decompress pivot flags - for (int i = 0; i < N; i++) { + for (uint32_t i = 0; i < N; i++) { is_pivot_column[i] = 0; } - for (int col_byte = 0; col_byte < N / 8; col_byte++) { + for (uint32_t col_byte = 0; col_byte < N / 8; col_byte++) { is_pivot_column[col_byte * 8 + 0] = compressed[col_byte] & 0x1; is_pivot_column[col_byte * 8 + 1] = (compressed[col_byte] >> 1) & 0x1; is_pivot_column[col_byte * 8 + 2] = (compressed[col_byte] >> 2) & 0x1; @@ -652,3 +650,32 @@ void normalized_monomial_right(normalized_IS_t *res, } } } /* end normalized_monomial_right */ + +/// \param A[out]: pointer to allocated normalized struct, which get filled with the +/// non-IS of the generator matrix G +/// \param G[in]: generator matrix to extract the non-IS from. +/// \param is_pivot_column[in]: array identifying a pivot column via a 1 +void normalized_copy_from_generator_non_information_set(normalized_IS_t *A , + const generator_mat_t *const G, + const uint8_t *const is_pivot_column) { + // we simply copy the last N-K columns even if they are not the information set. + for (uint64_t i = 0; i < K; i++) { + memcpy((uint8_t *)A->values[i], ((uint8_t *)G->values[i]) + K, K); + } + + // now we scan if we need to fix the non information set + uint32_t ctr = 0; + for (; ctr < K && is_pivot_column[ctr] == 1; ctr++) {} + + // easy part: the last N-K columns are the non IS + if (ctr == K) { return; } + + // "hard" part: copy all remaining columns < K into the non information set part + for(uint32_t j = 0; j < N-K && is_pivot_column[ctr] == 0; j++) { + /// copy column + for (uint32_t k = 0; k < K; k++) { + A->values[k][j] = G->values[k][ctr]; + } + ctr += 1; + } +} diff --git a/Reference_Implementation/lib/monomial.c b/Reference_Implementation/lib/monomial.c index 20c7446..fa26ea2 100644 --- a/Reference_Implementation/lib/monomial.c +++ b/Reference_Implementation/lib/monomial.c @@ -106,7 +106,7 @@ void monomial_sample_salt(monomial_t *res, const uint16_t round_index) { SHAKE_STATE_STRUCT shake_monomial_state = {0}; const int shake_buffer_len = SEED_LENGTH_BYTES + HASH_DIGEST_LENGTH + sizeof(uint16_t); - uint8_t shake_input_buffer[shake_buffer_len]; + uint8_t shake_input_buffer[SEED_LENGTH_BYTES + HASH_DIGEST_LENGTH + sizeof(uint16_t)]; memcpy(shake_input_buffer, seed, SEED_LENGTH_BYTES); memcpy(shake_input_buffer + SEED_LENGTH_BYTES, salt, HASH_DIGEST_LENGTH); memcpy(shake_input_buffer + SEED_LENGTH_BYTES + HASH_DIGEST_LENGTH, &round_index, sizeof(uint16_t)); diff --git a/Reference_Implementation/lib/seedtree.c b/Reference_Implementation/lib/seedtree.c index e4483fd..97399f2 100644 --- a/Reference_Implementation/lib/seedtree.c +++ b/Reference_Implementation/lib/seedtree.c @@ -60,9 +60,8 @@ void BuildGGM(unsigned char seed_tree[NUM_NODES_SEED_TREE * SEED_LENGTH_BYTES], const unsigned char salt[HASH_DIGEST_LENGTH]) { /* input buffer to the CSPRNG, contains the seed to be expanded, a salt, * and the integer index of the node being expanded for domain separation */ - const uint32_t csprng_input_len = SALT_LENGTH_BYTES + - SEED_LENGTH_BYTES; - unsigned char csprng_input[csprng_input_len]; + const uint32_t csprng_input_len = SALT_LENGTH_BYTES + SEED_LENGTH_BYTES; + unsigned char csprng_input[SALT_LENGTH_BYTES + SEED_LENGTH_BYTES]; SHAKE_STATE_STRUCT tree_csprng_state; memcpy(csprng_input+SEED_LENGTH_BYTES, salt, SALT_LENGTH_BYTES); @@ -236,9 +235,8 @@ uint32_t RebuildGGM(unsigned char seed_tree[NUM_NODES_SEED_TREE*SEED_LENGTH_BYTE unsigned char flags_tree_to_publish[NUM_NODES_SEED_TREE] = {0}; compute_seeds_to_publish(flags_tree_to_publish, indices_to_publish); - const uint32_t csprng_input_len = SALT_LENGTH_BYTES + - SEED_LENGTH_BYTES; - unsigned char csprng_input[csprng_input_len]; + const uint32_t csprng_input_len = SALT_LENGTH_BYTES + SEED_LENGTH_BYTES; + unsigned char csprng_input[SALT_LENGTH_BYTES + SEED_LENGTH_BYTES]; SHAKE_STATE_STRUCT tree_csprng_state; const uint16_t off[LOG2(T)+1] = TREE_OFFSETS; diff --git a/Reference_Implementation/lib/transpose.c b/Reference_Implementation/lib/transpose.c index bb05e1b..f7be8ca 100644 --- a/Reference_Implementation/lib/transpose.c +++ b/Reference_Implementation/lib/transpose.c @@ -256,4 +256,4 @@ void matrix_transpose_stride(uint8_t *dst, } } #endif -} \ No newline at end of file +}