|
|
@@ -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); |
|
|
|
} |