Skip to content

Commit

Permalink
imported fix from CROSS upstream: endianness-aware csprng
Browse files Browse the repository at this point in the history
  • Loading branch information
rtjk committed Nov 8, 2024
1 parent 8bf124f commit 0b43d63
Show file tree
Hide file tree
Showing 39 changed files with 1,445 additions and 329 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/82938638cb6bcb680d9472e544a61be38db806cc
- **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/82938638cb6bcb680d9472e544a61be38db806cc
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: 82938638cb6bcb680d9472e544a61be38db806cc
sig_meta_path: 'generate/crypto_sign/{pqclean_scheme}/META.yml'
sig_scheme_path: 'generate/crypto_sign/{pqclean_scheme}'
kems:
Expand Down
47 changes: 39 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,37 @@ 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
}

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

/* CSPRNG sampling fixed weight strings */
Expand Down Expand Up @@ -249,14 +280,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 +329,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 +376,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 +424,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
47 changes: 39 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,37 @@ 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
}

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

/* CSPRNG sampling fixed weight strings */
Expand Down Expand Up @@ -249,14 +280,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 +329,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 +376,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 +424,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
47 changes: 39 additions & 8 deletions src/sig/cross/upcross_cross-rsdp-128-fast_avx2/csprng_hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,37 @@ 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
}

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

/* CSPRNG sampling fixed weight strings */
Expand Down Expand Up @@ -249,14 +280,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 +329,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 +376,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 +424,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
Loading

0 comments on commit 0b43d63

Please sign in to comment.