/* * SPDX-License-Identifier: Apache-2.0 * * This file was generated from * https://github.com/pq-crystals/kyber/commit/e0d1c6ff * * Files from that repository are listed here surrounded by * "* begin: [file] *" and "* end: [file] *" comments. * * The following changes have been made: * - include guards have been removed, * - include directives have been removed, * - "#ifdef KYBER90S" blocks have been evaluated with "KYBER90S" undefined, * - functions outside of kem.c have been made static.
*/
For Keccak and AES we are using public-domain code from sources and by authors listed in comments on top of the respective files.
** end: ref/LICENSE **/
/** begin: ref/AUTHORS ** Joppe Bos, Léo Ducas, Eike Kiltz, Tancrède Lepoint, Vadim Lyubashevsky, John Schanck, Peter Schwabe, Gregor Seiler, Damien Stehlé
** end: ref/AUTHORS **/
// We need to provide an implementation of randombytes to avoid an unused // function warning. We don't use the randomized API in freebl, so we'll make // calling randombytes an error. staticvoid
randombytes(uint8_t *out, size_t outlen)
{ // this memset is to avoid "maybe-uninitialized" warnings that gcc-11 issues // for the (unused) crypto_kem_keypair and crypto_kem_enc functions.
memset(out, 0, outlen);
assert(0);
}
/************************************************* * Name: verify * * Description: Compare two arrays for equality in constant time. * * Arguments: const uint8_t *a: pointer to first byte array * const uint8_t *b: pointer to second byte array * size_t len: length of the byte arrays * * Returns 0 if the byte arrays are equal, 1 otherwise
**************************************************/ staticint
verify(const uint8_t *a, const uint8_t *b, size_t len)
{ return NSS_SecureMemcmp(a, b, len);
}
/************************************************* * Name: cmov * * Description: Copy len bytes from x to r if b is 1; * don't modify x if b is 0. Requires b to be in {0,1}; * assumes two's complement representation of negative integers. * Runs in constant time. * * Arguments: uint8_t *r: pointer to output byte array * const uint8_t *x: pointer to input byte array * size_t len: Amount of bytes to be copied * uint8_t b: Condition bit; has to be in {0,1}
**************************************************/ staticvoid
cmov(uint8_t *r, const uint8_t *x, size_t len, uint8_t b)
{
NSS_SecureSelect(r, r, x, len, b);
}
/** begin: ref/params.h **/ #ifndef KYBER_K #define KYBER_K 3 /* Change this for different security strengths */ #endif
//#define KYBER_90S /* Uncomment this if you want the 90S variant */
/* Don't change parameters below this line */ #if (KYBER_K == 2) #define KYBER_NAMESPACE(s) pqcrystals_kyber512_ref_##s #elif (KYBER_K == 3) #define KYBER_NAMESPACE(s) pqcrystals_kyber768_ref_##s #elif (KYBER_K == 4) #define KYBER_NAMESPACE(s) pqcrystals_kyber1024_ref_##s #else #error"KYBER_K must be in {2,3,4}" #endif
#define KYBER_N 256 #define KYBER_Q 3329
#define KYBER_SYMBYTES 32 /* size in bytes of hashes, and seeds */ #define KYBER_SSBYTES 32 /* size in bytes of shared key */
/** begin: ref/reduce.c **/ /************************************************* * Name: montgomery_reduce * * Description: Montgomery reduction; given a 32-bit integer a, computes * 16-bit integer congruent to a * R^-1 mod q, where R=2^16 * * Arguments: - int32_t a: input integer to be reduced; * has to be in {-q2^15,...,q2^15-1} * * Returns: integer in {-q+1,...,q-1} congruent to a * R^-1 modulo q.
**************************************************/ static int16_t
montgomery_reduce(int32_t a)
{
int16_t t;
t = (int16_t)a * QINV;
t = (a - (int32_t)t * KYBER_Q) >> 16; return t;
}
/************************************************* * Name: barrett_reduce * * Description: Barrett reduction; given a 16-bit integer a, computes * centered representative congruent to a mod q in {-(q-1)/2,...,(q-1)/2} * * Arguments: - int16_t a: input integer to be reduced * * Returns: integer in {-(q-1)/2,...,(q-1)/2} congruent to a modulo q.
**************************************************/ static int16_t
barrett_reduce(int16_t a)
{
int16_t t; const int16_t v = ((1 << 26) + KYBER_Q / 2) / KYBER_Q;
t = ((int32_t)v * a + (1 << 25)) >> 26;
t *= KYBER_Q; return a - t;
} /** end: ref/reduce.c **/
/** begin: ref/cbd.c **/ /************************************************* * Name: load32_littleendian * * Description: load 4 bytes into a 32-bit integer * in little-endian order * * Arguments: - const uint8_t *x: pointer to input byte array * * Returns 32-bit unsigned integer loaded from x
**************************************************/ static uint32_t
load32_littleendian(const uint8_t x[4])
{
uint32_t r;
r = (uint32_t)x[0];
r |= (uint32_t)x[1] << 8;
r |= (uint32_t)x[2] << 16;
r |= (uint32_t)x[3] << 24; return r;
}
/************************************************* * Name: load24_littleendian * * Description: load 3 bytes into a 32-bit integer * in little-endian order. * This function is only needed for Kyber-512 * * Arguments: - const uint8_t *x: pointer to input byte array * * Returns 32-bit unsigned integer loaded from x (most significant byte is zero)
**************************************************/ #if KYBER_ETA1 == 3 static uint32_t
load24_littleendian(const uint8_t x[3])
{
uint32_t r;
r = (uint32_t)x[0];
r |= (uint32_t)x[1] << 8;
r |= (uint32_t)x[2] << 16; return r;
} #endif
/************************************************* * Name: cbd2 * * Description: Given an array of uniformly random bytes, compute * polynomial with coefficients distributed according to * a centered binomial distribution with parameter eta=2 * * Arguments: - poly *r: pointer to output polynomial * - const uint8_t *buf: pointer to input byte array
**************************************************/ staticvoid
cbd2(poly *r, const uint8_t buf[2 * KYBER_N / 4])
{ unsignedint i, j;
uint32_t t, d;
int16_t a, b;
for (i = 0; i < KYBER_N / 8; i++) {
t = load32_littleendian(buf + 4 * i);
d = t & 0x55555555;
d += (t >> 1) & 0x55555555;
for (j = 0; j < 8; j++) {
a = (d >> (4 * j + 0)) & 0x3;
b = (d >> (4 * j + 2)) & 0x3;
r->coeffs[8 * i + j] = a - b;
}
}
}
/************************************************* * Name: cbd3 * * Description: Given an array of uniformly random bytes, compute * polynomial with coefficients distributed according to * a centered binomial distribution with parameter eta=3. * This function is only needed for Kyber-512 * * Arguments: - poly *r: pointer to output polynomial * - const uint8_t *buf: pointer to input byte array
**************************************************/ #if KYBER_ETA1 == 3 staticvoid
cbd3(poly *r, const uint8_t buf[3 * KYBER_N / 4])
{ unsignedint i, j;
uint32_t t, d;
int16_t a, b;
for (i = 0; i < KYBER_N / 4; i++) {
t = load24_littleendian(buf + 3 * i);
d = t & 0x00249249;
d += (t >> 1) & 0x00249249;
d += (t >> 2) & 0x00249249;
for (j = 0; j < 4; j++) {
a = (d >> (6 * j + 0)) & 0x7;
b = (d >> (6 * j + 3)) & 0x7;
r->coeffs[4 * i + j] = a - b;
}
}
} #endif
/************************************************* * Name: fqmul * * Description: Multiplication followed by Montgomery reduction * * Arguments: - int16_t a: first factor * - int16_t b: second factor * * Returns 16-bit integer congruent to a*b*R^{-1} mod q
**************************************************/ static int16_t
fqmul(int16_t a, int16_t b)
{ return montgomery_reduce((int32_t)a * b);
}
/************************************************* * Name: ntt * * Description: Inplace number-theoretic transform (NTT) in Rq. * input is in standard order, output is in bitreversed order * * Arguments: - int16_t r[256]: pointer to input/output vector of elements of Zq
**************************************************/ staticvoid
ntt(int16_t r[256])
{ unsignedint len, start, j, k;
int16_t t, zeta;
k = 1; for (len = 128; len >= 2; len >>= 1) { for (start = 0; start < 256; start = j + len) {
zeta = zetas[k++]; for (j = start; j < start + len; j++) {
t = fqmul(zeta, r[j + len]);
r[j + len] = r[j] - t;
r[j] = r[j] + t;
}
}
}
}
/************************************************* * Name: invntt_tomont * * Description: Inplace inverse number-theoretic transform in Rq and * multiplication by Montgomery factor 2^16. * Input is in bitreversed order, output is in standard order * * Arguments: - int16_t r[256]: pointer to input/output vector of elements of Zq
**************************************************/ staticvoid
invntt(int16_t r[256])
{ unsignedint start, len, j, k;
int16_t t, zeta; const int16_t f = 1441; // mont^2/128
for (i = 0; i < KYBER_N / 8; i++) {
msg[i] = 0; for (j = 0; j < 8; j++) {
t = a->coeffs[8 * i + j]; // t += ((int16_t)t >> 15) & KYBER_Q; // t = (((t << 1) + KYBER_Q/2)/KYBER_Q) & 1;
t <<= 1;
t += 1665;
t *= 80635;
t >>= 28;
t &= 1;
msg[i] |= t << j;
}
}
}
/************************************************* * Name: poly_getnoise_eta1 * * Description: Sample a polynomial deterministically from a seed and a nonce, * with output polynomial close to centered binomial distribution * with parameter KYBER_ETA1 * * Arguments: - poly *r: pointer to output polynomial * - const uint8_t *seed: pointer to input seed * (of length KYBER_SYMBYTES bytes) * - uint8_t nonce: one-byte input nonce
**************************************************/ staticvoid
poly_getnoise_eta1(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
{
uint8_t buf[KYBER_ETA1 * KYBER_N / 4];
prf(buf, sizeof(buf), seed, nonce);
poly_cbd_eta1(r, buf);
}
/************************************************* * Name: poly_getnoise_eta2 * * Description: Sample a polynomial deterministically from a seed and a nonce, * with output polynomial close to centered binomial distribution * with parameter KYBER_ETA2 * * Arguments: - poly *r: pointer to output polynomial * - const uint8_t *seed: pointer to input seed * (of length KYBER_SYMBYTES bytes) * - uint8_t nonce: one-byte input nonce
**************************************************/ staticvoid
poly_getnoise_eta2(poly *r, const uint8_t seed[KYBER_SYMBYTES], uint8_t nonce)
{
uint8_t buf[KYBER_ETA2 * KYBER_N / 4];
prf(buf, sizeof(buf), seed, nonce);
poly_cbd_eta2(r, buf);
}
/************************************************* * Name: poly_ntt * * Description: Computes negacyclic number-theoretic transform (NTT) of * a polynomial in place; * inputs assumed to be in normal order, output in bitreversed order * * Arguments: - uint16_t *r: pointer to in/output polynomial
**************************************************/ staticvoid
poly_ntt(poly *r)
{
ntt(r->coeffs);
poly_reduce(r);
}
/************************************************* * Name: poly_invntt_tomont * * Description: Computes inverse of negacyclic number-theoretic transform (NTT) * of a polynomial in place; * inputs assumed to be in bitreversed order, output in normal order * * Arguments: - uint16_t *a: pointer to in/output polynomial
**************************************************/ staticvoid
poly_invntt_tomont(poly *r)
{
invntt(r->coeffs);
}
/************************************************* * Name: poly_basemul_montgomery * * Description: Multiplication of two polynomials in NTT domain * * Arguments: - poly *r: pointer to output polynomial * - const poly *a: pointer to first input polynomial * - const poly *b: pointer to second input polynomial
**************************************************/ staticvoid
poly_basemul_montgomery(poly *r, const poly *a, const poly *b)
{ unsignedint i; for (i = 0; i < KYBER_N / 4; i++) {
basemul(&r->coeffs[4 * i], &a->coeffs[4 * i], &b->coeffs[4 * i], zetas[64 + i]);
basemul(&r->coeffs[4 * i + 2], &a->coeffs[4 * i + 2], &b->coeffs[4 * i + 2], -zetas[64 + i]);
}
}
/************************************************* * Name: poly_tomont * * Description: Inplace conversion of all coefficients of a polynomial * from normal domain to Montgomery domain * * Arguments: - poly *r: pointer to input/output polynomial
**************************************************/ staticvoid
poly_tomont(poly *r)
{ unsignedint i; const int16_t f = (1ULL << 32) % KYBER_Q; for (i = 0; i < KYBER_N; i++)
r->coeffs[i] = montgomery_reduce((int32_t)r->coeffs[i] * f);
}
/************************************************* * Name: poly_reduce * * Description: Applies Barrett reduction to all coefficients of a polynomial * for details of the Barrett reduction see comments in reduce.c * * Arguments: - poly *r: pointer to input/output polynomial
**************************************************/ staticvoid
poly_reduce(poly *r)
{ unsignedint i; for (i = 0; i < KYBER_N; i++)
r->coeffs[i] = barrett_reduce(r->coeffs[i]);
}
/************************************************* * Name: poly_add * * Description: Add two polynomials; no modular reduction is performed * * Arguments: - poly *r: pointer to output polynomial * - const poly *a: pointer to first input polynomial * - const poly *b: pointer to second input polynomial
**************************************************/ staticvoid
poly_add(poly *r, const poly *a, const poly *b)
{ unsignedint i; for (i = 0; i < KYBER_N; i++)
r->coeffs[i] = a->coeffs[i] + b->coeffs[i];
}
/************************************************* * Name: poly_sub * * Description: Subtract two polynomials; no modular reduction is performed * * Arguments: - poly *r: pointer to output polynomial * - const poly *a: pointer to first input polynomial * - const poly *b: pointer to second input polynomial
**************************************************/ staticvoid
poly_sub(poly *r, const poly *a, const poly *b)
{ unsignedint i; for (i = 0; i < KYBER_N; i++)
r->coeffs[i] = a->coeffs[i] - b->coeffs[i];
} /** end: ref/poly.c **/
/** begin: ref/polyvec.c **/ /************************************************* * Name: polyvec_compress * * Description: Compress and serialize vector of polynomials * * Arguments: - uint8_t *r: pointer to output byte array * (needs space for KYBER_POLYVECCOMPRESSEDBYTES) * - const polyvec *a: pointer to input vector of polynomials
**************************************************/ staticvoid
polyvec_compress(uint8_t r[KYBER_POLYVECCOMPRESSEDBYTES], const polyvec *a)
{ unsignedint i, j, k;
uint64_t d0;
for (k = 0; k < 4; k++)
r->vec[i].coeffs[4 * j + k] = ((uint32_t)(t[k] & 0x3FF) * KYBER_Q + 512) >> 10;
}
} #else #error"KYBER_POLYVECCOMPRESSEDBYTES needs to be in {320*KYBER_K, 352*KYBER_K}" #endif
}
/************************************************* * Name: polyvec_tobytes * * Description: Serialize vector of polynomials * * Arguments: - uint8_t *r: pointer to output byte array * (needs space for KYBER_POLYVECBYTES) * - const polyvec *a: pointer to input vector of polynomials
**************************************************/ staticvoid
polyvec_tobytes(uint8_t r[KYBER_POLYVECBYTES], const polyvec *a)
{ unsignedint i; for (i = 0; i < KYBER_K; i++)
poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]);
}
/************************************************* * Name: polyvec_frombytes * * Description: De-serialize vector of polynomials; * inverse of polyvec_tobytes * * Arguments: - uint8_t *r: pointer to output byte array * - const polyvec *a: pointer to input vector of polynomials * (of length KYBER_POLYVECBYTES)
**************************************************/ staticvoid
polyvec_frombytes(polyvec *r, const uint8_t a[KYBER_POLYVECBYTES])
{ unsignedint i; for (i = 0; i < KYBER_K; i++)
poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES);
}
/************************************************* * Name: polyvec_ntt * * Description: Apply forward NTT to all elements of a vector of polynomials * * Arguments: - polyvec *r: pointer to in/output vector of polynomials
**************************************************/ staticvoid
polyvec_ntt(polyvec *r)
{ unsignedint i; for (i = 0; i < KYBER_K; i++)
poly_ntt(&r->vec[i]);
}
/************************************************* * Name: polyvec_invntt_tomont * * Description: Apply inverse NTT to all elements of a vector of polynomials * and multiply by Montgomery factor 2^16 * * Arguments: - polyvec *r: pointer to in/output vector of polynomials
**************************************************/ staticvoid
polyvec_invntt_tomont(polyvec *r)
{ unsignedint i; for (i = 0; i < KYBER_K; i++)
poly_invntt_tomont(&r->vec[i]);
}
/************************************************* * Name: polyvec_basemul_acc_montgomery * * Description: Multiply elements of a and b in NTT domain, accumulate into r, * and multiply by 2^-16. * * Arguments: - poly *r: pointer to output polynomial * - const polyvec *a: pointer to first input vector of polynomials * - const polyvec *b: pointer to second input vector of polynomials
**************************************************/ staticvoid
polyvec_basemul_acc_montgomery(poly *r, const polyvec *a, const polyvec *b)
{ unsignedint i;
poly t;
poly_basemul_montgomery(r, &a->vec[0], &b->vec[0]); for (i = 1; i < KYBER_K; i++) {
poly_basemul_montgomery(&t, &a->vec[i], &b->vec[i]);
poly_add(r, r, &t);
}
poly_reduce(r);
}
/************************************************* * Name: polyvec_reduce * * Description: Applies Barrett reduction to each coefficient * of each element of a vector of polynomials; * for details of the Barrett reduction see comments in reduce.c * * Arguments: - polyvec *r: pointer to input/output polynomial
**************************************************/ staticvoid
polyvec_reduce(polyvec *r)
{ unsignedint i; for (i = 0; i < KYBER_K; i++)
poly_reduce(&r->vec[i]);
}
/************************************************* * Name: polyvec_add * * Description: Add vectors of polynomials * * Arguments: - polyvec *r: pointer to output vector of polynomials * - const polyvec *a: pointer to first input vector of polynomials * - const polyvec *b: pointer to second input vector of polynomials
**************************************************/ staticvoid
polyvec_add(polyvec *r, const polyvec *a, const polyvec *b)
{ unsignedint i; for (i = 0; i < KYBER_K; i++)
poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
} /** end: ref/polyvec.c **/
/** begin: ref/indcpa.c **/ /************************************************* * Name: pack_pk * * Description: Serialize the public key as concatenation of the * serialized vector of polynomials pk * and the public seed used to generate the matrix A. * * Arguments: uint8_t *r: pointer to the output serialized public key * polyvec *pk: pointer to the input public-key polyvec * const uint8_t *seed: pointer to the input public seed
**************************************************/ staticvoid
pack_pk(uint8_t r[KYBER_INDCPA_PUBLICKEYBYTES],
polyvec *pk, const uint8_t seed[KYBER_SYMBYTES])
{
size_t i;
polyvec_tobytes(r, pk); for (i = 0; i < KYBER_SYMBYTES; i++)
r[i + KYBER_POLYVECBYTES] = seed[i];
}
/************************************************* * Name: unpack_pk * * Description: De-serialize public key from a byte array; * approximate inverse of pack_pk * * Arguments: - polyvec *pk: pointer to output public-key polynomial vector * - uint8_t *seed: pointer to output seed to generate matrix A * - const uint8_t *packedpk: pointer to input serialized public key
**************************************************/ staticvoid
unpack_pk(polyvec *pk,
uint8_t seed[KYBER_SYMBYTES], const uint8_t packedpk[KYBER_INDCPA_PUBLICKEYBYTES])
{
size_t i;
polyvec_frombytes(pk, packedpk); for (i = 0; i < KYBER_SYMBYTES; i++)
seed[i] = packedpk[i + KYBER_POLYVECBYTES];
}
/************************************************* * Name: unpack_sk * * Description: De-serialize the secret key; inverse of pack_sk * * Arguments: - polyvec *sk: pointer to output vector of polynomials (secret key) * - const uint8_t *packedsk: pointer to input serialized secret key
**************************************************/ staticvoid
unpack_sk(polyvec *sk, const uint8_t packedsk[KYBER_INDCPA_SECRETKEYBYTES])
{
polyvec_frombytes(sk, packedsk);
}
/************************************************* * Name: pack_ciphertext * * Description: Serialize the ciphertext as concatenation of the * compressed and serialized vector of polynomials b * and the compressed and serialized polynomial v * * Arguments: uint8_t *r: pointer to the output serialized ciphertext * poly *pk: pointer to the input vector of polynomials b * poly *v: pointer to the input polynomial v
**************************************************/ staticvoid
pack_ciphertext(uint8_t r[KYBER_INDCPA_BYTES], polyvec *b, poly *v)
{
polyvec_compress(r, b);
poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v);
}
/************************************************* * Name: unpack_ciphertext * * Description: De-serialize and decompress ciphertext from a byte array; * approximate inverse of pack_ciphertext * * Arguments: - polyvec *b: pointer to the output vector of polynomials b * - poly *v: pointer to the output polynomial v * - const uint8_t *c: pointer to the input serialized ciphertext
**************************************************/ staticvoid
unpack_ciphertext(polyvec *b, poly *v, const uint8_t c[KYBER_INDCPA_BYTES])
{
polyvec_decompress(b, c);
poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES);
}
/************************************************* * Name: rej_uniform * * Description: Run rejection sampling on uniform random bytes to generate * uniform random integers mod q * * Arguments: - int16_t *r: pointer to output buffer * - unsigned int len: requested number of 16-bit integers (uniform mod q) * - const uint8_t *buf: pointer to input buffer (assumed to be uniformly random bytes) * - unsigned int buflen: length of input buffer in bytes * * Returns number of sampled 16-bit integers (at most len)
**************************************************/ staticunsignedint
rej_uniform(int16_t *r, unsignedint len, const uint8_t *buf, unsignedint buflen)
{ unsignedint ctr, pos;
uint16_t val0, val1;
if (val0 < KYBER_Q)
r[ctr++] = val0; if (ctr < len && val1 < KYBER_Q)
r[ctr++] = val1;
}
return ctr;
}
#define gen_a(A, B) gen_matrix(A, B, 0) #define gen_at(A, B) gen_matrix(A, B, 1)
/************************************************* * Name: gen_matrix * * Description: Deterministically generate matrix A (or the transpose of A) * from a seed. Entries of the matrix are polynomials that look * uniformly random. Performs rejection sampling on output of * a XOF * * Arguments: - polyvec *a: pointer to ouptput matrix A * - const uint8_t *seed: pointer to input seed * - int transposed: boolean deciding whether A or A^T is generated
**************************************************/ #define GEN_MATRIX_NBLOCKS ((12 * KYBER_N / 8 * (1 << 12) / KYBER_Q + XOF_BLOCKBYTES) / XOF_BLOCKBYTES) // Not static for benchmarking staticvoid
gen_matrix(polyvec *a, const uint8_t seed[KYBER_SYMBYTES], int transposed)
{ unsignedint ctr, i, j, k; unsignedint buflen, off;
uint8_t buf[GEN_MATRIX_NBLOCKS * XOF_BLOCKBYTES + 2];
xof_state state;
for (i = 0; i < KYBER_K; i++) { for (j = 0; j < KYBER_K; j++) { if (transposed)
xof_absorb(&state, seed, i, j); else
xof_absorb(&state, seed, j, i);
for (i = 0; i < KYBER_K; i++)
poly_getnoise_eta1(&skpv.vec[i], noiseseed, nonce++); for (i = 0; i < KYBER_K; i++)
poly_getnoise_eta1(&e.vec[i], noiseseed, nonce++);
polyvec_ntt(&skpv);
polyvec_ntt(&e);
// matrix-vector multiplication for (i = 0; i < KYBER_K; i++) {
polyvec_basemul_acc_montgomery(&pkpv.vec[i], &a[i], &skpv);
poly_tomont(&pkpv.vec[i]);
}
for (i = 0; i < KYBER_K; i++)
poly_getnoise_eta1(sp.vec + i, coins, nonce++); for (i = 0; i < KYBER_K; i++)
poly_getnoise_eta2(ep.vec + i, coins, nonce++);
poly_getnoise_eta2(&epp, coins, nonce++);
polyvec_ntt(&sp);
// matrix-vector multiplication for (i = 0; i < KYBER_K; i++)
polyvec_basemul_acc_montgomery(&b.vec[i], &at[i], &sp);
/** begin: ref/fips202.c **/ /* Based on the public domain implementation in crypto_hash/keccakc512/simple/ from * http://bench.cr.yp.to/supercop.html by Ronny Van Keer and the public domain "TweetFips202" * implementation from https://twitter.com/tweetfips202 by Gilles Van Assche, Daniel J. Bernstein,
* and Peter Schwabe */
// thetaRhoPiChiIotaPrepareTheta(round+1, E, A)
Da = BCu ^ ROL(BCe, 1);
De = BCa ^ ROL(BCi, 1);
Di = BCe ^ ROL(BCo, 1); Do = BCi ^ ROL(BCu, 1);
Du = BCo ^ ROL(BCa, 1);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.