diff --git a/Modules/PQClean/crypto_kem/kyber1024/aarch64/poly.c b/Modules/PQClean/crypto_kem/kyber1024/aarch64/poly.c index 0c26205d..df57a731 100644 --- a/Modules/PQClean/crypto_kem/kyber1024/aarch64/poly.c +++ b/Modules/PQClean/crypto_kem/kyber1024/aarch64/poly.c @@ -39,6 +39,7 @@ #include "reduce.h" #include "cbd.h" #include "symmetric.h" +#include "verify.h" /************************************************* * Name: poly_compress @@ -184,12 +185,11 @@ void poly_frombytes(int16_t r[KYBER_N], const uint8_t a[KYBER_POLYBYTES]) { **************************************************/ void poly_frommsg(int16_t r[KYBER_N], const uint8_t msg[KYBER_INDCPA_MSGBYTES]) { unsigned int i, j; - int16_t mask; for (i = 0; i < KYBER_N / 8; i++) { for (j = 0; j < 8; j++) { - mask = -(int16_t)((msg[i] >> j) & 1); - r[8 * i + j] = mask & ((KYBER_Q + 1) / 2); + r->coeffs[8*i+j] = 0; + cmov_int16(r->coeffs+8*i+j, ((KYBER_Q+1)/2), (msg[i] >> j)&1); } } } diff --git a/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.c b/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.c index ca304086..c4449111 100644 --- a/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.c +++ b/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.c @@ -52,3 +52,20 @@ void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) { r[i] ^= b & (r[i] ^ x[i]); } } + +/************************************************* +* Name: cmov_int16 +* +* Description: Copy 16 bits from v to r if b is 1; +* don't modify v if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: uint16_t *r: pointer to output byte array +* uint16_t v: pointer to input byte array +* uint16_t b: Condition bit; has to be in {0,1} +**************************************************/ +void cmov_int16(int16_t *r, int16_t v, uint16_t b) { + b = -b; + *r ^= b & ((*r) ^ v); +} diff --git a/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.h b/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.h index 4819e0db..2f5aee76 100644 --- a/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.h +++ b/Modules/PQClean/crypto_kem/kyber1024/aarch64/verify.h @@ -17,4 +17,7 @@ int verify(const uint8_t *a, const uint8_t *b, size_t len); #define cmov KYBER_NAMESPACE(cmov) void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); +#define cmov_int16 KYBER_NAMESPACE(cmov_int16) +void cmov_int16(int16_t *r, int16_t v, uint16_t b); + #endif diff --git a/Modules/PQClean/crypto_kem/kyber1024/clean/poly.c b/Modules/PQClean/crypto_kem/kyber1024/clean/poly.c index a4a8877e..67fb8d17 100644 --- a/Modules/PQClean/crypto_kem/kyber1024/clean/poly.c +++ b/Modules/PQClean/crypto_kem/kyber1024/clean/poly.c @@ -4,6 +4,7 @@ #include "poly.h" #include "reduce.h" #include "symmetric.h" +#include "verify.h" #include /************************************************* @@ -128,12 +129,11 @@ void PQCLEAN_KYBER1024_CLEAN_poly_frombytes(poly *r, const uint8_t a[KYBER_POLYB **************************************************/ void PQCLEAN_KYBER1024_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]) { size_t i, j; - int16_t mask; for (i = 0; i < KYBER_N / 8; i++) { for (j = 0; j < 8; j++) { - mask = -(int16_t)((msg[i] >> j) & 1); - r->coeffs[8 * i + j] = mask & ((KYBER_Q + 1) / 2); + r->coeffs[8*i+j] = 0; + cmov_int16(r->coeffs+8*i+j, ((KYBER_Q+1)/2), (msg[i] >> j)&1); } } } diff --git a/Modules/PQClean/crypto_kem/kyber1024/clean/verify.c b/Modules/PQClean/crypto_kem/kyber1024/clean/verify.c index 1c99d185..db85ed4d 100644 --- a/Modules/PQClean/crypto_kem/kyber1024/clean/verify.c +++ b/Modules/PQClean/crypto_kem/kyber1024/clean/verify.c @@ -45,3 +45,20 @@ void PQCLEAN_KYBER1024_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint r[i] ^= b & (r[i] ^ x[i]); } } + +/************************************************* +* Name: PQCLEAN_KYBER1024_CLEAN_cmov_int16 +* +* Description: Copy 16 bits from v to r if b is 1; +* don't modify v if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: uint16_t *r: pointer to output byte array +* uint16_t v: pointer to input byte array +* uint16_t b: Condition bit; has to be in {0,1} +**************************************************/ +void PQCLEAN_KYBER1024_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b) { + b = -b; + *r ^= b & ((*r) ^ v); +} diff --git a/Modules/PQClean/crypto_kem/kyber1024/clean/verify.h b/Modules/PQClean/crypto_kem/kyber1024/clean/verify.h index c8b24b08..3f366a10 100644 --- a/Modules/PQClean/crypto_kem/kyber1024/clean/verify.h +++ b/Modules/PQClean/crypto_kem/kyber1024/clean/verify.h @@ -8,4 +8,5 @@ int PQCLEAN_KYBER1024_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t le void PQCLEAN_KYBER1024_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); +void PQCLEAN_KYBER1024_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b); #endif diff --git a/Modules/PQClean/crypto_kem/kyber512/aarch64/poly.c b/Modules/PQClean/crypto_kem/kyber512/aarch64/poly.c index 3cb9ecc4..a0e4b3f9 100644 --- a/Modules/PQClean/crypto_kem/kyber512/aarch64/poly.c +++ b/Modules/PQClean/crypto_kem/kyber512/aarch64/poly.c @@ -39,6 +39,7 @@ #include "reduce.h" #include "cbd.h" #include "symmetric.h" +#include "verify.h" /************************************************* * Name: poly_compress @@ -171,12 +172,11 @@ void poly_frombytes(int16_t r[KYBER_N], const uint8_t a[KYBER_POLYBYTES]) { **************************************************/ void poly_frommsg(int16_t r[KYBER_N], const uint8_t msg[KYBER_INDCPA_MSGBYTES]) { unsigned int i, j; - int16_t mask; for (i = 0; i < KYBER_N / 8; i++) { for (j = 0; j < 8; j++) { - mask = -(int16_t)((msg[i] >> j) & 1); - r[8 * i + j] = mask & ((KYBER_Q + 1) / 2); + r->coeffs[8*i+j] = 0; + cmov_int16(r->coeffs+8*i+j, ((KYBER_Q+1)/2), (msg[i] >> j)&1); } } } diff --git a/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.c b/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.c index ca304086..c4449111 100644 --- a/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.c +++ b/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.c @@ -52,3 +52,20 @@ void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) { r[i] ^= b & (r[i] ^ x[i]); } } + +/************************************************* +* Name: cmov_int16 +* +* Description: Copy 16 bits from v to r if b is 1; +* don't modify v if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: uint16_t *r: pointer to output byte array +* uint16_t v: pointer to input byte array +* uint16_t b: Condition bit; has to be in {0,1} +**************************************************/ +void cmov_int16(int16_t *r, int16_t v, uint16_t b) { + b = -b; + *r ^= b & ((*r) ^ v); +} diff --git a/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.h b/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.h index 81b6525d..130e39b5 100644 --- a/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.h +++ b/Modules/PQClean/crypto_kem/kyber512/aarch64/verify.h @@ -17,4 +17,6 @@ int verify(const uint8_t *a, const uint8_t *b, size_t len); #define cmov KYBER_NAMESPACE(cmov) void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); +#define cmov_int16 KYBER_NAMESPACE(cmov_int16) +void cmov_int16(int16_t *r, int16_t v, uint16_t b); #endif diff --git a/Modules/PQClean/crypto_kem/kyber512/clean/poly.c b/Modules/PQClean/crypto_kem/kyber512/clean/poly.c index 0a52ac87..cc79cea9 100644 --- a/Modules/PQClean/crypto_kem/kyber512/clean/poly.c +++ b/Modules/PQClean/crypto_kem/kyber512/clean/poly.c @@ -4,6 +4,7 @@ #include "poly.h" #include "reduce.h" #include "symmetric.h" +#include "verify.h" #include /************************************************* @@ -115,12 +116,11 @@ void PQCLEAN_KYBER512_CLEAN_poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBY **************************************************/ void PQCLEAN_KYBER512_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]) { size_t i, j; - int16_t mask; for (i = 0; i < KYBER_N / 8; i++) { for (j = 0; j < 8; j++) { - mask = -(int16_t)((msg[i] >> j) & 1); - r->coeffs[8 * i + j] = mask & ((KYBER_Q + 1) / 2); + r->coeffs[8*i+j] = 0; + cmov_int16(r->coeffs+8*i+j, ((KYBER_Q+1)/2), (msg[i] >> j)&1); } } } diff --git a/Modules/PQClean/crypto_kem/kyber512/clean/verify.c b/Modules/PQClean/crypto_kem/kyber512/clean/verify.c index 772293f0..26750c60 100644 --- a/Modules/PQClean/crypto_kem/kyber512/clean/verify.c +++ b/Modules/PQClean/crypto_kem/kyber512/clean/verify.c @@ -45,3 +45,20 @@ void PQCLEAN_KYBER512_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8 r[i] ^= b & (r[i] ^ x[i]); } } + +/************************************************* +* Name: PQCLEAN_KYBER512_CLEAN_cmov_int16 +* +* Description: Copy 16 bits from v to r if b is 1; +* don't modify v if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: uint16_t *r: pointer to output byte array +* uint16_t v: pointer to input byte array +* uint16_t b: Condition bit; has to be in {0,1} +**************************************************/ +void PQCLEAN_KYBER512_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b) { + b = -b; + *r ^= b & ((*r) ^ v); +} diff --git a/Modules/PQClean/crypto_kem/kyber512/clean/verify.h b/Modules/PQClean/crypto_kem/kyber512/clean/verify.h index 47c5579a..c23aafce 100644 --- a/Modules/PQClean/crypto_kem/kyber512/clean/verify.h +++ b/Modules/PQClean/crypto_kem/kyber512/clean/verify.h @@ -8,4 +8,5 @@ int PQCLEAN_KYBER512_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len void PQCLEAN_KYBER512_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); +void PQCLEAN_KYBER512_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b); #endif diff --git a/Modules/PQClean/crypto_kem/kyber768/aarch64/poly.c b/Modules/PQClean/crypto_kem/kyber768/aarch64/poly.c index 3cb9ecc4..a0e4b3f9 100644 --- a/Modules/PQClean/crypto_kem/kyber768/aarch64/poly.c +++ b/Modules/PQClean/crypto_kem/kyber768/aarch64/poly.c @@ -39,6 +39,7 @@ #include "reduce.h" #include "cbd.h" #include "symmetric.h" +#include "verify.h" /************************************************* * Name: poly_compress @@ -171,12 +172,11 @@ void poly_frombytes(int16_t r[KYBER_N], const uint8_t a[KYBER_POLYBYTES]) { **************************************************/ void poly_frommsg(int16_t r[KYBER_N], const uint8_t msg[KYBER_INDCPA_MSGBYTES]) { unsigned int i, j; - int16_t mask; for (i = 0; i < KYBER_N / 8; i++) { for (j = 0; j < 8; j++) { - mask = -(int16_t)((msg[i] >> j) & 1); - r[8 * i + j] = mask & ((KYBER_Q + 1) / 2); + r->coeffs[8*i+j] = 0; + cmov_int16(r->coeffs+8*i+j, ((KYBER_Q+1)/2), (msg[i] >> j)&1); } } } diff --git a/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.c b/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.c index ca304086..c4449111 100644 --- a/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.c +++ b/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.c @@ -52,3 +52,20 @@ void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b) { r[i] ^= b & (r[i] ^ x[i]); } } + +/************************************************* +* Name: cmov_int16 +* +* Description: Copy 16 bits from v to r if b is 1; +* don't modify v if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: uint16_t *r: pointer to output byte array +* uint16_t v: pointer to input byte array +* uint16_t b: Condition bit; has to be in {0,1} +**************************************************/ +void cmov_int16(int16_t *r, int16_t v, uint16_t b) { + b = -b; + *r ^= b & ((*r) ^ v); +} diff --git a/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.h b/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.h index a52767b3..87fa3603 100644 --- a/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.h +++ b/Modules/PQClean/crypto_kem/kyber768/aarch64/verify.h @@ -17,4 +17,6 @@ int verify(const uint8_t *a, const uint8_t *b, size_t len); #define cmov KYBER_NAMESPACE(cmov) void cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); +#define cmov_int16 KYBER_NAMESPACE(cmov_int16) +void cmov_int16(int16_t *r, int16_t v, uint16_t b) #endif diff --git a/Modules/PQClean/crypto_kem/kyber768/clean/poly.c b/Modules/PQClean/crypto_kem/kyber768/clean/poly.c index 45f89ae4..cc9f6032 100644 --- a/Modules/PQClean/crypto_kem/kyber768/clean/poly.c +++ b/Modules/PQClean/crypto_kem/kyber768/clean/poly.c @@ -4,6 +4,7 @@ #include "poly.h" #include "reduce.h" #include "symmetric.h" +#include "verify.h" #include /************************************************* @@ -115,12 +116,11 @@ void PQCLEAN_KYBER768_CLEAN_poly_frombytes(poly *r, const uint8_t a[KYBER_POLYBY **************************************************/ void PQCLEAN_KYBER768_CLEAN_poly_frommsg(poly *r, const uint8_t msg[KYBER_INDCPA_MSGBYTES]) { size_t i, j; - int16_t mask; for (i = 0; i < KYBER_N / 8; i++) { for (j = 0; j < 8; j++) { - mask = -(int16_t)((msg[i] >> j) & 1); - r->coeffs[8 * i + j] = mask & ((KYBER_Q + 1) / 2); + r->coeffs[8*i+j] = 0; + cmov_int16(r->coeffs+8*i+j, ((KYBER_Q+1)/2), (msg[i] >> j)&1); } } } diff --git a/Modules/PQClean/crypto_kem/kyber768/clean/verify.c b/Modules/PQClean/crypto_kem/kyber768/clean/verify.c index 426c3fae..03b71566 100644 --- a/Modules/PQClean/crypto_kem/kyber768/clean/verify.c +++ b/Modules/PQClean/crypto_kem/kyber768/clean/verify.c @@ -45,3 +45,20 @@ void PQCLEAN_KYBER768_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8 r[i] ^= b & (r[i] ^ x[i]); } } + +/************************************************* +* Name: PQCLEAN_KYBER768_CLEAN_cmov_int16 +* +* Description: Copy 16 bits from v to r if b is 1; +* don't modify v if b is 0. Requires b to be in {0,1}; +* assumes two's complement representation of negative integers. +* Runs in constant time. +* +* Arguments: uint16_t *r: pointer to output byte array +* uint16_t v: pointer to input byte array +* uint16_t b: Condition bit; has to be in {0,1} +**************************************************/ +void PQCLEAN_KYBER768_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b) { + b = -b; + *r ^= b & ((*r) ^ v); +} diff --git a/Modules/PQClean/crypto_kem/kyber768/clean/verify.h b/Modules/PQClean/crypto_kem/kyber768/clean/verify.h index 6361d8e4..e0f42e2b 100644 --- a/Modules/PQClean/crypto_kem/kyber768/clean/verify.h +++ b/Modules/PQClean/crypto_kem/kyber768/clean/verify.h @@ -8,4 +8,5 @@ int PQCLEAN_KYBER768_CLEAN_verify(const uint8_t *a, const uint8_t *b, size_t len void PQCLEAN_KYBER768_CLEAN_cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b); +void PQCLEAN_KYBER768_CLEAN_cmov_int16(int16_t *r, int16_t v, uint16_t b); #endif