frodo: FrodoKEM KE method
This commit is contained in:
parent
283323227f
commit
03589a6cd7
|
@ -154,6 +154,7 @@ ARG_ENABL_SET([mgf1], [enable the MGF1 software implementation plugin.
|
|||
ARG_ENABL_SET([newhope], [enable New Hope crypto plugin.])
|
||||
ARG_DISBL_SET([nonce], [disable nonce generation plugin.])
|
||||
ARG_ENABL_SET([ntru], [enables the NTRU crypto plugin.])
|
||||
ARG_ENABL_SET([frodo], [enable FrodoKEM Post Quantum Safe plugin.])
|
||||
ARG_ENABL_SET([oqs], [enable Open Quantum Safe (liboqs) plugin.])
|
||||
ARG_ENABL_SET([openssl], [enables the OpenSSL crypto plugin.])
|
||||
ARG_ENABL_SET([wolfssl], [enables the wolfSSL crypto plugin.])
|
||||
|
@ -1503,6 +1504,7 @@ ADD_PLUGIN([ctr], [s charon scripts nm cmd])
|
|||
ADD_PLUGIN([ccm], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([gcm], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([ntru], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([frodo], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([oqs], [s charon scripts nm cmd])
|
||||
ADD_PLUGIN([drbg], [s charon pki scripts nm cmd])
|
||||
ADD_PLUGIN([newhope], [s charon scripts nm cmd])
|
||||
|
@ -1676,6 +1678,7 @@ AM_CONDITIONAL(USE_NEWHOPE, test x$newhope = xtrue)
|
|||
AM_CONDITIONAL(USE_BLISS, test x$bliss = xtrue)
|
||||
AM_CONDITIONAL(USE_DRBG, test x$drbg = xtrue)
|
||||
AM_CONDITIONAL(USE_OQS, test x$oqs = xtrue)
|
||||
AM_CONDITIONAL(USE_FRODO, test x$frodo = xtrue)
|
||||
|
||||
# charon plugins
|
||||
# ----------------
|
||||
|
@ -1959,6 +1962,7 @@ AC_CONFIG_FILES([
|
|||
src/libstrongswan/plugins/bliss/tests/Makefile
|
||||
src/libstrongswan/plugins/newhope/Makefile
|
||||
src/libstrongswan/plugins/newhope/tests/Makefile
|
||||
src/libstrongswan/plugins/frodo/Makefile
|
||||
src/libstrongswan/plugins/oqs/Makefile
|
||||
src/libstrongswan/plugins/oqs/tests/Makefile
|
||||
src/libstrongswan/plugins/test_vectors/Makefile
|
||||
|
|
|
@ -681,6 +681,13 @@ if MONOLITHIC
|
|||
endif
|
||||
endif
|
||||
|
||||
if USE_FRODO
|
||||
SUBDIRS += plugins/frodo
|
||||
if MONOLITHIC
|
||||
libstrongswan_la_LIBADD += plugins/frodo/libstrongswan-frodo.la
|
||||
endif
|
||||
endif
|
||||
|
||||
if USE_TEST_VECTORS
|
||||
SUBDIRS += plugins/test_vectors
|
||||
if MONOLITHIC
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src/libstrongswan
|
||||
|
||||
AM_CFLAGS = \
|
||||
$(PLUGIN_CFLAGS)
|
||||
|
||||
# these files are also used by the tests, we can't directly refer to them
|
||||
# because of the subdirectory, which would cause distclean to fail
|
||||
noinst_LTLIBRARIES = libfrodo.la
|
||||
libfrodo_la_SOURCES = \
|
||||
frodo.h frodo.c \
|
||||
frodo_params.h frodo_params.c \
|
||||
frodo_utils.h frodo_utils.c
|
||||
|
||||
if MONOLITHIC
|
||||
noinst_LTLIBRARIES += libstrongswan-frodo.la
|
||||
else
|
||||
plugin_LTLIBRARIES = libstrongswan-frodo.la
|
||||
endif
|
||||
|
||||
libstrongswan_frodo_la_SOURCES = \
|
||||
frodo_plugin.h frodo_plugin.c
|
||||
|
||||
libstrongswan_frodo_la_LDFLAGS = -module -avoid-version
|
||||
|
||||
libstrongswan_frodo_la_LIBADD = libfrodo.la
|
|
@ -0,0 +1,596 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (C) Microsoft Corporation
|
||||
*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "frodo.h"
|
||||
#include "frodo_params.h"
|
||||
#include "frodo_utils.h"
|
||||
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_frodo_t private_frodo_t;
|
||||
|
||||
/**
|
||||
* Private data of an frodo_t object.
|
||||
*/
|
||||
struct private_frodo_t {
|
||||
|
||||
/**
|
||||
* Public frodo_t interface.
|
||||
*/
|
||||
frodo_t public;
|
||||
|
||||
/**
|
||||
* key exchange method
|
||||
*/
|
||||
key_exchange_method_t method;
|
||||
|
||||
/**
|
||||
* If TRUE use AES128 for generating matrix A, otherwise use SHAKE128
|
||||
*/
|
||||
bool use_aes;
|
||||
|
||||
/**
|
||||
* Frodo parameters
|
||||
*/
|
||||
const frodo_params_t *params;
|
||||
|
||||
/**
|
||||
* Public Key
|
||||
*/
|
||||
uint8_t *public_key;
|
||||
|
||||
/**
|
||||
* Secret Key
|
||||
*/
|
||||
uint8_t *secret_key;
|
||||
|
||||
/**
|
||||
* Ciphertext
|
||||
*/
|
||||
uint8_t *ciphertext;
|
||||
|
||||
/**
|
||||
* Shared secret
|
||||
*/
|
||||
uint8_t *shared_secret;
|
||||
|
||||
/**
|
||||
* NIST CTR DRBG
|
||||
*/
|
||||
drbg_t *drbg;
|
||||
|
||||
/**
|
||||
* SHAKE-128 or SHAKE-256 eXtended Output Function
|
||||
*/
|
||||
xof_t *xof;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static bool need_drbg(private_frodo_t *this)
|
||||
{
|
||||
uint32_t strength = 256;
|
||||
rng_t *entropy;
|
||||
|
||||
if (this->drbg)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* entropy will be owned by drbg */
|
||||
entropy = lib->crypto->create_rng(lib->crypto, RNG_TRUE);
|
||||
if (!entropy)
|
||||
{
|
||||
DBG1(DBG_LIB, "could not attach entropy source for DRBG");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->drbg = lib->crypto->create_drbg(lib->crypto, DRBG_CTR_AES256,
|
||||
strength, entropy, chunk_empty);
|
||||
if (!this->drbg)
|
||||
{
|
||||
DBG1(DBG_LIB, "could not instantiate DRBG at %u bit security", strength);
|
||||
entropy->destroy(entropy);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generator function shared between encaps and decaps shared secret
|
||||
*/
|
||||
static bool generate(private_frodo_t *this, chunk_t G2in, uint8_t *k,
|
||||
uint16_t *Bp, uint16_t *C)
|
||||
{
|
||||
const uint32_t n_x_nb = this->params->n * this->params->nb;
|
||||
const uint32_t nb_x_nb = this->params->nb * this->params->nb;
|
||||
const uint32_t log_q = this->params->log_q;
|
||||
const uint32_t seed_A_len = this->params->seed_A_len;
|
||||
const uint32_t ss_len = this->params->ss_len;
|
||||
const uint32_t pk_len = this->params->pk_len;
|
||||
|
||||
uint8_t *mu = G2in.ptr + ss_len;
|
||||
uint8_t *pk_seedA = this->public_key;
|
||||
uint8_t *pk_b = this->public_key + seed_A_len;
|
||||
uint16_t B[n_x_nb], Sp[n_x_nb], Ep[n_x_nb], Epp[nb_x_nb], V[nb_x_nb];
|
||||
|
||||
chunk_t seedSE = chunk_alloc(1 + ss_len);
|
||||
|
||||
if (!this->xof->set_seed(this->xof, G2in) ||
|
||||
!this->xof->get_bytes(this->xof, ss_len, seedSE.ptr + 1) ||
|
||||
!this->xof->get_bytes(this->xof, ss_len, k))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*seedSE.ptr = 0x96;
|
||||
|
||||
/* Generate Sp and Ep, and compute Bp = Sp*A + Ep. Generate A on-the-fly */
|
||||
if (!this->xof->set_seed(this->xof, seedSE) ||
|
||||
!this->xof->get_bytes(this->xof,
|
||||
n_x_nb * sizeof(uint16_t), (uint8_t*)Sp) ||
|
||||
!this->xof->get_bytes(this->xof,
|
||||
n_x_nb * sizeof(uint16_t), (uint8_t*)Ep) ||
|
||||
!this->xof->get_bytes(this->xof,
|
||||
nb_x_nb * sizeof(uint16_t), (uint8_t*)Epp))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
frodo_sample_n(this->params, Sp, n_x_nb);
|
||||
frodo_sample_n(this->params, Ep, n_x_nb);
|
||||
frodo_mul_add_sa_plus_e(this->params, Bp, Sp, Ep, pk_seedA, this->use_aes);
|
||||
|
||||
/* Generate Epp, and compute V = Sp*B + Epp */
|
||||
frodo_sample_n(this->params, Epp, nb_x_nb);
|
||||
frodo_unpack(B, n_x_nb, pk_b, pk_len - seed_A_len, log_q);
|
||||
frodo_mul_add_sb_plus_e(this->params, V, B, Sp, Epp);
|
||||
|
||||
/* Encode mu, and compute C = V + enc(mu) (mod q) */
|
||||
frodo_key_encode(this->params, C, (uint16_t*)mu);
|
||||
frodo_add(this->params, C, V, C);
|
||||
|
||||
/* Cleanup */
|
||||
memwipe((uint8_t *)Sp, n_x_nb * sizeof(uint16_t));
|
||||
memwipe((uint8_t *)Ep, n_x_nb * sizeof(uint16_t));
|
||||
memwipe((uint8_t *)Epp, nb_x_nb * sizeof(uint16_t));
|
||||
memwipe((uint8_t *)V, nb_x_nb * sizeof(uint16_t));
|
||||
chunk_clear(&seedSE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the shared secret and encrypt it with the configured public key
|
||||
*/
|
||||
static bool encaps_shared_secret(private_frodo_t *this)
|
||||
{
|
||||
const uint32_t n_x_nb = this->params->n * this->params->nb;
|
||||
const uint32_t nb_x_nb = this->params->nb * this->params->nb;
|
||||
const uint32_t log_q = this->params->log_q;
|
||||
const uint32_t extr_bits = this->params->extr_bits;
|
||||
const uint32_t ct_c1_len = (n_x_nb * log_q)/8;
|
||||
const uint32_t ct_c2_len = (nb_x_nb * log_q)/8;
|
||||
const uint32_t mu_len = (nb_x_nb * extr_bits)/8;
|
||||
const uint32_t ss_len = this->params->ss_len;
|
||||
const uint32_t ct_len = this->params->ct_len;
|
||||
const uint32_t pk_len = this->params->pk_len;
|
||||
|
||||
chunk_t pk = chunk_create(this->public_key, pk_len);
|
||||
chunk_t G2in = chunk_alloca(ss_len + mu_len);
|
||||
uint8_t *pkh = G2in.ptr;
|
||||
uint8_t *mu = G2in.ptr + ss_len;
|
||||
uint8_t *ct_c1, *ct_c2;
|
||||
uint8_t Fin[ct_len + ss_len];
|
||||
uint8_t *Fin_ct = &Fin[0];
|
||||
uint8_t *Fin_k = &Fin[ct_len];
|
||||
uint8_t k[ss_len];
|
||||
uint16_t Bp[n_x_nb], C[nb_x_nb];
|
||||
|
||||
if (!this->ciphertext)
|
||||
{
|
||||
this->ciphertext = malloc(ct_len);
|
||||
}
|
||||
ct_c1 = this->ciphertext;
|
||||
ct_c2 = this->ciphertext + ct_c1_len;
|
||||
|
||||
/* pkh <- G_1(pk) */
|
||||
if (!this->xof->set_seed(this->xof, pk) ||
|
||||
!this->xof->get_bytes(this->xof, ss_len, pkh))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Generate random mu */
|
||||
if (!this->drbg->generate(this->drbg, mu_len, mu))
|
||||
{
|
||||
DBG1(DBG_LIB, "could not generate mu");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!generate(this, G2in, k, Bp, C))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
frodo_pack(ct_c1, ct_c1_len, Bp, n_x_nb, log_q);
|
||||
frodo_pack(ct_c2, ct_c2_len, C, nb_x_nb, log_q);
|
||||
|
||||
/* Compute ss = F(ct||KK) */
|
||||
memcpy(Fin_ct, this->ciphertext, ct_len);
|
||||
memcpy(Fin_k, k, ss_len);
|
||||
|
||||
if (!this->xof->set_seed(this->xof, chunk_create(Fin, ct_len + ss_len)) ||
|
||||
!this->xof->get_bytes(this->xof, ss_len, this->shared_secret))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
memwipe(mu, mu_len);
|
||||
memwipe(k, ss_len);
|
||||
memwipe(Fin_k, ss_len);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decapsulate the shared secret using the secret key
|
||||
*/
|
||||
static bool decaps_shared_secret(private_frodo_t *this)
|
||||
{
|
||||
const uint32_t n_x_nb = this->params->n * this->params->nb;
|
||||
const uint32_t nb_x_nb = this->params->nb * this->params->nb;
|
||||
const uint32_t log_q = this->params->log_q;
|
||||
const uint32_t extr_bits = this->params->extr_bits;
|
||||
const uint32_t ct_c1_len = (n_x_nb * log_q)/8;
|
||||
const uint32_t ct_c2_len = (nb_x_nb * log_q)/8;
|
||||
const uint32_t mu_len = (nb_x_nb * extr_bits)/8;
|
||||
const uint32_t ss_len = this->params->ss_len;
|
||||
const uint32_t ct_len = this->params->ct_len;
|
||||
const uint32_t pk_len = this->params->pk_len;
|
||||
|
||||
chunk_t G2in = chunk_alloca(ss_len + mu_len);
|
||||
uint8_t *pkh = G2in.ptr;
|
||||
uint8_t *muprime = G2in.ptr + ss_len;
|
||||
uint8_t *ct_c1 = this->ciphertext;
|
||||
uint8_t *ct_c2 = this->ciphertext + ct_c1_len;
|
||||
uint8_t *sk_s = this->secret_key;
|
||||
uint16_t *sk_S = (uint16_t *)(this->secret_key + ss_len + pk_len);
|
||||
uint8_t *sk_pkh = this->secret_key + ss_len + pk_len + 2*n_x_nb;
|
||||
uint8_t Fin[ct_len + ss_len];
|
||||
uint8_t *Fin_ct = &Fin[0];
|
||||
uint8_t *Fin_k = &Fin[ct_len];
|
||||
uint8_t kprime[ss_len];
|
||||
uint16_t Bp[n_x_nb], BBp[n_x_nb];
|
||||
uint16_t W[nb_x_nb], C[nb_x_nb], CC[nb_x_nb];
|
||||
|
||||
/* Compute W = C - Bp*S (mod q), and decode the randomness mu */
|
||||
frodo_unpack(Bp, n_x_nb, ct_c1, ct_c1_len, log_q);
|
||||
frodo_unpack(C, nb_x_nb, ct_c2, ct_c2_len, log_q);
|
||||
frodo_mul_bs(this->params, W, Bp, sk_S);
|
||||
frodo_sub(this->params, W, C, W);
|
||||
frodo_key_decode(this->params, (uint16_t*)muprime, W);
|
||||
memcpy(pkh, sk_pkh, ss_len);
|
||||
|
||||
if (!generate(this, G2in, kprime, BBp, CC))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Prepare input to F */
|
||||
memcpy(Fin_ct, this->ciphertext, ct_len);
|
||||
|
||||
/* Reducing BBp modulo q */
|
||||
for (int i = 0; i < n_x_nb; i++)
|
||||
{
|
||||
BBp[i] = BBp[i] & ((1 << log_q) - 1);
|
||||
}
|
||||
|
||||
/* Is (Bp == BBp & C == CC) = true */
|
||||
if (memcmp(Bp, BBp, n_x_nb * sizeof(uint16_t)) == 0 &&
|
||||
memcmp(C, CC, nb_x_nb * sizeof(uint16_t)) == 0)
|
||||
{
|
||||
/* Load k' to do ss = F(ct || k') */
|
||||
memcpy(Fin_k, kprime, ss_len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Load s to do ss = F(ct || s) */
|
||||
memcpy(Fin_k, sk_s, ss_len);
|
||||
}
|
||||
|
||||
if (!this->xof->set_seed(this->xof, chunk_create(Fin, ct_len + ss_len)) ||
|
||||
!this->xof->get_bytes(this->xof, ss_len, this->shared_secret))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Cleanup: */
|
||||
memwipe((uint8_t *)W, nb_x_nb * sizeof(uint16_t));
|
||||
memwipe(muprime, mu_len);
|
||||
memwipe(kprime, ss_len);
|
||||
memwipe(Fin_k, ss_len);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static bool set_ciphertext(private_frodo_t *this, chunk_t value)
|
||||
{
|
||||
if (value.len != this->params->ct_len)
|
||||
{
|
||||
DBG1(DBG_LIB, "wrong %N ciphertext size of %u bytes, %u bytes expected",
|
||||
key_exchange_method_names, this->method, value.len,
|
||||
this->params->ct_len);
|
||||
return FALSE;
|
||||
}
|
||||
this->ciphertext = malloc(value.len);
|
||||
memcpy(this->ciphertext, value.ptr, value.len);
|
||||
|
||||
return decaps_shared_secret(this);
|
||||
}
|
||||
|
||||
METHOD(key_exchange_t, get_public_key, bool,
|
||||
private_frodo_t *this, chunk_t *value)
|
||||
{
|
||||
/* responder action */
|
||||
if (this->ciphertext)
|
||||
{
|
||||
*value = chunk_clone(
|
||||
chunk_create(this->ciphertext, this->params->ct_len));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* initiator action */
|
||||
if (!this->secret_key)
|
||||
{
|
||||
const uint32_t n_x_nb = this->params->n * this->params->nb;
|
||||
const uint32_t log_q = this->params->log_q;
|
||||
const uint32_t seed_A_len = this->params->seed_A_len;
|
||||
const uint32_t ss_len = this->params->ss_len;
|
||||
const uint32_t pk_len = this->params->pk_len;
|
||||
|
||||
uint8_t *pk_seedA, *pk_b, *sk_pos;
|
||||
uint16_t B[n_x_nb], S[n_x_nb], E[n_x_nb];
|
||||
uint8_t randomness[ss_len + ss_len + seed_A_len];
|
||||
uint8_t *randomness_s = &randomness[0];
|
||||
uint8_t *randomness_seedSE = &randomness[ss_len];
|
||||
uint8_t *randomness_z = &randomness[ss_len + ss_len];
|
||||
uint8_t seedSE[1 + ss_len];
|
||||
|
||||
this->secret_key = malloc(this->params->sk_len);
|
||||
pk_seedA = this->public_key;
|
||||
pk_b = this->public_key + seed_A_len;
|
||||
|
||||
/* Do we need an entropy source? */
|
||||
/* TODO */
|
||||
/* Generate the secret value s and the seeds for S, E and seed_A */
|
||||
if (!need_drbg(this) ||
|
||||
!this->drbg->generate(this->drbg, 2*ss_len + seed_A_len, randomness))
|
||||
{
|
||||
DBG1(DBG_LIB, "could not generate randomness");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Generate seed_A as part of the public key */
|
||||
if (!this->xof->set_seed(this->xof,
|
||||
chunk_create(randomness_z, seed_A_len)) ||
|
||||
!this->xof->get_bytes(this->xof, seed_A_len, pk_seedA))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Generate S and E, and compute B = A*S + E. Generate A on-the-fly */
|
||||
seedSE[0] = 0x5F;
|
||||
memcpy(&seedSE[1], randomness_seedSE, ss_len);
|
||||
|
||||
if (!this->xof->set_seed(this->xof, chunk_create(seedSE, 1 + ss_len)) ||
|
||||
!this->xof->get_bytes(this->xof,
|
||||
n_x_nb * sizeof(uint16_t), (uint8_t*)S) ||
|
||||
!this->xof->get_bytes(this->xof,
|
||||
n_x_nb * sizeof(uint16_t), (uint8_t*)E))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
frodo_sample_n(this->params, S, n_x_nb);
|
||||
frodo_sample_n(this->params, E, n_x_nb);
|
||||
|
||||
if (!frodo_mul_add_as_plus_e(this->params, B, S, E, this->public_key,
|
||||
this->use_aes))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Encode the second part of the public key */
|
||||
frodo_pack(pk_b, pk_len - seed_A_len, B, n_x_nb, log_q);
|
||||
|
||||
/* Add s, pk and S to the secret key */
|
||||
sk_pos = this->secret_key;
|
||||
memcpy(sk_pos, randomness_s, ss_len);
|
||||
sk_pos += ss_len;
|
||||
memcpy(sk_pos, this->public_key, pk_len);
|
||||
sk_pos += pk_len;
|
||||
memcpy(sk_pos, S, n_x_nb * sizeof(uint16_t));
|
||||
sk_pos += n_x_nb * sizeof(uint16_t);
|
||||
|
||||
/* Add H(pk) to the secret key */
|
||||
if (!this->xof->set_seed(this->xof,
|
||||
chunk_create(this->public_key, pk_len)) ||
|
||||
!this->xof->get_bytes(this->xof, ss_len, sk_pos))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
memwipe((uint8_t *)S, n_x_nb * sizeof(uint16_t));
|
||||
memwipe((uint8_t *)E, n_x_nb * sizeof(uint16_t));
|
||||
memwipe(randomness, ss_len + ss_len + seed_A_len);
|
||||
memwipe(seedSE, 1 + ss_len);
|
||||
}
|
||||
*value = chunk_clone(chunk_create(this->public_key, this->params->pk_len));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
METHOD(key_exchange_t, get_shared_secret, bool,
|
||||
private_frodo_t *this, chunk_t *secret)
|
||||
{
|
||||
*secret = chunk_clone(
|
||||
chunk_create(this->shared_secret, this->params->ss_len));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(key_exchange_t, set_public_key, bool,
|
||||
private_frodo_t *this, chunk_t value)
|
||||
{
|
||||
/* initiator action */
|
||||
if (this->secret_key)
|
||||
{
|
||||
return set_ciphertext(this, value);
|
||||
}
|
||||
|
||||
/* responder action */
|
||||
if (value.len != this->params->pk_len)
|
||||
{
|
||||
DBG1(DBG_LIB, "wrong %N public key size of %u bytes, %u bytes expected",
|
||||
key_exchange_method_names, this->method, value.len,
|
||||
this->params->pk_len);
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(this->public_key, value.ptr, value.len);
|
||||
|
||||
return need_drbg(this) && encaps_shared_secret(this);
|
||||
}
|
||||
|
||||
|
||||
METHOD(key_exchange_t, get_method, key_exchange_method_t,
|
||||
private_frodo_t *this)
|
||||
{
|
||||
return this->method;
|
||||
}
|
||||
|
||||
METHOD(key_exchange_t, set_seed, bool,
|
||||
private_frodo_t *this, chunk_t value, drbg_t *drbg)
|
||||
{
|
||||
DESTROY_IF(this->drbg);
|
||||
this->drbg = drbg->get_ref(drbg);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(key_exchange_t, destroy, void,
|
||||
private_frodo_t *this)
|
||||
{
|
||||
DESTROY_IF(this->drbg);
|
||||
this->xof->destroy(this->xof);
|
||||
|
||||
memwipe(this->secret_key, this->params->sk_len);
|
||||
free(this->secret_key);
|
||||
memwipe(this->shared_secret, this->params->ss_len);
|
||||
free(this->shared_secret);
|
||||
free(this->public_key);
|
||||
free(this->ciphertext);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Described in header.
|
||||
*/
|
||||
frodo_t *frodo_create(key_exchange_method_t method)
|
||||
{
|
||||
private_frodo_t *this;
|
||||
const frodo_params_t *params;
|
||||
frodo_kem_type_t id;
|
||||
bool use_aes;
|
||||
xof_t *xof;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case KE_FRODO_SHAKE_L1:
|
||||
id = FRODO_KEM_L1;
|
||||
use_aes = FALSE;
|
||||
break;
|
||||
case KE_FRODO_SHAKE_L3:
|
||||
id = FRODO_KEM_L3;
|
||||
use_aes = FALSE;
|
||||
break;
|
||||
case KE_FRODO_SHAKE_L5:
|
||||
id = FRODO_KEM_L5;
|
||||
use_aes = FALSE;
|
||||
break;
|
||||
case KE_FRODO_AES_L1:
|
||||
id = FRODO_KEM_L1;
|
||||
use_aes = TRUE;
|
||||
break;
|
||||
case KE_FRODO_AES_L3:
|
||||
id = FRODO_KEM_L3;
|
||||
use_aes = TRUE;
|
||||
break;
|
||||
case KE_FRODO_AES_L5:
|
||||
id = FRODO_KEM_L5;
|
||||
use_aes = TRUE;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
params = frodo_params_get_by_id(id);
|
||||
|
||||
xof = lib->crypto->create_xof(lib->crypto, params->xof_type);
|
||||
if (!xof)
|
||||
{
|
||||
DBG1(DBG_LIB, "could not instantiate %N", ext_out_function_names,
|
||||
params->xof_type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.ke = {
|
||||
.get_method = _get_method,
|
||||
.get_public_key = _get_public_key,
|
||||
.set_public_key = _set_public_key,
|
||||
.get_shared_secret = _get_shared_secret,
|
||||
.set_seed = _set_seed,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.method = method,
|
||||
.use_aes = use_aes,
|
||||
.params = params,
|
||||
.xof = xof,
|
||||
.public_key = malloc(params->pk_len),
|
||||
.shared_secret = malloc(params->ss_len),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup frodo frodo
|
||||
* @{ @ingroup frodo_p
|
||||
*/
|
||||
|
||||
#ifndef FRODO_H_
|
||||
#define FRODO_H_
|
||||
|
||||
typedef struct frodo_t frodo_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Quantum-safe key encapsulation implementation using FrodoKEM
|
||||
*/
|
||||
struct frodo_t {
|
||||
|
||||
/**
|
||||
* Implements key_exchange_t interface.
|
||||
*/
|
||||
key_exchange_t ke;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new frodo_t object.
|
||||
*
|
||||
* @param method key exchange method
|
||||
* @return frodo_t object, NULL if not supported
|
||||
*/
|
||||
frodo_t *frodo_create(key_exchange_method_t method);
|
||||
|
||||
#endif /** FRODO_H_ @}*/
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (C) Microsoft Corporation
|
||||
*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "frodo_params.h"
|
||||
|
||||
const uint16_t cdf_table_1[] = { 4643, 13363, 20579, 25843, 29227,
|
||||
31145, 32103, 32525, 32689, 32745,
|
||||
32762, 32766, 32767
|
||||
};
|
||||
const uint16_t cdf_table_3[] = { 5638, 15915, 23689, 28571, 31116,
|
||||
32217, 32613, 32731, 32760, 32766,
|
||||
32767
|
||||
};
|
||||
const uint16_t cdf_table_5[] = { 9142, 23462, 30338, 32361, 32725,
|
||||
32765, 32767
|
||||
};
|
||||
|
||||
/**
|
||||
* FrodoKEM parameter definitions
|
||||
*/
|
||||
static const frodo_params_t frodo_params[] = {
|
||||
|
||||
{
|
||||
FRODO_KEM_L1, /* Frodo KEM ID */
|
||||
640, /* Lattice dimension n */
|
||||
8, /* Dimension n_bar */
|
||||
15, /* Logarithm of modulus q */
|
||||
2, /* Extracted bits extr_bits */
|
||||
16, /* Size of seed_A seed_A_len */
|
||||
16, /* Size of shared secret ss_len */
|
||||
9720, /* Size of ciphertext ct_len */
|
||||
9616, /* Size of public key pk_len */
|
||||
19888, /* Size of secret key sk_len */
|
||||
13, /* Size of CDF table cdf_table_len */
|
||||
cdf_table_1, /* CDF table */
|
||||
XOF_SHAKE_128, /* SHAKE XOF */
|
||||
},
|
||||
|
||||
{
|
||||
FRODO_KEM_L3, /* Frodo KEM ID */
|
||||
976, /* Lattice dimension n */
|
||||
8, /* Dimension n_bar */
|
||||
16, /* Logarithm of modulus q */
|
||||
3, /* Extracted bits extr_bits */
|
||||
16, /* Size of seed_A seed_A_len */
|
||||
24, /* Size of shared secret ss_len */
|
||||
15744, /* Size of ciphertext ct_len */
|
||||
15632, /* Size of public key pk_len */
|
||||
31296, /* Size of secret key sk_len */
|
||||
11, /* Size of CDF table cdf_table_len */
|
||||
cdf_table_3, /* CDF table */
|
||||
XOF_SHAKE_256, /* SHAKE XOF */
|
||||
},
|
||||
|
||||
{
|
||||
FRODO_KEM_L5, /* Frodo KEM ID */
|
||||
1344, /* Lattice dimension n */
|
||||
8, /* Dimension n_bar */
|
||||
16, /* Logarithm of modulus q */
|
||||
4, /* Extracted bits extr_bits */
|
||||
16, /* Size of seed_A seed_A_len */
|
||||
32, /* Size of shared secret ss_len */
|
||||
21632, /* Size of ciphertext ct_len */
|
||||
21520, /* Size of public key pk_len */
|
||||
43088, /* Size of secret key sk_len */
|
||||
7, /* Size of CDF table cdf_table_len */
|
||||
cdf_table_5, /* CDF table */
|
||||
XOF_SHAKE_256, /* SHAKE XOF */
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
const frodo_params_t* frodo_params_get_by_id(frodo_kem_type_t id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < countof(frodo_params); i++)
|
||||
{
|
||||
if (frodo_params[i].id == id)
|
||||
{
|
||||
return &frodo_params[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (C) Microsoft Corporation
|
||||
*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup frodo_params frodo_params
|
||||
* @{ @ingroup frodo_p
|
||||
*/
|
||||
|
||||
#ifndef FRODO_PARAMS_H_
|
||||
#define FRODO_PARAMS_H_
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct frodo_params_t frodo_params_t;
|
||||
typedef enum frodo_kem_type_t frodo_kem_type_t;
|
||||
|
||||
/**
|
||||
* FrodoKEM types with various security strengths
|
||||
*/
|
||||
enum frodo_kem_type_t {
|
||||
FRODO_KEM_L1,
|
||||
FRODO_KEM_L3,
|
||||
FRODO_KEM_L5,
|
||||
};
|
||||
|
||||
/**
|
||||
* FrodoKEM parameter definitions
|
||||
*/
|
||||
struct frodo_params_t {
|
||||
|
||||
/**
|
||||
* Frodo key exchange ID
|
||||
*/
|
||||
const frodo_kem_type_t id;
|
||||
|
||||
/**
|
||||
* Lattice dimension
|
||||
*/
|
||||
const uint32_t n;
|
||||
|
||||
/**
|
||||
* Dimension n_bar
|
||||
*/
|
||||
const uint32_t nb;
|
||||
|
||||
/**
|
||||
* Logarithm of modulus q
|
||||
*/
|
||||
const uint32_t log_q;
|
||||
|
||||
/**
|
||||
* Extracted bits
|
||||
*/
|
||||
const uint32_t extr_bits;
|
||||
|
||||
/**
|
||||
* Size of seed_A
|
||||
*/
|
||||
const uint32_t seed_A_len;
|
||||
|
||||
/**
|
||||
* Size of shared secret
|
||||
*/
|
||||
const uint32_t ss_len;
|
||||
|
||||
/**
|
||||
* Size of ciphertext
|
||||
*/
|
||||
const uint32_t ct_len;
|
||||
|
||||
/**
|
||||
* Size of public key
|
||||
*/
|
||||
const uint32_t pk_len;
|
||||
|
||||
/**
|
||||
* Size of secret key
|
||||
*/
|
||||
const uint32_t sk_len;
|
||||
|
||||
/**
|
||||
* Size of CDF table
|
||||
*/
|
||||
const uint32_t cdf_table_len;
|
||||
|
||||
/**
|
||||
* CDF table
|
||||
*/
|
||||
const uint16_t *cdf_table;
|
||||
|
||||
/**
|
||||
* SHAKE extended output function
|
||||
*/
|
||||
ext_out_function_t xof_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Frodo parameters by Frodo key exchange ID
|
||||
*
|
||||
* @param id Frodo KEM ID
|
||||
* @return Frodo parameters
|
||||
*/
|
||||
const frodo_params_t* frodo_params_get_by_id(frodo_kem_type_t id);
|
||||
|
||||
#endif /** FRODO_PARAMS_H_ @}*/
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
#include "frodo_plugin.h"
|
||||
#include "frodo.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
typedef struct private_frodo_plugin_t private_frodo_plugin_t;
|
||||
|
||||
/**
|
||||
* private data of frodo_plugin
|
||||
*/
|
||||
struct private_frodo_plugin_t {
|
||||
|
||||
/**
|
||||
* public functions
|
||||
*/
|
||||
frodo_plugin_t public;
|
||||
};
|
||||
|
||||
METHOD(plugin_t, get_name, char*,
|
||||
private_frodo_plugin_t *this)
|
||||
{
|
||||
return "frodo";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_frodo_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_REGISTER(KE, frodo_create),
|
||||
PLUGIN_PROVIDE(KE, KE_FRODO_SHAKE_L1),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_128),
|
||||
PLUGIN_DEPENDS(DRBG, DRBG_CTR_AES256),
|
||||
PLUGIN_DEPENDS(RNG, RNG_TRUE),
|
||||
PLUGIN_PROVIDE(KE, KE_FRODO_SHAKE_L3),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_256),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_128),
|
||||
PLUGIN_DEPENDS(DRBG, DRBG_CTR_AES256),
|
||||
PLUGIN_DEPENDS(RNG, RNG_TRUE),
|
||||
PLUGIN_PROVIDE(KE, KE_FRODO_SHAKE_L5),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_256),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_128),
|
||||
PLUGIN_DEPENDS(DRBG, DRBG_CTR_AES256),
|
||||
PLUGIN_DEPENDS(RNG, RNG_TRUE),
|
||||
PLUGIN_PROVIDE(KE, KE_FRODO_AES_L1),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_128),
|
||||
PLUGIN_DEPENDS(CRYPTER, ENCR_AES_ECB, 16),
|
||||
PLUGIN_DEPENDS(DRBG, DRBG_CTR_AES256),
|
||||
PLUGIN_DEPENDS(RNG, RNG_TRUE),
|
||||
PLUGIN_PROVIDE(KE, KE_FRODO_AES_L3),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_256),
|
||||
PLUGIN_DEPENDS(CRYPTER, ENCR_AES_ECB, 16),
|
||||
PLUGIN_DEPENDS(DRBG, DRBG_CTR_AES256),
|
||||
PLUGIN_DEPENDS(RNG, RNG_TRUE),
|
||||
PLUGIN_PROVIDE(KE, KE_FRODO_AES_L5),
|
||||
PLUGIN_DEPENDS(XOF, XOF_SHAKE_256),
|
||||
PLUGIN_DEPENDS(CRYPTER, ENCR_AES_ECB, 16),
|
||||
PLUGIN_DEPENDS(DRBG, DRBG_CTR_AES256),
|
||||
PLUGIN_DEPENDS(RNG, RNG_TRUE),
|
||||
};
|
||||
*features = f;
|
||||
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_frodo_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* see header file
|
||||
*/
|
||||
plugin_t *frodo_plugin_create()
|
||||
{
|
||||
private_frodo_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup frodo_p frodo
|
||||
* @ingroup plugins
|
||||
*
|
||||
* @defgroup frodo_plugin frodo_plugin
|
||||
* @{ @ingroup frodo_p
|
||||
*/
|
||||
|
||||
#ifndef FRODO_PLUGIN_H_
|
||||
#define FRODO_PLUGIN_H_
|
||||
|
||||
#include <plugins/plugin.h>
|
||||
|
||||
typedef struct frodo_plugin_t frodo_plugin_t;
|
||||
|
||||
/**
|
||||
* Plugin implementing Frodo-based key exchange
|
||||
*/
|
||||
struct frodo_plugin_t {
|
||||
|
||||
/**
|
||||
* implements plugin interface
|
||||
*/
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
#endif /** FRODO_PLUGIN_H_ @}*/
|
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (C) Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "frodo_utils.h"
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_pack(u_char *out, size_t outlen, uint16_t *in, size_t inlen,
|
||||
u_char lsb)
|
||||
{
|
||||
size_t i = 0; /* whole bytes already filled in */
|
||||
size_t j = 0; /* whole uint16_t already copied */
|
||||
uint16_t w = 0; /* the leftover, not yet copied */
|
||||
u_char bits = 0; /* the number of lsb in w */
|
||||
|
||||
memset(out, 0x00, outlen);
|
||||
|
||||
while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0))))
|
||||
{
|
||||
u_char b = 0; /* bits in out[i] already filled in */
|
||||
|
||||
/**
|
||||
* in: | | |********|********|
|
||||
* ^
|
||||
* j
|
||||
* w : | ****|
|
||||
* ^
|
||||
* bits
|
||||
* out:|**|**|**|**|**|**|**|**|* |
|
||||
* ^^
|
||||
* ib
|
||||
*/
|
||||
while (b < 8)
|
||||
{
|
||||
int nbits = min(8 - b, bits);
|
||||
uint16_t mask = (1 << nbits) - 1;
|
||||
u_char t = (w >> (bits - nbits)) & mask; /* the bits to copy from w to out */
|
||||
|
||||
out[i] = out[i] + (t << (8 - b - nbits));
|
||||
b += nbits;
|
||||
bits -= nbits;
|
||||
|
||||
/* not strictly necessary; mostly for debugging */
|
||||
w &= ~(mask << bits);
|
||||
|
||||
if (bits == 0)
|
||||
{
|
||||
if (j < inlen)
|
||||
{
|
||||
w = in[j];
|
||||
bits = lsb;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; /* the input vector is exhausted */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (b == 8)
|
||||
{
|
||||
i++; /* out[i] is filled in */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_unpack(uint16_t *out, size_t outlen, u_char *in, size_t inlen,
|
||||
u_char lsb)
|
||||
{
|
||||
size_t i = 0; /* whole uint16_t already filled in */
|
||||
size_t j = 0; /* whole bytes already copied */
|
||||
u_char w = 0; /* the leftover, not yet copied */
|
||||
u_char bits = 0; /* the number of lsb bits of w */
|
||||
|
||||
memset(out, 0, outlen * sizeof(uint16_t));
|
||||
|
||||
while (i < outlen && (j < inlen || ((j == inlen) && (bits > 0))))
|
||||
{
|
||||
u_char b = 0; /* bits in out[i] already filled in */
|
||||
|
||||
/**
|
||||
* in: | | | | | | |**|**|...
|
||||
* ^
|
||||
* j
|
||||
* w : | *|
|
||||
* ^
|
||||
* bits
|
||||
* out:| *****| *****| *** | |...
|
||||
* ^ ^
|
||||
* i b
|
||||
*/
|
||||
while (b < lsb)
|
||||
{
|
||||
int nbits = min(lsb - b, bits);
|
||||
uint16_t mask = (1 << nbits) - 1;
|
||||
u_char t = (w >> (bits - nbits)) & mask; /* the bits to copy from w to out */
|
||||
|
||||
out[i] = out[i] + (t << (lsb - b - nbits));
|
||||
b += nbits;
|
||||
bits -= nbits;
|
||||
|
||||
/* not strictly necessary; mostly for debugging */
|
||||
w &= ~(mask << bits);
|
||||
|
||||
if (bits == 0)
|
||||
{
|
||||
if (j < inlen)
|
||||
{
|
||||
w = in[j];
|
||||
bits = 8;
|
||||
j++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; /* the input vector is exhausted */
|
||||
}
|
||||
}
|
||||
}
|
||||
if (b == lsb)
|
||||
{
|
||||
i++; /* out[i] is filled in */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_sample_n(const frodo_params_t *params, uint16_t *s, size_t n)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
uint8_t sample = 0;
|
||||
uint16_t prnd = s[i] >> 1; /* Drop the least significant bit */
|
||||
uint8_t sign = s[i] & 0x1; /* Pick the least significant bit */
|
||||
|
||||
/* No need to compare with the last value */
|
||||
for (j = 0; j < params->cdf_table_len - 1; j++)
|
||||
{
|
||||
/**
|
||||
* Constant time comparison: 1 if CDF_TABLE[j] < s, 0 otherwise.
|
||||
* Uses the fact that CDF_TABLE[j] and s fit in 15 bits
|
||||
*/
|
||||
sample += (uint16_t)(params->cdf_table[j] - prnd) >> 15;
|
||||
}
|
||||
/* Assuming that sign is either 0 or 1, flips sample iff sign = 1 */
|
||||
s[i] = ((-sign) ^ sample) + sign;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate square matrix A by using SHAKE128
|
||||
*/
|
||||
static bool generate_matrix_by_shake(const frodo_params_t *params, uint16_t *A,
|
||||
uint8_t *seed_A)
|
||||
{
|
||||
const uint32_t seed_A_len = params->seed_A_len;
|
||||
const uint32_t n = params->n;
|
||||
|
||||
uint8_t seed_A_separated[2 + seed_A_len];
|
||||
uint16_t *seed_A_origin = (uint16_t*)&seed_A_separated;
|
||||
uint16_t i;
|
||||
bool success = FALSE;
|
||||
xof_t *xof;
|
||||
|
||||
memcpy(&seed_A_separated[2], seed_A, seed_A_len);
|
||||
|
||||
/* Instantiate a SHAKE-128 eXtended Output Function */
|
||||
xof = lib->crypto->create_xof(lib->crypto, XOF_SHAKE_128);
|
||||
if (!xof)
|
||||
{
|
||||
DBG1(DBG_LIB, "could not instantiate %N", ext_out_function_names,
|
||||
XOF_SHAKE_128);
|
||||
return FALSE;
|
||||
}
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
seed_A_origin[0] = i;
|
||||
|
||||
if (!xof->set_seed(xof, chunk_create(seed_A_separated, 2 + seed_A_len)))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
if (!xof->get_bytes(xof, 2*n, (uint8_t*)(A + i*n)))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
success = TRUE;
|
||||
|
||||
err:
|
||||
xof->destroy(xof);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate square matrix A by using AES128
|
||||
*/
|
||||
static bool generate_matrix_by_aes(const frodo_params_t *params, uint16_t *A,
|
||||
uint8_t *seed_A)
|
||||
{
|
||||
const uint32_t n = params->n;
|
||||
const uint32_t A_len = n * n * sizeof(uint16_t);
|
||||
|
||||
crypter_t *crypter;
|
||||
chunk_t A_chunk;
|
||||
bool success = FALSE;
|
||||
uint32_t block_len, step, k;
|
||||
uint16_t i, j;
|
||||
|
||||
memset((uint8_t*)A, 0x00, A_len);
|
||||
|
||||
crypter = lib->crypto->create_crypter(lib->crypto, ENCR_AES_ECB, 16);
|
||||
if (!crypter)
|
||||
{
|
||||
DBG1(DBG_LIB, "could not instantiate AES_ECB-128");
|
||||
return FALSE;
|
||||
}
|
||||
block_len = crypter->get_block_size(crypter);
|
||||
step = block_len / sizeof(uint16_t);
|
||||
|
||||
if (!crypter->set_key(crypter, chunk_create(seed_A, params->seed_A_len)))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* ECB encryption */
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (j = 0; j < n; j += step)
|
||||
{
|
||||
k = i*n + j;
|
||||
A[k] = i;
|
||||
A[k + 1] = j;
|
||||
}
|
||||
}
|
||||
A_chunk = chunk_create((uint8_t*)A, A_len);
|
||||
|
||||
if (!crypter->encrypt(crypter, A_chunk, chunk_empty, NULL))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
success = TRUE;
|
||||
|
||||
err:
|
||||
crypter->destroy(crypter);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
bool frodo_mul_add_as_plus_e(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *s, uint16_t *e, uint8_t *seed_A,
|
||||
bool use_aes)
|
||||
{
|
||||
const uint32_t n = params->n;
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t n_x_n = n * n;
|
||||
|
||||
int16_t A[n_x_n];
|
||||
int i, j, k;
|
||||
|
||||
if (use_aes ? !generate_matrix_by_aes (params, A, seed_A) :
|
||||
!generate_matrix_by_shake(params, A, seed_A))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(out, e, nb * n * sizeof(uint16_t));
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
/* Matrix multiplication-addition A*s + e */
|
||||
for (k = 0; k < nb; k++)
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
sum += A[i*n + j] * s[k*n + j];
|
||||
}
|
||||
|
||||
/* Adding e. No need to reduce modulo 2^15,
|
||||
* extra bits are taken care of during packing later on.
|
||||
*/
|
||||
out[i*nb + k] += sum;}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
bool frodo_mul_add_sa_plus_e(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *s, uint16_t *e, uint8_t *seed_A,
|
||||
bool use_aes)
|
||||
{
|
||||
const uint32_t n = params->n;
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t n_x_n = n * n;
|
||||
|
||||
int16_t A[n_x_n];
|
||||
int i, j, k;
|
||||
|
||||
if (use_aes ? !generate_matrix_by_aes (params, A, seed_A) :
|
||||
!generate_matrix_by_shake(params, A, seed_A))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
memcpy(out, e, nb * n * sizeof(uint16_t));
|
||||
|
||||
/* Matrix multiplication-addition A*s + e*/
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (k = 0; k < nb; k++)
|
||||
{
|
||||
uint16_t sum = 0;
|
||||
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
sum += A[j*n + i] * s[k*n + j];
|
||||
}
|
||||
|
||||
/* Adding e. No need to reduce modulo 2^15,
|
||||
* extra bits are taken care of during packing later on.
|
||||
*/
|
||||
out[k*n + i] += sum;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_mul_add_sb_plus_e(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *b, uint16_t *s, uint16_t *e)
|
||||
{
|
||||
const uint32_t n = params->n;
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t log_q = params->log_q;
|
||||
|
||||
int i, j, k;
|
||||
|
||||
for (k = 0; k < nb; k++)
|
||||
{
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
out[k*nb + i] = e[k*nb + i];
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
out[k*nb + i] += s[k*n + j] * b[j*nb + i];
|
||||
}
|
||||
out[k*nb + i] = (uint32_t)(out[k*nb + i]) & ((1 << log_q) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_mul_bs(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *b, uint16_t *s)
|
||||
{
|
||||
const uint32_t n = params->n;
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t log_q = params->log_q;
|
||||
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0; i < nb; i++)
|
||||
{
|
||||
for (j = 0; j < nb; j++)
|
||||
{
|
||||
out[i*nb + j] = 0;
|
||||
for (k = 0; k < n; k++)
|
||||
{
|
||||
out[i*nb + j] += b[i*n + k] * s[j*n + k];
|
||||
}
|
||||
out[i*nb + j] = (uint32_t)(out[i*nb + j]) & ((1 << log_q) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_add(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *a, uint16_t *b)
|
||||
{
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t log_q = params->log_q;
|
||||
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < (nb * nb); i++)
|
||||
{
|
||||
out[i] = (a[i] + b[i]) & ((1 << log_q) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void frodo_sub(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *a, uint16_t *b)
|
||||
{
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t log_q = params->log_q;
|
||||
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < (nb * nb); i++)
|
||||
{
|
||||
out[i] = (a[i] - b[i]) & ((1 << log_q) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_key_encode(const frodo_params_t *params, uint16_t *out, uint16_t *in)
|
||||
{
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t log_q = params->log_q;
|
||||
const uint32_t extr_bits = params->extr_bits;
|
||||
|
||||
u_int i, j, npieces_word = 8;
|
||||
u_int nwords = (nb * nb)/8;
|
||||
uint64_t temp, mask = ((uint64_t)1 << extr_bits) - 1;
|
||||
uint16_t* pos = out;
|
||||
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
temp = 0;
|
||||
for(j = 0; j < extr_bits; j++)
|
||||
{
|
||||
temp |= ((uint64_t)((uint8_t*)in)[i*extr_bits + j]) << (8*j);
|
||||
}
|
||||
for (j = 0; j < npieces_word; j++)
|
||||
{
|
||||
*pos = (uint16_t)((temp & mask) << (log_q - extr_bits));
|
||||
temp >>= extr_bits;
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
void frodo_key_decode(const frodo_params_t *params, uint16_t *out, uint16_t *in)
|
||||
{
|
||||
const uint32_t nb = params->nb;
|
||||
const uint32_t log_q = params->log_q;
|
||||
const uint32_t extr_bits = params->extr_bits;
|
||||
|
||||
u_int i, j, index = 0, npieces_word = 8;
|
||||
u_int nwords = (nb * nb) / 8;
|
||||
uint16_t temp;
|
||||
u_int maskex = ((uint16_t)1 << extr_bits) - 1;
|
||||
u_int maskq = ((uint16_t)1 << log_q) - 1;
|
||||
uint8_t *pos = (uint8_t*)out;
|
||||
uint64_t templong;
|
||||
|
||||
for (i = 0; i < nwords; i++)
|
||||
{
|
||||
templong = 0;
|
||||
for (j = 0; j < npieces_word; j++)
|
||||
{
|
||||
/* temp = floor(in*2^{-11}+0.5) */
|
||||
temp = ((in[index] & maskq) +
|
||||
(1 << (log_q - extr_bits - 1))) >> (log_q - extr_bits);
|
||||
templong |= ((uint64_t)(temp & maskex)) << (extr_bits * j);
|
||||
index++;
|
||||
}
|
||||
for(j = 0; j < extr_bits; j++)
|
||||
{
|
||||
pos[i*extr_bits + j] = (templong >> (8*j)) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (C) Microsoft Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup frodo_utils frodo_utls
|
||||
* @{ @ingroup frodo_p
|
||||
*/
|
||||
|
||||
#ifndef FRODO_UTILS_H_
|
||||
#define FRODO_UTILS_H_
|
||||
|
||||
#include "frodo_params.h"
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Pack the input uint16 vector into a char output vector,
|
||||
* copying lsb bits from each input element.
|
||||
* If inlen * lsb / 8 > outlen, only outlen * 8 bits are copied.
|
||||
*
|
||||
* @param out
|
||||
* @param outlen
|
||||
* @param in
|
||||
* @param inlen
|
||||
* @param lsb
|
||||
*/
|
||||
void frodo_pack(u_char *out, size_t outlen, uint16_t *in, size_t inlen,
|
||||
u_char lsb);
|
||||
|
||||
/**
|
||||
* Unpack the input char vector into a uint16_t output vector,
|
||||
* copying lsb bits for each output element from input.
|
||||
* outlen must be at least ceil(inlen * 8 / lsb).
|
||||
*
|
||||
* @param out
|
||||
* @param outlen
|
||||
* @param in
|
||||
* @param inlen
|
||||
* @param lsb
|
||||
*/
|
||||
void frodo_unpack(uint16_t *out, size_t outlen, u_char *in, size_t inlen,
|
||||
u_char lsb);
|
||||
|
||||
/**
|
||||
* Fills vector s with n samples from the noise distribution which requires
|
||||
* 16 bits to sample. The distribution is specified by its CDF.
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param s pseudo-random values (are overwritten by output)
|
||||
* @param n size of s
|
||||
*/
|
||||
void frodo_sample_n(const frodo_params_t *params, uint16_t *s, size_t n);
|
||||
|
||||
/**
|
||||
* Generate-and-multiply: generate matrix A (N x N) row-wise,
|
||||
* multiply by s on the right.
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param out out = A*s + e (N x N_BAR)
|
||||
* @param s array (N x N_BAR)
|
||||
* @param e array (N x N_BAR)
|
||||
* @param seed_A seed for matrix A
|
||||
* @param use_aes if TRUE use AES128 for matrix A, otherwise use SHAKE128
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
bool frodo_mul_add_as_plus_e(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *s, uint16_t *e, uint8_t *seed_A,
|
||||
bool use_aes);
|
||||
|
||||
/**
|
||||
* Generate-and-multiply: generate matrix A (N x N) column-wise,
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param out out = s'*A + e' (N_BAR x N)
|
||||
* @param s array (N_BAR x N)
|
||||
* @param e array (N_BAR x N)
|
||||
* @param seed_A seed for matrix A
|
||||
* @param use_aes if TRUE use AES128 for matrix A, otherwise use SHAKE128
|
||||
* @return TRUE if successful
|
||||
*/
|
||||
bool frodo_mul_add_sa_plus_e(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *s, uint16_t *e, uint8_t *seed_A,
|
||||
bool use_aes);
|
||||
|
||||
/**
|
||||
* Multiply by s on the left
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param b array (N x N_BAR)
|
||||
* @param s array (N_BAR x N)
|
||||
* @param e array (N_BAR x N_BAR)
|
||||
* @param out out = s*b + e (N_BAR x N_BAR)
|
||||
*/
|
||||
void frodo_mul_add_sb_plus_e(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *b, uint16_t *s, uint16_t *e);
|
||||
|
||||
/**
|
||||
* Multiply by s on the right
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param out out = b*s (N_BAR x N_BAR)
|
||||
* @param b array (N_BAR x N),
|
||||
* @param s array (N x N_BAR)
|
||||
*/
|
||||
void frodo_mul_bs(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *b, uint16_t *s);
|
||||
|
||||
/**
|
||||
* Add a and b
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param out c = a + b (N_BAR x N_AR)
|
||||
* @param a array (N_BAR x N_BAR)
|
||||
* @param b array (N_BAR x N_BAR)
|
||||
*/
|
||||
void frodo_add(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *a, uint16_t *b);
|
||||
|
||||
/**
|
||||
* Subtract a and b
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param out c = a - b (N_BAR x N_AR)
|
||||
* @param a array (N_BAR x N_BAR)
|
||||
* @param b array (N_BAR x N_BAR)
|
||||
*/
|
||||
void frodo_sub(const frodo_params_t *params, uint16_t *out,
|
||||
uint16_t *a, uint16_t *b);
|
||||
|
||||
/**
|
||||
* Encode
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param out encoded key
|
||||
* @param in key to be encoded
|
||||
*/
|
||||
void frodo_key_encode(const frodo_params_t *params, uint16_t *out, uint16_t *in);
|
||||
|
||||
/**
|
||||
* Decode
|
||||
*
|
||||
* @param params parameter set
|
||||
* @param out decoded key
|
||||
* @param in key to be decoded
|
||||
*/
|
||||
void frodo_key_decode(const frodo_params_t *params, uint16_t *out, uint16_t *in);
|
||||
|
||||
#endif /** FRODO_UTILS_H_ @}*/
|
Loading…
Reference in New Issue