Make Frodo code endian-agnostic

This commit is contained in:
Douglas Stebila 2019-03-31 21:44:36 -04:00
parent 028fb2120e
commit 9cb1c56ac1
4 changed files with 43 additions and 5 deletions

View File

@ -13,5 +13,7 @@ void PQCLEAN_FRODOKEM640SHAKE_CLEAN_key_decode(uint16_t *out, const uint16_t *in
void PQCLEAN_FRODOKEM640SHAKE_CLEAN_pack(unsigned char *out, size_t outlen, const uint16_t *in, size_t inlen, unsigned char lsb); void PQCLEAN_FRODOKEM640SHAKE_CLEAN_pack(unsigned char *out, size_t outlen, const uint16_t *in, size_t inlen, unsigned char lsb);
void PQCLEAN_FRODOKEM640SHAKE_CLEAN_unpack(uint16_t *out, size_t outlen, const unsigned char *in, size_t inlen, unsigned char lsb); void PQCLEAN_FRODOKEM640SHAKE_CLEAN_unpack(uint16_t *out, size_t outlen, const unsigned char *in, size_t inlen, unsigned char lsb);
void PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes(uint8_t *mem, size_t n); void PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes(uint8_t *mem, size_t n);
uint16_t PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(uint16_t n);
uint16_t PQCLEAN_FRODOKEM640SHAKE_CLEAN_UINT16_TO_LE(uint16_t n);
#endif #endif

View File

@ -41,6 +41,9 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigne
shake_input_seedSE[0] = 0x5F; shake_input_seedSE[0] = 0x5F;
memcpy(&shake_input_seedSE[1], randomness_seedSE, CRYPTO_BYTES); memcpy(&shake_input_seedSE[1], randomness_seedSE, CRYPTO_BYTES);
shake((uint8_t *)S, 2 * PARAMS_N * PARAMS_NBAR * sizeof(uint16_t), shake_input_seedSE, 1 + CRYPTO_BYTES); shake((uint8_t *)S, 2 * PARAMS_N * PARAMS_NBAR * sizeof(uint16_t), shake_input_seedSE, 1 + CRYPTO_BYTES);
for (size_t i = 0; i < 2 * PARAMS_N * PARAMS_NBAR; i++) {
S[i] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(S[i]);
}
PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(S, PARAMS_N * PARAMS_NBAR); PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(S, PARAMS_N * PARAMS_NBAR);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(E, PARAMS_N * PARAMS_NBAR); PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(E, PARAMS_N * PARAMS_NBAR);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_as_plus_e(B, S, E, pk); PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_as_plus_e(B, S, E, pk);
@ -51,6 +54,9 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_crypto_kem_keypair(unsigned char *pk, unsigne
// Add s, pk and S to the secret key // Add s, pk and S to the secret key
memcpy(sk_s, randomness_s, CRYPTO_BYTES); memcpy(sk_s, randomness_s, CRYPTO_BYTES);
memcpy(sk_pk, pk, CRYPTO_PUBLICKEYBYTES); memcpy(sk_pk, pk, CRYPTO_PUBLICKEYBYTES);
for (size_t i = 0; i < PARAMS_N * PARAMS_NBAR; i++) {
sk_S[i] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_UINT16_TO_LE(sk_S[i]);
}
memcpy(sk_S, S, 2 * PARAMS_N * PARAMS_NBAR); memcpy(sk_S, S, 2 * PARAMS_N * PARAMS_NBAR);
// Add H(pk) to the secret key // Add H(pk) to the secret key
@ -97,7 +103,10 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_crypto_kem_enc(unsigned char *ct, unsigned ch
// Generate Sp and Ep, and compute Bp = Sp*A + Ep. Generate A on-the-fly // Generate Sp and Ep, and compute Bp = Sp*A + Ep. Generate A on-the-fly
shake_input_seedSE[0] = 0x96; shake_input_seedSE[0] = 0x96;
memcpy(&shake_input_seedSE[1], seedSE, CRYPTO_BYTES); memcpy(&shake_input_seedSE[1], seedSE, CRYPTO_BYTES);
shake((uint8_t *)Sp, (2 * PARAMS_N + PARAMS_NBAR)*PARAMS_NBAR * sizeof(uint16_t), shake_input_seedSE, 1 + CRYPTO_BYTES); shake((uint8_t *)Sp, (2 * PARAMS_N + PARAMS_NBAR) * PARAMS_NBAR * sizeof(uint16_t), shake_input_seedSE, 1 + CRYPTO_BYTES);
for (size_t i = 0; i < (2 * PARAMS_N + PARAMS_NBAR) * PARAMS_NBAR; i++) {
Sp[i] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(Sp[i]);
}
PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Sp, PARAMS_N * PARAMS_NBAR); PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Sp, PARAMS_N * PARAMS_NBAR);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Ep, PARAMS_N * PARAMS_NBAR); PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Ep, PARAMS_N * PARAMS_NBAR);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_sa_plus_e(Bp, Sp, Ep, pk_seedA); PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_sa_plus_e(Bp, Sp, Ep, pk_seedA);
@ -147,6 +156,7 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_crypto_kem_dec(unsigned char *ss, const unsig
const uint8_t *sk_s = &sk[0]; const uint8_t *sk_s = &sk[0];
const uint8_t *sk_pk = &sk[CRYPTO_BYTES]; const uint8_t *sk_pk = &sk[CRYPTO_BYTES];
const uint16_t *sk_S = (uint16_t *) &sk[CRYPTO_BYTES + CRYPTO_PUBLICKEYBYTES]; const uint16_t *sk_S = (uint16_t *) &sk[CRYPTO_BYTES + CRYPTO_PUBLICKEYBYTES];
uint16_t S[PARAMS_N * PARAMS_NBAR]; // contains secret data
const uint8_t *sk_pkh = &sk[CRYPTO_BYTES + CRYPTO_PUBLICKEYBYTES + 2 * PARAMS_N * PARAMS_NBAR]; const uint8_t *sk_pkh = &sk[CRYPTO_BYTES + CRYPTO_PUBLICKEYBYTES + 2 * PARAMS_N * PARAMS_NBAR];
const uint8_t *pk_seedA = &sk_pk[0]; const uint8_t *pk_seedA = &sk_pk[0];
const uint8_t *pk_b = &sk_pk[BYTES_SEED_A]; const uint8_t *pk_b = &sk_pk[BYTES_SEED_A];
@ -161,10 +171,14 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_crypto_kem_dec(unsigned char *ss, const unsig
uint8_t *Fin_k = &Fin[CRYPTO_CIPHERTEXTBYTES]; // contains secret data uint8_t *Fin_k = &Fin[CRYPTO_CIPHERTEXTBYTES]; // contains secret data
uint8_t shake_input_seedSEprime[1 + CRYPTO_BYTES]; // contains secret data uint8_t shake_input_seedSEprime[1 + CRYPTO_BYTES]; // contains secret data
for (size_t i = 0; i < PARAMS_N * PARAMS_NBAR; i++) {
S[i] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(sk_S[i]);
}
// Compute W = C - Bp*S (mod q), and decode the randomness mu // Compute W = C - Bp*S (mod q), and decode the randomness mu
PQCLEAN_FRODOKEM640SHAKE_CLEAN_unpack(Bp, PARAMS_N * PARAMS_NBAR, ct_c1, (PARAMS_LOGQ * PARAMS_N * PARAMS_NBAR) / 8, PARAMS_LOGQ); PQCLEAN_FRODOKEM640SHAKE_CLEAN_unpack(Bp, PARAMS_N * PARAMS_NBAR, ct_c1, (PARAMS_LOGQ * PARAMS_N * PARAMS_NBAR) / 8, PARAMS_LOGQ);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_unpack(C, PARAMS_NBAR * PARAMS_NBAR, ct_c2, (PARAMS_LOGQ * PARAMS_NBAR * PARAMS_NBAR) / 8, PARAMS_LOGQ); PQCLEAN_FRODOKEM640SHAKE_CLEAN_unpack(C, PARAMS_NBAR * PARAMS_NBAR, ct_c2, (PARAMS_LOGQ * PARAMS_NBAR * PARAMS_NBAR) / 8, PARAMS_LOGQ);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_bs(W, Bp, sk_S); PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_bs(W, Bp, S);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_sub(W, C, W); PQCLEAN_FRODOKEM640SHAKE_CLEAN_sub(W, C, W);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_key_decode((uint16_t *)muprime, W); PQCLEAN_FRODOKEM640SHAKE_CLEAN_key_decode((uint16_t *)muprime, W);
@ -175,7 +189,10 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_crypto_kem_dec(unsigned char *ss, const unsig
// Generate Sp and Ep, and compute BBp = Sp*A + Ep. Generate A on-the-fly // Generate Sp and Ep, and compute BBp = Sp*A + Ep. Generate A on-the-fly
shake_input_seedSEprime[0] = 0x96; shake_input_seedSEprime[0] = 0x96;
memcpy(&shake_input_seedSEprime[1], seedSEprime, CRYPTO_BYTES); memcpy(&shake_input_seedSEprime[1], seedSEprime, CRYPTO_BYTES);
shake((uint8_t *)Sp, (2 * PARAMS_N + PARAMS_NBAR)*PARAMS_NBAR * sizeof(uint16_t), shake_input_seedSEprime, 1 + CRYPTO_BYTES); shake((uint8_t *)Sp, (2 * PARAMS_N + PARAMS_NBAR) * PARAMS_NBAR * sizeof(uint16_t), shake_input_seedSEprime, 1 + CRYPTO_BYTES);
for (size_t i = 0; i < (2 * PARAMS_N + PARAMS_NBAR) * PARAMS_NBAR; i++) {
Sp[i] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(Sp[i]);
}
PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Sp, PARAMS_N * PARAMS_NBAR); PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Sp, PARAMS_N * PARAMS_NBAR);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Ep, PARAMS_N * PARAMS_NBAR); PQCLEAN_FRODOKEM640SHAKE_CLEAN_sample_n(Ep, PARAMS_N * PARAMS_NBAR);
PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_sa_plus_e(BBp, Sp, Ep, pk_seedA); PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_sa_plus_e(BBp, Sp, Ep, pk_seedA);
@ -210,6 +227,7 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_crypto_kem_dec(unsigned char *ss, const unsig
// Cleanup: // Cleanup:
PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)W, PARAMS_NBAR * PARAMS_NBAR * sizeof(uint16_t)); PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)W, PARAMS_NBAR * PARAMS_NBAR * sizeof(uint16_t));
PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)Sp, PARAMS_N * PARAMS_NBAR * sizeof(uint16_t)); PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)Sp, PARAMS_N * PARAMS_NBAR * sizeof(uint16_t));
PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)S, PARAMS_N * PARAMS_NBAR * sizeof(uint16_t));
PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)Ep, PARAMS_N * PARAMS_NBAR * sizeof(uint16_t)); PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)Ep, PARAMS_N * PARAMS_NBAR * sizeof(uint16_t));
PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)Epp, PARAMS_NBAR * PARAMS_NBAR * sizeof(uint16_t)); PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes((uint8_t *)Epp, PARAMS_NBAR * PARAMS_NBAR * sizeof(uint16_t));
PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes(muprime, BYTES_MU); PQCLEAN_FRODOKEM640SHAKE_CLEAN_clear_bytes(muprime, BYTES_MU);

View File

@ -10,6 +10,7 @@
#include "fips202.h" #include "fips202.h"
#include "api.h" #include "api.h"
#include "common.h"
#include "params.h" #include "params.h"
int PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_as_plus_e(uint16_t *out, const uint16_t *s, const uint16_t *e, const uint8_t *seed_A) { int PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_as_plus_e(uint16_t *out, const uint16_t *s, const uint16_t *e, const uint8_t *seed_A) {
@ -23,9 +24,12 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_as_plus_e(uint16_t *out, const uint16
uint16_t *seed_A_origin = (uint16_t *)&seed_A_separated; uint16_t *seed_A_origin = (uint16_t *)&seed_A_separated;
memcpy(&seed_A_separated[2], seed_A, BYTES_SEED_A); memcpy(&seed_A_separated[2], seed_A, BYTES_SEED_A);
for (i = 0; i < PARAMS_N; i++) { for (i = 0; i < PARAMS_N; i++) {
seed_A_origin[0] = (uint16_t) i; seed_A_origin[0] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_UINT16_TO_LE(i);
shake128((unsigned char *)(A + i * PARAMS_N), (unsigned long long)(2 * PARAMS_N), seed_A_separated, 2 + BYTES_SEED_A); shake128((unsigned char *)(A + i * PARAMS_N), (unsigned long long)(2 * PARAMS_N), seed_A_separated, 2 + BYTES_SEED_A);
} }
for (i = 0; i < PARAMS_N * PARAMS_N; i++) {
A[i] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(A[i]);
}
memcpy(out, e, PARAMS_NBAR * PARAMS_N * sizeof(uint16_t)); memcpy(out, e, PARAMS_NBAR * PARAMS_N * sizeof(uint16_t));
for (i = 0; i < PARAMS_N; i++) { // Matrix multiplication-addition A*s + e for (i = 0; i < PARAMS_N; i++) { // Matrix multiplication-addition A*s + e
@ -53,9 +57,12 @@ int PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_add_sa_plus_e(uint16_t *out, const uint16
uint16_t *seed_A_origin = (uint16_t *)&seed_A_separated; uint16_t *seed_A_origin = (uint16_t *)&seed_A_separated;
memcpy(&seed_A_separated[2], seed_A, BYTES_SEED_A); memcpy(&seed_A_separated[2], seed_A, BYTES_SEED_A);
for (i = 0; i < PARAMS_N; i++) { for (i = 0; i < PARAMS_N; i++) {
seed_A_origin[0] = (uint16_t) i; seed_A_origin[0] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_UINT16_TO_LE(i);
shake128((unsigned char *)(A + i * PARAMS_N), (unsigned long long)(2 * PARAMS_N), seed_A_separated, 2 + BYTES_SEED_A); shake128((unsigned char *)(A + i * PARAMS_N), (unsigned long long)(2 * PARAMS_N), seed_A_separated, 2 + BYTES_SEED_A);
} }
for (i = 0; i < PARAMS_N * PARAMS_N; i++) {
A[i] = PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(A[i]);
}
memcpy(out, e, PARAMS_NBAR * PARAMS_N * sizeof(uint16_t)); memcpy(out, e, PARAMS_NBAR * PARAMS_N * sizeof(uint16_t));
for (i = 0; i < PARAMS_N; i++) { // Matrix multiplication-addition A*s + e for (i = 0; i < PARAMS_N; i++) { // Matrix multiplication-addition A*s + e

View File

@ -12,6 +12,17 @@
#define min(x, y) (((x) < (y)) ? (x) : (y)) #define min(x, y) (((x) < (y)) ? (x) : (y))
uint16_t PQCLEAN_FRODOKEM640SHAKE_CLEAN_LE_TO_UINT16(const uint16_t n) {
return (((uint8_t *) &(n))[0] | (((uint8_t *) &(n))[1] << 8));
}
uint16_t PQCLEAN_FRODOKEM640SHAKE_CLEAN_UINT16_TO_LE(const uint16_t n) {
uint16_t y;
uint8_t *z = (uint8_t *) &y;
z[0] = n & 0xFF;
z[1] = (n & 0xFF00) >> 8;
return y;
}
void PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_bs(uint16_t *out, const uint16_t *b, const uint16_t *s) { void PQCLEAN_FRODOKEM640SHAKE_CLEAN_mul_bs(uint16_t *out, const uint16_t *b, const uint16_t *s) {
// Multiply by s on the right // Multiply by s on the right