Skip to content

Commit

Permalink
imported fix from CROSS upstream: endianness-aware csprng (#1983)
Browse files Browse the repository at this point in the history
* Revert "Disable erroring TravisCI build"

This reverts commit b59d78c.

Signed-off-by: Basil Hess <bhe@zurich.ibm.com>

* disable cross on s390x

Signed-off-by: Basil Hess <bhe@zurich.ibm.com>

* remove status badge

Signed-off-by: Basil Hess <bhe@zurich.ibm.com>

* imported fix from CROSS upstream: endianness-aware csprng

Signed-off-by: rtjk <47841774+rtjk@users.noreply.github.com>

* reenable cross on s390x
Signed-off-by: rtjk <47841774+rtjk@users.noreply.github.com>

* fix more endianness issues, add file creation to copy_from_upstream.py
Signed-off-by: rtjk <47841774+rtjk@users.noreply.github.com>

* revert: add file creation to copy_from_upstream.py
Signed-off-by: rtjk <47841774+rtjk@users.noreply.github.com>

---------

Signed-off-by: Basil Hess <bhe@zurich.ibm.com>
Signed-off-by: rtjk <47841774+rtjk@users.noreply.github.com>
Co-authored-by: Basil Hess <bhe@zurich.ibm.com>
  • Loading branch information
rtjk and bhess authored Nov 11, 2024
1 parent e26d36e commit 1dfb70b
Show file tree
Hide file tree
Showing 87 changed files with 1,865 additions and 425 deletions.
4 changes: 2 additions & 2 deletions docs/algorithms/sig/cross.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
- **Principal submitters**: Marco Baldi, Alessandro Barenghi, Sebastian Bitzer, Patrick Karl, Felice Manganiello, Alessio Pavoni, Gerardo Pelosi, Paolo Santini, Jonas Schupp, Freeman Slaughter, Antonia Wachter-Zeh, Violetta Weger.
- **Auxiliary submitters**: Marco Gianvecchio.
- **Authors' website**: https://www.cross-crypto.com/
- **Specification version**: 1.2 + Keccak_x4 + PQClean fixes.
- **Specification version**: 1.2 + Keccak_x4 + PQClean fixes + endianness fix.
- **Primary Source**<a name="primary-source"></a>:
- **Source**: https://github.com/rtjk/CROSS-PQClean/commit/577d7c761c684637923c8648644cf2f4d7b41954
- **Source**: https://github.com/rtjk/CROSS-PQClean/commit/d3bf2db85ba4a181418c95171d36afdca0d43464
- **Implementation license (SPDX-Identifier)**: CC0-1.0


Expand Down
4 changes: 2 additions & 2 deletions docs/algorithms/sig/cross.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ crypto-assumption: hardness of the restricted syndrome decoding problem for rand
linear codes on a finite field
website: https://www.cross-crypto.com/
nist-round: 1
spec-version: 1.2 + Keccak_x4 + PQClean fixes
spec-version: 1.2 + Keccak_x4 + PQClean fixes + endianness fix
primary-upstream:
source: https://github.com/rtjk/CROSS-PQClean/commit/577d7c761c684637923c8648644cf2f4d7b41954
source: https://github.com/rtjk/CROSS-PQClean/commit/d3bf2db85ba4a181418c95171d36afdca0d43464
spdx-license-identifier: CC0-1.0
parameter-sets:
- name: cross-rsdp-128-balanced
Expand Down
2 changes: 1 addition & 1 deletion scripts/copy_from_upstream/copy_from_upstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ upstreams:
name: upcross
git_url: https://github.com/rtjk/CROSS-PQClean.git
git_branch: master
git_commit: 577d7c761c684637923c8648644cf2f4d7b41954
git_commit: d3bf2db85ba4a181418c95171d36afdca0d43464
sig_meta_path: 'generate/crypto_sign/{pqclean_scheme}/META.yml'
sig_scheme_path: 'generate/crypto_sign/{pqclean_scheme}'
kems:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void PQCLEAN_CROSSRSDP128BALANCED_AVX2_expand_digest_to_fixed_weight(uint8_t fix
memset(fixed_weight_string, 1, W);
memset(fixed_weight_string + W, 0, T - W);

uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
int pos_in_buf = 8;

Expand All @@ -56,7 +56,7 @@ void PQCLEAN_CROSSRSDP128BALANCED_AVX2_expand_digest_to_fixed_weight(uint8_t fix
/* refill randomness buffer if needed */
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down
56 changes: 48 additions & 8 deletions src/sig/cross/upcross_cross-rsdp-128-balanced_avx2/csprng_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,46 @@ FQ_ELEM fq_star_rnd_state(CSPRNG_STATE_T *const csprng_state) {
return rnd_value + 1;
} /* end fq_star_rnd_state */

/********************* Endianness detection and handling **********************/

#define BIG_ENDIAN_SYSTEM 0 // assume little-endian by default

/* Check if we are on a big-endian system:
* the __BYTE_ORDER__ macro is defined by the compiler
* recent versions of GCC and Clang define it
* other methods to detect endianness might be needed when using different compilers */
#if defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#undef BIG_ENDIAN_SYSTEM
#define BIG_ENDIAN_SYSTEM 1
#endif

static inline uint64_t to_little_endian64(uint64_t x) {
/* When compiling on a big-endian system, swap the bytes */
#if BIG_ENDIAN_SYSTEM
return __builtin_bswap64(x);
#else
return x;
#endif
}

static inline uint32_t to_little_endian32(uint32_t x) {
/* When compiling on a big-endian system, swap the bytes */
#if BIG_ENDIAN_SYSTEM
return __builtin_bswap32(x);
#else
return x;
#endif
}

static inline uint16_t to_little_endian16(uint16_t x) {
/* When compiling on a big-endian system, swap the bytes */
#if BIG_ENDIAN_SYSTEM
return __builtin_bswap16(x);
#else
return x;
#endif
}

/***************** Specialized CSPRNGs for non binary domains *****************/

/* CSPRNG sampling fixed weight strings */
Expand Down Expand Up @@ -249,14 +289,14 @@ void CSPRNG_fq_vec(FQ_ELEM res[N],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_FQ_VEC, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;
while (placed < N) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down Expand Up @@ -298,14 +338,14 @@ void CSPRNG_fq_vec_beta(FQ_ELEM res[T],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_FQ_VEC_BETA, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;
while (placed < T) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down Expand Up @@ -345,15 +385,15 @@ void CSPRNG_fq_mat(FQ_ELEM res[K][N - K],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_FQ_MAT, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;

while (placed < K * (N - K)) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down Expand Up @@ -393,14 +433,14 @@ void CSPRNG_zz_vec(FZ_ELEM res[N],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_ZZ_VEC, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;
while (placed < N) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void PQCLEAN_CROSSRSDP128BALANCED_CLEAN_expand_digest_to_fixed_weight(uint8_t fi
memset(fixed_weight_string, 1, W);
memset(fixed_weight_string + W, 0, T - W);

uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
int pos_in_buf = 8;

Expand All @@ -56,7 +56,7 @@ void PQCLEAN_CROSSRSDP128BALANCED_CLEAN_expand_digest_to_fixed_weight(uint8_t fi
/* refill randomness buffer if needed */
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down
56 changes: 48 additions & 8 deletions src/sig/cross/upcross_cross-rsdp-128-balanced_clean/csprng_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,46 @@ FQ_ELEM fq_star_rnd_state(CSPRNG_STATE_T *const csprng_state) {
return rnd_value + 1;
} /* end fq_star_rnd_state */

/********************* Endianness detection and handling **********************/

#define BIG_ENDIAN_SYSTEM 0 // assume little-endian by default

/* Check if we are on a big-endian system:
* the __BYTE_ORDER__ macro is defined by the compiler
* recent versions of GCC and Clang define it
* other methods to detect endianness might be needed when using different compilers */
#if defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#undef BIG_ENDIAN_SYSTEM
#define BIG_ENDIAN_SYSTEM 1
#endif

static inline uint64_t to_little_endian64(uint64_t x) {
/* When compiling on a big-endian system, swap the bytes */
#if BIG_ENDIAN_SYSTEM
return __builtin_bswap64(x);
#else
return x;
#endif
}

static inline uint32_t to_little_endian32(uint32_t x) {
/* When compiling on a big-endian system, swap the bytes */
#if BIG_ENDIAN_SYSTEM
return __builtin_bswap32(x);
#else
return x;
#endif
}

static inline uint16_t to_little_endian16(uint16_t x) {
/* When compiling on a big-endian system, swap the bytes */
#if BIG_ENDIAN_SYSTEM
return __builtin_bswap16(x);
#else
return x;
#endif
}

/***************** Specialized CSPRNGs for non binary domains *****************/

/* CSPRNG sampling fixed weight strings */
Expand Down Expand Up @@ -249,14 +289,14 @@ void CSPRNG_fq_vec(FQ_ELEM res[N],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_FQ_VEC, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;
while (placed < N) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down Expand Up @@ -298,14 +338,14 @@ void CSPRNG_fq_vec_beta(FQ_ELEM res[T],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_FQ_VEC_BETA, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;
while (placed < T) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down Expand Up @@ -345,15 +385,15 @@ void CSPRNG_fq_mat(FQ_ELEM res[K][N - K],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_FQ_MAT, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;

while (placed < K * (N - K)) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down Expand Up @@ -393,14 +433,14 @@ void CSPRNG_zz_vec(FZ_ELEM res[N],
* in from the left end */
csprng_randombytes(CSPRNG_buffer, BUFSIZE_ZZ_VEC, csprng_state);
int placed = 0;
uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
/* position of the next fresh byte in CSPRNG_buffer*/
int pos_in_buf = 8;
while (placed < N) {
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void PQCLEAN_CROSSRSDP128BALANCED_CLEAN_generate_seed_tree_from_root(unsigned ch
memcpy(csprng_input,
seed_tree + father_node_storage_idx * SEED_LENGTH_BYTES,
SEED_LENGTH_BYTES);
*((uint16_t *)(csprng_input + SALT_LENGTH_BYTES + SEED_LENGTH_BYTES)) = father_node_idx;
*((uint16_t *)(csprng_input + SALT_LENGTH_BYTES + SEED_LENGTH_BYTES)) = to_little_endian16(father_node_idx);
/* expand the children (stored contiguously) */
initialize_csprng(&tree_csprng_state, csprng_input, csprng_input_len);
csprng_randombytes(seed_tree + (LEFT_CHILD(father_node_idx) - missing_nodes_before[level + 1] ) *SEED_LENGTH_BYTES,
Expand Down Expand Up @@ -253,7 +253,7 @@ int PQCLEAN_CROSSRSDP128BALANCED_CLEAN_regenerate_round_seeds(unsigned char
memcpy(csprng_input,
seed_tree + (father_node_storage_idx)*SEED_LENGTH_BYTES,
SEED_LENGTH_BYTES);
*((uint16_t *)(csprng_input + SALT_LENGTH_BYTES + SEED_LENGTH_BYTES)) = father_node_idx;
*((uint16_t *)(csprng_input + SALT_LENGTH_BYTES + SEED_LENGTH_BYTES)) = to_little_endian16(father_node_idx);
/* expand the children (stored contiguously) */
initialize_csprng(&tree_csprng_state, csprng_input, csprng_input_len);
csprng_randombytes(seed_tree + (LEFT_CHILD(father_node_idx) - missing_nodes_before[level + 1])*SEED_LENGTH_BYTES,
Expand Down
4 changes: 2 additions & 2 deletions src/sig/cross/upcross_cross-rsdp-128-fast_avx2/csprng_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void PQCLEAN_CROSSRSDP128FAST_AVX2_expand_digest_to_fixed_weight(uint8_t fixed_w
memset(fixed_weight_string, 1, W);
memset(fixed_weight_string + W, 0, T - W);

uint64_t sub_buffer = *(uint64_t *)CSPRNG_buffer;
uint64_t sub_buffer = to_little_endian64(*(uint64_t *)CSPRNG_buffer);
int bits_in_sub_buf = 64;
int pos_in_buf = 8;

Expand All @@ -56,7 +56,7 @@ void PQCLEAN_CROSSRSDP128FAST_AVX2_expand_digest_to_fixed_weight(uint8_t fixed_w
/* refill randomness buffer if needed */
if (bits_in_sub_buf <= 32) {
/* get 32 fresh bits from main buffer with a single load */
uint32_t refresh_buf = *(uint32_t *) (CSPRNG_buffer + pos_in_buf);
uint32_t refresh_buf = to_little_endian32(*(uint32_t *) (CSPRNG_buffer + pos_in_buf));
pos_in_buf += 4;
sub_buffer |= ((uint64_t) refresh_buf) << bits_in_sub_buf;
bits_in_sub_buf += 32;
Expand Down
Loading

0 comments on commit 1dfb70b

Please sign in to comment.