From 0f148a6991e8ef7cee45e784c3a20330ae5dec0f Mon Sep 17 00:00:00 2001 From: "John M. Schanck" Date: Mon, 5 Oct 2020 14:09:11 -0400 Subject: [PATCH] ntru: packaging script update. resolves #331 --- crypto_kem/ntruhps2048509/META.yml | 4 ++-- crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.c | 4 ++-- crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.h | 3 ++- crypto_kem/ntruhps2048509/avx2/kem.c | 7 +------ crypto_kem/ntruhps2048509/avx2/owcpa.c | 8 ++++++-- crypto_kem/ntruhps2048509/avx2/sample.c | 1 - crypto_kem/ntruhps2048509/avx2/sample.h | 2 ++ crypto_kem/ntruhps2048509/clean/kem.c | 7 +------ crypto_kem/ntruhps2048509/clean/owcpa.c | 8 ++++++-- crypto_kem/ntruhps2048509/clean/poly_r2_inv.c | 8 ++++---- crypto_kem/ntruhps2048509/clean/poly_s3_inv.c | 8 ++++---- crypto_kem/ntruhps2048509/clean/sample.c | 1 - crypto_kem/ntruhps2048509/clean/sample.h | 2 ++ crypto_kem/ntruhps2048677/META.yml | 4 ++-- crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.c | 4 ++-- crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.h | 3 ++- crypto_kem/ntruhps2048677/avx2/kem.c | 7 +------ crypto_kem/ntruhps2048677/avx2/owcpa.c | 8 ++++++-- crypto_kem/ntruhps2048677/avx2/sample.c | 1 - crypto_kem/ntruhps2048677/avx2/sample.h | 2 ++ crypto_kem/ntruhps2048677/clean/kem.c | 7 +------ crypto_kem/ntruhps2048677/clean/owcpa.c | 8 ++++++-- crypto_kem/ntruhps2048677/clean/poly_r2_inv.c | 8 ++++---- crypto_kem/ntruhps2048677/clean/poly_s3_inv.c | 8 ++++---- crypto_kem/ntruhps2048677/clean/sample.c | 1 - crypto_kem/ntruhps2048677/clean/sample.h | 2 ++ crypto_kem/ntruhps4096821/META.yml | 4 ++-- crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.c | 4 ++-- crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.h | 3 ++- crypto_kem/ntruhps4096821/avx2/kem.c | 7 +------ crypto_kem/ntruhps4096821/avx2/owcpa.c | 8 ++++++-- crypto_kem/ntruhps4096821/avx2/sample.c | 1 - crypto_kem/ntruhps4096821/avx2/sample.h | 2 ++ crypto_kem/ntruhps4096821/clean/kem.c | 7 +------ crypto_kem/ntruhps4096821/clean/owcpa.c | 8 ++++++-- crypto_kem/ntruhps4096821/clean/poly_r2_inv.c | 8 ++++---- crypto_kem/ntruhps4096821/clean/poly_s3_inv.c | 8 ++++---- crypto_kem/ntruhps4096821/clean/sample.c | 1 - crypto_kem/ntruhps4096821/clean/sample.h | 2 ++ crypto_kem/ntruhrss701/META.yml | 4 ++-- crypto_kem/ntruhrss701/avx2/kem.c | 7 +------ crypto_kem/ntruhrss701/avx2/owcpa.c | 8 ++++++-- crypto_kem/ntruhrss701/avx2/sample.h | 1 + crypto_kem/ntruhrss701/clean/kem.c | 7 +------ crypto_kem/ntruhrss701/clean/owcpa.c | 8 ++++++-- crypto_kem/ntruhrss701/clean/poly_r2_inv.c | 8 ++++---- crypto_kem/ntruhrss701/clean/poly_s3_inv.c | 8 ++++---- crypto_kem/ntruhrss701/clean/sample.h | 1 + 48 files changed, 122 insertions(+), 119 deletions(-) diff --git a/crypto_kem/ntruhps2048509/META.yml b/crypto_kem/ntruhps2048509/META.yml index 23c00e17..e04dcd86 100644 --- a/crypto_kem/ntruhps2048509/META.yml +++ b/crypto_kem/ntruhps2048509/META.yml @@ -23,9 +23,9 @@ auxiliary-submitters: - Zhenfei Zhang implementations: - name: clean - version: https://github.com/jschanck/ntru/tree/ff3c84e1 reference implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 reference implementation - name: avx2 - version: https://github.com/jschanck/ntru/tree/ff3c84e1 avx2 implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 avx2 implementation supported_platforms: - architecture: x86_64 operating_systems: diff --git a/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.c b/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.c index cef509b6..44fa15bf 100644 --- a/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.c +++ b/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.c @@ -1,8 +1,8 @@ -#include "crypto_sort_int32.h" -#include // Based on supercop-20200820/crypto_sort/int32/avx2 +#include "crypto_sort_int32.h" +#include #define int32 int32_t typedef __m256i int32x8; diff --git a/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.h b/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.h index fdc31858..5a121e16 100644 --- a/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.h +++ b/crypto_kem/ntruhps2048509/avx2/crypto_sort_int32.h @@ -1,10 +1,11 @@ #ifndef CRYPTO_SORT #define CRYPTO_SORT + #include "params.h" + #include #include - void PQCLEAN_NTRUHPS2048509_AVX2_crypto_sort_int32(int32_t *x, size_t n); #endif diff --git a/crypto_kem/ntruhps2048509/avx2/kem.c b/crypto_kem/ntruhps2048509/avx2/kem.c index 035ba0f3..eccc0c1c 100644 --- a/crypto_kem/ntruhps2048509/avx2/kem.c +++ b/crypto_kem/ntruhps2048509/avx2/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHPS2048509_AVX2_crypto_kem_dec(uint8_t *k, const uint8_t *c, con uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHPS2048509_AVX2_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHPS2048509_AVX2_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHPS2048509_AVX2_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhps2048509/avx2/owcpa.c b/crypto_kem/ntruhps2048509/avx2/owcpa.c index cad75af6..ca793e59 100644 --- a/crypto_kem/ntruhps2048509/avx2/owcpa.c +++ b/crypto_kem/ntruhps2048509/avx2/owcpa.c @@ -123,11 +123,15 @@ int PQCLEAN_NTRUHPS2048509_AVX2_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHPS2048509_AVX2_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHPS2048509_AVX2_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; fail |= owcpa_check_m(m); /* b = c - Lift(m) mod (q, x^n - 1) */ diff --git a/crypto_kem/ntruhps2048509/avx2/sample.c b/crypto_kem/ntruhps2048509/avx2/sample.c index 70c24b8b..b5802670 100644 --- a/crypto_kem/ntruhps2048509/avx2/sample.c +++ b/crypto_kem/ntruhps2048509/avx2/sample.c @@ -1,4 +1,3 @@ -#include "crypto_sort_int32.h" #include "sample.h" void PQCLEAN_NTRUHPS2048509_AVX2_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]) { diff --git a/crypto_kem/ntruhps2048509/avx2/sample.h b/crypto_kem/ntruhps2048509/avx2/sample.h index 0ff71465..5c29211e 100644 --- a/crypto_kem/ntruhps2048509/avx2/sample.h +++ b/crypto_kem/ntruhps2048509/avx2/sample.h @@ -4,6 +4,8 @@ #include "params.h" #include "poly.h" +#include "crypto_sort_int32.h" + void PQCLEAN_NTRUHPS2048509_AVX2_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHPS2048509_AVX2_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]); diff --git a/crypto_kem/ntruhps2048509/clean/kem.c b/crypto_kem/ntruhps2048509/clean/kem.c index 3b2f41b9..00831572 100644 --- a/crypto_kem/ntruhps2048509/clean/kem.c +++ b/crypto_kem/ntruhps2048509/clean/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHPS2048509_CLEAN_crypto_kem_dec(uint8_t *k, const uint8_t *c, co uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHPS2048509_CLEAN_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHPS2048509_CLEAN_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHPS2048509_CLEAN_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhps2048509/clean/owcpa.c b/crypto_kem/ntruhps2048509/clean/owcpa.c index 1a187bf6..8bd2ed20 100644 --- a/crypto_kem/ntruhps2048509/clean/owcpa.c +++ b/crypto_kem/ntruhps2048509/clean/owcpa.c @@ -123,11 +123,15 @@ int PQCLEAN_NTRUHPS2048509_CLEAN_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHPS2048509_CLEAN_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHPS2048509_CLEAN_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; fail |= owcpa_check_m(m); /* b = c - Lift(m) mod (q, x^n - 1) */ diff --git a/crypto_kem/ntruhps2048509/clean/poly_r2_inv.c b/crypto_kem/ntruhps2048509/clean/poly_r2_inv.c index 030d6621..bfcb974c 100644 --- a/crypto_kem/ntruhps2048509/clean/poly_r2_inv.c +++ b/crypto_kem/ntruhps2048509/clean/poly_r2_inv.c @@ -3,14 +3,14 @@ #include "poly.h" /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHPS2048509_CLEAN_poly_R2_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -37,7 +37,7 @@ void PQCLEAN_NTRUHPS2048509_CLEAN_poly_R2_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = g.coeffs[0] & f.coeffs[0]; - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhps2048509/clean/poly_s3_inv.c b/crypto_kem/ntruhps2048509/clean/poly_s3_inv.c index 67047f5c..32cd39ca 100644 --- a/crypto_kem/ntruhps2048509/clean/poly_s3_inv.c +++ b/crypto_kem/ntruhps2048509/clean/poly_s3_inv.c @@ -11,14 +11,14 @@ static inline uint8_t mod3(uint8_t a) { /* a between 0 and 9 */ } /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHPS2048509_CLEAN_poly_S3_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -45,7 +45,7 @@ void PQCLEAN_NTRUHPS2048509_CLEAN_poly_S3_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = mod3((uint8_t) (2 * g.coeffs[0] * f.coeffs[0])); - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhps2048509/clean/sample.c b/crypto_kem/ntruhps2048509/clean/sample.c index 5f3052c7..2b22beb7 100644 --- a/crypto_kem/ntruhps2048509/clean/sample.c +++ b/crypto_kem/ntruhps2048509/clean/sample.c @@ -1,4 +1,3 @@ -#include "crypto_sort_int32.h" #include "sample.h" void PQCLEAN_NTRUHPS2048509_CLEAN_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]) { diff --git a/crypto_kem/ntruhps2048509/clean/sample.h b/crypto_kem/ntruhps2048509/clean/sample.h index ba7609e6..802b8300 100644 --- a/crypto_kem/ntruhps2048509/clean/sample.h +++ b/crypto_kem/ntruhps2048509/clean/sample.h @@ -4,6 +4,8 @@ #include "params.h" #include "poly.h" +#include "crypto_sort_int32.h" + void PQCLEAN_NTRUHPS2048509_CLEAN_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHPS2048509_CLEAN_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]); diff --git a/crypto_kem/ntruhps2048677/META.yml b/crypto_kem/ntruhps2048677/META.yml index 539f7d0f..90e464c5 100644 --- a/crypto_kem/ntruhps2048677/META.yml +++ b/crypto_kem/ntruhps2048677/META.yml @@ -23,9 +23,9 @@ auxiliary-submitters: - Zhenfei Zhang implementations: - name: clean - version: https://github.com/jschanck/ntru/tree/ff3c84e1 reference implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 reference implementation - name: avx2 - version: https://github.com/jschanck/ntru/tree/ff3c84e1 avx2 implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 avx2 implementation supported_platforms: - architecture: x86_64 operating_systems: diff --git a/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.c b/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.c index 874b4cd7..db24137a 100644 --- a/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.c +++ b/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.c @@ -1,8 +1,8 @@ -#include "crypto_sort_int32.h" -#include // Based on supercop-20200820/crypto_sort/int32/avx2 +#include "crypto_sort_int32.h" +#include #define int32 int32_t typedef __m256i int32x8; diff --git a/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.h b/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.h index 84d40c07..12f221b0 100644 --- a/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.h +++ b/crypto_kem/ntruhps2048677/avx2/crypto_sort_int32.h @@ -1,10 +1,11 @@ #ifndef CRYPTO_SORT #define CRYPTO_SORT + #include "params.h" + #include #include - void PQCLEAN_NTRUHPS2048677_AVX2_crypto_sort_int32(int32_t *x, size_t n); #endif diff --git a/crypto_kem/ntruhps2048677/avx2/kem.c b/crypto_kem/ntruhps2048677/avx2/kem.c index 067490b4..d42da6e3 100644 --- a/crypto_kem/ntruhps2048677/avx2/kem.c +++ b/crypto_kem/ntruhps2048677/avx2/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHPS2048677_AVX2_crypto_kem_dec(uint8_t *k, const uint8_t *c, con uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHPS2048677_AVX2_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHPS2048677_AVX2_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHPS2048677_AVX2_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhps2048677/avx2/owcpa.c b/crypto_kem/ntruhps2048677/avx2/owcpa.c index a8e80311..374b6836 100644 --- a/crypto_kem/ntruhps2048677/avx2/owcpa.c +++ b/crypto_kem/ntruhps2048677/avx2/owcpa.c @@ -123,11 +123,15 @@ int PQCLEAN_NTRUHPS2048677_AVX2_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHPS2048677_AVX2_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHPS2048677_AVX2_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; fail |= owcpa_check_m(m); /* b = c - Lift(m) mod (q, x^n - 1) */ diff --git a/crypto_kem/ntruhps2048677/avx2/sample.c b/crypto_kem/ntruhps2048677/avx2/sample.c index 1ce7cb7e..994c8eac 100644 --- a/crypto_kem/ntruhps2048677/avx2/sample.c +++ b/crypto_kem/ntruhps2048677/avx2/sample.c @@ -1,4 +1,3 @@ -#include "crypto_sort_int32.h" #include "sample.h" void PQCLEAN_NTRUHPS2048677_AVX2_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]) { diff --git a/crypto_kem/ntruhps2048677/avx2/sample.h b/crypto_kem/ntruhps2048677/avx2/sample.h index aa423e20..c7ac518b 100644 --- a/crypto_kem/ntruhps2048677/avx2/sample.h +++ b/crypto_kem/ntruhps2048677/avx2/sample.h @@ -4,6 +4,8 @@ #include "params.h" #include "poly.h" +#include "crypto_sort_int32.h" + void PQCLEAN_NTRUHPS2048677_AVX2_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHPS2048677_AVX2_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]); diff --git a/crypto_kem/ntruhps2048677/clean/kem.c b/crypto_kem/ntruhps2048677/clean/kem.c index 250d8f32..8378dc25 100644 --- a/crypto_kem/ntruhps2048677/clean/kem.c +++ b/crypto_kem/ntruhps2048677/clean/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHPS2048677_CLEAN_crypto_kem_dec(uint8_t *k, const uint8_t *c, co uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHPS2048677_CLEAN_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHPS2048677_CLEAN_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHPS2048677_CLEAN_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhps2048677/clean/owcpa.c b/crypto_kem/ntruhps2048677/clean/owcpa.c index cc310da0..261553d7 100644 --- a/crypto_kem/ntruhps2048677/clean/owcpa.c +++ b/crypto_kem/ntruhps2048677/clean/owcpa.c @@ -123,11 +123,15 @@ int PQCLEAN_NTRUHPS2048677_CLEAN_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHPS2048677_CLEAN_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHPS2048677_CLEAN_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; fail |= owcpa_check_m(m); /* b = c - Lift(m) mod (q, x^n - 1) */ diff --git a/crypto_kem/ntruhps2048677/clean/poly_r2_inv.c b/crypto_kem/ntruhps2048677/clean/poly_r2_inv.c index 8be864d8..2bc45e07 100644 --- a/crypto_kem/ntruhps2048677/clean/poly_r2_inv.c +++ b/crypto_kem/ntruhps2048677/clean/poly_r2_inv.c @@ -3,14 +3,14 @@ #include "poly.h" /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHPS2048677_CLEAN_poly_R2_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -37,7 +37,7 @@ void PQCLEAN_NTRUHPS2048677_CLEAN_poly_R2_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = g.coeffs[0] & f.coeffs[0]; - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhps2048677/clean/poly_s3_inv.c b/crypto_kem/ntruhps2048677/clean/poly_s3_inv.c index 19466db0..00c0ad8f 100644 --- a/crypto_kem/ntruhps2048677/clean/poly_s3_inv.c +++ b/crypto_kem/ntruhps2048677/clean/poly_s3_inv.c @@ -11,14 +11,14 @@ static inline uint8_t mod3(uint8_t a) { /* a between 0 and 9 */ } /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHPS2048677_CLEAN_poly_S3_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -45,7 +45,7 @@ void PQCLEAN_NTRUHPS2048677_CLEAN_poly_S3_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = mod3((uint8_t) (2 * g.coeffs[0] * f.coeffs[0])); - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhps2048677/clean/sample.c b/crypto_kem/ntruhps2048677/clean/sample.c index 41ba484e..587189cc 100644 --- a/crypto_kem/ntruhps2048677/clean/sample.c +++ b/crypto_kem/ntruhps2048677/clean/sample.c @@ -1,4 +1,3 @@ -#include "crypto_sort_int32.h" #include "sample.h" void PQCLEAN_NTRUHPS2048677_CLEAN_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]) { diff --git a/crypto_kem/ntruhps2048677/clean/sample.h b/crypto_kem/ntruhps2048677/clean/sample.h index c32b1001..a919891f 100644 --- a/crypto_kem/ntruhps2048677/clean/sample.h +++ b/crypto_kem/ntruhps2048677/clean/sample.h @@ -4,6 +4,8 @@ #include "params.h" #include "poly.h" +#include "crypto_sort_int32.h" + void PQCLEAN_NTRUHPS2048677_CLEAN_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHPS2048677_CLEAN_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]); diff --git a/crypto_kem/ntruhps4096821/META.yml b/crypto_kem/ntruhps4096821/META.yml index 3850df26..2621f03f 100644 --- a/crypto_kem/ntruhps4096821/META.yml +++ b/crypto_kem/ntruhps4096821/META.yml @@ -23,9 +23,9 @@ auxiliary-submitters: - Zhenfei Zhang implementations: - name: clean - version: https://github.com/jschanck/ntru/tree/ff3c84e1 reference implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 reference implementation - name: avx2 - version: https://github.com/jschanck/ntru/tree/ff3c84e1 avx2 implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 avx2 implementation supported_platforms: - architecture: x86_64 operating_systems: diff --git a/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.c b/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.c index d4c16d25..2023a7e7 100644 --- a/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.c +++ b/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.c @@ -1,8 +1,8 @@ -#include "crypto_sort_int32.h" -#include // Based on supercop-20200820/crypto_sort/int32/avx2 +#include "crypto_sort_int32.h" +#include #define int32 int32_t typedef __m256i int32x8; diff --git a/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.h b/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.h index 209e2188..63d91ade 100644 --- a/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.h +++ b/crypto_kem/ntruhps4096821/avx2/crypto_sort_int32.h @@ -1,10 +1,11 @@ #ifndef CRYPTO_SORT #define CRYPTO_SORT + #include "params.h" + #include #include - void PQCLEAN_NTRUHPS4096821_AVX2_crypto_sort_int32(int32_t *x, size_t n); #endif diff --git a/crypto_kem/ntruhps4096821/avx2/kem.c b/crypto_kem/ntruhps4096821/avx2/kem.c index c3500df7..cc7e3887 100644 --- a/crypto_kem/ntruhps4096821/avx2/kem.c +++ b/crypto_kem/ntruhps4096821/avx2/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHPS4096821_AVX2_crypto_kem_dec(uint8_t *k, const uint8_t *c, con uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHPS4096821_AVX2_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHPS4096821_AVX2_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHPS4096821_AVX2_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhps4096821/avx2/owcpa.c b/crypto_kem/ntruhps4096821/avx2/owcpa.c index 163787e7..36cdafd0 100644 --- a/crypto_kem/ntruhps4096821/avx2/owcpa.c +++ b/crypto_kem/ntruhps4096821/avx2/owcpa.c @@ -123,11 +123,15 @@ int PQCLEAN_NTRUHPS4096821_AVX2_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHPS4096821_AVX2_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHPS4096821_AVX2_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; fail |= owcpa_check_m(m); /* b = c - Lift(m) mod (q, x^n - 1) */ diff --git a/crypto_kem/ntruhps4096821/avx2/sample.c b/crypto_kem/ntruhps4096821/avx2/sample.c index 41c62d1a..fa8b8286 100644 --- a/crypto_kem/ntruhps4096821/avx2/sample.c +++ b/crypto_kem/ntruhps4096821/avx2/sample.c @@ -1,4 +1,3 @@ -#include "crypto_sort_int32.h" #include "sample.h" void PQCLEAN_NTRUHPS4096821_AVX2_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]) { diff --git a/crypto_kem/ntruhps4096821/avx2/sample.h b/crypto_kem/ntruhps4096821/avx2/sample.h index 3387cbcc..73649dc0 100644 --- a/crypto_kem/ntruhps4096821/avx2/sample.h +++ b/crypto_kem/ntruhps4096821/avx2/sample.h @@ -4,6 +4,8 @@ #include "params.h" #include "poly.h" +#include "crypto_sort_int32.h" + void PQCLEAN_NTRUHPS4096821_AVX2_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHPS4096821_AVX2_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]); diff --git a/crypto_kem/ntruhps4096821/clean/kem.c b/crypto_kem/ntruhps4096821/clean/kem.c index deaba324..40a96575 100644 --- a/crypto_kem/ntruhps4096821/clean/kem.c +++ b/crypto_kem/ntruhps4096821/clean/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHPS4096821_CLEAN_crypto_kem_dec(uint8_t *k, const uint8_t *c, co uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHPS4096821_CLEAN_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHPS4096821_CLEAN_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHPS4096821_CLEAN_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhps4096821/clean/owcpa.c b/crypto_kem/ntruhps4096821/clean/owcpa.c index 977bb113..d6627caf 100644 --- a/crypto_kem/ntruhps4096821/clean/owcpa.c +++ b/crypto_kem/ntruhps4096821/clean/owcpa.c @@ -123,11 +123,15 @@ int PQCLEAN_NTRUHPS4096821_CLEAN_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHPS4096821_CLEAN_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHPS4096821_CLEAN_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; fail |= owcpa_check_m(m); /* b = c - Lift(m) mod (q, x^n - 1) */ diff --git a/crypto_kem/ntruhps4096821/clean/poly_r2_inv.c b/crypto_kem/ntruhps4096821/clean/poly_r2_inv.c index 43b733bd..8d110d28 100644 --- a/crypto_kem/ntruhps4096821/clean/poly_r2_inv.c +++ b/crypto_kem/ntruhps4096821/clean/poly_r2_inv.c @@ -3,14 +3,14 @@ #include "poly.h" /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHPS4096821_CLEAN_poly_R2_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -37,7 +37,7 @@ void PQCLEAN_NTRUHPS4096821_CLEAN_poly_R2_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = g.coeffs[0] & f.coeffs[0]; - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhps4096821/clean/poly_s3_inv.c b/crypto_kem/ntruhps4096821/clean/poly_s3_inv.c index 0cd00e97..35b38d8e 100644 --- a/crypto_kem/ntruhps4096821/clean/poly_s3_inv.c +++ b/crypto_kem/ntruhps4096821/clean/poly_s3_inv.c @@ -11,14 +11,14 @@ static inline uint8_t mod3(uint8_t a) { /* a between 0 and 9 */ } /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHPS4096821_CLEAN_poly_S3_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -45,7 +45,7 @@ void PQCLEAN_NTRUHPS4096821_CLEAN_poly_S3_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = mod3((uint8_t) (2 * g.coeffs[0] * f.coeffs[0])); - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhps4096821/clean/sample.c b/crypto_kem/ntruhps4096821/clean/sample.c index 028cbd51..3e94cde9 100644 --- a/crypto_kem/ntruhps4096821/clean/sample.c +++ b/crypto_kem/ntruhps4096821/clean/sample.c @@ -1,4 +1,3 @@ -#include "crypto_sort_int32.h" #include "sample.h" void PQCLEAN_NTRUHPS4096821_CLEAN_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]) { diff --git a/crypto_kem/ntruhps4096821/clean/sample.h b/crypto_kem/ntruhps4096821/clean/sample.h index 1587f757..c2dbdd86 100644 --- a/crypto_kem/ntruhps4096821/clean/sample.h +++ b/crypto_kem/ntruhps4096821/clean/sample.h @@ -4,6 +4,8 @@ #include "params.h" #include "poly.h" +#include "crypto_sort_int32.h" + void PQCLEAN_NTRUHPS4096821_CLEAN_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHPS4096821_CLEAN_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]); diff --git a/crypto_kem/ntruhrss701/META.yml b/crypto_kem/ntruhrss701/META.yml index 231e4113..5df494e0 100644 --- a/crypto_kem/ntruhrss701/META.yml +++ b/crypto_kem/ntruhrss701/META.yml @@ -23,9 +23,9 @@ auxiliary-submitters: - Zhenfei Zhang implementations: - name: clean - version: https://github.com/jschanck/ntru/tree/ff3c84e1 reference implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 reference implementation - name: avx2 - version: https://github.com/jschanck/ntru/tree/ff3c84e1 avx2 implementation + version: https://github.com/jschanck/ntru/tree/b4b08d67 avx2 implementation supported_platforms: - architecture: x86_64 operating_systems: diff --git a/crypto_kem/ntruhrss701/avx2/kem.c b/crypto_kem/ntruhrss701/avx2/kem.c index 73b9259e..2085aa8d 100644 --- a/crypto_kem/ntruhrss701/avx2/kem.c +++ b/crypto_kem/ntruhrss701/avx2/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHRSS701_AVX2_crypto_kem_dec(uint8_t *k, const uint8_t *c, const uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHRSS701_AVX2_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHRSS701_AVX2_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHRSS701_AVX2_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhrss701/avx2/owcpa.c b/crypto_kem/ntruhrss701/avx2/owcpa.c index 55e17579..72f3447d 100644 --- a/crypto_kem/ntruhrss701/avx2/owcpa.c +++ b/crypto_kem/ntruhrss701/avx2/owcpa.c @@ -106,11 +106,15 @@ int PQCLEAN_NTRUHRSS701_AVX2_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHRSS701_AVX2_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHRSS701_AVX2_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; /* b = c - Lift(m) mod (q, x^n - 1) */ PQCLEAN_NTRUHRSS701_AVX2_poly_lift(liftm, m); diff --git a/crypto_kem/ntruhrss701/avx2/sample.h b/crypto_kem/ntruhrss701/avx2/sample.h index d5234c36..753cd18d 100644 --- a/crypto_kem/ntruhrss701/avx2/sample.h +++ b/crypto_kem/ntruhrss701/avx2/sample.h @@ -4,6 +4,7 @@ #include "params.h" #include "poly.h" + void PQCLEAN_NTRUHRSS701_AVX2_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHRSS701_AVX2_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]); diff --git a/crypto_kem/ntruhrss701/clean/kem.c b/crypto_kem/ntruhrss701/clean/kem.c index fc38e3d7..31887355 100644 --- a/crypto_kem/ntruhrss701/clean/kem.c +++ b/crypto_kem/ntruhrss701/clean/kem.c @@ -42,12 +42,7 @@ int PQCLEAN_NTRUHRSS701_CLEAN_crypto_kem_dec(uint8_t *k, const uint8_t *c, const uint8_t rm[NTRU_OWCPA_MSGBYTES]; uint8_t buf[NTRU_PRFKEYBYTES + NTRU_CIPHERTEXTBYTES]; - fail = 0; - - /* Check that unused bits of last byte of ciphertext are zero */ - fail |= c[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); - - fail |= PQCLEAN_NTRUHRSS701_CLEAN_owcpa_dec(rm, c, sk); + fail = PQCLEAN_NTRUHRSS701_CLEAN_owcpa_dec(rm, c, sk); /* If fail = 0 then c = Enc(h, rm). There is no need to re-encapsulate. */ /* See comment in PQCLEAN_NTRUHRSS701_CLEAN_owcpa_dec for details. */ diff --git a/crypto_kem/ntruhrss701/clean/owcpa.c b/crypto_kem/ntruhrss701/clean/owcpa.c index 52994767..68402ebc 100644 --- a/crypto_kem/ntruhrss701/clean/owcpa.c +++ b/crypto_kem/ntruhrss701/clean/owcpa.c @@ -106,11 +106,15 @@ int PQCLEAN_NTRUHRSS701_CLEAN_owcpa_dec(unsigned char *rm, PQCLEAN_NTRUHRSS701_CLEAN_poly_S3_mul(m, mf, finv3); PQCLEAN_NTRUHRSS701_CLEAN_poly_S3_tobytes(rm + NTRU_PACK_TRINARY_BYTES, m); - /* NOTE: For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ + fail = 0; + + /* Check that unused bits of last byte of ciphertext are zero */ + fail |= ciphertext[NTRU_CIPHERTEXTBYTES - 1] & (0xff << (8 - (7 & (NTRU_LOGQ * NTRU_PACK_DEG)))); + + /* For the IND-CCA2 KEM we must ensure that c = Enc(h, (r,m)). */ /* We can avoid re-computing r*h + Lift(m) as long as we check that */ /* r (defined as b/h mod (q, Phi_n)) and m are in the message space. */ /* (m can take any value in S3 in NTRU_HRSS) */ - fail = 0; /* b = c - Lift(m) mod (q, x^n - 1) */ PQCLEAN_NTRUHRSS701_CLEAN_poly_lift(liftm, m); diff --git a/crypto_kem/ntruhrss701/clean/poly_r2_inv.c b/crypto_kem/ntruhrss701/clean/poly_r2_inv.c index 3925508a..7d5ff25a 100644 --- a/crypto_kem/ntruhrss701/clean/poly_r2_inv.c +++ b/crypto_kem/ntruhrss701/clean/poly_r2_inv.c @@ -3,14 +3,14 @@ #include "poly.h" /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHRSS701_CLEAN_poly_R2_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -37,7 +37,7 @@ void PQCLEAN_NTRUHRSS701_CLEAN_poly_R2_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = g.coeffs[0] & f.coeffs[0]; - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhrss701/clean/poly_s3_inv.c b/crypto_kem/ntruhrss701/clean/poly_s3_inv.c index fd672ca2..41bf0a77 100644 --- a/crypto_kem/ntruhrss701/clean/poly_s3_inv.c +++ b/crypto_kem/ntruhrss701/clean/poly_s3_inv.c @@ -11,14 +11,14 @@ static inline uint8_t mod3(uint8_t a) { /* a between 0 and 9 */ } /* return -1 if x<0 and y<0; otherwise return 0 */ -static inline int both_negative_mask(int x, int y) { +static inline int16_t both_negative_mask(int16_t x, int16_t y) { return (x & y) >> 15; } void PQCLEAN_NTRUHRSS701_CLEAN_poly_S3_inv(poly *r, const poly *a) { poly f, g, v, w; - int i, loop, delta; - int sign, swap, t; + int16_t i, loop, delta; + int16_t sign, swap, t; for (i = 0; i < NTRU_N; ++i) { v.coeffs[i] = 0; @@ -45,7 +45,7 @@ void PQCLEAN_NTRUHRSS701_CLEAN_poly_S3_inv(poly *r, const poly *a) { v.coeffs[0] = 0; sign = mod3((uint8_t) (2 * g.coeffs[0] * f.coeffs[0])); - swap = both_negative_mask(-delta, -(int) g.coeffs[0]); + swap = both_negative_mask(-delta, -(int16_t) g.coeffs[0]); delta ^= swap & (delta ^ -delta); delta += 1; diff --git a/crypto_kem/ntruhrss701/clean/sample.h b/crypto_kem/ntruhrss701/clean/sample.h index b68a6624..d37a7b2d 100644 --- a/crypto_kem/ntruhrss701/clean/sample.h +++ b/crypto_kem/ntruhrss701/clean/sample.h @@ -4,6 +4,7 @@ #include "params.h" #include "poly.h" + void PQCLEAN_NTRUHRSS701_CLEAN_sample_fg(poly *f, poly *g, const unsigned char uniformbytes[NTRU_SAMPLE_FG_BYTES]); void PQCLEAN_NTRUHRSS701_CLEAN_sample_rm(poly *r, poly *m, const unsigned char uniformbytes[NTRU_SAMPLE_RM_BYTES]);