diff --git a/README.md b/README.md index 75d59645..696e00b5 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Users shouldn't expect any level of security provided by this code. The library | Falcon | 2 | | | Rainbow | 3 | | | SPHINCS+ SHA256/SHAKE256 | 3 | x | +| SIKE/p434 | 3 | x | ## Building diff --git a/src/kem/sike/includes/sike/sike.h b/src/kem/sike/includes/sike/sike.h index e71cde57..ca0d03d7 100644 --- a/src/kem/sike/includes/sike/sike.h +++ b/src/kem/sike/includes/sike/sike.h @@ -49,26 +49,33 @@ const uint8_t priv_key[SIKE_PRV_BYTESZ]); // boilerplate needed for integration -#define PQCLEAN_SIKE434_CLEAN_CRYPTO_SECRETKEYBYTES SIKE_PRV_BYTESZ +#define PQCLEAN_SIKE434_CLEAN_CRYPTO_SECRETKEYBYTES SIKE_PRV_BYTESZ+SIKE_MSG_BYTESZ #define PQCLEAN_SIKE434_CLEAN_CRYPTO_PUBLICKEYBYTES SIKE_PUB_BYTESZ #define PQCLEAN_SIKE434_CLEAN_CRYPTO_CIPHERTEXTBYTES SIKE_CT_BYTESZ #define PQCLEAN_SIKE434_CLEAN_CRYPTO_BYTES SIKE_SS_BYTESZ #define PQCLEAN_SIKE434_CLEAN_CRYPTO_ALGNAME "SIKE/p434" +#define PQCLEAN_SIKE434_AVX2_CRYPTO_SECRETKEYBYTES SIKE_PRV_BYTESZ+SIKE_MSG_BYTESZ +#define PQCLEAN_SIKE434_AVX2_CRYPTO_PUBLICKEYBYTES SIKE_PUB_BYTESZ +#define PQCLEAN_SIKE434_AVX2_CRYPTO_CIPHERTEXTBYTES SIKE_CT_BYTESZ +#define PQCLEAN_SIKE434_AVX2_CRYPTO_BYTES SIKE_SS_BYTESZ +#define PQCLEAN_SIKE434_AVX2_CRYPTO_ALGNAME "SIKE/p434" + static inline int PQCLEAN_SIKE434_CLEAN_crypto_kem_keypair(uint8_t *pk, uint8_t *sk) { - randombytes(sk, SIKE_MSG_BYTESZ); - SIKE_keypair(sk+SIKE_MSG_BYTESZ, pk); - memcpy(&sk[SIKE_PRV_BYTESZ+SIKE_MSG_BYTESZ], pk, SIKE_PUB_BYTESZ); - return 1; + SIKE_keypair(sk, pk); + // KATs require the public key to be concatenated after private key + // OZAPTF: maybe change KAT tester + memcpy(&sk[SIKE_MSG_BYTESZ+SIKE_PRV_BYTESZ], pk, SIKE_PUB_BYTESZ); + return 0; } static inline int PQCLEAN_SIKE434_CLEAN_crypto_kem_enc(uint8_t *ct, uint8_t *ss, const uint8_t *pk) { SIKE_encaps(ss,ct,pk); - return 1; + return 0; } static inline int PQCLEAN_SIKE434_CLEAN_crypto_kem_dec(uint8_t *ss, const uint8_t *ct, const uint8_t *sk) { SIKE_decaps(ss, ct, &sk[SIKE_PRV_BYTESZ+SIKE_MSG_BYTESZ], sk); - return 1; + return 0; } diff --git a/src/kem/sike/p434/sike.c b/src/kem/sike/p434/sike.c index f52fe5c4..83a9dc1d 100644 --- a/src/kem/sike/p434/sike.c +++ b/src/kem/sike/p434/sike.c @@ -411,10 +411,10 @@ int SIKE_keypair(uint8_t out_priv[SIKE_PRV_BYTESZ], uint8_t out_pub[SIKE_PUB_BYTESZ]) { // Calculate private key for Alice. Needs to be in range [0, 2^0xFA - 1] and < // 253 bits - randombytes(out_priv, SIKE_PRV_BYTESZ); - out_priv[31] = (out_priv[31] | 0x01) & 0x03; - - gen_iso_B(out_priv, out_pub); + randombytes(out_priv, SIKE_MSG_BYTESZ); + randombytes(&out_priv[SIKE_MSG_BYTESZ], SIKE_PRV_BYTESZ); + out_priv[SIKE_MSG_BYTESZ+28-1] = (out_priv[SIKE_MSG_BYTESZ+28-1] & 0x01); + gen_iso_B(&out_priv[SIKE_MSG_BYTESZ], out_pub); return 1; } @@ -430,7 +430,7 @@ void SIKE_encaps(uint8_t out_shared_key[SIKE_SS_BYTESZ], shake256incctx ctx; // Generate secret key for A - // secret key A = SHA256({0,1}^n || pub_key)) mod SIDH_PRV_A_BITSZ + // secret key A = SHAKE256({0,1}^n || pub_key)) mod SIDH_PRV_A_BITSZ randombytes(temp, SIKE_MSG_BYTESZ); shake256_inc_init(&ctx); @@ -444,7 +444,7 @@ void SIKE_encaps(uint8_t out_shared_key[SIKE_SS_BYTESZ], gen_iso_A(secret, out_ciphertext); // Generate c1: - // h = SHA256(j-invariant) + // h = SHAKE256(j-invariant) // c1 = h ^ m ex_iso_A(secret, pub_key, j); shake256(secret, sizeof secret, j, sizeof j); @@ -461,14 +461,14 @@ void SIKE_encaps(uint8_t out_shared_key[SIKE_SS_BYTESZ], shake256_inc_finalize(&ctx); shake256_inc_squeeze(secret, 32, &ctx); shake256_inc_ctx_release(&ctx); - // Generate shared secret out_shared_key = SHA256(m||out_ciphertext) + // Generate shared secret out_shared_key = SHAKE256(m||out_ciphertext) memcpy(out_shared_key, secret, SIKE_SS_BYTESZ); } void SIKE_decaps(uint8_t out_shared_key[SIKE_SS_BYTESZ], const uint8_t ciphertext[SIKE_CT_BYTESZ], const uint8_t pub_key[SIKE_PUB_BYTESZ], - const uint8_t priv_key[SIKE_PRV_BYTESZ]) { + const uint8_t priv_key[SIKE_MSG_BYTESZ + SIKE_PRV_BYTESZ]) { // Secret buffer is reused by the function to store some ephemeral // secret data. It's size must be maximum of 64, // SIKE_MSG_BYTESZ and SIDH_PRV_A_BITSZ in bytes. @@ -476,16 +476,12 @@ void SIKE_decaps(uint8_t out_shared_key[SIKE_SS_BYTESZ], uint8_t j[SIDH_JINV_BYTESZ]; uint8_t c0[SIKE_PUB_BYTESZ]; uint8_t temp[SIKE_MSG_BYTESZ]; - uint8_t shared_nok[SIKE_MSG_BYTESZ]; shake256incctx ctx; - // This is OK as we are only using ephemeral keys in BoringSSL - randombytes(shared_nok, SIKE_MSG_BYTESZ); - // Recover m // Let ciphertext = c0 || c1 - both have fixed sizes // m = F(j-invariant(c0, priv_key)) ^ c1 - ex_iso_B(priv_key, ciphertext, j); + ex_iso_B(&priv_key[SIKE_MSG_BYTESZ], ciphertext, j); shake256(secret, sizeof secret, j, sizeof j); @@ -507,7 +503,7 @@ void SIKE_decaps(uint8_t out_shared_key[SIKE_SS_BYTESZ], crypto_word_t ok = ct_uint_eq( ct_mem_eq(c0, ciphertext, SIKE_PUB_BYTESZ), 1); for (size_t i = 0; i < SIKE_MSG_BYTESZ; i++) { - temp[i] = ct_select_8(ok, temp[i], shared_nok[i]); + temp[i] = ct_select_8(ok, temp[i], priv_key[i]); } shake256_inc_init(&ctx); @@ -517,6 +513,6 @@ void SIKE_decaps(uint8_t out_shared_key[SIKE_SS_BYTESZ], shake256_inc_squeeze(secret, 32, &ctx); shake256_inc_ctx_release(&ctx); - // Generate shared secret out_shared_key = SHA256(m||ciphertext) + // Generate shared secret out_shared_key = SHAKE256(m||ciphertext) memcpy(out_shared_key, secret, SIKE_SS_BYTESZ); } diff --git a/test/katrunner/Cargo.toml b/test/katrunner/Cargo.toml index c5adb4dc..fd07d6f3 100644 --- a/test/katrunner/Cargo.toml +++ b/test/katrunner/Cargo.toml @@ -11,4 +11,4 @@ hex = "0.4.2" threadpool = "1.8.1" rust-crypto = "^0.2" lazy_static = "1.4.0" -aes_ctr_drbg = "0.0.2" \ No newline at end of file +aes_ctr_drbg = "0.0.2" diff --git a/test/katrunner/src/main.rs b/test/katrunner/src/main.rs index f6ee752c..0da5c3e5 100644 --- a/test/katrunner/src/main.rs +++ b/test/katrunner/src/main.rs @@ -130,9 +130,10 @@ fn test_kem_vector(el: &TestVector) { // Check keygen pk.resize(el.kem.pk.len(), 0); sk.resize(el.kem.sk.len(), 0); - assert_eq!( - pqc_keygen(p, pk.as_mut_ptr(), sk.as_mut_ptr()), - true); + assert_eq!( + pqc_keygen(p, pk.as_mut_ptr(), sk.as_mut_ptr()), + true); + assert_eq!(sk, el.kem.sk); assert_eq!(pk, el.kem.pk);