1
1
mirror of https://github.com/henrydcase/pqc.git synced 2024-11-22 15:39:07 +00:00

Namespace Kyber768 and Dilithium-III

This commit is contained in:
Joost Rijneveld 2019-01-22 17:38:22 +01:00
parent 8228363495
commit 4cac434f47
No known key found for this signature in database
GPG Key ID: A4FE39CF49CBC553
34 changed files with 593 additions and 477 deletions

View File

@ -10,12 +10,12 @@
#define CRYPTO_ALGNAME "Kyber768" #define CRYPTO_ALGNAME "Kyber768"
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk); int PQCLEAN_KYBER768_crypto_kem_keypair(unsigned char *pk, unsigned char *sk);
int crypto_kem_enc(unsigned char *ct, unsigned char *ss, int PQCLEAN_KYBER768_crypto_kem_enc(unsigned char *ct, unsigned char *ss,
const unsigned char *pk); const unsigned char *pk);
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, int PQCLEAN_KYBER768_crypto_kem_dec(unsigned char *ss, const unsigned char *ct,
const unsigned char *sk); const unsigned char *sk);
#endif #endif

View File

@ -31,7 +31,7 @@ static uint64_t load_littleendian(const unsigned char *x, int bytes) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *buf: pointer to input byte array * - const unsigned char *buf: pointer to input byte array
**************************************************/ **************************************************/
void cbd(poly *r, const unsigned char *buf) { void PQCLEAN_KYBER768_cbd(poly *r, const unsigned char *buf) {
#if KYBER_ETA == 3 #if KYBER_ETA == 3
uint32_t t, d, a[4], b[4]; uint32_t t, d, a[4], b[4];
int i, j; int i, j;

View File

@ -4,6 +4,6 @@
#include "poly.h" #include "poly.h"
#include <stdint.h> #include <stdint.h>
void cbd(poly *r, const unsigned char *buf); void PQCLEAN_KYBER768_cbd(poly *r, const unsigned char *buf);
#endif #endif

View File

@ -20,7 +20,7 @@
static void pack_pk(unsigned char *r, const polyvec *pk, static void pack_pk(unsigned char *r, const polyvec *pk,
const unsigned char *seed) { const unsigned char *seed) {
int i; int i;
polyvec_compress(r, pk); PQCLEAN_KYBER768_polyvec_compress(r, pk);
for (i = 0; i < KYBER_SYMBYTES; i++) { for (i = 0; i < KYBER_SYMBYTES; i++) {
r[i + KYBER_POLYVECCOMPRESSEDBYTES] = seed[i]; r[i + KYBER_POLYVECCOMPRESSEDBYTES] = seed[i];
} }
@ -42,7 +42,7 @@ static void pack_pk(unsigned char *r, const polyvec *pk,
static void unpack_pk(polyvec *pk, unsigned char *seed, static void unpack_pk(polyvec *pk, unsigned char *seed,
const unsigned char *packedpk) { const unsigned char *packedpk) {
int i; int i;
polyvec_decompress(pk, packedpk); PQCLEAN_KYBER768_polyvec_decompress(pk, packedpk);
for (i = 0; i < KYBER_SYMBYTES; i++) { for (i = 0; i < KYBER_SYMBYTES; i++) {
seed[i] = packedpk[i + KYBER_POLYVECCOMPRESSEDBYTES]; seed[i] = packedpk[i + KYBER_POLYVECCOMPRESSEDBYTES];
@ -61,8 +61,8 @@ static void unpack_pk(polyvec *pk, unsigned char *seed,
*polynomials b const unsigned char *seed: pointer to the input polynomial v *polynomials b const unsigned char *seed: pointer to the input polynomial v
**************************************************/ **************************************************/
static void pack_ciphertext(unsigned char *r, const polyvec *b, const poly *v) { static void pack_ciphertext(unsigned char *r, const polyvec *b, const poly *v) {
polyvec_compress(r, b); PQCLEAN_KYBER768_polyvec_compress(r, b);
poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v); PQCLEAN_KYBER768_poly_compress(r + KYBER_POLYVECCOMPRESSEDBYTES, v);
} }
/************************************************* /*************************************************
@ -78,8 +78,8 @@ static void pack_ciphertext(unsigned char *r, const polyvec *b, const poly *v) {
*ciphertext *ciphertext
**************************************************/ **************************************************/
static void unpack_ciphertext(polyvec *b, poly *v, const unsigned char *c) { static void unpack_ciphertext(polyvec *b, poly *v, const unsigned char *c) {
polyvec_decompress(b, c); PQCLEAN_KYBER768_polyvec_decompress(b, c);
poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES); PQCLEAN_KYBER768_poly_decompress(v, c + KYBER_POLYVECCOMPRESSEDBYTES);
} }
/************************************************* /*************************************************
@ -92,7 +92,7 @@ static void unpack_ciphertext(polyvec *b, poly *v, const unsigned char *c) {
*(secret key) *(secret key)
**************************************************/ **************************************************/
static void pack_sk(unsigned char *r, const polyvec *sk) { static void pack_sk(unsigned char *r, const polyvec *sk) {
polyvec_tobytes(r, sk); PQCLEAN_KYBER768_polyvec_tobytes(r, sk);
} }
/************************************************* /*************************************************
@ -107,11 +107,11 @@ static void pack_sk(unsigned char *r, const polyvec *sk) {
*secret key *secret key
**************************************************/ **************************************************/
static void unpack_sk(polyvec *sk, const unsigned char *packedsk) { static void unpack_sk(polyvec *sk, const unsigned char *packedsk) {
polyvec_frombytes(sk, packedsk); PQCLEAN_KYBER768_polyvec_frombytes(sk, packedsk);
} }
#define gen_a(A, B) gen_matrix(A, B, 0) #define gen_a(A, B) PQCLEAN_KYBER768_gen_matrix(A, B, 0)
#define gen_at(A, B) gen_matrix(A, B, 1) #define gen_at(A, B) PQCLEAN_KYBER768_gen_matrix(A, B, 1)
/************************************************* /*************************************************
* Name: gen_matrix * Name: gen_matrix
@ -126,8 +126,8 @@ static void unpack_sk(polyvec *sk, const unsigned char *packedsk) {
* - int transposed: boolean deciding whether A or A^T * - int transposed: boolean deciding whether A or A^T
*is generated *is generated
**************************************************/ **************************************************/
void gen_matrix(polyvec *a, const unsigned char *seed, void PQCLEAN_KYBER768_gen_matrix(polyvec *a, const unsigned char *seed,
int transposed) // Not static for benchmarking int transposed) // Not static for benchmarking
{ {
unsigned int pos = 0, ctr; unsigned int pos = 0, ctr;
uint16_t val; uint16_t val;
@ -185,7 +185,7 @@ void gen_matrix(polyvec *a, const unsigned char *seed,
* - unsigned char *sk: pointer to output private key (of length * - unsigned char *sk: pointer to output private key (of length
*KYBER_INDCPA_SECRETKEYBYTES bytes) *KYBER_INDCPA_SECRETKEYBYTES bytes)
**************************************************/ **************************************************/
void indcpa_keypair(unsigned char *pk, unsigned char *sk) { void PQCLEAN_KYBER768_indcpa_keypair(unsigned char *pk, unsigned char *sk) {
polyvec a[KYBER_K], e, pkpv, skpv; polyvec a[KYBER_K], e, pkpv, skpv;
unsigned char buf[KYBER_SYMBYTES + KYBER_SYMBYTES]; unsigned char buf[KYBER_SYMBYTES + KYBER_SYMBYTES];
unsigned char *publicseed = buf; unsigned char *publicseed = buf;
@ -199,22 +199,22 @@ void indcpa_keypair(unsigned char *pk, unsigned char *sk) {
gen_a(a, publicseed); gen_a(a, publicseed);
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_getnoise(skpv.vec + i, noiseseed, nonce++); PQCLEAN_KYBER768_poly_getnoise(skpv.vec + i, noiseseed, nonce++);
} }
polyvec_ntt(&skpv); PQCLEAN_KYBER768_polyvec_ntt(&skpv);
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_getnoise(e.vec + i, noiseseed, nonce++); PQCLEAN_KYBER768_poly_getnoise(e.vec + i, noiseseed, nonce++);
} }
// matrix-vector multiplication // matrix-vector multiplication
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
polyvec_pointwise_acc(&pkpv.vec[i], &skpv, a + i); PQCLEAN_KYBER768_polyvec_pointwise_acc(&pkpv.vec[i], &skpv, a + i);
} }
polyvec_invntt(&pkpv); PQCLEAN_KYBER768_polyvec_invntt(&pkpv);
polyvec_add(&pkpv, &pkpv, &e); PQCLEAN_KYBER768_polyvec_add(&pkpv, &pkpv, &e);
pack_sk(sk, &skpv); pack_sk(sk, &skpv);
pack_pk(pk, &pkpv, publicseed); pack_pk(pk, &pkpv, publicseed);
@ -236,8 +236,9 @@ void indcpa_keypair(unsigned char *pk, unsigned char *sk) {
*as seed (of length KYBER_SYMBYTES bytes) to deterministically generate all *as seed (of length KYBER_SYMBYTES bytes) to deterministically generate all
*randomness *randomness
**************************************************/ **************************************************/
void indcpa_enc(unsigned char *c, const unsigned char *m, void PQCLEAN_KYBER768_indcpa_enc(unsigned char *c, const unsigned char *m,
const unsigned char *pk, const unsigned char *coins) { const unsigned char *pk,
const unsigned char *coins) {
polyvec sp, pkpv, ep, at[KYBER_K], bp; polyvec sp, pkpv, ep, at[KYBER_K], bp;
poly v, k, epp; poly v, k, epp;
unsigned char seed[KYBER_SYMBYTES]; unsigned char seed[KYBER_SYMBYTES];
@ -246,37 +247,37 @@ void indcpa_enc(unsigned char *c, const unsigned char *m,
unpack_pk(&pkpv, seed, pk); unpack_pk(&pkpv, seed, pk);
poly_frommsg(&k, m); PQCLEAN_KYBER768_poly_frommsg(&k, m);
polyvec_ntt(&pkpv); PQCLEAN_KYBER768_polyvec_ntt(&pkpv);
gen_at(at, seed); gen_at(at, seed);
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_getnoise(sp.vec + i, coins, nonce++); PQCLEAN_KYBER768_poly_getnoise(sp.vec + i, coins, nonce++);
} }
polyvec_ntt(&sp); PQCLEAN_KYBER768_polyvec_ntt(&sp);
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_getnoise(ep.vec + i, coins, nonce++); PQCLEAN_KYBER768_poly_getnoise(ep.vec + i, coins, nonce++);
} }
// matrix-vector multiplication // matrix-vector multiplication
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
polyvec_pointwise_acc(&bp.vec[i], &sp, at + i); PQCLEAN_KYBER768_polyvec_pointwise_acc(&bp.vec[i], &sp, at + i);
} }
polyvec_invntt(&bp); PQCLEAN_KYBER768_polyvec_invntt(&bp);
polyvec_add(&bp, &bp, &ep); PQCLEAN_KYBER768_polyvec_add(&bp, &bp, &ep);
polyvec_pointwise_acc(&v, &pkpv, &sp); PQCLEAN_KYBER768_polyvec_pointwise_acc(&v, &pkpv, &sp);
poly_invntt(&v); PQCLEAN_KYBER768_poly_invntt(&v);
poly_getnoise(&epp, coins, nonce++); PQCLEAN_KYBER768_poly_getnoise(&epp, coins, nonce++);
poly_add(&v, &v, &epp); PQCLEAN_KYBER768_poly_add(&v, &v, &epp);
poly_add(&v, &v, &k); PQCLEAN_KYBER768_poly_add(&v, &v, &k);
pack_ciphertext(c, &bp, &v); pack_ciphertext(c, &bp, &v);
} }
@ -294,20 +295,20 @@ void indcpa_enc(unsigned char *c, const unsigned char *m,
* - const unsigned char *sk: pointer to input secret key (of * - const unsigned char *sk: pointer to input secret key (of
*length KYBER_INDCPA_SECRETKEYBYTES) *length KYBER_INDCPA_SECRETKEYBYTES)
**************************************************/ **************************************************/
void indcpa_dec(unsigned char *m, const unsigned char *c, void PQCLEAN_KYBER768_indcpa_dec(unsigned char *m, const unsigned char *c,
const unsigned char *sk) { const unsigned char *sk) {
polyvec bp, skpv; polyvec bp, skpv;
poly v, mp; poly v, mp;
unpack_ciphertext(&bp, &v, c); unpack_ciphertext(&bp, &v, c);
unpack_sk(&skpv, sk); unpack_sk(&skpv, sk);
polyvec_ntt(&bp); PQCLEAN_KYBER768_polyvec_ntt(&bp);
polyvec_pointwise_acc(&mp, &skpv, &bp); PQCLEAN_KYBER768_polyvec_pointwise_acc(&mp, &skpv, &bp);
poly_invntt(&mp); PQCLEAN_KYBER768_poly_invntt(&mp);
poly_sub(&mp, &mp, &v); PQCLEAN_KYBER768_poly_sub(&mp, &mp, &v);
poly_tomsg(m, &mp); PQCLEAN_KYBER768_poly_tomsg(m, &mp);
} }

View File

@ -1,12 +1,13 @@
#ifndef INDCPA_H #ifndef INDCPA_H
#define INDCPA_H #define INDCPA_H
void indcpa_keypair(unsigned char *pk, unsigned char *sk); void PQCLEAN_KYBER768_indcpa_keypair(unsigned char *pk, unsigned char *sk);
void indcpa_enc(unsigned char *c, const unsigned char *m, void PQCLEAN_KYBER768_indcpa_enc(unsigned char *c, const unsigned char *m,
const unsigned char *pk, const unsigned char *coins); const unsigned char *pk,
const unsigned char *coins);
void indcpa_dec(unsigned char *m, const unsigned char *c, void PQCLEAN_KYBER768_indcpa_dec(unsigned char *m, const unsigned char *c,
const unsigned char *sk); const unsigned char *sk);
#endif #endif

View File

@ -18,9 +18,9 @@
* *
* Returns 0 (success) * Returns 0 (success)
**************************************************/ **************************************************/
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk) { int PQCLEAN_KYBER768_crypto_kem_keypair(unsigned char *pk, unsigned char *sk) {
size_t i; size_t i;
indcpa_keypair(pk, sk); PQCLEAN_KYBER768_indcpa_keypair(pk, sk);
for (i = 0; i < KYBER_INDCPA_PUBLICKEYBYTES; i++) { for (i = 0; i < KYBER_INDCPA_PUBLICKEYBYTES; i++) {
sk[i + KYBER_INDCPA_SECRETKEYBYTES] = pk[i]; sk[i + KYBER_INDCPA_SECRETKEYBYTES] = pk[i];
} }
@ -47,8 +47,8 @@ int crypto_kem_keypair(unsigned char *pk, unsigned char *sk) {
* *
* Returns 0 (success) * Returns 0 (success)
**************************************************/ **************************************************/
int crypto_kem_enc(unsigned char *ct, unsigned char *ss, int PQCLEAN_KYBER768_crypto_kem_enc(unsigned char *ct, unsigned char *ss,
const unsigned char *pk) { const unsigned char *pk) {
unsigned char kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins */ unsigned char kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins */
unsigned char buf[2 * KYBER_SYMBYTES]; unsigned char buf[2 * KYBER_SYMBYTES];
@ -60,8 +60,8 @@ int crypto_kem_enc(unsigned char *ct, unsigned char *ss,
contributory KEM */ contributory KEM */
sha3_512(kr, buf, 2 * KYBER_SYMBYTES); sha3_512(kr, buf, 2 * KYBER_SYMBYTES);
indcpa_enc(ct, buf, pk, PQCLEAN_KYBER768_indcpa_enc(
kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ ct, buf, pk, kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */
sha3_256(kr + KYBER_SYMBYTES, ct, sha3_256(kr + KYBER_SYMBYTES, ct,
KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */
@ -88,8 +88,8 @@ int crypto_kem_enc(unsigned char *ct, unsigned char *ss,
* *
* On failure, ss will contain a pseudo-random value. * On failure, ss will contain a pseudo-random value.
**************************************************/ **************************************************/
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, int PQCLEAN_KYBER768_crypto_kem_dec(unsigned char *ss, const unsigned char *ct,
const unsigned char *sk) { const unsigned char *sk) {
size_t i; size_t i;
int fail; int fail;
unsigned char cmp[KYBER_CIPHERTEXTBYTES]; unsigned char cmp[KYBER_CIPHERTEXTBYTES];
@ -98,7 +98,7 @@ int crypto_kem_dec(unsigned char *ss, const unsigned char *ct,
kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins, qrom-hash */ kr[2 * KYBER_SYMBYTES]; /* Will contain key, coins, qrom-hash */
const unsigned char *pk = sk + KYBER_INDCPA_SECRETKEYBYTES; const unsigned char *pk = sk + KYBER_INDCPA_SECRETKEYBYTES;
indcpa_dec(buf, ct, sk); PQCLEAN_KYBER768_indcpa_dec(buf, ct, sk);
for (i = 0; i < KYBER_SYMBYTES; for (i = 0; i < KYBER_SYMBYTES;
i++) { /* Multitarget countermeasure for coins + contributory KEM */ i++) { /* Multitarget countermeasure for coins + contributory KEM */
@ -107,16 +107,17 @@ int crypto_kem_dec(unsigned char *ss, const unsigned char *ct,
} }
sha3_512(kr, buf, 2 * KYBER_SYMBYTES); sha3_512(kr, buf, 2 * KYBER_SYMBYTES);
indcpa_enc(cmp, buf, pk, PQCLEAN_KYBER768_indcpa_enc(
kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */ cmp, buf, pk, kr + KYBER_SYMBYTES); /* coins are in kr+KYBER_SYMBYTES */
fail = verify(ct, cmp, KYBER_CIPHERTEXTBYTES); fail = PQCLEAN_KYBER768_verify(ct, cmp, KYBER_CIPHERTEXTBYTES);
sha3_256(kr + KYBER_SYMBYTES, ct, sha3_256(kr + KYBER_SYMBYTES, ct,
KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */ KYBER_CIPHERTEXTBYTES); /* overwrite coins in kr with H(c) */
cmov(kr, sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES, PQCLEAN_KYBER768_cmov(
fail); /* Overwrite pre-k with z on re-encryption failure */ kr, sk + KYBER_SECRETKEYBYTES - KYBER_SYMBYTES, KYBER_SYMBYTES,
fail); /* Overwrite pre-k with z on re-encryption failure */
sha3_256( sha3_256(
ss, kr, ss, kr,

View File

@ -2,48 +2,55 @@
#include "fips202.h" #include "fips202.h"
#include "verify.h" #include "verify.h"
void kyber_uake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb) { void PQCLEAN_KYBER768_kyber_uake_initA(u8 *send, u8 *tk, u8 *sk,
crypto_kem_keypair(send, sk); const u8 *pkb) {
crypto_kem_enc(send + KYBER_PUBLICKEYBYTES, tk, pkb); PQCLEAN_KYBER768_crypto_kem_keypair(send, sk);
PQCLEAN_KYBER768_crypto_kem_enc(send + KYBER_PUBLICKEYBYTES, tk, pkb);
} }
void kyber_uake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb) { void PQCLEAN_KYBER768_kyber_uake_sharedB(u8 *send, u8 *k, const u8 *recv,
const u8 *skb) {
unsigned char buf[2 * KYBER_SYMBYTES]; unsigned char buf[2 * KYBER_SYMBYTES];
crypto_kem_enc(send, buf, recv); PQCLEAN_KYBER768_crypto_kem_enc(send, buf, recv);
crypto_kem_dec(buf + KYBER_SYMBYTES, recv + KYBER_PUBLICKEYBYTES, skb); PQCLEAN_KYBER768_crypto_kem_dec(buf + KYBER_SYMBYTES,
recv + KYBER_PUBLICKEYBYTES, skb);
shake256(k, KYBER_SYMBYTES, buf, 2 * KYBER_SYMBYTES); shake256(k, KYBER_SYMBYTES, buf, 2 * KYBER_SYMBYTES);
} }
void kyber_uake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk) { void PQCLEAN_KYBER768_kyber_uake_sharedA(u8 *k, const u8 *recv, const u8 *tk,
const u8 *sk) {
unsigned char buf[2 * KYBER_SYMBYTES]; unsigned char buf[2 * KYBER_SYMBYTES];
int i; int i;
crypto_kem_dec(buf, recv, sk); PQCLEAN_KYBER768_crypto_kem_dec(buf, recv, sk);
for (i = 0; i < KYBER_SYMBYTES; i++) { for (i = 0; i < KYBER_SYMBYTES; i++) {
buf[i + KYBER_SYMBYTES] = tk[i]; buf[i + KYBER_SYMBYTES] = tk[i];
} }
shake256(k, KYBER_SYMBYTES, buf, 2 * KYBER_SYMBYTES); shake256(k, KYBER_SYMBYTES, buf, 2 * KYBER_SYMBYTES);
} }
void kyber_ake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb) { void PQCLEAN_KYBER768_kyber_ake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb) {
crypto_kem_keypair(send, sk); PQCLEAN_KYBER768_crypto_kem_keypair(send, sk);
crypto_kem_enc(send + KYBER_PUBLICKEYBYTES, tk, pkb); PQCLEAN_KYBER768_crypto_kem_enc(send + KYBER_PUBLICKEYBYTES, tk, pkb);
} }
void kyber_ake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb, void PQCLEAN_KYBER768_kyber_ake_sharedB(u8 *send, u8 *k, const u8 *recv,
const u8 *pka) { const u8 *skb, const u8 *pka) {
unsigned char buf[3 * KYBER_SYMBYTES]; unsigned char buf[3 * KYBER_SYMBYTES];
crypto_kem_enc(send, buf, recv); PQCLEAN_KYBER768_crypto_kem_enc(send, buf, recv);
crypto_kem_enc(send + KYBER_CIPHERTEXTBYTES, buf + KYBER_SYMBYTES, pka); PQCLEAN_KYBER768_crypto_kem_enc(send + KYBER_CIPHERTEXTBYTES,
crypto_kem_dec(buf + 2 * KYBER_SYMBYTES, recv + KYBER_PUBLICKEYBYTES, skb); buf + KYBER_SYMBYTES, pka);
PQCLEAN_KYBER768_crypto_kem_dec(buf + 2 * KYBER_SYMBYTES,
recv + KYBER_PUBLICKEYBYTES, skb);
shake256(k, KYBER_SYMBYTES, buf, 3 * KYBER_SYMBYTES); shake256(k, KYBER_SYMBYTES, buf, 3 * KYBER_SYMBYTES);
} }
void kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk, void PQCLEAN_KYBER768_kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk,
const u8 *ska) { const u8 *sk, const u8 *ska) {
unsigned char buf[3 * KYBER_SYMBYTES]; unsigned char buf[3 * KYBER_SYMBYTES];
int i; int i;
crypto_kem_dec(buf, recv, sk); PQCLEAN_KYBER768_crypto_kem_dec(buf, recv, sk);
crypto_kem_dec(buf + KYBER_SYMBYTES, recv + KYBER_CIPHERTEXTBYTES, ska); PQCLEAN_KYBER768_crypto_kem_dec(buf + KYBER_SYMBYTES,
recv + KYBER_CIPHERTEXTBYTES, ska);
for (i = 0; i < KYBER_SYMBYTES; i++) { for (i = 0; i < KYBER_SYMBYTES; i++) {
buf[i + 2 * KYBER_SYMBYTES] = tk[i]; buf[i + 2 * KYBER_SYMBYTES] = tk[i];
} }

View File

@ -12,18 +12,20 @@
typedef unsigned char u8; typedef unsigned char u8;
void kyber_uake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb); void PQCLEAN_KYBER768_kyber_uake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb);
void kyber_uake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb); void PQCLEAN_KYBER768_kyber_uake_sharedB(u8 *send, u8 *k, const u8 *recv,
const u8 *skb);
void kyber_uake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk); void PQCLEAN_KYBER768_kyber_uake_sharedA(u8 *k, const u8 *recv, const u8 *tk,
const u8 *sk);
void kyber_ake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb); void PQCLEAN_KYBER768_kyber_ake_initA(u8 *send, u8 *tk, u8 *sk, const u8 *pkb);
void kyber_ake_sharedB(u8 *send, u8 *k, const u8 *recv, const u8 *skb, void PQCLEAN_KYBER768_kyber_ake_sharedB(u8 *send, u8 *k, const u8 *recv,
const u8 *pka); const u8 *skb, const u8 *pka);
void kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk, const u8 *sk, void PQCLEAN_KYBER768_kyber_ake_sharedA(u8 *k, const u8 *recv, const u8 *tk,
const u8 *ska); const u8 *sk, const u8 *ska);
#endif #endif

View File

@ -3,9 +3,9 @@
#include "params.h" #include "params.h"
#include "reduce.h" #include "reduce.h"
extern const uint16_t omegas_inv_bitrev_montgomery[]; extern const uint16_t PQCLEAN_KYBER768_omegas_inv_bitrev_montgomery[];
extern const uint16_t psis_inv_montgomery[]; extern const uint16_t PQCLEAN_KYBER768_psis_inv_montgomery[];
extern const uint16_t zetas[]; extern const uint16_t PQCLEAN_KYBER768_zetas[];
/************************************************* /*************************************************
* Name: ntt * Name: ntt
@ -17,23 +17,25 @@ extern const uint16_t zetas[];
* *
* Arguments: - uint16_t *p: pointer to in/output polynomial * Arguments: - uint16_t *p: pointer to in/output polynomial
**************************************************/ **************************************************/
void ntt(uint16_t *p) { void PQCLEAN_KYBER768_ntt(uint16_t *p) {
int level, start, j, k; int level, start, j, k;
uint16_t zeta, t; uint16_t zeta, t;
k = 1; k = 1;
for (level = 7; level >= 0; level--) { for (level = 7; level >= 0; level--) {
for (start = 0; start < KYBER_N; start = j + (1 << level)) { for (start = 0; start < KYBER_N; start = j + (1 << level)) {
zeta = zetas[k++]; zeta = PQCLEAN_KYBER768_zetas[k++];
for (j = start; j < start + (1 << level); ++j) { for (j = start; j < start + (1 << level); ++j) {
t = montgomery_reduce((uint32_t)zeta * p[j + (1 << level)]); t = PQCLEAN_KYBER768_montgomery_reduce((uint32_t)zeta *
p[j + (1 << level)]);
p[j + (1 << level)] = barrett_reduce(p[j] + 4 * KYBER_Q - t); p[j + (1 << level)] =
PQCLEAN_KYBER768_barrett_reduce(p[j] + 4 * KYBER_Q - t);
if (level & 1) { /* odd level */ if (level & 1) { /* odd level */
p[j] = p[j] + t; /* Omit reduction (be lazy) */ p[j] = p[j] + t; /* Omit reduction (be lazy) */
} else { } else {
p[j] = barrett_reduce(p[j] + t); p[j] = PQCLEAN_KYBER768_barrett_reduce(p[j] + t);
} }
} }
} }
@ -49,7 +51,7 @@ void ntt(uint16_t *p) {
* *
* Arguments: - uint16_t *a: pointer to in/output polynomial * Arguments: - uint16_t *a: pointer to in/output polynomial
**************************************************/ **************************************************/
void invntt(uint16_t *a) { void PQCLEAN_KYBER768_invntt(uint16_t *a) {
int start, j, jTwiddle, level; int start, j, jTwiddle, level;
uint16_t temp, W; uint16_t temp, W;
uint32_t t; uint32_t t;
@ -58,11 +60,12 @@ void invntt(uint16_t *a) {
for (start = 0; start < (1 << level); start++) { for (start = 0; start < (1 << level); start++) {
jTwiddle = 0; jTwiddle = 0;
for (j = start; j < KYBER_N - 1; j += 2 * (1 << level)) { for (j = start; j < KYBER_N - 1; j += 2 * (1 << level)) {
W = omegas_inv_bitrev_montgomery[jTwiddle++]; W = PQCLEAN_KYBER768_omegas_inv_bitrev_montgomery[jTwiddle++];
temp = a[j]; temp = a[j];
if (level & 1) { /* odd level */ if (level & 1) { /* odd level */
a[j] = barrett_reduce((temp + a[j + (1 << level)])); a[j] = PQCLEAN_KYBER768_barrett_reduce(
(temp + a[j + (1 << level)]));
} else { } else {
a[j] = (temp + a[j] = (temp +
a[j + (1 << level)]); /* Omit reduction (be lazy) */ a[j + (1 << level)]); /* Omit reduction (be lazy) */
@ -70,12 +73,13 @@ void invntt(uint16_t *a) {
t = (W * ((uint32_t)temp + 4 * KYBER_Q - a[j + (1 << level)])); t = (W * ((uint32_t)temp + 4 * KYBER_Q - a[j + (1 << level)]));
a[j + (1 << level)] = montgomery_reduce(t); a[j + (1 << level)] = PQCLEAN_KYBER768_montgomery_reduce(t);
} }
} }
} }
for (j = 0; j < KYBER_N; j++) { for (j = 0; j < KYBER_N; j++) {
a[j] = montgomery_reduce((a[j] * psis_inv_montgomery[j])); a[j] = PQCLEAN_KYBER768_montgomery_reduce(
(a[j] * PQCLEAN_KYBER768_psis_inv_montgomery[j]));
} }
} }

View File

@ -3,7 +3,7 @@
#include <stdint.h> #include <stdint.h>
void ntt(uint16_t *p); void PQCLEAN_KYBER768_ntt(uint16_t *p);
void invntt(uint16_t *a); void PQCLEAN_KYBER768_invntt(uint16_t *a);
#endif #endif

View File

@ -14,14 +14,16 @@
* Arguments: - unsigned char *r: pointer to output byte array * Arguments: - unsigned char *r: pointer to output byte array
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void poly_compress(unsigned char *r, const poly *a) { void PQCLEAN_KYBER768_poly_compress(unsigned char *r, const poly *a) {
uint32_t t[8]; uint32_t t[8];
unsigned int i, j, k = 0; unsigned int i, j, k = 0;
for (i = 0; i < KYBER_N; i += 8) { for (i = 0; i < KYBER_N; i += 8) {
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
t[j] = t[j] = (((PQCLEAN_KYBER768_freeze(a->coeffs[i + j]) << 3) +
(((freeze(a->coeffs[i + j]) << 3) + KYBER_Q / 2) / KYBER_Q) & 7; KYBER_Q / 2) /
KYBER_Q) &
7;
} }
r[k] = t[0] | (t[1] << 3) | (t[2] << 6); r[k] = t[0] | (t[1] << 3) | (t[2] << 6);
@ -40,7 +42,7 @@ void poly_compress(unsigned char *r, const poly *a) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *a: pointer to input byte array * - const unsigned char *a: pointer to input byte array
**************************************************/ **************************************************/
void poly_decompress(poly *r, const unsigned char *a) { void PQCLEAN_KYBER768_poly_decompress(poly *r, const unsigned char *a) {
unsigned int i; unsigned int i;
for (i = 0; i < KYBER_N; i += 8) { for (i = 0; i < KYBER_N; i += 8) {
r->coeffs[i + 0] = (((a[0] & 7) * KYBER_Q) + 4) >> 3; r->coeffs[i + 0] = (((a[0] & 7) * KYBER_Q) + 4) >> 3;
@ -65,13 +67,13 @@ void poly_decompress(poly *r, const unsigned char *a) {
* Arguments: - unsigned char *r: pointer to output byte array * Arguments: - unsigned char *r: pointer to output byte array
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void poly_tobytes(unsigned char *r, const poly *a) { void PQCLEAN_KYBER768_poly_tobytes(unsigned char *r, const poly *a) {
int i, j; int i, j;
uint16_t t[8]; uint16_t t[8];
for (i = 0; i < KYBER_N / 8; i++) { for (i = 0; i < KYBER_N / 8; i++) {
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
t[j] = freeze(a->coeffs[8 * i + j]); t[j] = PQCLEAN_KYBER768_freeze(a->coeffs[8 * i + j]);
} }
r[13 * i + 0] = t[0] & 0xff; r[13 * i + 0] = t[0] & 0xff;
@ -99,7 +101,7 @@ void poly_tobytes(unsigned char *r, const poly *a) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *a: pointer to input byte array * - const unsigned char *a: pointer to input byte array
**************************************************/ **************************************************/
void poly_frombytes(poly *r, const unsigned char *a) { void PQCLEAN_KYBER768_poly_frombytes(poly *r, const unsigned char *a) {
int i; int i;
for (i = 0; i < KYBER_N / 8; i++) { for (i = 0; i < KYBER_N / 8; i++) {
r->coeffs[8 * i + 0] = r->coeffs[8 * i + 0] =
@ -136,7 +138,8 @@ void poly_frombytes(poly *r, const unsigned char *a) {
* - const unsigned char *seed: pointer to input seed * - const unsigned char *seed: pointer to input seed
* - unsigned char nonce: one-byte input nonce * - unsigned char nonce: one-byte input nonce
**************************************************/ **************************************************/
void poly_getnoise(poly *r, const unsigned char *seed, unsigned char nonce) { void PQCLEAN_KYBER768_poly_getnoise(poly *r, const unsigned char *seed,
unsigned char nonce) {
unsigned char buf[KYBER_ETA * KYBER_N / 4]; unsigned char buf[KYBER_ETA * KYBER_N / 4];
unsigned char extseed[KYBER_SYMBYTES + 1]; unsigned char extseed[KYBER_SYMBYTES + 1];
int i; int i;
@ -148,7 +151,7 @@ void poly_getnoise(poly *r, const unsigned char *seed, unsigned char nonce) {
shake256(buf, KYBER_ETA * KYBER_N / 4, extseed, KYBER_SYMBYTES + 1); shake256(buf, KYBER_ETA * KYBER_N / 4, extseed, KYBER_SYMBYTES + 1);
cbd(r, buf); PQCLEAN_KYBER768_cbd(r, buf);
} }
/************************************************* /*************************************************
@ -161,8 +164,8 @@ void poly_getnoise(poly *r, const unsigned char *seed, unsigned char nonce) {
* *
* Arguments: - uint16_t *r: pointer to in/output polynomial * Arguments: - uint16_t *r: pointer to in/output polynomial
**************************************************/ **************************************************/
void poly_ntt(poly *r) { void PQCLEAN_KYBER768_poly_ntt(poly *r) {
ntt(r->coeffs); PQCLEAN_KYBER768_ntt(r->coeffs);
} }
/************************************************* /*************************************************
@ -174,8 +177,8 @@ void poly_ntt(poly *r) {
* *
* Arguments: - uint16_t *a: pointer to in/output polynomial * Arguments: - uint16_t *a: pointer to in/output polynomial
**************************************************/ **************************************************/
void poly_invntt(poly *r) { void PQCLEAN_KYBER768_poly_invntt(poly *r) {
invntt(r->coeffs); PQCLEAN_KYBER768_invntt(r->coeffs);
} }
/************************************************* /*************************************************
@ -187,10 +190,11 @@ void poly_invntt(poly *r) {
* - const poly *a: pointer to first input polynomial * - const poly *a: pointer to first input polynomial
* - const poly *b: pointer to second input polynomial * - const poly *b: pointer to second input polynomial
**************************************************/ **************************************************/
void poly_add(poly *r, const poly *a, const poly *b) { void PQCLEAN_KYBER768_poly_add(poly *r, const poly *a, const poly *b) {
int i; int i;
for (i = 0; i < KYBER_N; i++) { for (i = 0; i < KYBER_N; i++) {
r->coeffs[i] = barrett_reduce(a->coeffs[i] + b->coeffs[i]); r->coeffs[i] =
PQCLEAN_KYBER768_barrett_reduce(a->coeffs[i] + b->coeffs[i]);
} }
} }
@ -203,11 +207,11 @@ void poly_add(poly *r, const poly *a, const poly *b) {
* - const poly *a: pointer to first input polynomial * - const poly *a: pointer to first input polynomial
* - const poly *b: pointer to second input polynomial * - const poly *b: pointer to second input polynomial
**************************************************/ **************************************************/
void poly_sub(poly *r, const poly *a, const poly *b) { void PQCLEAN_KYBER768_poly_sub(poly *r, const poly *a, const poly *b) {
int i; int i;
for (i = 0; i < KYBER_N; i++) { for (i = 0; i < KYBER_N; i++) {
r->coeffs[i] = r->coeffs[i] = PQCLEAN_KYBER768_barrett_reduce(
barrett_reduce(a->coeffs[i] + 3 * KYBER_Q - b->coeffs[i]); a->coeffs[i] + 3 * KYBER_Q - b->coeffs[i]);
} }
} }
@ -219,7 +223,8 @@ void poly_sub(poly *r, const poly *a, const poly *b) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *msg: pointer to input message * - const unsigned char *msg: pointer to input message
**************************************************/ **************************************************/
void poly_frommsg(poly *r, const unsigned char msg[KYBER_SYMBYTES]) { void PQCLEAN_KYBER768_poly_frommsg(poly *r,
const unsigned char msg[KYBER_SYMBYTES]) {
uint16_t i, j, mask; uint16_t i, j, mask;
for (i = 0; i < KYBER_SYMBYTES; i++) { for (i = 0; i < KYBER_SYMBYTES; i++) {
@ -238,14 +243,16 @@ void poly_frommsg(poly *r, const unsigned char msg[KYBER_SYMBYTES]) {
* Arguments: - unsigned char *msg: pointer to output message * Arguments: - unsigned char *msg: pointer to output message
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void poly_tomsg(unsigned char msg[KYBER_SYMBYTES], const poly *a) { void PQCLEAN_KYBER768_poly_tomsg(unsigned char msg[KYBER_SYMBYTES],
const poly *a) {
uint16_t t; uint16_t t;
int i, j; int i, j;
for (i = 0; i < KYBER_SYMBYTES; i++) { for (i = 0; i < KYBER_SYMBYTES; i++) {
msg[i] = 0; msg[i] = 0;
for (j = 0; j < 8; j++) { for (j = 0; j < 8; j++) {
t = (((freeze(a->coeffs[8 * i + j]) << 1) + KYBER_Q / 2) / t = (((PQCLEAN_KYBER768_freeze(a->coeffs[8 * i + j]) << 1) +
KYBER_Q / 2) /
KYBER_Q) & KYBER_Q) &
1; 1;
msg[i] |= t << j; msg[i] |= t << j;

View File

@ -12,21 +12,24 @@ typedef struct {
uint16_t coeffs[KYBER_N]; uint16_t coeffs[KYBER_N];
} poly; } poly;
void poly_compress(unsigned char *r, const poly *a); void PQCLEAN_KYBER768_poly_compress(unsigned char *r, const poly *a);
void poly_decompress(poly *r, const unsigned char *a); void PQCLEAN_KYBER768_poly_decompress(poly *r, const unsigned char *a);
void poly_tobytes(unsigned char *r, const poly *a); void PQCLEAN_KYBER768_poly_tobytes(unsigned char *r, const poly *a);
void poly_frombytes(poly *r, const unsigned char *a); void PQCLEAN_KYBER768_poly_frombytes(poly *r, const unsigned char *a);
void poly_frommsg(poly *r, const unsigned char msg[KYBER_SYMBYTES]); void PQCLEAN_KYBER768_poly_frommsg(poly *r,
void poly_tomsg(unsigned char msg[KYBER_SYMBYTES], const poly *a); const unsigned char msg[KYBER_SYMBYTES]);
void PQCLEAN_KYBER768_poly_tomsg(unsigned char msg[KYBER_SYMBYTES],
const poly *a);
void poly_getnoise(poly *r, const unsigned char *seed, unsigned char nonce); void PQCLEAN_KYBER768_poly_getnoise(poly *r, const unsigned char *seed,
unsigned char nonce);
void poly_ntt(poly *r); void PQCLEAN_KYBER768_poly_ntt(poly *r);
void poly_invntt(poly *r); void PQCLEAN_KYBER768_poly_invntt(poly *r);
void poly_add(poly *r, const poly *a, const poly *b); void PQCLEAN_KYBER768_poly_add(poly *r, const poly *a, const poly *b);
void poly_sub(poly *r, const poly *a, const poly *b); void PQCLEAN_KYBER768_poly_sub(poly *r, const poly *a, const poly *b);
#endif #endif

View File

@ -12,13 +12,15 @@
* Arguments: - unsigned char *r: pointer to output byte array * Arguments: - unsigned char *r: pointer to output byte array
* - const polyvec *a: pointer to input vector of polynomials * - const polyvec *a: pointer to input vector of polynomials
**************************************************/ **************************************************/
void polyvec_compress(unsigned char *r, const polyvec *a) { void PQCLEAN_KYBER768_polyvec_compress(unsigned char *r, const polyvec *a) {
int i, j, k; int i, j, k;
uint16_t t[8]; uint16_t t[8];
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
for (j = 0; j < KYBER_N / 8; j++) { for (j = 0; j < KYBER_N / 8; j++) {
for (k = 0; k < 8; k++) { for (k = 0; k < 8; k++) {
t[k] = ((((uint32_t)freeze(a->vec[i].coeffs[8 * j + k]) << 11) + t[k] = ((((uint32_t)PQCLEAN_KYBER768_freeze(
a->vec[i].coeffs[8 * j + k])
<< 11) +
KYBER_Q / 2) / KYBER_Q / 2) /
KYBER_Q) & KYBER_Q) &
0x7ff; 0x7ff;
@ -49,7 +51,7 @@ void polyvec_compress(unsigned char *r, const polyvec *a) {
* Arguments: - polyvec *r: pointer to output vector of polynomials * Arguments: - polyvec *r: pointer to output vector of polynomials
* - unsigned char *a: pointer to input byte array * - unsigned char *a: pointer to input byte array
**************************************************/ **************************************************/
void polyvec_decompress(polyvec *r, const unsigned char *a) { void PQCLEAN_KYBER768_polyvec_decompress(polyvec *r, const unsigned char *a) {
int i, j; int i, j;
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
for (j = 0; j < KYBER_N / 8; j++) { for (j = 0; j < KYBER_N / 8; j++) {
@ -115,10 +117,10 @@ void polyvec_decompress(polyvec *r, const unsigned char *a) {
* Arguments: - unsigned char *r: pointer to output byte array * Arguments: - unsigned char *r: pointer to output byte array
* - const polyvec *a: pointer to input vector of polynomials * - const polyvec *a: pointer to input vector of polynomials
**************************************************/ **************************************************/
void polyvec_tobytes(unsigned char *r, const polyvec *a) { void PQCLEAN_KYBER768_polyvec_tobytes(unsigned char *r, const polyvec *a) {
int i; int i;
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]); PQCLEAN_KYBER768_poly_tobytes(r + i * KYBER_POLYBYTES, &a->vec[i]);
} }
} }
@ -131,10 +133,10 @@ void polyvec_tobytes(unsigned char *r, const polyvec *a) {
* Arguments: - unsigned char *r: pointer to output byte array * Arguments: - unsigned char *r: pointer to output byte array
* - const polyvec *a: pointer to input vector of polynomials * - const polyvec *a: pointer to input vector of polynomials
**************************************************/ **************************************************/
void polyvec_frombytes(polyvec *r, const unsigned char *a) { void PQCLEAN_KYBER768_polyvec_frombytes(polyvec *r, const unsigned char *a) {
int i; int i;
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES); PQCLEAN_KYBER768_poly_frombytes(&r->vec[i], a + i * KYBER_POLYBYTES);
} }
} }
@ -145,10 +147,10 @@ void polyvec_frombytes(polyvec *r, const unsigned char *a) {
* *
* Arguments: - polyvec *r: pointer to in/output vector of polynomials * Arguments: - polyvec *r: pointer to in/output vector of polynomials
**************************************************/ **************************************************/
void polyvec_ntt(polyvec *r) { void PQCLEAN_KYBER768_polyvec_ntt(polyvec *r) {
int i; int i;
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_ntt(&r->vec[i]); PQCLEAN_KYBER768_poly_ntt(&r->vec[i]);
} }
} }
@ -159,10 +161,10 @@ void polyvec_ntt(polyvec *r) {
* *
* Arguments: - polyvec *r: pointer to in/output vector of polynomials * Arguments: - polyvec *r: pointer to in/output vector of polynomials
**************************************************/ **************************************************/
void polyvec_invntt(polyvec *r) { void PQCLEAN_KYBER768_polyvec_invntt(polyvec *r) {
int i; int i;
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_invntt(&r->vec[i]); PQCLEAN_KYBER768_poly_invntt(&r->vec[i]);
} }
} }
@ -175,18 +177,22 @@ void polyvec_invntt(polyvec *r) {
* - const polyvec *a: pointer to first input vector of polynomials * - const polyvec *a: pointer to first input vector of polynomials
* - const polyvec *b: pointer to second input vector of polynomials * - const polyvec *b: pointer to second input vector of polynomials
**************************************************/ **************************************************/
void polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) { void PQCLEAN_KYBER768_polyvec_pointwise_acc(poly *r, const polyvec *a,
const polyvec *b) {
int i, j; int i, j;
uint16_t t; uint16_t t;
for (j = 0; j < KYBER_N; j++) { for (j = 0; j < KYBER_N; j++) {
t = montgomery_reduce( t = PQCLEAN_KYBER768_montgomery_reduce(
4613 * (uint32_t)b->vec[0].coeffs[j]); // 4613 = 2^{2*18} % q 4613 * (uint32_t)b->vec[0].coeffs[j]); // 4613 = 2^{2*18} % q
r->coeffs[j] = montgomery_reduce(a->vec[0].coeffs[j] * t); r->coeffs[j] =
PQCLEAN_KYBER768_montgomery_reduce(a->vec[0].coeffs[j] * t);
for (i = 1; i < KYBER_K; i++) { for (i = 1; i < KYBER_K; i++) {
t = montgomery_reduce(4613 * (uint32_t)b->vec[i].coeffs[j]); t = PQCLEAN_KYBER768_montgomery_reduce(
r->coeffs[j] += montgomery_reduce(a->vec[i].coeffs[j] * t); 4613 * (uint32_t)b->vec[i].coeffs[j]);
r->coeffs[j] +=
PQCLEAN_KYBER768_montgomery_reduce(a->vec[i].coeffs[j] * t);
} }
r->coeffs[j] = barrett_reduce(r->coeffs[j]); r->coeffs[j] = PQCLEAN_KYBER768_barrett_reduce(r->coeffs[j]);
} }
} }
@ -199,9 +205,10 @@ void polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b) {
* - const polyvec *a: pointer to first input vector of polynomials * - const polyvec *a: pointer to first input vector of polynomials
* - const polyvec *b: pointer to second input vector of polynomials * - const polyvec *b: pointer to second input vector of polynomials
**************************************************/ **************************************************/
void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b) { void PQCLEAN_KYBER768_polyvec_add(polyvec *r, const polyvec *a,
const polyvec *b) {
int i; int i;
for (i = 0; i < KYBER_K; i++) { for (i = 0; i < KYBER_K; i++) {
poly_add(&r->vec[i], &a->vec[i], &b->vec[i]); PQCLEAN_KYBER768_poly_add(&r->vec[i], &a->vec[i], &b->vec[i]);
} }
} }

View File

@ -8,17 +8,19 @@ typedef struct {
poly vec[KYBER_K]; poly vec[KYBER_K];
} polyvec; } polyvec;
void polyvec_compress(unsigned char *r, const polyvec *a); void PQCLEAN_KYBER768_polyvec_compress(unsigned char *r, const polyvec *a);
void polyvec_decompress(polyvec *r, const unsigned char *a); void PQCLEAN_KYBER768_polyvec_decompress(polyvec *r, const unsigned char *a);
void polyvec_tobytes(unsigned char *r, const polyvec *a); void PQCLEAN_KYBER768_polyvec_tobytes(unsigned char *r, const polyvec *a);
void polyvec_frombytes(polyvec *r, const unsigned char *a); void PQCLEAN_KYBER768_polyvec_frombytes(polyvec *r, const unsigned char *a);
void polyvec_ntt(polyvec *r); void PQCLEAN_KYBER768_polyvec_ntt(polyvec *r);
void polyvec_invntt(polyvec *r); void PQCLEAN_KYBER768_polyvec_invntt(polyvec *r);
void polyvec_pointwise_acc(poly *r, const polyvec *a, const polyvec *b); void PQCLEAN_KYBER768_polyvec_pointwise_acc(poly *r, const polyvec *a,
const polyvec *b);
void polyvec_add(polyvec *r, const polyvec *a, const polyvec *b); void PQCLEAN_KYBER768_polyvec_add(polyvec *r, const polyvec *a,
const polyvec *b);
#endif #endif

View File

@ -35,7 +35,7 @@ g^(-(i-1))/n*mont))
*/ */
const uint16_t zetas[KYBER_N] = { const uint16_t PQCLEAN_KYBER768_zetas[KYBER_N] = {
990, 7427, 2634, 6819, 578, 3281, 2143, 1095, 484, 6362, 3336, 5382, 990, 7427, 2634, 6819, 578, 3281, 2143, 1095, 484, 6362, 3336, 5382,
6086, 3823, 877, 5656, 3583, 7010, 6414, 263, 1285, 291, 7143, 7338, 6086, 3823, 877, 5656, 3583, 7010, 6414, 263, 1285, 291, 7143, 7338,
1581, 5134, 5184, 5932, 4042, 5775, 2468, 3, 606, 729, 5383, 962, 1581, 5134, 5184, 5932, 4042, 5775, 2468, 3, 606, 729, 5383, 962,
@ -59,7 +59,7 @@ const uint16_t zetas[KYBER_N] = {
1990, 4067, 2036, 2069, 3567, 7371, 2368, 339, 6947, 2159, 654, 7327, 1990, 4067, 2036, 2069, 3567, 7371, 2368, 339, 6947, 2159, 654, 7327,
2768, 6676, 987, 2214}; 2768, 6676, 987, 2214};
const uint16_t omegas_inv_bitrev_montgomery[KYBER_N / 2] = { const uint16_t PQCLEAN_KYBER768_omegas_inv_bitrev_montgomery[KYBER_N / 2] = {
990, 254, 862, 5047, 6586, 5538, 4400, 7103, 2025, 6804, 3858, 1595, 990, 254, 862, 5047, 6586, 5538, 4400, 7103, 2025, 6804, 3858, 1595,
2299, 4345, 1319, 7197, 7678, 5213, 1906, 3639, 1749, 2497, 2547, 6100, 2299, 4345, 1319, 7197, 7678, 5213, 1906, 3639, 1749, 2497, 2547, 6100,
343, 538, 7390, 6396, 7418, 1267, 671, 4098, 5724, 491, 4146, 412, 343, 538, 7390, 6396, 7418, 1267, 671, 4098, 5724, 491, 4146, 412,
@ -72,7 +72,7 @@ const uint16_t omegas_inv_bitrev_montgomery[KYBER_N / 2] = {
2920, 594, 6189, 6662, 3247, 771, 5822, 1742, 4206, 3686, 776, 5987, 2920, 594, 6189, 6662, 3247, 771, 5822, 1742, 4206, 3686, 776, 5987,
8, 4021, 38, 5658, 3017, 6143, 889, 4216}; 8, 4021, 38, 5658, 3017, 6143, 889, 4216};
const uint16_t psis_inv_montgomery[KYBER_N] = { const uint16_t PQCLEAN_KYBER768_psis_inv_montgomery[KYBER_N] = {
1024, 4972, 5779, 6907, 4943, 4168, 315, 5580, 90, 497, 1123, 142, 1024, 4972, 5779, 6907, 4943, 4168, 315, 5580, 90, 497, 1123, 142,
4710, 5527, 2443, 4871, 698, 2489, 2394, 4003, 684, 2241, 2390, 7224, 4710, 5527, 2443, 4871, 698, 2489, 2394, 4003, 684, 2241, 2390, 7224,
5072, 2064, 4741, 1687, 6841, 482, 7441, 1235, 2126, 4742, 2802, 5744, 5072, 2064, 4741, 1687, 6841, 482, 7441, 1235, 2126, 4742, 2802, 5744,

View File

@ -17,7 +17,7 @@ static const uint32_t rlog = 18;
* Returns: unsigned integer in {0,...,2^13-1} congruent to a * R^-1 modulo * Returns: unsigned integer in {0,...,2^13-1} congruent to a * R^-1 modulo
*q. *q.
**************************************************/ **************************************************/
uint16_t montgomery_reduce(uint32_t a) { uint16_t PQCLEAN_KYBER768_montgomery_reduce(uint32_t a) {
uint32_t u; uint32_t u;
u = (a * qinv); u = (a * qinv);
@ -37,7 +37,7 @@ uint16_t montgomery_reduce(uint32_t a) {
* *
* Returns: unsigned integer in {0,...,11768} congruent to a modulo q. * Returns: unsigned integer in {0,...,11768} congruent to a modulo q.
**************************************************/ **************************************************/
uint16_t barrett_reduce(uint16_t a) { uint16_t PQCLEAN_KYBER768_barrett_reduce(uint16_t a) {
uint32_t u; uint32_t u;
u = a >> 13; //((uint32_t) a * sinv) >> 16; u = a >> 13; //((uint32_t) a * sinv) >> 16;
@ -56,10 +56,10 @@ uint16_t barrett_reduce(uint16_t a) {
* *
* Returns: unsigned integer in {0,...,q-1} congruent to a modulo q. * Returns: unsigned integer in {0,...,q-1} congruent to a modulo q.
**************************************************/ **************************************************/
uint16_t freeze(uint16_t x) { uint16_t PQCLEAN_KYBER768_freeze(uint16_t x) {
uint16_t m, r; uint16_t m, r;
int16_t c; int16_t c;
r = barrett_reduce(x); r = PQCLEAN_KYBER768_barrett_reduce(x);
m = r - KYBER_Q; m = r - KYBER_Q;
c = m; c = m;

View File

@ -3,10 +3,10 @@
#include <stdint.h> #include <stdint.h>
uint16_t freeze(uint16_t x); uint16_t PQCLEAN_KYBER768_freeze(uint16_t x);
uint16_t montgomery_reduce(uint32_t a); uint16_t PQCLEAN_KYBER768_montgomery_reduce(uint32_t a);
uint16_t barrett_reduce(uint16_t a); uint16_t PQCLEAN_KYBER768_barrett_reduce(uint16_t a);
#endif #endif

View File

@ -12,7 +12,8 @@
* *
* Returns 0 if the byte arrays are equal, 1 otherwise * Returns 0 if the byte arrays are equal, 1 otherwise
**************************************************/ **************************************************/
int verify(const unsigned char *a, const unsigned char *b, size_t len) { int PQCLEAN_KYBER768_verify(const unsigned char *a, const unsigned char *b,
size_t len) {
uint64_t r; uint64_t r;
size_t i; size_t i;
r = 0; r = 0;
@ -38,8 +39,8 @@ int verify(const unsigned char *a, const unsigned char *b, size_t len) {
* size_t len: Amount of bytes to be copied * size_t len: Amount of bytes to be copied
* unsigned char b: Condition bit; has to be in {0,1} * unsigned char b: Condition bit; has to be in {0,1}
**************************************************/ **************************************************/
void cmov(unsigned char *r, const unsigned char *x, size_t len, void PQCLEAN_KYBER768_cmov(unsigned char *r, const unsigned char *x, size_t len,
unsigned char b) { unsigned char b) {
size_t i; size_t i;
b = -b; b = -b;

View File

@ -3,9 +3,10 @@
#include <stdio.h> #include <stdio.h>
int verify(const unsigned char *a, const unsigned char *b, size_t len); int PQCLEAN_KYBER768_verify(const unsigned char *a, const unsigned char *b,
size_t len);
void cmov(unsigned char *r, const unsigned char *x, size_t len, void PQCLEAN_KYBER768_cmov(unsigned char *r, const unsigned char *x, size_t len,
unsigned char b); unsigned char b);
#endif #endif

View File

@ -9,14 +9,19 @@
#define CRYPTO_ALGNAME "Dilithium-III" #define CRYPTO_ALGNAME "Dilithium-III"
int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); int PQCLEAN_DILITHIUMIII_crypto_sign_keypair(unsigned char *pk,
unsigned char *sk);
int crypto_sign(unsigned char *sm, unsigned long long *smlen, int PQCLEAN_DILITHIUMIII_crypto_sign(unsigned char *sm,
const unsigned char *msg, unsigned long long len, unsigned long long *smlen,
const unsigned char *sk); const unsigned char *msg,
unsigned long long len,
const unsigned char *sk);
int crypto_sign_open(unsigned char *m, unsigned long long *mlen, int PQCLEAN_DILITHIUMIII_crypto_sign_open(unsigned char *m,
const unsigned char *sm, unsigned long long smlen, unsigned long long *mlen,
const unsigned char *pk); const unsigned char *sm,
unsigned long long smlen,
const unsigned char *pk);
#endif #endif

View File

@ -4,7 +4,7 @@
#include "reduce.h" #include "reduce.h"
/* Roots of unity in order needed by forward ntt */ /* Roots of unity in order needed by forward ntt */
static const uint32_t zetas[N] = { static const uint32_t PQCLEAN_DILITHIUMIII_zetas[N] = {
0, 25847, 5771523, 7861508, 237124, 7602457, 7504169, 466468, 0, 25847, 5771523, 7861508, 237124, 7602457, 7504169, 466468,
1826347, 2353451, 8021166, 6288512, 3119733, 5495562, 3111497, 2680103, 1826347, 2353451, 8021166, 6288512, 3119733, 5495562, 3111497, 2680103,
2725464, 1024112, 7300517, 3585928, 7830929, 7260833, 2619752, 6271868, 2725464, 1024112, 7300517, 3585928, 7830929, 7260833, 2619752, 6271868,
@ -39,7 +39,7 @@ static const uint32_t zetas[N] = {
7826001, 3919660, 8332111, 7018208, 3937738, 1400424, 7534263, 1976782}; 7826001, 3919660, 8332111, 7018208, 3937738, 1400424, 7534263, 1976782};
/* Roots of unity in order needed by inverse ntt */ /* Roots of unity in order needed by inverse ntt */
static const uint32_t zetas_inv[N] = { static const uint32_t PQCLEAN_DILITHIUMIII_zetas_inv[N] = {
6403635, 846154, 6979993, 4442679, 1362209, 48306, 4460757, 554416, 6403635, 846154, 6979993, 4442679, 1362209, 48306, 4460757, 554416,
3545687, 6767575, 976891, 8196974, 2286327, 420899, 2235985, 2939036, 3545687, 6767575, 976891, 8196974, 2286327, 420899, 2235985, 2939036,
3833893, 260646, 1104333, 1667432, 6470041, 1803090, 6656817, 426683, 3833893, 260646, 1104333, 1667432, 6470041, 1803090, 6656817, 426683,
@ -83,16 +83,17 @@ static const uint32_t zetas_inv[N] = {
* *
* Arguments: - uint32_t p[N]: input/output coefficient array * Arguments: - uint32_t p[N]: input/output coefficient array
**************************************************/ **************************************************/
void ntt(uint32_t p[N]) { void PQCLEAN_DILITHIUMIII_ntt(uint32_t p[N]) {
unsigned int len, start, j, k; unsigned int len, start, j, k;
uint32_t zeta, t; uint32_t zeta, t;
k = 1; k = 1;
for (len = 128; len > 0; len >>= 1) { for (len = 128; len > 0; len >>= 1) {
for (start = 0; start < N; start = j + len) { for (start = 0; start < N; start = j + len) {
zeta = zetas[k++]; zeta = PQCLEAN_DILITHIUMIII_zetas[k++];
for (j = start; j < start + len; ++j) { for (j = start; j < start + len; ++j) {
t = montgomery_reduce((uint64_t)zeta * p[j + len]); t = PQCLEAN_DILITHIUMIII_montgomery_reduce((uint64_t)zeta *
p[j + len]);
p[j + len] = p[j] + 2 * Q - t; p[j + len] = p[j] + 2 * Q - t;
p[j] = p[j] + t; p[j] = p[j] + t;
} }
@ -110,7 +111,7 @@ void ntt(uint32_t p[N]) {
* *
* Arguments: - uint32_t p[N]: input/output coefficient array * Arguments: - uint32_t p[N]: input/output coefficient array
**************************************************/ **************************************************/
void invntt_frominvmont(uint32_t p[N]) { void PQCLEAN_DILITHIUMIII_invntt_frominvmont(uint32_t p[N]) {
unsigned int start, len, j, k; unsigned int start, len, j, k;
uint32_t t, zeta; uint32_t t, zeta;
const uint32_t f = const uint32_t f =
@ -119,17 +120,18 @@ void invntt_frominvmont(uint32_t p[N]) {
k = 0; k = 0;
for (len = 1; len < N; len <<= 1) { for (len = 1; len < N; len <<= 1) {
for (start = 0; start < N; start = j + len) { for (start = 0; start < N; start = j + len) {
zeta = zetas_inv[k++]; zeta = PQCLEAN_DILITHIUMIII_zetas_inv[k++];
for (j = start; j < start + len; ++j) { for (j = start; j < start + len; ++j) {
t = p[j]; t = p[j];
p[j] = t + p[j + len]; p[j] = t + p[j + len];
p[j + len] = t + 256 * Q - p[j + len]; p[j + len] = t + 256 * Q - p[j + len];
p[j + len] = montgomery_reduce((uint64_t)zeta * p[j + len]); p[j + len] = PQCLEAN_DILITHIUMIII_montgomery_reduce(
(uint64_t)zeta * p[j + len]);
} }
} }
} }
for (j = 0; j < N; ++j) { for (j = 0; j < N; ++j) {
p[j] = montgomery_reduce((uint64_t)f * p[j]); p[j] = PQCLEAN_DILITHIUMIII_montgomery_reduce((uint64_t)f * p[j]);
} }
} }

View File

@ -4,7 +4,7 @@
#include "params.h" #include "params.h"
#include <stdint.h> #include <stdint.h>
void ntt(uint32_t p[N]); void PQCLEAN_DILITHIUMIII_ntt(uint32_t p[N]);
void invntt_frominvmont(uint32_t p[N]); void PQCLEAN_DILITHIUMIII_invntt_frominvmont(uint32_t p[N]);
#endif #endif

View File

@ -12,8 +12,9 @@
* - const unsigned char rho[]: byte array containing rho * - const unsigned char rho[]: byte array containing rho
* - const polyveck *t1: pointer to vector t1 * - const polyveck *t1: pointer to vector t1
**************************************************/ **************************************************/
void pack_pk(unsigned char pk[CRYPTO_PUBLICKEYBYTES], void PQCLEAN_DILITHIUMIII_pack_pk(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
const unsigned char rho[SEEDBYTES], const polyveck *t1) { const unsigned char rho[SEEDBYTES],
const polyveck *t1) {
unsigned int i; unsigned int i;
for (i = 0; i < SEEDBYTES; ++i) { for (i = 0; i < SEEDBYTES; ++i) {
@ -22,7 +23,8 @@ void pack_pk(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
pk += SEEDBYTES; pk += SEEDBYTES;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyt1_pack(pk + i * POLT1_SIZE_PACKED, t1->vec + i); PQCLEAN_DILITHIUMIII_polyt1_pack(pk + i * POLT1_SIZE_PACKED,
t1->vec + i);
} }
} }
@ -35,8 +37,9 @@ void pack_pk(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
* - const polyveck *t1: pointer to output vector t1 * - const polyveck *t1: pointer to output vector t1
* - unsigned char pk[]: byte array containing bit-packed pk * - unsigned char pk[]: byte array containing bit-packed pk
**************************************************/ **************************************************/
void unpack_pk(unsigned char rho[SEEDBYTES], polyveck *t1, void PQCLEAN_DILITHIUMIII_unpack_pk(
const unsigned char pk[CRYPTO_PUBLICKEYBYTES]) { unsigned char rho[SEEDBYTES], polyveck *t1,
const unsigned char pk[CRYPTO_PUBLICKEYBYTES]) {
unsigned int i; unsigned int i;
for (i = 0; i < SEEDBYTES; ++i) { for (i = 0; i < SEEDBYTES; ++i) {
@ -45,7 +48,8 @@ void unpack_pk(unsigned char rho[SEEDBYTES], polyveck *t1,
pk += SEEDBYTES; pk += SEEDBYTES;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyt1_unpack(t1->vec + i, pk + i * POLT1_SIZE_PACKED); PQCLEAN_DILITHIUMIII_polyt1_unpack(t1->vec + i,
pk + i * POLT1_SIZE_PACKED);
} }
} }
@ -62,11 +66,12 @@ void unpack_pk(unsigned char rho[SEEDBYTES], polyveck *t1,
* - const polyveck *s2: pointer to vector s2 * - const polyveck *s2: pointer to vector s2
* - const polyveck *t0: pointer to vector t0 * - const polyveck *t0: pointer to vector t0
**************************************************/ **************************************************/
void pack_sk(unsigned char sk[CRYPTO_SECRETKEYBYTES], void PQCLEAN_DILITHIUMIII_pack_sk(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char rho[SEEDBYTES], const unsigned char rho[SEEDBYTES],
const unsigned char key[SEEDBYTES], const unsigned char key[SEEDBYTES],
const unsigned char tr[CRHBYTES], const polyvecl *s1, const unsigned char tr[CRHBYTES],
const polyveck *s2, const polyveck *t0) { const polyvecl *s1, const polyveck *s2,
const polyveck *t0) {
unsigned int i; unsigned int i;
for (i = 0; i < SEEDBYTES; ++i) { for (i = 0; i < SEEDBYTES; ++i) {
@ -85,17 +90,20 @@ void pack_sk(unsigned char sk[CRYPTO_SECRETKEYBYTES],
sk += CRHBYTES; sk += CRHBYTES;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
polyeta_pack(sk + i * POLETA_SIZE_PACKED, s1->vec + i); PQCLEAN_DILITHIUMIII_polyeta_pack(sk + i * POLETA_SIZE_PACKED,
s1->vec + i);
} }
sk += L * POLETA_SIZE_PACKED; sk += L * POLETA_SIZE_PACKED;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyeta_pack(sk + i * POLETA_SIZE_PACKED, s2->vec + i); PQCLEAN_DILITHIUMIII_polyeta_pack(sk + i * POLETA_SIZE_PACKED,
s2->vec + i);
} }
sk += K * POLETA_SIZE_PACKED; sk += K * POLETA_SIZE_PACKED;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyt0_pack(sk + i * POLT0_SIZE_PACKED, t0->vec + i); PQCLEAN_DILITHIUMIII_polyt0_pack(sk + i * POLT0_SIZE_PACKED,
t0->vec + i);
} }
} }
@ -112,9 +120,10 @@ void pack_sk(unsigned char sk[CRYPTO_SECRETKEYBYTES],
* - const polyveck *r0: pointer to output vector t0 * - const polyveck *r0: pointer to output vector t0
* - unsigned char sk[]: byte array containing bit-packed sk * - unsigned char sk[]: byte array containing bit-packed sk
**************************************************/ **************************************************/
void unpack_sk(unsigned char rho[SEEDBYTES], unsigned char key[SEEDBYTES], void PQCLEAN_DILITHIUMIII_unpack_sk(
unsigned char tr[CRHBYTES], polyvecl *s1, polyveck *s2, unsigned char rho[SEEDBYTES], unsigned char key[SEEDBYTES],
polyveck *t0, const unsigned char sk[CRYPTO_SECRETKEYBYTES]) { unsigned char tr[CRHBYTES], polyvecl *s1, polyveck *s2, polyveck *t0,
const unsigned char sk[CRYPTO_SECRETKEYBYTES]) {
unsigned int i; unsigned int i;
for (i = 0; i < SEEDBYTES; ++i) { for (i = 0; i < SEEDBYTES; ++i) {
@ -133,17 +142,20 @@ void unpack_sk(unsigned char rho[SEEDBYTES], unsigned char key[SEEDBYTES],
sk += CRHBYTES; sk += CRHBYTES;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
polyeta_unpack(s1->vec + i, sk + i * POLETA_SIZE_PACKED); PQCLEAN_DILITHIUMIII_polyeta_unpack(s1->vec + i,
sk + i * POLETA_SIZE_PACKED);
} }
sk += L * POLETA_SIZE_PACKED; sk += L * POLETA_SIZE_PACKED;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyeta_unpack(s2->vec + i, sk + i * POLETA_SIZE_PACKED); PQCLEAN_DILITHIUMIII_polyeta_unpack(s2->vec + i,
sk + i * POLETA_SIZE_PACKED);
} }
sk += K * POLETA_SIZE_PACKED; sk += K * POLETA_SIZE_PACKED;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyt0_unpack(t0->vec + i, sk + i * POLT0_SIZE_PACKED); PQCLEAN_DILITHIUMIII_polyt0_unpack(t0->vec + i,
sk + i * POLT0_SIZE_PACKED);
} }
} }
@ -157,13 +169,14 @@ void unpack_sk(unsigned char rho[SEEDBYTES], unsigned char key[SEEDBYTES],
* - const polyveck *h: pointer to hint vector h * - const polyveck *h: pointer to hint vector h
* - const poly *c: pointer to challenge polynomial * - const poly *c: pointer to challenge polynomial
**************************************************/ **************************************************/
void pack_sig(unsigned char sig[CRYPTO_BYTES], const polyvecl *z, void PQCLEAN_DILITHIUMIII_pack_sig(unsigned char sig[CRYPTO_BYTES],
const polyveck *h, const poly *c) { const polyvecl *z, const polyveck *h,
const poly *c) {
unsigned int i, j, k; unsigned int i, j, k;
uint64_t signs, mask; uint64_t signs, mask;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
polyz_pack(sig + i * POLZ_SIZE_PACKED, z->vec + i); PQCLEAN_DILITHIUMIII_polyz_pack(sig + i * POLZ_SIZE_PACKED, z->vec + i);
} }
sig += L * POLZ_SIZE_PACKED; sig += L * POLZ_SIZE_PACKED;
@ -217,13 +230,14 @@ void pack_sig(unsigned char sig[CRYPTO_BYTES], const polyvecl *z,
* *
* Returns 1 in case of malformed signature; otherwise 0. * Returns 1 in case of malformed signature; otherwise 0.
**************************************************/ **************************************************/
int unpack_sig(polyvecl *z, polyveck *h, poly *c, int PQCLEAN_DILITHIUMIII_unpack_sig(polyvecl *z, polyveck *h, poly *c,
const unsigned char sig[CRYPTO_BYTES]) { const unsigned char sig[CRYPTO_BYTES]) {
unsigned int i, j, k; unsigned int i, j, k;
uint64_t signs, mask; uint64_t signs, mask;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
polyz_unpack(z->vec + i, sig + i * POLZ_SIZE_PACKED); PQCLEAN_DILITHIUMIII_polyz_unpack(z->vec + i,
sig + i * POLZ_SIZE_PACKED);
} }
sig += L * POLZ_SIZE_PACKED; sig += L * POLZ_SIZE_PACKED;

View File

@ -4,22 +4,27 @@
#include "params.h" #include "params.h"
#include "polyvec.h" #include "polyvec.h"
void pack_pk(unsigned char pk[CRYPTO_PUBLICKEYBYTES], void PQCLEAN_DILITHIUMIII_pack_pk(unsigned char pk[CRYPTO_PUBLICKEYBYTES],
const unsigned char rho[SEEDBYTES], const polyveck *t1); const unsigned char rho[SEEDBYTES],
void pack_sk(unsigned char sk[CRYPTO_SECRETKEYBYTES], const polyveck *t1);
const unsigned char rho[SEEDBYTES], void PQCLEAN_DILITHIUMIII_pack_sk(unsigned char sk[CRYPTO_SECRETKEYBYTES],
const unsigned char key[SEEDBYTES], const unsigned char rho[SEEDBYTES],
const unsigned char tr[CRHBYTES], const polyvecl *s1, const unsigned char key[SEEDBYTES],
const polyveck *s2, const polyveck *t0); const unsigned char tr[CRHBYTES],
void pack_sig(unsigned char sig[CRYPTO_BYTES], const polyvecl *z, const polyvecl *s1, const polyveck *s2,
const polyveck *h, const poly *c); const polyveck *t0);
void PQCLEAN_DILITHIUMIII_pack_sig(unsigned char sig[CRYPTO_BYTES],
const polyvecl *z, const polyveck *h,
const poly *c);
void unpack_pk(unsigned char rho[SEEDBYTES], polyveck *t1, void PQCLEAN_DILITHIUMIII_unpack_pk(
const unsigned char pk[CRYPTO_PUBLICKEYBYTES]); unsigned char rho[SEEDBYTES], polyveck *t1,
void unpack_sk(unsigned char rho[SEEDBYTES], unsigned char key[SEEDBYTES], const unsigned char pk[CRYPTO_PUBLICKEYBYTES]);
unsigned char tr[CRHBYTES], polyvecl *s1, polyveck *s2, void PQCLEAN_DILITHIUMIII_unpack_sk(
polyveck *t0, const unsigned char sk[CRYPTO_SECRETKEYBYTES]); unsigned char rho[SEEDBYTES], unsigned char key[SEEDBYTES],
int unpack_sig(polyvecl *z, polyveck *h, poly *c, unsigned char tr[CRHBYTES], polyvecl *s1, polyveck *s2, polyveck *t0,
const unsigned char sig[CRYPTO_BYTES]); const unsigned char sk[CRYPTO_SECRETKEYBYTES]);
int PQCLEAN_DILITHIUMIII_unpack_sig(polyvecl *z, polyveck *h, poly *c,
const unsigned char sig[CRYPTO_BYTES]);
#endif #endif

View File

@ -14,11 +14,11 @@
* *
* Arguments: - poly *a: pointer to input/output polynomial * Arguments: - poly *a: pointer to input/output polynomial
**************************************************/ **************************************************/
void poly_reduce(poly *a) { void PQCLEAN_DILITHIUMIII_poly_reduce(poly *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
a->coeffs[i] = reduce32(a->coeffs[i]); a->coeffs[i] = PQCLEAN_DILITHIUMIII_reduce32(a->coeffs[i]);
} }
} }
@ -30,11 +30,11 @@ void poly_reduce(poly *a) {
* *
* Arguments: - poly *a: pointer to input/output polynomial * Arguments: - poly *a: pointer to input/output polynomial
**************************************************/ **************************************************/
void poly_csubq(poly *a) { void PQCLEAN_DILITHIUMIII_poly_csubq(poly *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
a->coeffs[i] = csubq(a->coeffs[i]); a->coeffs[i] = PQCLEAN_DILITHIUMIII_csubq(a->coeffs[i]);
} }
} }
@ -46,11 +46,11 @@ void poly_csubq(poly *a) {
* *
* Arguments: - poly *a: pointer to input/output polynomial * Arguments: - poly *a: pointer to input/output polynomial
**************************************************/ **************************************************/
void poly_freeze(poly *a) { void PQCLEAN_DILITHIUMIII_poly_freeze(poly *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
a->coeffs[i] = freeze(a->coeffs[i]); a->coeffs[i] = PQCLEAN_DILITHIUMIII_freeze(a->coeffs[i]);
} }
} }
@ -63,7 +63,7 @@ void poly_freeze(poly *a) {
* - const poly *a: pointer to first summand * - const poly *a: pointer to first summand
* - const poly *b: pointer to second summand * - const poly *b: pointer to second summand
**************************************************/ **************************************************/
void poly_add(poly *c, const poly *a, const poly *b) { void PQCLEAN_DILITHIUMIII_poly_add(poly *c, const poly *a, const poly *b) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
@ -83,7 +83,7 @@ void poly_add(poly *c, const poly *a, const poly *b) {
* - const poly *b: pointer to second input polynomial to be * - const poly *b: pointer to second input polynomial to be
* subtraced from first input polynomial * subtraced from first input polynomial
**************************************************/ **************************************************/
void poly_sub(poly *c, const poly *a, const poly *b) { void PQCLEAN_DILITHIUMIII_poly_sub(poly *c, const poly *a, const poly *b) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
@ -99,7 +99,7 @@ void poly_sub(poly *c, const poly *a, const poly *b) {
* *
* Arguments: - poly *a: pointer to input/output polynomial * Arguments: - poly *a: pointer to input/output polynomial
**************************************************/ **************************************************/
void poly_neg(poly *a) { void PQCLEAN_DILITHIUMIII_poly_neg(poly *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
@ -116,7 +116,7 @@ void poly_neg(poly *a) {
* Arguments: - poly *a: pointer to input/output polynomial * Arguments: - poly *a: pointer to input/output polynomial
* - unsigned int k: exponent * - unsigned int k: exponent
**************************************************/ **************************************************/
void poly_shiftl(poly *a, unsigned int k) { void PQCLEAN_DILITHIUMIII_poly_shiftl(poly *a, unsigned int k) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
@ -132,8 +132,8 @@ void poly_shiftl(poly *a, unsigned int k) {
* *
* Arguments: - poly *a: pointer to input/output polynomial * Arguments: - poly *a: pointer to input/output polynomial
**************************************************/ **************************************************/
void poly_ntt(poly *a) { void PQCLEAN_DILITHIUMIII_poly_ntt(poly *a) {
ntt(a->coeffs); PQCLEAN_DILITHIUMIII_ntt(a->coeffs);
} }
/************************************************* /*************************************************
@ -144,8 +144,8 @@ void poly_ntt(poly *a) {
* *
* Arguments: - poly *a: pointer to input/output polynomial * Arguments: - poly *a: pointer to input/output polynomial
**************************************************/ **************************************************/
void poly_invntt_montgomery(poly *a) { void PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(poly *a) {
invntt_frominvmont(a->coeffs); PQCLEAN_DILITHIUMIII_invntt_frominvmont(a->coeffs);
} }
/************************************************* /*************************************************
@ -160,11 +160,13 @@ void poly_invntt_montgomery(poly *a) {
* - const poly *a: pointer to first input polynomial * - const poly *a: pointer to first input polynomial
* - const poly *b: pointer to second input polynomial * - const poly *b: pointer to second input polynomial
**************************************************/ **************************************************/
void poly_pointwise_invmontgomery(poly *c, const poly *a, const poly *b) { void PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(poly *c, const poly *a,
const poly *b) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
c->coeffs[i] = montgomery_reduce((uint64_t)a->coeffs[i] * b->coeffs[i]); c->coeffs[i] = PQCLEAN_DILITHIUMIII_montgomery_reduce(
(uint64_t)a->coeffs[i] * b->coeffs[i]);
} }
} }
@ -181,11 +183,12 @@ void poly_pointwise_invmontgomery(poly *c, const poly *a, const poly *b) {
*a0 *a0
* - const poly *v: pointer to input polynomial * - const poly *v: pointer to input polynomial
**************************************************/ **************************************************/
void poly_power2round(poly *a1, poly *a0, const poly *a) { void PQCLEAN_DILITHIUMIII_poly_power2round(poly *a1, poly *a0, const poly *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
a1->coeffs[i] = power2round(a->coeffs[i], a0->coeffs + i); a1->coeffs[i] =
PQCLEAN_DILITHIUMIII_power2round(a->coeffs[i], a0->coeffs + i);
} }
} }
@ -203,11 +206,12 @@ void poly_power2round(poly *a1, poly *a0, const poly *a) {
*a0 *a0
* - const poly *c: pointer to input polynomial * - const poly *c: pointer to input polynomial
**************************************************/ **************************************************/
void poly_decompose(poly *a1, poly *a0, const poly *a) { void PQCLEAN_DILITHIUMIII_poly_decompose(poly *a1, poly *a0, const poly *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
a1->coeffs[i] = decompose(a->coeffs[i], a0->coeffs + i); a1->coeffs[i] =
PQCLEAN_DILITHIUMIII_decompose(a->coeffs[i], a0->coeffs + i);
} }
} }
@ -225,11 +229,13 @@ void poly_decompose(poly *a1, poly *a0, const poly *a) {
* *
* Returns number of 1 bits. * Returns number of 1 bits.
**************************************************/ **************************************************/
unsigned int poly_make_hint(poly *h, const poly *a, const poly *b) { unsigned int PQCLEAN_DILITHIUMIII_poly_make_hint(poly *h, const poly *a,
const poly *b) {
unsigned int i, s = 0; unsigned int i, s = 0;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
h->coeffs[i] = make_hint(a->coeffs[i], b->coeffs[i]); h->coeffs[i] =
PQCLEAN_DILITHIUMIII_make_hint(a->coeffs[i], b->coeffs[i]);
s += h->coeffs[i]; s += h->coeffs[i];
} }
return s; return s;
@ -244,11 +250,12 @@ unsigned int poly_make_hint(poly *h, const poly *a, const poly *b) {
* - const poly *b: pointer to input polynomial * - const poly *b: pointer to input polynomial
* - const poly *h: pointer to input hint polynomial * - const poly *h: pointer to input hint polynomial
**************************************************/ **************************************************/
void poly_use_hint(poly *a, const poly *b, const poly *h) { void PQCLEAN_DILITHIUMIII_poly_use_hint(poly *a, const poly *b, const poly *h) {
unsigned int i; unsigned int i;
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
a->coeffs[i] = use_hint(b->coeffs[i], h->coeffs[i]); a->coeffs[i] =
PQCLEAN_DILITHIUMIII_use_hint(b->coeffs[i], h->coeffs[i]);
} }
} }
@ -263,7 +270,7 @@ void poly_use_hint(poly *a, const poly *b, const poly *h) {
* *
* Returns 0 if norm is strictly smaller than B and 1 otherwise. * Returns 0 if norm is strictly smaller than B and 1 otherwise.
**************************************************/ **************************************************/
int poly_chknorm(const poly *a, uint32_t B) { int PQCLEAN_DILITHIUMIII_poly_chknorm(const poly *a, uint32_t B) {
unsigned int i; unsigned int i;
int32_t t; int32_t t;
@ -293,7 +300,7 @@ int poly_chknorm(const poly *a, uint32_t B) {
* Arguments: - poly *a: pointer to output polynomial * Arguments: - poly *a: pointer to output polynomial
* - const unsigned char *buf: array of random bytes * - const unsigned char *buf: array of random bytes
**************************************************/ **************************************************/
void poly_uniform(poly *a, const unsigned char *buf) { void PQCLEAN_DILITHIUMIII_poly_uniform(poly *a, const unsigned char *buf) {
unsigned int ctr, pos; unsigned int ctr, pos;
uint32_t t; uint32_t t;
@ -364,8 +371,9 @@ static unsigned int rej_eta(uint32_t *a, unsigned int len,
* SEEDBYTES * SEEDBYTES
* - unsigned char nonce: nonce byte * - unsigned char nonce: nonce byte
**************************************************/ **************************************************/
void poly_uniform_eta(poly *a, const unsigned char seed[SEEDBYTES], void PQCLEAN_DILITHIUMIII_poly_uniform_eta(poly *a,
unsigned char nonce) { const unsigned char seed[SEEDBYTES],
unsigned char nonce) {
unsigned int i, ctr; unsigned int i, ctr;
unsigned char inbuf[SEEDBYTES + 1]; unsigned char inbuf[SEEDBYTES + 1];
/* Probability that we need more than 2 blocks: < 2^{-84} /* Probability that we need more than 2 blocks: < 2^{-84}
@ -448,9 +456,8 @@ static unsigned int rej_gamma1m1(uint32_t *a, unsigned int len,
* SEEDBYTES + CRHBYTES * SEEDBYTES + CRHBYTES
* - uint16_t nonce: 16-bit nonce * - uint16_t nonce: 16-bit nonce
**************************************************/ **************************************************/
void poly_uniform_gamma1m1(poly *a, void PQCLEAN_DILITHIUMIII_poly_uniform_gamma1m1(
const unsigned char seed[SEEDBYTES + CRHBYTES], poly *a, const unsigned char seed[SEEDBYTES + CRHBYTES], uint16_t nonce) {
uint16_t nonce) {
unsigned int i, ctr; unsigned int i, ctr;
unsigned char inbuf[SEEDBYTES + CRHBYTES + 2]; unsigned char inbuf[SEEDBYTES + CRHBYTES + 2];
/* Probability that we need more than 5 blocks: < 2^{-81} /* Probability that we need more than 5 blocks: < 2^{-81}
@ -486,7 +493,7 @@ void poly_uniform_gamma1m1(poly *a,
* POLETA_SIZE_PACKED bytes * POLETA_SIZE_PACKED bytes
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void polyeta_pack(unsigned char *r, const poly *a) { void PQCLEAN_DILITHIUMIII_polyeta_pack(unsigned char *r, const poly *a) {
#if ETA > 7 #if ETA > 7
#error "polyeta_pack() assumes ETA <= 7" #error "polyeta_pack() assumes ETA <= 7"
#endif #endif
@ -533,7 +540,7 @@ void polyeta_pack(unsigned char *r, const poly *a) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *a: byte array with bit-packed polynomial * - const unsigned char *a: byte array with bit-packed polynomial
**************************************************/ **************************************************/
void polyeta_unpack(poly *r, const unsigned char *a) { void PQCLEAN_DILITHIUMIII_polyeta_unpack(poly *r, const unsigned char *a) {
unsigned int i; unsigned int i;
#if ETA <= 3 #if ETA <= 3
@ -578,7 +585,7 @@ void polyeta_unpack(poly *r, const unsigned char *a) {
* POLT1_SIZE_PACKED bytes * POLT1_SIZE_PACKED bytes
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void polyt1_pack(unsigned char *r, const poly *a) { void PQCLEAN_DILITHIUMIII_polyt1_pack(unsigned char *r, const poly *a) {
#if D != 14 #if D != 14
#error "polyt1_pack() assumes D == 14" #error "polyt1_pack() assumes D == 14"
#endif #endif
@ -613,7 +620,7 @@ void polyt1_pack(unsigned char *r, const poly *a) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *a: byte array with bit-packed polynomial * - const unsigned char *a: byte array with bit-packed polynomial
**************************************************/ **************************************************/
void polyt1_unpack(poly *r, const unsigned char *a) { void PQCLEAN_DILITHIUMIII_polyt1_unpack(poly *r, const unsigned char *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N / 8; ++i) { for (i = 0; i < N / 8; ++i) {
@ -646,7 +653,7 @@ void polyt1_unpack(poly *r, const unsigned char *a) {
* POLT0_SIZE_PACKED bytes * POLT0_SIZE_PACKED bytes
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void polyt0_pack(unsigned char *r, const poly *a) { void PQCLEAN_DILITHIUMIII_polyt0_pack(unsigned char *r, const poly *a) {
unsigned int i; unsigned int i;
uint32_t t[4]; uint32_t t[4];
@ -678,7 +685,7 @@ void polyt0_pack(unsigned char *r, const poly *a) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *a: byte array with bit-packed polynomial * - const unsigned char *a: byte array with bit-packed polynomial
**************************************************/ **************************************************/
void polyt0_unpack(poly *r, const unsigned char *a) { void PQCLEAN_DILITHIUMIII_polyt0_unpack(poly *r, const unsigned char *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N / 4; ++i) { for (i = 0; i < N / 4; ++i) {
@ -714,7 +721,7 @@ void polyt0_unpack(poly *r, const unsigned char *a) {
* POLZ_SIZE_PACKED bytes * POLZ_SIZE_PACKED bytes
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void polyz_pack(unsigned char *r, const poly *a) { void PQCLEAN_DILITHIUMIII_polyz_pack(unsigned char *r, const poly *a) {
#if GAMMA1 > (1 << 19) #if GAMMA1 > (1 << 19)
#error "polyz_pack() assumes GAMMA1 <= 2^{19}" #error "polyz_pack() assumes GAMMA1 <= 2^{19}"
#endif #endif
@ -747,7 +754,7 @@ void polyz_pack(unsigned char *r, const poly *a) {
* Arguments: - poly *r: pointer to output polynomial * Arguments: - poly *r: pointer to output polynomial
* - const unsigned char *a: byte array with bit-packed polynomial * - const unsigned char *a: byte array with bit-packed polynomial
**************************************************/ **************************************************/
void polyz_unpack(poly *r, const unsigned char *a) { void PQCLEAN_DILITHIUMIII_polyz_unpack(poly *r, const unsigned char *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N / 2; ++i) { for (i = 0; i < N / 2; ++i) {
@ -776,7 +783,7 @@ void polyz_unpack(poly *r, const unsigned char *a) {
* POLW1_SIZE_PACKED bytes * POLW1_SIZE_PACKED bytes
* - const poly *a: pointer to input polynomial * - const poly *a: pointer to input polynomial
**************************************************/ **************************************************/
void polyw1_pack(unsigned char *r, const poly *a) { void PQCLEAN_DILITHIUMIII_polyw1_pack(unsigned char *r, const poly *a) {
unsigned int i; unsigned int i;
for (i = 0; i < N / 2; ++i) { for (i = 0; i < N / 2; ++i) {

View File

@ -9,43 +9,45 @@ typedef struct {
uint32_t coeffs[N]; uint32_t coeffs[N];
} poly __attribute__((aligned(32))); } poly __attribute__((aligned(32)));
void poly_reduce(poly *a); void PQCLEAN_DILITHIUMIII_poly_reduce(poly *a);
void poly_csubq(poly *a); void PQCLEAN_DILITHIUMIII_poly_csubq(poly *a);
void poly_freeze(poly *a); void PQCLEAN_DILITHIUMIII_poly_freeze(poly *a);
void poly_add(poly *c, const poly *a, const poly *b); void PQCLEAN_DILITHIUMIII_poly_add(poly *c, const poly *a, const poly *b);
void poly_sub(poly *c, const poly *a, const poly *b); void PQCLEAN_DILITHIUMIII_poly_sub(poly *c, const poly *a, const poly *b);
void poly_neg(poly *a); void PQCLEAN_DILITHIUMIII_poly_neg(poly *a);
void poly_shiftl(poly *a, unsigned int k); void PQCLEAN_DILITHIUMIII_poly_shiftl(poly *a, unsigned int k);
void poly_ntt(poly *a); void PQCLEAN_DILITHIUMIII_poly_ntt(poly *a);
void poly_invntt_montgomery(poly *a); void PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(poly *a);
void poly_pointwise_invmontgomery(poly *c, const poly *a, const poly *b); void PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(poly *c, const poly *a,
const poly *b);
void poly_power2round(poly *a1, poly *a0, const poly *a); void PQCLEAN_DILITHIUMIII_poly_power2round(poly *a1, poly *a0, const poly *a);
void poly_decompose(poly *a1, poly *a0, const poly *a); void PQCLEAN_DILITHIUMIII_poly_decompose(poly *a1, poly *a0, const poly *a);
unsigned int poly_make_hint(poly *h, const poly *a, const poly *b); unsigned int PQCLEAN_DILITHIUMIII_poly_make_hint(poly *h, const poly *a,
void poly_use_hint(poly *a, const poly *b, const poly *h); const poly *b);
void PQCLEAN_DILITHIUMIII_poly_use_hint(poly *a, const poly *b, const poly *h);
int poly_chknorm(const poly *a, uint32_t B); int PQCLEAN_DILITHIUMIII_poly_chknorm(const poly *a, uint32_t B);
void poly_uniform(poly *a, const unsigned char *buf); void PQCLEAN_DILITHIUMIII_poly_uniform(poly *a, const unsigned char *buf);
void poly_uniform_eta(poly *a, const unsigned char seed[SEEDBYTES], void PQCLEAN_DILITHIUMIII_poly_uniform_eta(poly *a,
unsigned char nonce); const unsigned char seed[SEEDBYTES],
void poly_uniform_gamma1m1(poly *a, unsigned char nonce);
const unsigned char seed[SEEDBYTES + CRHBYTES], void PQCLEAN_DILITHIUMIII_poly_uniform_gamma1m1(
uint16_t nonce); poly *a, const unsigned char seed[SEEDBYTES + CRHBYTES], uint16_t nonce);
void polyeta_pack(unsigned char *r, const poly *a); void PQCLEAN_DILITHIUMIII_polyeta_pack(unsigned char *r, const poly *a);
void polyeta_unpack(poly *r, const unsigned char *a); void PQCLEAN_DILITHIUMIII_polyeta_unpack(poly *r, const unsigned char *a);
void polyt1_pack(unsigned char *r, const poly *a); void PQCLEAN_DILITHIUMIII_polyt1_pack(unsigned char *r, const poly *a);
void polyt1_unpack(poly *r, const unsigned char *a); void PQCLEAN_DILITHIUMIII_polyt1_unpack(poly *r, const unsigned char *a);
void polyt0_pack(unsigned char *r, const poly *a); void PQCLEAN_DILITHIUMIII_polyt0_pack(unsigned char *r, const poly *a);
void polyt0_unpack(poly *r, const unsigned char *a); void PQCLEAN_DILITHIUMIII_polyt0_unpack(poly *r, const unsigned char *a);
void polyz_pack(unsigned char *r, const poly *a); void PQCLEAN_DILITHIUMIII_polyz_pack(unsigned char *r, const poly *a);
void polyz_unpack(poly *r, const unsigned char *a); void PQCLEAN_DILITHIUMIII_polyz_unpack(poly *r, const unsigned char *a);
void polyw1_pack(unsigned char *r, const poly *a); void PQCLEAN_DILITHIUMIII_polyw1_pack(unsigned char *r, const poly *a);
#endif #endif

View File

@ -15,11 +15,11 @@
* *
* Arguments: - polyvecl *v: pointer to input/output vector * Arguments: - polyvecl *v: pointer to input/output vector
**************************************************/ **************************************************/
void polyvecl_freeze(polyvecl *v) { void PQCLEAN_DILITHIUMIII_polyvecl_freeze(polyvecl *v) {
unsigned int i; unsigned int i;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
poly_freeze(v->vec + i); PQCLEAN_DILITHIUMIII_poly_freeze(v->vec + i);
} }
} }
@ -33,11 +33,12 @@ void polyvecl_freeze(polyvecl *v) {
* - const polyvecl *u: pointer to first summand * - const polyvecl *u: pointer to first summand
* - const polyvecl *v: pointer to second summand * - const polyvecl *v: pointer to second summand
**************************************************/ **************************************************/
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v) { void PQCLEAN_DILITHIUMIII_polyvecl_add(polyvecl *w, const polyvecl *u,
const polyvecl *v) {
unsigned int i; unsigned int i;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
poly_add(w->vec + i, u->vec + i, v->vec + i); PQCLEAN_DILITHIUMIII_poly_add(w->vec + i, u->vec + i, v->vec + i);
} }
} }
@ -49,11 +50,11 @@ void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v) {
* *
* Arguments: - polyvecl *v: pointer to input/output vector * Arguments: - polyvecl *v: pointer to input/output vector
**************************************************/ **************************************************/
void polyvecl_ntt(polyvecl *v) { void PQCLEAN_DILITHIUMIII_polyvecl_ntt(polyvecl *v) {
unsigned int i; unsigned int i;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
poly_ntt(v->vec + i); PQCLEAN_DILITHIUMIII_poly_ntt(v->vec + i);
} }
} }
@ -70,16 +71,18 @@ void polyvecl_ntt(polyvecl *v) {
* - const polyvecl *u: pointer to first input vector * - const polyvecl *u: pointer to first input vector
* - const polyvecl *v: pointer to second input vector * - const polyvecl *v: pointer to second input vector
**************************************************/ **************************************************/
void polyvecl_pointwise_acc_invmontgomery(poly *w, const polyvecl *u, void PQCLEAN_DILITHIUMIII_polyvecl_pointwise_acc_invmontgomery(
const polyvecl *v) { poly *w, const polyvecl *u, const polyvecl *v) {
unsigned int i; unsigned int i;
poly t; poly t;
poly_pointwise_invmontgomery(w, u->vec + 0, v->vec + 0); PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(w, u->vec + 0,
v->vec + 0);
for (i = 1; i < L; ++i) { for (i = 1; i < L; ++i) {
poly_pointwise_invmontgomery(&t, u->vec + i, v->vec + i); PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(&t, u->vec + i,
poly_add(w, w, &t); v->vec + i);
PQCLEAN_DILITHIUMIII_poly_add(w, w, &t);
} }
} }
@ -95,12 +98,12 @@ void polyvecl_pointwise_acc_invmontgomery(poly *w, const polyvecl *u,
* Returns 0 if norm of all polynomials is strictly smaller than B and 1 * Returns 0 if norm of all polynomials is strictly smaller than B and 1
* otherwise. * otherwise.
**************************************************/ **************************************************/
int polyvecl_chknorm(const polyvecl *v, uint32_t bound) { int PQCLEAN_DILITHIUMIII_polyvecl_chknorm(const polyvecl *v, uint32_t bound) {
unsigned int i; unsigned int i;
int ret = 0; int ret = 0;
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
ret |= poly_chknorm(v->vec + i, bound); ret |= PQCLEAN_DILITHIUMIII_poly_chknorm(v->vec + i, bound);
} }
return ret; return ret;
@ -118,11 +121,11 @@ int polyvecl_chknorm(const polyvecl *v, uint32_t bound) {
* *
* Arguments: - polyveck *v: pointer to input/output vector * Arguments: - polyveck *v: pointer to input/output vector
**************************************************/ **************************************************/
void polyveck_reduce(polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_reduce(polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_reduce(v->vec + i); PQCLEAN_DILITHIUMIII_poly_reduce(v->vec + i);
} }
} }
@ -134,11 +137,11 @@ void polyveck_reduce(polyveck *v) {
* *
* Arguments: - polyveck *v: pointer to input/output vector * Arguments: - polyveck *v: pointer to input/output vector
**************************************************/ **************************************************/
void polyveck_csubq(polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_csubq(polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_csubq(v->vec + i); PQCLEAN_DILITHIUMIII_poly_csubq(v->vec + i);
} }
} }
@ -150,11 +153,11 @@ void polyveck_csubq(polyveck *v) {
* *
* Arguments: - polyveck *v: pointer to input/output vector * Arguments: - polyveck *v: pointer to input/output vector
**************************************************/ **************************************************/
void polyveck_freeze(polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_freeze(polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_freeze(v->vec + i); PQCLEAN_DILITHIUMIII_poly_freeze(v->vec + i);
} }
} }
@ -168,11 +171,12 @@ void polyveck_freeze(polyveck *v) {
* - const polyveck *u: pointer to first summand * - const polyveck *u: pointer to first summand
* - const polyveck *v: pointer to second summand * - const polyveck *v: pointer to second summand
**************************************************/ **************************************************/
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_add(polyveck *w, const polyveck *u,
const polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_add(w->vec + i, u->vec + i, v->vec + i); PQCLEAN_DILITHIUMIII_poly_add(w->vec + i, u->vec + i, v->vec + i);
} }
} }
@ -188,11 +192,12 @@ void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) {
* - const polyveck *v: pointer to second input vector to be * - const polyveck *v: pointer to second input vector to be
* subtracted from first input vector * subtracted from first input vector
**************************************************/ **************************************************/
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_sub(polyveck *w, const polyveck *u,
const polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_sub(w->vec + i, u->vec + i, v->vec + i); PQCLEAN_DILITHIUMIII_poly_sub(w->vec + i, u->vec + i, v->vec + i);
} }
} }
@ -205,11 +210,11 @@ void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) {
* Arguments: - polyveck *v: pointer to input/output vector * Arguments: - polyveck *v: pointer to input/output vector
* - unsigned int k: exponent * - unsigned int k: exponent
**************************************************/ **************************************************/
void polyveck_shiftl(polyveck *v, unsigned int k) { void PQCLEAN_DILITHIUMIII_polyveck_shiftl(polyveck *v, unsigned int k) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_shiftl(v->vec + i, k); PQCLEAN_DILITHIUMIII_poly_shiftl(v->vec + i, k);
} }
} }
@ -221,11 +226,11 @@ void polyveck_shiftl(polyveck *v, unsigned int k) {
* *
* Arguments: - polyveck *v: pointer to input/output vector * Arguments: - polyveck *v: pointer to input/output vector
**************************************************/ **************************************************/
void polyveck_ntt(polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_ntt(polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_ntt(v->vec + i); PQCLEAN_DILITHIUMIII_poly_ntt(v->vec + i);
} }
} }
@ -238,11 +243,11 @@ void polyveck_ntt(polyveck *v) {
* *
* Arguments: - polyveck *v: pointer to input/output vector * Arguments: - polyveck *v: pointer to input/output vector
**************************************************/ **************************************************/
void polyveck_invntt_montgomery(polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_invntt_montgomery(polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_invntt_montgomery(v->vec + i); PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(v->vec + i);
} }
} }
@ -258,12 +263,12 @@ void polyveck_invntt_montgomery(polyveck *v) {
* Returns 0 if norm of all polynomials are strictly smaller than B and 1 * Returns 0 if norm of all polynomials are strictly smaller than B and 1
* otherwise. * otherwise.
**************************************************/ **************************************************/
int polyveck_chknorm(const polyveck *v, uint32_t bound) { int PQCLEAN_DILITHIUMIII_polyveck_chknorm(const polyveck *v, uint32_t bound) {
unsigned int i; unsigned int i;
int ret = 0; int ret = 0;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
ret |= poly_chknorm(v->vec + i, bound); ret |= PQCLEAN_DILITHIUMIII_poly_chknorm(v->vec + i, bound);
} }
return ret; return ret;
@ -283,11 +288,13 @@ int polyveck_chknorm(const polyveck *v, uint32_t bound) {
* coefficients Q + a0 * coefficients Q + a0
* - const polyveck *v: pointer to input vector * - const polyveck *v: pointer to input vector
**************************************************/ **************************************************/
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_power2round(polyveck *v1, polyveck *v0,
const polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_power2round(v1->vec + i, v0->vec + i, v->vec + i); PQCLEAN_DILITHIUMIII_poly_power2round(v1->vec + i, v0->vec + i,
v->vec + i);
} }
} }
@ -306,11 +313,13 @@ void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) {
* coefficients Q + a0 * coefficients Q + a0
* - const polyveck *v: pointer to input vector * - const polyveck *v: pointer to input vector
**************************************************/ **************************************************/
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) { void PQCLEAN_DILITHIUMIII_polyveck_decompose(polyveck *v1, polyveck *v0,
const polyveck *v) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_decompose(v1->vec + i, v0->vec + i, v->vec + i); PQCLEAN_DILITHIUMIII_poly_decompose(v1->vec + i, v0->vec + i,
v->vec + i);
} }
} }
@ -325,12 +334,14 @@ void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) {
* *
* Returns number of 1 bits. * Returns number of 1 bits.
**************************************************/ **************************************************/
unsigned int polyveck_make_hint(polyveck *h, const polyveck *u, unsigned int PQCLEAN_DILITHIUMIII_polyveck_make_hint(polyveck *h,
const polyveck *v) { const polyveck *u,
const polyveck *v) {
unsigned int i, s = 0; unsigned int i, s = 0;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
s += poly_make_hint(h->vec + i, u->vec + i, v->vec + i); s += PQCLEAN_DILITHIUMIII_poly_make_hint(h->vec + i, u->vec + i,
v->vec + i);
} }
return s; return s;
@ -346,10 +357,11 @@ unsigned int polyveck_make_hint(polyveck *h, const polyveck *u,
* - const polyveck *u: pointer to input vector * - const polyveck *u: pointer to input vector
* - const polyveck *h: pointer to input hint vector * - const polyveck *h: pointer to input hint vector
**************************************************/ **************************************************/
void polyveck_use_hint(polyveck *w, const polyveck *u, const polyveck *h) { void PQCLEAN_DILITHIUMIII_polyveck_use_hint(polyveck *w, const polyveck *u,
const polyveck *h) {
unsigned int i; unsigned int i;
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_use_hint(w->vec + i, u->vec + i, h->vec + i); PQCLEAN_DILITHIUMIII_poly_use_hint(w->vec + i, u->vec + i, h->vec + i);
} }
} }

View File

@ -10,38 +10,45 @@ typedef struct {
poly vec[L]; poly vec[L];
} polyvecl; } polyvecl;
void polyvecl_freeze(polyvecl *v); void PQCLEAN_DILITHIUMIII_polyvecl_freeze(polyvecl *v);
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v); void PQCLEAN_DILITHIUMIII_polyvecl_add(polyvecl *w, const polyvecl *u,
const polyvecl *v);
void polyvecl_ntt(polyvecl *v); void PQCLEAN_DILITHIUMIII_polyvecl_ntt(polyvecl *v);
void polyvecl_pointwise_acc_invmontgomery(poly *w, const polyvecl *u, void PQCLEAN_DILITHIUMIII_polyvecl_pointwise_acc_invmontgomery(
const polyvecl *v); poly *w, const polyvecl *u, const polyvecl *v);
int polyvecl_chknorm(const polyvecl *v, uint32_t bound); int PQCLEAN_DILITHIUMIII_polyvecl_chknorm(const polyvecl *v, uint32_t bound);
/* Vectors of polynomials of length K */ /* Vectors of polynomials of length K */
typedef struct { typedef struct {
poly vec[K]; poly vec[K];
} polyveck; } polyveck;
void polyveck_reduce(polyveck *v); void PQCLEAN_DILITHIUMIII_polyveck_reduce(polyveck *v);
void polyveck_csubq(polyveck *v); void PQCLEAN_DILITHIUMIII_polyveck_csubq(polyveck *v);
void polyveck_freeze(polyveck *v); void PQCLEAN_DILITHIUMIII_polyveck_freeze(polyveck *v);
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v); void PQCLEAN_DILITHIUMIII_polyveck_add(polyveck *w, const polyveck *u,
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v); const polyveck *v);
void polyveck_shiftl(polyveck *v, unsigned int k); void PQCLEAN_DILITHIUMIII_polyveck_sub(polyveck *w, const polyveck *u,
const polyveck *v);
void PQCLEAN_DILITHIUMIII_polyveck_shiftl(polyveck *v, unsigned int k);
void polyveck_ntt(polyveck *v); void PQCLEAN_DILITHIUMIII_polyveck_ntt(polyveck *v);
void polyveck_invntt_montgomery(polyveck *v); void PQCLEAN_DILITHIUMIII_polyveck_invntt_montgomery(polyveck *v);
int polyveck_chknorm(const polyveck *v, uint32_t bound); int PQCLEAN_DILITHIUMIII_polyveck_chknorm(const polyveck *v, uint32_t bound);
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v); void PQCLEAN_DILITHIUMIII_polyveck_power2round(polyveck *v1, polyveck *v0,
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v); const polyveck *v);
unsigned int polyveck_make_hint(polyveck *h, const polyveck *u, void PQCLEAN_DILITHIUMIII_polyveck_decompose(polyveck *v1, polyveck *v0,
const polyveck *v); const polyveck *v);
void polyveck_use_hint(polyveck *w, const polyveck *u, const polyveck *h); unsigned int PQCLEAN_DILITHIUMIII_polyveck_make_hint(polyveck *h,
const polyveck *u,
const polyveck *v);
void PQCLEAN_DILITHIUMIII_polyveck_use_hint(polyveck *w, const polyveck *u,
const polyveck *h);
#endif #endif

View File

@ -12,7 +12,7 @@
* *
* Returns r. * Returns r.
**************************************************/ **************************************************/
uint32_t montgomery_reduce(uint64_t a) { uint32_t PQCLEAN_DILITHIUMIII_montgomery_reduce(uint64_t a) {
uint64_t t; uint64_t t;
t = a * QINV; t = a * QINV;
@ -33,7 +33,7 @@ uint32_t montgomery_reduce(uint64_t a) {
* *
* Returns r. * Returns r.
**************************************************/ **************************************************/
uint32_t reduce32(uint32_t a) { uint32_t PQCLEAN_DILITHIUMIII_reduce32(uint32_t a) {
uint32_t t; uint32_t t;
t = a & 0x7FFFFF; t = a & 0x7FFFFF;
@ -51,7 +51,7 @@ uint32_t reduce32(uint32_t a) {
* *
* Returns r. * Returns r.
**************************************************/ **************************************************/
uint32_t csubq(uint32_t a) { uint32_t PQCLEAN_DILITHIUMIII_csubq(uint32_t a) {
a -= Q; a -= Q;
a += ((int32_t)a >> 31) & Q; a += ((int32_t)a >> 31) & Q;
return a; return a;
@ -67,8 +67,8 @@ uint32_t csubq(uint32_t a) {
* *
* Returns r. * Returns r.
**************************************************/ **************************************************/
uint32_t freeze(uint32_t a) { uint32_t PQCLEAN_DILITHIUMIII_freeze(uint32_t a) {
a = reduce32(a); a = PQCLEAN_DILITHIUMIII_reduce32(a);
a = csubq(a); a = PQCLEAN_DILITHIUMIII_csubq(a);
return a; return a;
} }

View File

@ -7,15 +7,15 @@
#define QINV 4236238847U // -q^(-1) mod 2^32 #define QINV 4236238847U // -q^(-1) mod 2^32
/* a <= Q*2^32 => r < 2*Q */ /* a <= Q*2^32 => r < 2*Q */
uint32_t montgomery_reduce(uint64_t a); uint32_t PQCLEAN_DILITHIUMIII_montgomery_reduce(uint64_t a);
/* r < 2*Q */ /* r < 2*Q */
uint32_t reduce32(uint32_t a); uint32_t PQCLEAN_DILITHIUMIII_reduce32(uint32_t a);
/* a < 2*Q => r < Q */ /* a < 2*Q => r < Q */
uint32_t csubq(uint32_t a); uint32_t PQCLEAN_DILITHIUMIII_csubq(uint32_t a);
/* r < Q */ /* r < Q */
uint32_t freeze(uint32_t a); uint32_t PQCLEAN_DILITHIUMIII_freeze(uint32_t a);
#endif #endif

View File

@ -13,7 +13,7 @@
* *
* Returns a1. * Returns a1.
**************************************************/ **************************************************/
uint32_t power2round(uint32_t a, uint32_t *a0) { uint32_t PQCLEAN_DILITHIUMIII_power2round(uint32_t a, uint32_t *a0) {
int32_t t; int32_t t;
/* Centralized remainder mod 2^D */ /* Centralized remainder mod 2^D */
@ -39,7 +39,7 @@ uint32_t power2round(uint32_t a, uint32_t *a0) {
* *
* Returns a1. * Returns a1.
**************************************************/ **************************************************/
uint32_t decompose(uint32_t a, uint32_t *a0) { uint32_t PQCLEAN_DILITHIUMIII_decompose(uint32_t a, uint32_t *a0) {
#if ALPHA != (Q - 1) / 16 #if ALPHA != (Q - 1) / 16
#error "decompose assumes ALPHA == (Q-1)/16" #error "decompose assumes ALPHA == (Q-1)/16"
#endif #endif
@ -77,10 +77,12 @@ uint32_t decompose(uint32_t a, uint32_t *a0) {
* *
* Returns 1 if high bits of a and b differ and 0 otherwise. * Returns 1 if high bits of a and b differ and 0 otherwise.
**************************************************/ **************************************************/
unsigned int make_hint(const uint32_t a, const uint32_t b) { unsigned int PQCLEAN_DILITHIUMIII_make_hint(const uint32_t a,
const uint32_t b) {
uint32_t t; uint32_t t;
return decompose(a, &t) != decompose(b, &t); return PQCLEAN_DILITHIUMIII_decompose(a, &t) !=
PQCLEAN_DILITHIUMIII_decompose(b, &t);
} }
/************************************************* /*************************************************
@ -93,10 +95,11 @@ unsigned int make_hint(const uint32_t a, const uint32_t b) {
* *
* Returns corrected high bits. * Returns corrected high bits.
**************************************************/ **************************************************/
uint32_t use_hint(const uint32_t a, const unsigned int hint) { uint32_t PQCLEAN_DILITHIUMIII_use_hint(const uint32_t a,
const unsigned int hint) {
uint32_t a0, a1; uint32_t a0, a1;
a1 = decompose(a, &a0); a1 = PQCLEAN_DILITHIUMIII_decompose(a, &a0);
if (hint == 0) { if (hint == 0) {
return a1; return a1;
} }

View File

@ -3,9 +3,9 @@
#include <stdint.h> #include <stdint.h>
uint32_t power2round(uint32_t a, uint32_t *a0); uint32_t PQCLEAN_DILITHIUMIII_power2round(uint32_t a, uint32_t *a0);
uint32_t decompose(uint32_t a, uint32_t *a0); uint32_t PQCLEAN_DILITHIUMIII_decompose(uint32_t a, uint32_t *a0);
unsigned int make_hint(uint32_t a, uint32_t b); unsigned int PQCLEAN_DILITHIUMIII_make_hint(uint32_t a, uint32_t b);
uint32_t use_hint(uint32_t a, unsigned int hint); uint32_t PQCLEAN_DILITHIUMIII_use_hint(uint32_t a, unsigned int hint);
#endif #endif

View File

@ -17,7 +17,8 @@
* Arguments: - polyvecl mat[K]: output matrix * Arguments: - polyvecl mat[K]: output matrix
* - const unsigned char rho[]: byte array containing seed rho * - const unsigned char rho[]: byte array containing seed rho
**************************************************/ **************************************************/
void expand_mat(polyvecl mat[K], const unsigned char rho[SEEDBYTES]) { void PQCLEAN_DILITHIUMIII_expand_mat(polyvecl mat[K],
const unsigned char rho[SEEDBYTES]) {
unsigned int i, j; unsigned int i, j;
unsigned char inbuf[SEEDBYTES + 1]; unsigned char inbuf[SEEDBYTES + 1];
/* Don't change this to smaller values, /* Don't change this to smaller values,
@ -34,7 +35,7 @@ void expand_mat(polyvecl mat[K], const unsigned char rho[SEEDBYTES]) {
for (j = 0; j < L; ++j) { for (j = 0; j < L; ++j) {
inbuf[SEEDBYTES] = i + (j << 4); inbuf[SEEDBYTES] = i + (j << 4);
shake128(outbuf, sizeof(outbuf), inbuf, SEEDBYTES + 1); shake128(outbuf, sizeof(outbuf), inbuf, SEEDBYTES + 1);
poly_uniform(mat[i].vec + j, outbuf); PQCLEAN_DILITHIUMIII_poly_uniform(mat[i].vec + j, outbuf);
} }
} }
} }
@ -50,7 +51,8 @@ void expand_mat(polyvecl mat[K], const unsigned char rho[SEEDBYTES]) {
* - const unsigned char mu[]: byte array containing mu * - const unsigned char mu[]: byte array containing mu
* - const polyveck *w1: pointer to vector w1 * - const polyveck *w1: pointer to vector w1
**************************************************/ **************************************************/
void challenge(poly *c, const unsigned char mu[CRHBYTES], const polyveck *w1) { void PQCLEAN_DILITHIUMIII_challenge(poly *c, const unsigned char mu[CRHBYTES],
const polyveck *w1) {
unsigned int i, b, pos; unsigned int i, b, pos;
unsigned char inbuf[CRHBYTES + K * POLW1_SIZE_PACKED]; unsigned char inbuf[CRHBYTES + K * POLW1_SIZE_PACKED];
unsigned char outbuf[SHAKE256_RATE]; unsigned char outbuf[SHAKE256_RATE];
@ -60,7 +62,8 @@ void challenge(poly *c, const unsigned char mu[CRHBYTES], const polyveck *w1) {
inbuf[i] = mu[i]; inbuf[i] = mu[i];
} }
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyw1_pack(inbuf + CRHBYTES + i * POLW1_SIZE_PACKED, w1->vec + i); PQCLEAN_DILITHIUMIII_polyw1_pack(
inbuf + CRHBYTES + i * POLW1_SIZE_PACKED, w1->vec + i);
} }
shake256_absorb(state, inbuf, sizeof(inbuf)); shake256_absorb(state, inbuf, sizeof(inbuf));
@ -106,7 +109,8 @@ void challenge(poly *c, const unsigned char mu[CRHBYTES], const polyveck *w1) {
* *
* Returns 0 (success) * Returns 0 (success)
**************************************************/ **************************************************/
int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) { int PQCLEAN_DILITHIUMIII_crypto_sign_keypair(unsigned char *pk,
unsigned char *sk) {
unsigned int i; unsigned int i;
unsigned char seedbuf[3 * SEEDBYTES]; unsigned char seedbuf[3 * SEEDBYTES];
unsigned char tr[CRHBYTES]; unsigned char tr[CRHBYTES];
@ -124,36 +128,37 @@ int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) {
key = rho + 2 * SEEDBYTES; key = rho + 2 * SEEDBYTES;
/* Expand matrix */ /* Expand matrix */
expand_mat(mat, rho); PQCLEAN_DILITHIUMIII_expand_mat(mat, rho);
/* Sample short vectors s1 and s2 */ /* Sample short vectors s1 and s2 */
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
poly_uniform_eta(s1.vec + i, rhoprime, nonce++); PQCLEAN_DILITHIUMIII_poly_uniform_eta(s1.vec + i, rhoprime, nonce++);
} }
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_uniform_eta(s2.vec + i, rhoprime, nonce++); PQCLEAN_DILITHIUMIII_poly_uniform_eta(s2.vec + i, rhoprime, nonce++);
} }
/* Matrix-vector multiplication */ /* Matrix-vector multiplication */
s1hat = s1; s1hat = s1;
polyvecl_ntt(&s1hat); PQCLEAN_DILITHIUMIII_polyvecl_ntt(&s1hat);
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyvecl_pointwise_acc_invmontgomery(t.vec + i, mat + i, &s1hat); PQCLEAN_DILITHIUMIII_polyvecl_pointwise_acc_invmontgomery(
poly_reduce(t.vec + i); t.vec + i, mat + i, &s1hat);
poly_invntt_montgomery(t.vec + i); PQCLEAN_DILITHIUMIII_poly_reduce(t.vec + i);
PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(t.vec + i);
} }
/* Add noise vector s2 */ /* Add noise vector s2 */
polyveck_add(&t, &t, &s2); PQCLEAN_DILITHIUMIII_polyveck_add(&t, &t, &s2);
/* Extract t1 and write public key */ /* Extract t1 and write public key */
polyveck_freeze(&t); PQCLEAN_DILITHIUMIII_polyveck_freeze(&t);
polyveck_power2round(&t1, &t0, &t); PQCLEAN_DILITHIUMIII_polyveck_power2round(&t1, &t0, &t);
pack_pk(pk, rho, &t1); PQCLEAN_DILITHIUMIII_pack_pk(pk, rho, &t1);
/* Compute CRH(rho, t1) and write secret key */ /* Compute CRH(rho, t1) and write secret key */
shake256(tr, CRHBYTES, pk, CRYPTO_PUBLICKEYBYTES); shake256(tr, CRHBYTES, pk, CRYPTO_PUBLICKEYBYTES);
pack_sk(sk, rho, key, tr, &s1, &s2, &t0); PQCLEAN_DILITHIUMIII_pack_sk(sk, rho, key, tr, &s1, &s2, &t0);
return 0; return 0;
} }
@ -174,9 +179,11 @@ int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) {
* *
* Returns 0 (success) * Returns 0 (success)
**************************************************/ **************************************************/
int crypto_sign(unsigned char *sm, unsigned long long *smlen, int PQCLEAN_DILITHIUMIII_crypto_sign(unsigned char *sm,
const unsigned char *m, unsigned long long mlen, unsigned long long *smlen,
const unsigned char *sk) { const unsigned char *m,
unsigned long long mlen,
const unsigned char *sk) {
unsigned long long i, j; unsigned long long i, j;
unsigned int n; unsigned int n;
unsigned char unsigned char
@ -192,7 +199,7 @@ int crypto_sign(unsigned char *sm, unsigned long long *smlen,
rho = seedbuf; rho = seedbuf;
key = seedbuf + SEEDBYTES; key = seedbuf + SEEDBYTES;
mu = seedbuf + 2 * SEEDBYTES; mu = seedbuf + 2 * SEEDBYTES;
unpack_sk(rho, key, tr, &s1, &s2, &t0, sk); PQCLEAN_DILITHIUMIII_unpack_sk(rho, key, tr, &s1, &s2, &t0, sk);
/* Copy tr and message into the sm buffer, /* Copy tr and message into the sm buffer,
* backwards since m and sm can be equal in SUPERCOP API */ * backwards since m and sm can be equal in SUPERCOP API */
@ -207,54 +214,57 @@ int crypto_sign(unsigned char *sm, unsigned long long *smlen,
shake256(mu, CRHBYTES, sm + CRYPTO_BYTES - CRHBYTES, CRHBYTES + mlen); shake256(mu, CRHBYTES, sm + CRYPTO_BYTES - CRHBYTES, CRHBYTES + mlen);
/* Expand matrix and transform vectors */ /* Expand matrix and transform vectors */
expand_mat(mat, rho); PQCLEAN_DILITHIUMIII_expand_mat(mat, rho);
polyvecl_ntt(&s1); PQCLEAN_DILITHIUMIII_polyvecl_ntt(&s1);
polyveck_ntt(&s2); PQCLEAN_DILITHIUMIII_polyveck_ntt(&s2);
polyveck_ntt(&t0); PQCLEAN_DILITHIUMIII_polyveck_ntt(&t0);
rej: rej:
/* Sample intermediate vector y */ /* Sample intermediate vector y */
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
poly_uniform_gamma1m1(y.vec + i, key, nonce++); PQCLEAN_DILITHIUMIII_poly_uniform_gamma1m1(y.vec + i, key, nonce++);
} }
/* Matrix-vector multiplication */ /* Matrix-vector multiplication */
yhat = y; yhat = y;
polyvecl_ntt(&yhat); PQCLEAN_DILITHIUMIII_polyvecl_ntt(&yhat);
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyvecl_pointwise_acc_invmontgomery(w.vec + i, mat + i, &yhat); PQCLEAN_DILITHIUMIII_polyvecl_pointwise_acc_invmontgomery(
poly_reduce(w.vec + i); w.vec + i, mat + i, &yhat);
poly_invntt_montgomery(w.vec + i); PQCLEAN_DILITHIUMIII_poly_reduce(w.vec + i);
PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(w.vec + i);
} }
/* Decompose w and call the random oracle */ /* Decompose w and call the random oracle */
polyveck_csubq(&w); PQCLEAN_DILITHIUMIII_polyveck_csubq(&w);
polyveck_decompose(&w1, &tmp, &w); PQCLEAN_DILITHIUMIII_polyveck_decompose(&w1, &tmp, &w);
challenge(&c, mu, &w1); PQCLEAN_DILITHIUMIII_challenge(&c, mu, &w1);
/* Compute z, reject if it reveals secret */ /* Compute z, reject if it reveals secret */
chat = c; chat = c;
poly_ntt(&chat); PQCLEAN_DILITHIUMIII_poly_ntt(&chat);
for (i = 0; i < L; ++i) { for (i = 0; i < L; ++i) {
poly_pointwise_invmontgomery(z.vec + i, &chat, s1.vec + i); PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(z.vec + i, &chat,
poly_invntt_montgomery(z.vec + i); s1.vec + i);
PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(z.vec + i);
} }
polyvecl_add(&z, &z, &y); PQCLEAN_DILITHIUMIII_polyvecl_add(&z, &z, &y);
polyvecl_freeze(&z); PQCLEAN_DILITHIUMIII_polyvecl_freeze(&z);
if (polyvecl_chknorm(&z, GAMMA1 - BETA)) { if (PQCLEAN_DILITHIUMIII_polyvecl_chknorm(&z, GAMMA1 - BETA)) {
goto rej; goto rej;
} }
/* Compute w - cs2, reject if w1 can not be computed from it */ /* Compute w - cs2, reject if w1 can not be computed from it */
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_pointwise_invmontgomery(wcs2.vec + i, &chat, s2.vec + i); PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(wcs2.vec + i, &chat,
poly_invntt_montgomery(wcs2.vec + i); s2.vec + i);
PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(wcs2.vec + i);
} }
polyveck_sub(&wcs2, &w, &wcs2); PQCLEAN_DILITHIUMIII_polyveck_sub(&wcs2, &w, &wcs2);
polyveck_freeze(&wcs2); PQCLEAN_DILITHIUMIII_polyveck_freeze(&wcs2);
polyveck_decompose(&tmp, &wcs20, &wcs2); PQCLEAN_DILITHIUMIII_polyveck_decompose(&tmp, &wcs20, &wcs2);
polyveck_csubq(&wcs20); PQCLEAN_DILITHIUMIII_polyveck_csubq(&wcs20);
if (polyveck_chknorm(&wcs20, GAMMA2 - BETA)) { if (PQCLEAN_DILITHIUMIII_polyveck_chknorm(&wcs20, GAMMA2 - BETA)) {
goto rej; goto rej;
} }
@ -268,24 +278,25 @@ rej:
/* Compute hints for w1 */ /* Compute hints for w1 */
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_pointwise_invmontgomery(ct0.vec + i, &chat, t0.vec + i); PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(ct0.vec + i, &chat,
poly_invntt_montgomery(ct0.vec + i); t0.vec + i);
PQCLEAN_DILITHIUMIII_poly_invntt_montgomery(ct0.vec + i);
} }
polyveck_csubq(&ct0); PQCLEAN_DILITHIUMIII_polyveck_csubq(&ct0);
if (polyveck_chknorm(&ct0, GAMMA2)) { if (PQCLEAN_DILITHIUMIII_polyveck_chknorm(&ct0, GAMMA2)) {
goto rej; goto rej;
} }
polyveck_add(&tmp, &wcs2, &ct0); PQCLEAN_DILITHIUMIII_polyveck_add(&tmp, &wcs2, &ct0);
polyveck_csubq(&tmp); PQCLEAN_DILITHIUMIII_polyveck_csubq(&tmp);
n = polyveck_make_hint(&h, &wcs2, &tmp); n = PQCLEAN_DILITHIUMIII_polyveck_make_hint(&h, &wcs2, &tmp);
if (n > OMEGA) { if (n > OMEGA) {
goto rej; goto rej;
} }
/* Write signature */ /* Write signature */
pack_sig(sm, &z, &h, &c); PQCLEAN_DILITHIUMIII_pack_sig(sm, &z, &h, &c);
*smlen = mlen + CRYPTO_BYTES; *smlen = mlen + CRYPTO_BYTES;
return 0; return 0;
@ -305,9 +316,11 @@ rej:
* *
* Returns 0 if signed message could be verified correctly and -1 otherwise * Returns 0 if signed message could be verified correctly and -1 otherwise
**************************************************/ **************************************************/
int crypto_sign_open(unsigned char *m, unsigned long long *mlen, int PQCLEAN_DILITHIUMIII_crypto_sign_open(unsigned char *m,
const unsigned char *sm, unsigned long long smlen, unsigned long long *mlen,
const unsigned char *pk) { const unsigned char *sm,
unsigned long long smlen,
const unsigned char *pk) {
unsigned long long i; unsigned long long i;
unsigned char rho[SEEDBYTES]; unsigned char rho[SEEDBYTES];
unsigned char mu[CRHBYTES]; unsigned char mu[CRHBYTES];
@ -321,11 +334,11 @@ int crypto_sign_open(unsigned char *m, unsigned long long *mlen,
*mlen = smlen - CRYPTO_BYTES; *mlen = smlen - CRYPTO_BYTES;
unpack_pk(rho, &t1, pk); PQCLEAN_DILITHIUMIII_unpack_pk(rho, &t1, pk);
if (unpack_sig(&z, &h, &c, sm)) { if (PQCLEAN_DILITHIUMIII_unpack_sig(&z, &h, &c, sm)) {
goto badsig; goto badsig;
} }
if (polyvecl_chknorm(&z, GAMMA1 - BETA)) { if (PQCLEAN_DILITHIUMIII_polyvecl_chknorm(&z, GAMMA1 - BETA)) {
goto badsig; goto badsig;
} }
@ -340,30 +353,32 @@ int crypto_sign_open(unsigned char *m, unsigned long long *mlen,
shake256(mu, CRHBYTES, m + CRYPTO_BYTES - CRHBYTES, CRHBYTES + *mlen); shake256(mu, CRHBYTES, m + CRYPTO_BYTES - CRHBYTES, CRHBYTES + *mlen);
/* Matrix-vector multiplication; compute Az - c2^dt1 */ /* Matrix-vector multiplication; compute Az - c2^dt1 */
expand_mat(mat, rho); PQCLEAN_DILITHIUMIII_expand_mat(mat, rho);
polyvecl_ntt(&z); PQCLEAN_DILITHIUMIII_polyvecl_ntt(&z);
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
polyvecl_pointwise_acc_invmontgomery(tmp1.vec + i, mat + i, &z); PQCLEAN_DILITHIUMIII_polyvecl_pointwise_acc_invmontgomery(tmp1.vec + i,
mat + i, &z);
} }
chat = c; chat = c;
poly_ntt(&chat); PQCLEAN_DILITHIUMIII_poly_ntt(&chat);
polyveck_shiftl(&t1, D); PQCLEAN_DILITHIUMIII_polyveck_shiftl(&t1, D);
polyveck_ntt(&t1); PQCLEAN_DILITHIUMIII_polyveck_ntt(&t1);
for (i = 0; i < K; ++i) { for (i = 0; i < K; ++i) {
poly_pointwise_invmontgomery(tmp2.vec + i, &chat, t1.vec + i); PQCLEAN_DILITHIUMIII_poly_pointwise_invmontgomery(tmp2.vec + i, &chat,
t1.vec + i);
} }
polyveck_sub(&tmp1, &tmp1, &tmp2); PQCLEAN_DILITHIUMIII_polyveck_sub(&tmp1, &tmp1, &tmp2);
polyveck_reduce(&tmp1); PQCLEAN_DILITHIUMIII_polyveck_reduce(&tmp1);
polyveck_invntt_montgomery(&tmp1); PQCLEAN_DILITHIUMIII_polyveck_invntt_montgomery(&tmp1);
/* Reconstruct w1 */ /* Reconstruct w1 */
polyveck_csubq(&tmp1); PQCLEAN_DILITHIUMIII_polyveck_csubq(&tmp1);
polyveck_use_hint(&w1, &tmp1, &h); PQCLEAN_DILITHIUMIII_polyveck_use_hint(&w1, &tmp1, &h);
/* Call random oracle and verify challenge */ /* Call random oracle and verify challenge */
challenge(&cp, mu, &w1); PQCLEAN_DILITHIUMIII_challenge(&cp, mu, &w1);
for (i = 0; i < N; ++i) { for (i = 0; i < N; ++i) {
if (c.coeffs[i] != cp.coeffs[i]) { if (c.coeffs[i] != cp.coeffs[i]) {
goto badsig; goto badsig;

View File

@ -5,17 +5,24 @@
#include "poly.h" #include "poly.h"
#include "polyvec.h" #include "polyvec.h"
void expand_mat(polyvecl mat[K], const unsigned char rho[SEEDBYTES]); void PQCLEAN_DILITHIUMIII_expand_mat(polyvecl mat[K],
void challenge(poly *c, const unsigned char mu[CRHBYTES], const polyveck *w1); const unsigned char rho[SEEDBYTES]);
void PQCLEAN_DILITHIUMIII_challenge(poly *c, const unsigned char mu[CRHBYTES],
const polyveck *w1);
int crypto_sign_keypair(unsigned char *pk, unsigned char *sk); int PQCLEAN_DILITHIUMIII_crypto_sign_keypair(unsigned char *pk,
unsigned char *sk);
int crypto_sign(unsigned char *sm, unsigned long long *smlen, int PQCLEAN_DILITHIUMIII_crypto_sign(unsigned char *sm,
const unsigned char *m, unsigned long long mlen, unsigned long long *smlen,
const unsigned char *sk); const unsigned char *m,
unsigned long long mlen,
const unsigned char *sk);
int crypto_sign_open(unsigned char *m, unsigned long long *mlen, int PQCLEAN_DILITHIUMIII_crypto_sign_open(unsigned char *m,
const unsigned char *sm, unsigned long long smlen, unsigned long long *mlen,
const unsigned char *pk); const unsigned char *sm,
unsigned long long smlen,
const unsigned char *pk);
#endif #endif