Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34504774
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
110 KB
Subscribers
None
View Options
diff --git a/cipher/dilithium-common.c b/cipher/dilithium-common.c
index 7e623d38..0053d8e9 100644
--- a/cipher/dilithium-common.c
+++ b/cipher/dilithium-common.c
@@ -1,1319 +1,1349 @@
/* dilithium-common.c - the Dilithium (common part)
* Copyright (C) 2025 g10 Code GmbH
*
* This file was modified for use by Libgcrypt.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* You can also use this file under the same licence of original code.
* SPDX-License-Identifier: CC0 OR Apache-2.0
*
*/
/*
Original code from:
Repository: https://github.com/pq-crystals/dilithium.git
Branch: master
Commit: 444cdcc84eb36b66fe27b3a2529ee48f6d8150c2
Licence:
Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html).
Authors:
Léo Ducas
Eike Kiltz
Tancrède Lepoint
Vadim Lyubashevsky
Gregor Seiler
Peter Schwabe
Damien Stehlé
Dilithium Home: https://github.com/pq-crystals/dilithium.git
*/
/*************** dilithium/ref/ntt.c */
static const int32_t zetas[N] = {
0, 25847, -2608894, -518909, 237124, -777960, -876248, 466468,
1826347, 2353451, -359251, -2091905, 3119733, -2884855, 3111497, 2680103,
2725464, 1024112, -1079900, 3585928, -549488, -1119584, 2619752, -2108549,
-2118186, -3859737, -1399561, -3277672, 1757237, -19422, 4010497, 280005,
2706023, 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439,
-3861115, -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299,
-1699267, -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596,
811944, 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779,
-3930395, -1528703, -3677745, -3041255, -1452451, 3475950, 2176455, -1585221,
-1257611, 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922,
3412210, -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047,
-671102, -1228525, -22981, -1308169, -381987, 1349076, 1852771, -1430430,
-3343383, 264944, 508951, 3097992, 44288, -1100098, 904516, 3958618,
-3724342, -8578, 1653064, -3249728, 2389356, -210977, 759969, -1316856,
189548, -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330,
1285669, -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961,
2091667, 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462,
266997, 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378,
900702, 1859098, 909542, 819034, 495491, -1613174, -43260, -522500,
-655327, -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838,
342297, 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044,
2842341, 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974,
-3767016, 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970,
-1333058, 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642,
-1279661, 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031,
-542412, -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993,
-2013608, 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385,
-3183426, 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107,
-3038916, 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078,
-426683, 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893,
-2939036, -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687,
-554416, 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782
};
/*************************************************
* Name: ntt
*
* Description: Forward NTT, in-place. No modular reduction is performed after
* additions or subtractions. Output vector is in bitreversed order.
*
* Arguments: - uint32_t p[N]: input/output coefficient array
**************************************************/
void ntt(int32_t a[N]) {
unsigned int len, start, j, k;
int32_t zeta, t;
k = 0;
for(len = 128; len > 0; len >>= 1) {
for(start = 0; start < N; start = j + len) {
zeta = zetas[++k];
for(j = start; j < start + len; ++j) {
t = montgomery_reduce((int64_t)zeta * a[j + len]);
a[j + len] = a[j] - t;
a[j] = a[j] + t;
}
}
}
}
/*************************************************
* Name: invntt_tomont
*
* Description: Inverse NTT and multiplication by Montgomery factor 2^32.
* In-place. No modular reductions after additions or
* subtractions; input coefficients need to be smaller than
* Q in absolute value. Output coefficient are smaller than Q in
* absolute value.
*
* Arguments: - uint32_t p[N]: input/output coefficient array
**************************************************/
void invntt_tomont(int32_t a[N]) {
unsigned int start, len, j, k;
int32_t t, zeta;
const int32_t f = 41978; /* mont^2/256 */
k = 256;
for(len = 1; len < N; len <<= 1) {
for(start = 0; start < N; start = j + len) {
zeta = -zetas[--k];
for(j = start; j < start + len; ++j) {
t = a[j];
a[j] = t + a[j + len];
a[j + len] = t - a[j + len];
a[j + len] = montgomery_reduce((int64_t)zeta * a[j + len]);
}
}
}
for(j = 0; j < N; ++j) {
a[j] = montgomery_reduce((int64_t)f * a[j]);
}
}
/*************** dilithium/ref/rounding.c */
/*************************************************
* Name: power2round
*
* Description: For finite field element a, compute a0, a1 such that
* a mod^+ Q = a1*2^D + a0 with -2^{D-1} < a0 <= 2^{D-1}.
* Assumes a to be standard representative.
*
* Arguments: - int32_t a: input element
* - int32_t *a0: pointer to output element a0
*
* Returns a1.
**************************************************/
int32_t power2round(int32_t *a0, int32_t a) {
int32_t a1;
a1 = (a + (1 << (D-1)) - 1) >> D;
*a0 = a - (a1 << D);
return a1;
}
/*************************************************
* Name: decompose
*
* Description: For finite field element a, compute high and low bits a0, a1 such
* that a mod^+ Q = a1*ALPHA + a0 with -ALPHA/2 < a0 <= ALPHA/2 except
* if a1 = (Q-1)/ALPHA where we set a1 = 0 and
* -ALPHA/2 <= a0 = a mod^+ Q - Q < 0. Assumes a to be standard
* representative.
*
* Arguments: - int32_t a: input element
* - int32_t *a0: pointer to output element a0
*
* Returns a1.
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define decompose decompose_88
-int32_t decompose(int32_t *a0, int32_t a) {
+int32_t decompose_88(int32_t *a0, int32_t a) {
int32_t a1;
a1 = (a + 127) >> 7;
a1 = (a1*11275 + (1 << 23)) >> 24;
a1 ^= ((43 - a1) >> 31) & a1;
*a0 = a - a1*2*GAMMA2_88;
*a0 -= (((Q-1)/2 - *a0) >> 31) & Q;
return a1;
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define decompose decompose_32
-int32_t decompose(int32_t *a0, int32_t a) {
+int32_t decompose_32(int32_t *a0, int32_t a) {
int32_t a1;
a1 = (a + 127) >> 7;
a1 = (a1*1025 + (1 << 21)) >> 22;
a1 &= 15;
*a0 = a - a1*2*GAMMA2_32;
*a0 -= (((Q-1)/2 - *a0) >> 31) & Q;
return a1;
}
#endif
/*************************************************
* Name: make_hint
*
* Description: Compute hint bit indicating whether the low bits of the
* input element overflow into the high bits.
*
* Arguments: - int32_t a0: low bits of input element
* - int32_t a1: high bits of input element
*
* Returns 1 if overflow.
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define make_hint make_hint_88
-unsigned int make_hint(int32_t a0, int32_t a1) {
+unsigned int make_hint_88(int32_t a0, int32_t a1) {
if(a0 > GAMMA2_88 || a0 < -GAMMA2_88 || (a0 == -GAMMA2_88 && a1 != 0))
return 1;
return 0;
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define make_hint make_hint_32
-unsigned int make_hint(int32_t a0, int32_t a1) {
+unsigned int make_hint_32(int32_t a0, int32_t a1) {
if(a0 > GAMMA2_32 || a0 < -GAMMA2_32 || (a0 == -GAMMA2_32 && a1 != 0))
return 1;
return 0;
}
#endif
/*************************************************
* Name: use_hint
*
* Description: Correct high bits according to hint.
*
* Arguments: - int32_t a: input element
* - unsigned int hint: hint bit
*
* Returns corrected high bits.
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define use_hint use_hint_88
-int32_t use_hint(int32_t a, unsigned int hint) {
+int32_t use_hint_88(int32_t a, unsigned int hint) {
int32_t a0, a1;
- a1 = decompose(&a0, a);
+ a1 = decompose_88(&a0, a);
if(hint == 0)
return a1;
if(a0 > 0)
return (a1 == 43) ? 0 : a1 + 1;
else
return (a1 == 0) ? 43 : a1 - 1;
}
#endif
-
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define use_hint use_hint_32
-int32_t use_hint(int32_t a, unsigned int hint) {
+int32_t use_hint_32(int32_t a, unsigned int hint) {
int32_t a0, a1;
- a1 = decompose(&a0, a);
+ a1 = decompose_32(&a0, a);
if(hint == 0)
return a1;
if(a0 > 0)
return (a1 + 1) & 15;
else
return (a1 - 1) & 15;
}
#endif
/*************** dilithium/ref/poly.c */
#ifdef DBENCH
#include "test/cpucycles.h"
extern const uint64_t timing_overhead;
extern uint64_t *tred, *tadd, *tmul, *tround, *tsample, *tpack;
#define DBENCH_START() uint64_t time = cpucycles()
#define DBENCH_STOP(t) t += cpucycles() - time - timing_overhead
#else
#define DBENCH_START()
#define DBENCH_STOP(t)
#endif
/*************************************************
* Name: poly_reduce
*
* Description: Inplace reduction of all coefficients of polynomial to
* representative in [-6283008,6283008].
*
* Arguments: - poly *a: pointer to input/output polynomial
**************************************************/
void poly_reduce(poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
a->coeffs[i] = reduce32(a->coeffs[i]);
DBENCH_STOP(*tred);
}
/*************************************************
* Name: poly_caddq
*
* Description: For all coefficients of in/out polynomial add Q if
* coefficient is negative.
*
* Arguments: - poly *a: pointer to input/output polynomial
**************************************************/
void poly_caddq(poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
a->coeffs[i] = caddq(a->coeffs[i]);
DBENCH_STOP(*tred);
}
/*************************************************
* Name: poly_add
*
* Description: Add polynomials. No modular reduction is performed.
*
* Arguments: - poly *c: pointer to output polynomial
* - const poly *a: pointer to first summand
* - const poly *b: pointer to second summand
**************************************************/
void poly_add(poly *c, const poly *a, const poly *b) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
c->coeffs[i] = a->coeffs[i] + b->coeffs[i];
DBENCH_STOP(*tadd);
}
/*************************************************
* Name: poly_sub
*
* Description: Subtract polynomials. No modular reduction is
* performed.
*
* Arguments: - poly *c: pointer to output polynomial
* - const poly *a: pointer to first input polynomial
* - const poly *b: pointer to second input polynomial to be
* subtraced from first input polynomial
**************************************************/
void poly_sub(poly *c, const poly *a, const poly *b) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
c->coeffs[i] = a->coeffs[i] - b->coeffs[i];
DBENCH_STOP(*tadd);
}
/*************************************************
* Name: poly_shiftl
*
* Description: Multiply polynomial by 2^D without modular reduction. Assumes
* input coefficients to be less than 2^{31-D} in absolute value.
*
* Arguments: - poly *a: pointer to input/output polynomial
**************************************************/
void poly_shiftl(poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
a->coeffs[i] <<= D;
DBENCH_STOP(*tmul);
}
/*************************************************
* Name: poly_ntt
*
* Description: Inplace forward NTT. Coefficients can grow by
* 8*Q in absolute value.
*
* Arguments: - poly *a: pointer to input/output polynomial
**************************************************/
void poly_ntt(poly *a) {
DBENCH_START();
ntt(a->coeffs);
DBENCH_STOP(*tmul);
}
/*************************************************
* Name: poly_invntt_tomont
*
* Description: Inplace inverse NTT and multiplication by 2^{32}.
* Input coefficients need to be less than Q in absolute
* value and output coefficients are again bounded by Q.
*
* Arguments: - poly *a: pointer to input/output polynomial
**************************************************/
void poly_invntt_tomont(poly *a) {
DBENCH_START();
invntt_tomont(a->coeffs);
DBENCH_STOP(*tmul);
}
/*************************************************
* Name: poly_pointwise_montgomery
*
* Description: Pointwise multiplication of polynomials in NTT domain
* representation and multiplication of resulting polynomial
* by 2^{-32}.
*
* Arguments: - poly *c: pointer to output polynomial
* - const poly *a: pointer to first input polynomial
* - const poly *b: pointer to second input polynomial
**************************************************/
void poly_pointwise_montgomery(poly *c, const poly *a, const poly *b) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
c->coeffs[i] = montgomery_reduce((int64_t)a->coeffs[i] * b->coeffs[i]);
DBENCH_STOP(*tmul);
}
/*************************************************
* Name: poly_power2round
*
* Description: For all coefficients c of the input polynomial,
* compute c0, c1 such that c mod Q = c1*2^D + c0
* with -2^{D-1} < c0 <= 2^{D-1}. Assumes coefficients to be
* standard representatives.
*
* Arguments: - poly *a1: pointer to output polynomial with coefficients c1
* - poly *a0: pointer to output polynomial with coefficients c0
* - const poly *a: pointer to input polynomial
**************************************************/
void poly_power2round(poly *a1, poly *a0, const poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
a1->coeffs[i] = power2round(&a0->coeffs[i], a->coeffs[i]);
DBENCH_STOP(*tround);
}
/*************************************************
* Name: poly_decompose
*
* Description: For all coefficients c of the input polynomial,
* compute high and low bits c0, c1 such c mod Q = c1*ALPHA + c0
* with -ALPHA/2 < c0 <= ALPHA/2 except c1 = (Q-1)/ALPHA where we
* set c1 = 0 and -ALPHA/2 <= c0 = c mod Q - Q < 0.
* Assumes coefficients to be standard representatives.
*
* Arguments: - poly *a1: pointer to output polynomial with coefficients c1
* - poly *a0: pointer to output polynomial with coefficients c0
* - const poly *a: pointer to input polynomial
**************************************************/
-void poly_decompose(poly *a1, poly *a0, const poly *a) {
+#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
+void poly_decompose_88(poly *a1, poly *a0, const poly *a) {
+ unsigned int i;
+ DBENCH_START();
+
+ for(i = 0; i < N; ++i)
+ a1->coeffs[i] = decompose_88(&a0->coeffs[i], a->coeffs[i]);
+
+ DBENCH_STOP(*tround);
+}
+#endif
+#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
+void poly_decompose_32(poly *a1, poly *a0, const poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
- a1->coeffs[i] = decompose(&a0->coeffs[i], a->coeffs[i]);
+ a1->coeffs[i] = decompose_32(&a0->coeffs[i], a->coeffs[i]);
DBENCH_STOP(*tround);
}
+#endif
/*************************************************
* Name: poly_make_hint
*
* Description: Compute hint polynomial. The coefficients of which indicate
* whether the low bits of the corresponding coefficient of
* the input polynomial overflow into the high bits.
*
* Arguments: - poly *h: pointer to output hint polynomial
* - const poly *a0: pointer to low part of input polynomial
* - const poly *a1: pointer to high part of input polynomial
*
* Returns number of 1 bits.
**************************************************/
-unsigned int poly_make_hint(poly *h, const poly *a0, const poly *a1) {
+#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
+unsigned int poly_make_hint_88(poly *h, const poly *a0, const poly *a1) {
unsigned int i, s = 0;
DBENCH_START();
for(i = 0; i < N; ++i) {
- h->coeffs[i] = make_hint(a0->coeffs[i], a1->coeffs[i]);
+ h->coeffs[i] = make_hint_88(a0->coeffs[i], a1->coeffs[i]);
s += h->coeffs[i];
}
DBENCH_STOP(*tround);
return s;
}
+#endif
+#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
+unsigned int poly_make_hint_32(poly *h, const poly *a0, const poly *a1) {
+ unsigned int i, s = 0;
+ DBENCH_START();
+
+ for(i = 0; i < N; ++i) {
+ h->coeffs[i] = make_hint_32(a0->coeffs[i], a1->coeffs[i]);
+ s += h->coeffs[i];
+ }
+
+ DBENCH_STOP(*tround);
+ return s;
+}
+#endif
/*************************************************
* Name: poly_use_hint
*
* Description: Use hint polynomial to correct the high bits of a polynomial.
*
* Arguments: - poly *b: pointer to output polynomial with corrected high bits
* - const poly *a: pointer to input polynomial
* - const poly *h: pointer to input hint polynomial
**************************************************/
-void poly_use_hint(poly *b, const poly *a, const poly *h) {
+#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
+void poly_use_hint_88(poly *b, const poly *a, const poly *h) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N; ++i)
- b->coeffs[i] = use_hint(a->coeffs[i], h->coeffs[i]);
+ b->coeffs[i] = use_hint_88(a->coeffs[i], h->coeffs[i]);
DBENCH_STOP(*tround);
}
+#endif
+#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
+void poly_use_hint_32(poly *b, const poly *a, const poly *h) {
+ unsigned int i;
+ DBENCH_START();
+
+ for(i = 0; i < N; ++i)
+ b->coeffs[i] = use_hint_32(a->coeffs[i], h->coeffs[i]);
+
+ DBENCH_STOP(*tround);
+}
+#endif
/*************************************************
* Name: poly_chknorm
*
* Description: Check infinity norm of polynomial against given bound.
* Assumes input coefficients were reduced by reduce32().
*
* Arguments: - const poly *a: pointer to polynomial
* - int32_t B: norm bound
*
* Returns 0 if norm is strictly smaller than B <= (Q-1)/8 and 1 otherwise.
**************************************************/
int poly_chknorm(const poly *a, int32_t B) {
unsigned int i;
int32_t t;
DBENCH_START();
if(B > (Q-1)/8)
return 1;
/* It is ok to leak which coefficient violates the bound since
the probability for each coefficient is independent of secret
data but we must not leak the sign of the centralized representative. */
for(i = 0; i < N; ++i) {
/* Absolute value */
t = a->coeffs[i] >> 31;
t = a->coeffs[i] - (t & 2*a->coeffs[i]);
if(t >= B) {
DBENCH_STOP(*tsample);
return 1;
}
}
DBENCH_STOP(*tsample);
return 0;
}
/*************************************************
* Name: rej_uniform
*
* Description: Sample uniformly random coefficients in [0, Q-1] by
* performing rejection sampling on array of random bytes.
*
* Arguments: - int32_t *a: pointer to output array (allocated)
* - unsigned int len: number of coefficients to be sampled
* - const uint8_t *buf: array of random bytes
* - unsigned int buflen: length of array of random bytes
*
* Returns number of sampled coefficients. Can be smaller than len if not enough
* random bytes were given.
**************************************************/
static unsigned int rej_uniform(int32_t *a,
unsigned int len,
const uint8_t *buf,
unsigned int buflen)
{
unsigned int ctr, pos;
uint32_t t;
DBENCH_START();
ctr = pos = 0;
while(ctr < len && pos + 3 <= buflen) {
t = buf[pos++];
t |= (uint32_t)buf[pos++] << 8;
t |= (uint32_t)buf[pos++] << 16;
t &= 0x7FFFFF;
if(t < Q)
a[ctr++] = t;
}
DBENCH_STOP(*tsample);
return ctr;
}
/*************************************************
* Name: poly_uniform
*
* Description: Sample polynomial with uniformly random coefficients
* in [0,Q-1] by performing rejection sampling on the
* output stream of SHAKE128(seed|nonce)
*
* Arguments: - poly *a: pointer to output polynomial
* - const uint8_t seed[]: byte array with seed of length SEEDBYTES
* - uint16_t nonce: 2-byte nonce
**************************************************/
#define POLY_UNIFORM_NBLOCKS ((768 + STREAM128_BLOCKBYTES - 1)/STREAM128_BLOCKBYTES)
void poly_uniform(poly *a,
const uint8_t seed[SEEDBYTES],
uint16_t nonce)
{
unsigned int i, ctr, off;
unsigned int buflen = POLY_UNIFORM_NBLOCKS*STREAM128_BLOCKBYTES;
uint8_t buf[POLY_UNIFORM_NBLOCKS*STREAM128_BLOCKBYTES + 2];
stream128_state state;
stream128_init(&state, seed, nonce);
stream128_squeezeblocks(buf, POLY_UNIFORM_NBLOCKS, &state);
ctr = rej_uniform(a->coeffs, N, buf, buflen);
while(ctr < N) {
off = buflen % 3;
for(i = 0; i < off; ++i)
buf[i] = buf[buflen - off + i];
stream128_squeezeblocks(buf + off, 1, &state);
buflen = STREAM128_BLOCKBYTES + off;
ctr += rej_uniform(a->coeffs + ctr, N - ctr, buf, buflen);
}
stream128_close(&state);
}
/*************************************************
* Name: rej_eta
*
* Description: Sample uniformly random coefficients in [-ETA, ETA] by
* performing rejection sampling on array of random bytes.
*
* Arguments: - int32_t *a: pointer to output array (allocated)
* - unsigned int len: number of coefficients to be sampled
* - const uint8_t *buf: array of random bytes
* - unsigned int buflen: length of array of random bytes
*
* Returns number of sampled coefficients. Can be smaller than len if not enough
* random bytes were given.
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2 || DILITHIUM_MODE == 5
-#define rej_eta rej_eta_2
-static unsigned int rej_eta(int32_t *a,
- unsigned int len,
- const uint8_t *buf,
- unsigned int buflen)
+static unsigned int rej_eta_2(int32_t *a,
+ unsigned int len,
+ const uint8_t *buf,
+ unsigned int buflen)
{
unsigned int ctr, pos;
uint32_t t0, t1;
DBENCH_START();
ctr = pos = 0;
while(ctr < len && pos < buflen) {
t0 = buf[pos] & 0x0F;
t1 = buf[pos++] >> 4;
if(t0 < 15) {
t0 = t0 - (205*t0 >> 10)*5;
a[ctr++] = 2 - t0;
}
if(t1 < 15 && ctr < len) {
t1 = t1 - (205*t1 >> 10)*5;
a[ctr++] = 2 - t1;
}
}
DBENCH_STOP(*tsample);
return ctr;
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3
-#define rej_eta rej_eta_4
-static unsigned int rej_eta(int32_t *a,
- unsigned int len,
- const uint8_t *buf,
- unsigned int buflen)
+static unsigned int rej_eta_4(int32_t *a,
+ unsigned int len,
+ const uint8_t *buf,
+ unsigned int buflen)
{
unsigned int ctr, pos;
uint32_t t0, t1;
DBENCH_START();
ctr = pos = 0;
while(ctr < len && pos < buflen) {
t0 = buf[pos] & 0x0F;
t1 = buf[pos++] >> 4;
if(t0 < 9)
a[ctr++] = 4 - t0;
if(t1 < 9 && ctr < len)
a[ctr++] = 4 - t1;
}
DBENCH_STOP(*tsample);
return ctr;
}
#endif
/*************************************************
* Name: poly_uniform_eta
*
* Description: Sample polynomial with uniformly random coefficients
* in [-ETA,ETA] by performing rejection sampling on the
* output stream from SHAKE256(seed|nonce)
*
* Arguments: - poly *a: pointer to output polynomial
* - const uint8_t seed[]: byte array with seed of length CRHBYTES
* - uint16_t nonce: 2-byte nonce
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2 || DILITHIUM_MODE == 5
-#define poly_uniform_eta poly_uniform_eta_2
#define POLY_UNIFORM_ETA_NBLOCKS_2 ((136 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
-void poly_uniform_eta(poly *a,
- const uint8_t seed[CRHBYTES],
- uint16_t nonce)
+void poly_uniform_eta_2(poly *a,
+ const uint8_t seed[CRHBYTES],
+ uint16_t nonce)
{
unsigned int ctr;
unsigned int buflen = POLY_UNIFORM_ETA_NBLOCKS_2*STREAM256_BLOCKBYTES;
uint8_t buf[POLY_UNIFORM_ETA_NBLOCKS_2*STREAM256_BLOCKBYTES];
stream256_state state;
stream256_init(&state, seed, nonce);
stream256_squeezeblocks(buf, POLY_UNIFORM_ETA_NBLOCKS_2, &state);
- ctr = rej_eta(a->coeffs, N, buf, buflen);
+ ctr = rej_eta_2(a->coeffs, N, buf, buflen);
while(ctr < N) {
stream256_squeezeblocks(buf, 1, &state);
- ctr += rej_eta(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
+ ctr += rej_eta_2(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
}
stream256_close(&state);
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3
-#define poly_uniform_eta poly_uniform_eta_4
#define POLY_UNIFORM_ETA_NBLOCKS_4 ((227 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
-void poly_uniform_eta(poly *a,
- const uint8_t seed[CRHBYTES],
- uint16_t nonce)
+void poly_uniform_eta_4(poly *a,
+ const uint8_t seed[CRHBYTES],
+ uint16_t nonce)
{
unsigned int ctr;
unsigned int buflen = POLY_UNIFORM_ETA_NBLOCKS_4*STREAM256_BLOCKBYTES;
uint8_t buf[POLY_UNIFORM_ETA_NBLOCKS_4*STREAM256_BLOCKBYTES];
stream256_state state;
stream256_init(&state, seed, nonce);
stream256_squeezeblocks(buf, POLY_UNIFORM_ETA_NBLOCKS_4, &state);
- ctr = rej_eta(a->coeffs, N, buf, buflen);
+ ctr = rej_eta_4(a->coeffs, N, buf, buflen);
while(ctr < N) {
stream256_squeezeblocks(buf, 1, &state);
- ctr += rej_eta(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
+ ctr += rej_eta_4(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
}
stream256_close(&state);
}
#endif
/*************************************************
* Name: poly_uniform_gamma1m1
*
* Description: Sample polynomial with uniformly random coefficients
* in [-(GAMMA1 - 1), GAMMA1] by unpacking output stream
* of SHAKE256(seed|nonce)
*
* Arguments: - poly *a: pointer to output polynomial
* - const uint8_t seed[]: byte array with seed of length CRHBYTES
* - uint16_t nonce: 16-bit nonce
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define polyz_unpack polyz_unpack_17
-#define poly_uniform_gamma1 poly_uniform_gamma1_17
-#define POLY_UNIFORM_GAMMA1_NBLOCKS ((POLYZ_PACKEDBYTES_17 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
+#define POLY_UNIFORM_GAMMA1_NBLOCKS_17 ((POLYZ_PACKEDBYTES_17 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
+void polyz_unpack_17(poly *r, const uint8_t *a);/* Forward declarations */
+void poly_uniform_gamma1_17(poly *a,
+ const uint8_t seed[CRHBYTES],
+ uint16_t nonce)
+{
+ uint8_t buf[POLY_UNIFORM_GAMMA1_NBLOCKS_17*STREAM256_BLOCKBYTES];
+ stream256_state state;
+
+ stream256_init(&state, seed, nonce);
+ stream256_squeezeblocks(buf, POLY_UNIFORM_GAMMA1_NBLOCKS_17, &state);
+ polyz_unpack_17(a, buf);
+ stream256_close(&state);
+}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define polyz_unpack polyz_unpack_19
-#define poly_uniform_gamma1 poly_uniform_gamma1_19
-#define POLY_UNIFORM_GAMMA1_NBLOCKS ((POLYZ_PACKEDBYTES_19 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
-#endif
-void polyz_unpack(poly *r, const uint8_t *a);/* Forward declarations */
-void poly_uniform_gamma1(poly *a,
- const uint8_t seed[CRHBYTES],
- uint16_t nonce)
+#define POLY_UNIFORM_GAMMA1_NBLOCKS_19 ((POLYZ_PACKEDBYTES_19 + STREAM256_BLOCKBYTES - 1)/STREAM256_BLOCKBYTES)
+void polyz_unpack_19(poly *r, const uint8_t *a);/* Forward declarations */
+void poly_uniform_gamma1_19(poly *a,
+ const uint8_t seed[CRHBYTES],
+ uint16_t nonce)
{
- uint8_t buf[POLY_UNIFORM_GAMMA1_NBLOCKS*STREAM256_BLOCKBYTES];
+ uint8_t buf[POLY_UNIFORM_GAMMA1_NBLOCKS_19*STREAM256_BLOCKBYTES];
stream256_state state;
stream256_init(&state, seed, nonce);
- stream256_squeezeblocks(buf, POLY_UNIFORM_GAMMA1_NBLOCKS, &state);
- polyz_unpack(a, buf);
+ stream256_squeezeblocks(buf, POLY_UNIFORM_GAMMA1_NBLOCKS_19, &state);
+ polyz_unpack_19(a, buf);
stream256_close(&state);
}
+#endif
/*************************************************
* Name: polyeta_pack
*
* Description: Bit-pack polynomial with coefficients in [-ETA,ETA].
*
* Arguments: - uint8_t *r: pointer to output byte array with at least
* POLYETA_PACKEDBYTES bytes
* - const poly *a: pointer to input polynomial
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2 || DILITHIUM_MODE == 5
-#define polyeta_pack polyeta_pack_2
-void polyeta_pack(uint8_t *r, const poly *a) {
+void polyeta_pack_2(uint8_t *r, const poly *a) {
unsigned int i;
uint8_t t[8];
DBENCH_START();
for(i = 0; i < N/8; ++i) {
t[0] = ETA2 - a->coeffs[8*i+0];
t[1] = ETA2 - a->coeffs[8*i+1];
t[2] = ETA2 - a->coeffs[8*i+2];
t[3] = ETA2 - a->coeffs[8*i+3];
t[4] = ETA2 - a->coeffs[8*i+4];
t[5] = ETA2 - a->coeffs[8*i+5];
t[6] = ETA2 - a->coeffs[8*i+6];
t[7] = ETA2 - a->coeffs[8*i+7];
r[3*i+0] = (t[0] >> 0) | (t[1] << 3) | (t[2] << 6);
r[3*i+1] = (t[2] >> 2) | (t[3] << 1) | (t[4] << 4) | (t[5] << 7);
r[3*i+2] = (t[5] >> 1) | (t[6] << 2) | (t[7] << 5);
}
DBENCH_STOP(*tpack);
}
#endif
-
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3
-#define polyeta_pack polyeta_pack_4
-void polyeta_pack(uint8_t *r, const poly *a) {
+void polyeta_pack_4(uint8_t *r, const poly *a) {
unsigned int i;
uint8_t t[8];
DBENCH_START();
for(i = 0; i < N/2; ++i) {
t[0] = ETA4 - a->coeffs[2*i+0];
t[1] = ETA4 - a->coeffs[2*i+1];
r[i] = t[0] | (t[1] << 4);
}
DBENCH_STOP(*tpack);
}
#endif
/*************************************************
* Name: polyeta_unpack
*
* Description: Unpack polynomial with coefficients in [-ETA,ETA].
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t *a: byte array with bit-packed polynomial
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2 || DILITHIUM_MODE == 5
-#define polyeta_unpack polyeta_unpack_2
-void polyeta_unpack(poly *r, const uint8_t *a) {
+void polyeta_unpack_2(poly *r, const uint8_t *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/8; ++i) {
r->coeffs[8*i+0] = (a[3*i+0] >> 0) & 7;
r->coeffs[8*i+1] = (a[3*i+0] >> 3) & 7;
r->coeffs[8*i+2] = ((a[3*i+0] >> 6) | (a[3*i+1] << 2)) & 7;
r->coeffs[8*i+3] = (a[3*i+1] >> 1) & 7;
r->coeffs[8*i+4] = (a[3*i+1] >> 4) & 7;
r->coeffs[8*i+5] = ((a[3*i+1] >> 7) | (a[3*i+2] << 1)) & 7;
r->coeffs[8*i+6] = (a[3*i+2] >> 2) & 7;
r->coeffs[8*i+7] = (a[3*i+2] >> 5) & 7;
r->coeffs[8*i+0] = ETA2 - r->coeffs[8*i+0];
r->coeffs[8*i+1] = ETA2 - r->coeffs[8*i+1];
r->coeffs[8*i+2] = ETA2 - r->coeffs[8*i+2];
r->coeffs[8*i+3] = ETA2 - r->coeffs[8*i+3];
r->coeffs[8*i+4] = ETA2 - r->coeffs[8*i+4];
r->coeffs[8*i+5] = ETA2 - r->coeffs[8*i+5];
r->coeffs[8*i+6] = ETA2 - r->coeffs[8*i+6];
r->coeffs[8*i+7] = ETA2 - r->coeffs[8*i+7];
}
DBENCH_STOP(*tpack);
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3
-#define polyeta_unpack polyeta_unpack_4
-void polyeta_unpack(poly *r, const uint8_t *a) {
+void polyeta_unpack_4(poly *r, const uint8_t *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/2; ++i) {
r->coeffs[2*i+0] = a[i] & 0x0F;
r->coeffs[2*i+1] = a[i] >> 4;
r->coeffs[2*i+0] = ETA4 - r->coeffs[2*i+0];
r->coeffs[2*i+1] = ETA4 - r->coeffs[2*i+1];
}
DBENCH_STOP(*tpack);
}
#endif
/*************************************************
* Name: polyt1_pack
*
* Description: Bit-pack polynomial t1 with coefficients fitting in 10 bits.
* Input coefficients are assumed to be standard representatives.
*
* Arguments: - uint8_t *r: pointer to output byte array with at least
* POLYT1_PACKEDBYTES bytes
* - const poly *a: pointer to input polynomial
**************************************************/
void polyt1_pack(uint8_t *r, const poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/4; ++i) {
r[5*i+0] = (a->coeffs[4*i+0] >> 0);
r[5*i+1] = (a->coeffs[4*i+0] >> 8) | (a->coeffs[4*i+1] << 2);
r[5*i+2] = (a->coeffs[4*i+1] >> 6) | (a->coeffs[4*i+2] << 4);
r[5*i+3] = (a->coeffs[4*i+2] >> 4) | (a->coeffs[4*i+3] << 6);
r[5*i+4] = (a->coeffs[4*i+3] >> 2);
}
DBENCH_STOP(*tpack);
}
/*************************************************
* Name: polyt1_unpack
*
* Description: Unpack polynomial t1 with 10-bit coefficients.
* Output coefficients are standard representatives.
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t *a: byte array with bit-packed polynomial
**************************************************/
void polyt1_unpack(poly *r, const uint8_t *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/4; ++i) {
r->coeffs[4*i+0] = ((a[5*i+0] >> 0) | ((uint32_t)a[5*i+1] << 8)) & 0x3FF;
r->coeffs[4*i+1] = ((a[5*i+1] >> 2) | ((uint32_t)a[5*i+2] << 6)) & 0x3FF;
r->coeffs[4*i+2] = ((a[5*i+2] >> 4) | ((uint32_t)a[5*i+3] << 4)) & 0x3FF;
r->coeffs[4*i+3] = ((a[5*i+3] >> 6) | ((uint32_t)a[5*i+4] << 2)) & 0x3FF;
}
DBENCH_STOP(*tpack);
}
/*************************************************
* Name: polyt0_pack
*
* Description: Bit-pack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}].
*
* Arguments: - uint8_t *r: pointer to output byte array with at least
* POLYT0_PACKEDBYTES bytes
* - const poly *a: pointer to input polynomial
**************************************************/
void polyt0_pack(uint8_t *r, const poly *a) {
unsigned int i;
uint32_t t[8];
DBENCH_START();
for(i = 0; i < N/8; ++i) {
t[0] = (1 << (D-1)) - a->coeffs[8*i+0];
t[1] = (1 << (D-1)) - a->coeffs[8*i+1];
t[2] = (1 << (D-1)) - a->coeffs[8*i+2];
t[3] = (1 << (D-1)) - a->coeffs[8*i+3];
t[4] = (1 << (D-1)) - a->coeffs[8*i+4];
t[5] = (1 << (D-1)) - a->coeffs[8*i+5];
t[6] = (1 << (D-1)) - a->coeffs[8*i+6];
t[7] = (1 << (D-1)) - a->coeffs[8*i+7];
r[13*i+ 0] = t[0];
r[13*i+ 1] = t[0] >> 8;
r[13*i+ 1] |= t[1] << 5;
r[13*i+ 2] = t[1] >> 3;
r[13*i+ 3] = t[1] >> 11;
r[13*i+ 3] |= t[2] << 2;
r[13*i+ 4] = t[2] >> 6;
r[13*i+ 4] |= t[3] << 7;
r[13*i+ 5] = t[3] >> 1;
r[13*i+ 6] = t[3] >> 9;
r[13*i+ 6] |= t[4] << 4;
r[13*i+ 7] = t[4] >> 4;
r[13*i+ 8] = t[4] >> 12;
r[13*i+ 8] |= t[5] << 1;
r[13*i+ 9] = t[5] >> 7;
r[13*i+ 9] |= t[6] << 6;
r[13*i+10] = t[6] >> 2;
r[13*i+11] = t[6] >> 10;
r[13*i+11] |= t[7] << 3;
r[13*i+12] = t[7] >> 5;
}
DBENCH_STOP(*tpack);
}
/*************************************************
* Name: polyt0_unpack
*
* Description: Unpack polynomial t0 with coefficients in ]-2^{D-1}, 2^{D-1}].
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t *a: byte array with bit-packed polynomial
**************************************************/
void polyt0_unpack(poly *r, const uint8_t *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/8; ++i) {
r->coeffs[8*i+0] = a[13*i+0];
r->coeffs[8*i+0] |= (uint32_t)a[13*i+1] << 8;
r->coeffs[8*i+0] &= 0x1FFF;
r->coeffs[8*i+1] = a[13*i+1] >> 5;
r->coeffs[8*i+1] |= (uint32_t)a[13*i+2] << 3;
r->coeffs[8*i+1] |= (uint32_t)a[13*i+3] << 11;
r->coeffs[8*i+1] &= 0x1FFF;
r->coeffs[8*i+2] = a[13*i+3] >> 2;
r->coeffs[8*i+2] |= (uint32_t)a[13*i+4] << 6;
r->coeffs[8*i+2] &= 0x1FFF;
r->coeffs[8*i+3] = a[13*i+4] >> 7;
r->coeffs[8*i+3] |= (uint32_t)a[13*i+5] << 1;
r->coeffs[8*i+3] |= (uint32_t)a[13*i+6] << 9;
r->coeffs[8*i+3] &= 0x1FFF;
r->coeffs[8*i+4] = a[13*i+6] >> 4;
r->coeffs[8*i+4] |= (uint32_t)a[13*i+7] << 4;
r->coeffs[8*i+4] |= (uint32_t)a[13*i+8] << 12;
r->coeffs[8*i+4] &= 0x1FFF;
r->coeffs[8*i+5] = a[13*i+8] >> 1;
r->coeffs[8*i+5] |= (uint32_t)a[13*i+9] << 7;
r->coeffs[8*i+5] &= 0x1FFF;
r->coeffs[8*i+6] = a[13*i+9] >> 6;
r->coeffs[8*i+6] |= (uint32_t)a[13*i+10] << 2;
r->coeffs[8*i+6] |= (uint32_t)a[13*i+11] << 10;
r->coeffs[8*i+6] &= 0x1FFF;
r->coeffs[8*i+7] = a[13*i+11] >> 3;
r->coeffs[8*i+7] |= (uint32_t)a[13*i+12] << 5;
r->coeffs[8*i+7] &= 0x1FFF;
r->coeffs[8*i+0] = (1 << (D-1)) - r->coeffs[8*i+0];
r->coeffs[8*i+1] = (1 << (D-1)) - r->coeffs[8*i+1];
r->coeffs[8*i+2] = (1 << (D-1)) - r->coeffs[8*i+2];
r->coeffs[8*i+3] = (1 << (D-1)) - r->coeffs[8*i+3];
r->coeffs[8*i+4] = (1 << (D-1)) - r->coeffs[8*i+4];
r->coeffs[8*i+5] = (1 << (D-1)) - r->coeffs[8*i+5];
r->coeffs[8*i+6] = (1 << (D-1)) - r->coeffs[8*i+6];
r->coeffs[8*i+7] = (1 << (D-1)) - r->coeffs[8*i+7];
}
DBENCH_STOP(*tpack);
}
/*************************************************
* Name: polyz_pack
*
* Description: Bit-pack polynomial with coefficients
* in [-(GAMMA1 - 1), GAMMA1].
*
* Arguments: - uint8_t *r: pointer to output byte array with at least
* POLYZ_PACKEDBYTES bytes
* - const poly *a: pointer to input polynomial
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define polyz_pack polyz_pack_17
-void polyz_pack(uint8_t *r, const poly *a) {
+void polyz_pack_17(uint8_t *r, const poly *a) {
unsigned int i;
uint32_t t[4];
DBENCH_START();
for(i = 0; i < N/4; ++i) {
t[0] = GAMMA1_17 - a->coeffs[4*i+0];
t[1] = GAMMA1_17 - a->coeffs[4*i+1];
t[2] = GAMMA1_17 - a->coeffs[4*i+2];
t[3] = GAMMA1_17 - a->coeffs[4*i+3];
r[9*i+0] = t[0];
r[9*i+1] = t[0] >> 8;
r[9*i+2] = t[0] >> 16;
r[9*i+2] |= t[1] << 2;
r[9*i+3] = t[1] >> 6;
r[9*i+4] = t[1] >> 14;
r[9*i+4] |= t[2] << 4;
r[9*i+5] = t[2] >> 4;
r[9*i+6] = t[2] >> 12;
r[9*i+6] |= t[3] << 6;
r[9*i+7] = t[3] >> 2;
r[9*i+8] = t[3] >> 10;
}
DBENCH_STOP(*tpack);
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define polyz_pack polyz_pack_19
-void polyz_pack(uint8_t *r, const poly *a) {
+void polyz_pack_19(uint8_t *r, const poly *a) {
unsigned int i;
uint32_t t[4];
DBENCH_START();
for(i = 0; i < N/2; ++i) {
t[0] = GAMMA1_19 - a->coeffs[2*i+0];
t[1] = GAMMA1_19 - a->coeffs[2*i+1];
r[5*i+0] = t[0];
r[5*i+1] = t[0] >> 8;
r[5*i+2] = t[0] >> 16;
r[5*i+2] |= t[1] << 4;
r[5*i+3] = t[1] >> 4;
r[5*i+4] = t[1] >> 12;
}
DBENCH_STOP(*tpack);
}
#endif
/*************************************************
* Name: polyz_unpack
*
* Description: Unpack polynomial z with coefficients
* in [-(GAMMA1 - 1), GAMMA1].
*
* Arguments: - poly *r: pointer to output polynomial
* - const uint8_t *a: byte array with bit-packed polynomial
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-void polyz_unpack(poly *r, const uint8_t *a) {
+void polyz_unpack_17(poly *r, const uint8_t *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/4; ++i) {
r->coeffs[4*i+0] = a[9*i+0];
r->coeffs[4*i+0] |= (uint32_t)a[9*i+1] << 8;
r->coeffs[4*i+0] |= (uint32_t)a[9*i+2] << 16;
r->coeffs[4*i+0] &= 0x3FFFF;
r->coeffs[4*i+1] = a[9*i+2] >> 2;
r->coeffs[4*i+1] |= (uint32_t)a[9*i+3] << 6;
r->coeffs[4*i+1] |= (uint32_t)a[9*i+4] << 14;
r->coeffs[4*i+1] &= 0x3FFFF;
r->coeffs[4*i+2] = a[9*i+4] >> 4;
r->coeffs[4*i+2] |= (uint32_t)a[9*i+5] << 4;
r->coeffs[4*i+2] |= (uint32_t)a[9*i+6] << 12;
r->coeffs[4*i+2] &= 0x3FFFF;
r->coeffs[4*i+3] = a[9*i+6] >> 6;
r->coeffs[4*i+3] |= (uint32_t)a[9*i+7] << 2;
r->coeffs[4*i+3] |= (uint32_t)a[9*i+8] << 10;
r->coeffs[4*i+3] &= 0x3FFFF;
r->coeffs[4*i+0] = GAMMA1_17 - r->coeffs[4*i+0];
r->coeffs[4*i+1] = GAMMA1_17 - r->coeffs[4*i+1];
r->coeffs[4*i+2] = GAMMA1_17 - r->coeffs[4*i+2];
r->coeffs[4*i+3] = GAMMA1_17 - r->coeffs[4*i+3];
}
DBENCH_STOP(*tpack);
}
#endif
-
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-void polyz_unpack(poly *r, const uint8_t *a) {
+void polyz_unpack_19(poly *r, const uint8_t *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/2; ++i) {
r->coeffs[2*i+0] = a[5*i+0];
r->coeffs[2*i+0] |= (uint32_t)a[5*i+1] << 8;
r->coeffs[2*i+0] |= (uint32_t)a[5*i+2] << 16;
r->coeffs[2*i+0] &= 0xFFFFF;
r->coeffs[2*i+1] = a[5*i+2] >> 4;
r->coeffs[2*i+1] |= (uint32_t)a[5*i+3] << 4;
r->coeffs[2*i+1] |= (uint32_t)a[5*i+4] << 12;
/* r->coeffs[2*i+1] &= 0xFFFFF; */ /* No effect, since we're anyway at 20 bits */
r->coeffs[2*i+0] = GAMMA1_19 - r->coeffs[2*i+0];
r->coeffs[2*i+1] = GAMMA1_19 - r->coeffs[2*i+1];
}
DBENCH_STOP(*tpack);
}
#endif
/*************************************************
* Name: polyw1_pack
*
* Description: Bit-pack polynomial w1 with coefficients in [0,15] or [0,43].
* Input coefficients are assumed to be standard representatives.
*
* Arguments: - uint8_t *r: pointer to output byte array with at least
* POLYW1_PACKEDBYTES bytes
* - const poly *a: pointer to input polynomial
**************************************************/
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define polyw1_pack polyw1_pack_88
-void polyw1_pack(uint8_t *r, const poly *a) {
+void polyw1_pack_88(uint8_t *r, const poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/4; ++i) {
r[3*i+0] = a->coeffs[4*i+0];
r[3*i+0] |= a->coeffs[4*i+1] << 6;
r[3*i+1] = a->coeffs[4*i+1] >> 2;
r[3*i+1] |= a->coeffs[4*i+2] << 4;
r[3*i+2] = a->coeffs[4*i+2] >> 4;
r[3*i+2] |= a->coeffs[4*i+3] << 2;
}
DBENCH_STOP(*tpack);
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define polyw1_pack polyw1_pack_32
-void polyw1_pack(uint8_t *r, const poly *a) {
+void polyw1_pack_32(uint8_t *r, const poly *a) {
unsigned int i;
DBENCH_START();
for(i = 0; i < N/2; ++i)
r[i] = a->coeffs[2*i+0] | (a->coeffs[2*i+1] << 4);
DBENCH_STOP(*tpack);
}
#endif
/*************** dilithium/ref/reduce.c */
/*************************************************
* Name: montgomery_reduce
*
* Description: For finite field element a with -2^{31}Q <= a <= Q*2^31,
* compute r \equiv a*2^{-32} (mod Q) such that -Q < r < Q.
*
* Arguments: - int64_t: finite field element a
*
* Returns r.
**************************************************/
int32_t montgomery_reduce(int64_t a) {
int32_t t;
t = (int64_t)(int32_t)a*QINV;
t = (a - (int64_t)t*Q) >> 32;
return t;
}
/*************************************************
* Name: reduce32
*
* Description: For finite field element a with a <= 2^{31} - 2^{22} - 1,
* compute r \equiv a (mod Q) such that -6283008 <= r <= 6283008.
*
* Arguments: - int32_t: finite field element a
*
* Returns r.
**************************************************/
int32_t reduce32(int32_t a) {
int32_t t;
t = (a + (1 << 22)) >> 23;
t = a - t*Q;
return t;
}
/*************************************************
* Name: caddq
*
* Description: Add Q if input coefficient is negative.
*
* Arguments: - int32_t: finite field element a
*
* Returns r.
**************************************************/
int32_t caddq(int32_t a) {
a += (a >> 31) & Q;
return a;
}
/*************************************************
* Name: freeze
*
* Description: For finite field element a, compute standard
* representative r = a mod^+ Q.
*
* Arguments: - int32_t: finite field element a
*
* Returns r.
**************************************************/
int32_t freeze(int32_t a) {
a = reduce32(a);
a = caddq(a);
return a;
}
diff --git a/cipher/dilithium-dep.c b/cipher/dilithium-dep.c
index 7ae01329..90320e7a 100644
--- a/cipher/dilithium-dep.c
+++ b/cipher/dilithium-dep.c
@@ -1,1170 +1,1244 @@
/* dilithium-dep.c - the Dilithium (DILITHIUM_MODE dependent part)
* Copyright (C) 2025 g10 Code GmbH
*
* This file was modified for use by Libgcrypt.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* You can also use this file under the same licence of original code.
* SPDX-License-Identifier: CC0 OR Apache-2.0
*
*/
/*
Original code from:
Repository: https://github.com/pq-crystals/dilithium.git
Branch: master
Commit: 444cdcc84eb36b66fe27b3a2529ee48f6d8150c2
Licence:
Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html).
Authors:
Léo Ducas
Eike Kiltz
Tancrède Lepoint
Vadim Lyubashevsky
Gregor Seiler
Peter Schwabe
Damien Stehlé
Dilithium Home: https://github.com/pq-crystals/dilithium.git
*/
/*************** dilithium/ref/polyvec.h */
/* Vectors of polynomials of length L */
typedef struct {
poly vec[L];
} polyvecl;
/* Vectors of polynomials of length K */
typedef struct {
poly vec[K];
} polyveck;
void polyvecl_pointwise_acc_montgomery(poly *w,
const polyvecl *u,
const polyvecl *v);
/*************** dilithium/ref/packing.c */
/*************************************************
* Name: pack_pk
*
* Description: Bit-pack public key pk = (rho, t1).
*
* Arguments: - uint8_t pk[]: output byte array
* - const uint8_t rho[]: byte array containing rho
* - const polyveck *t1: pointer to vector t1
**************************************************/
void pack_pk(uint8_t pk[CRYPTO_PUBLICKEYBYTES],
const uint8_t rho[SEEDBYTES],
const polyveck *t1)
{
unsigned int i;
for(i = 0; i < SEEDBYTES; ++i)
pk[i] = rho[i];
pk += SEEDBYTES;
for(i = 0; i < K; ++i)
polyt1_pack(pk + i*POLYT1_PACKEDBYTES, &t1->vec[i]);
}
/*************************************************
* Name: unpack_pk
*
* Description: Unpack public key pk = (rho, t1).
*
* Arguments: - const uint8_t rho[]: output byte array for rho
* - const polyveck *t1: pointer to output vector t1
* - uint8_t pk[]: byte array containing bit-packed pk
**************************************************/
void unpack_pk(uint8_t rho[SEEDBYTES],
polyveck *t1,
const uint8_t pk[CRYPTO_PUBLICKEYBYTES])
{
unsigned int i;
for(i = 0; i < SEEDBYTES; ++i)
rho[i] = pk[i];
pk += SEEDBYTES;
for(i = 0; i < K; ++i)
polyt1_unpack(&t1->vec[i], pk + i*POLYT1_PACKEDBYTES);
}
/*************************************************
* Name: pack_sk
*
* Description: Bit-pack secret key sk = (rho, tr, key, t0, s1, s2).
*
* Arguments: - uint8_t sk[]: output byte array
* - const uint8_t rho[]: byte array containing rho
* - const uint8_t tr[]: byte array containing tr
* - const uint8_t key[]: byte array containing key
* - const polyveck *t0: pointer to vector t0
* - const polyvecl *s1: pointer to vector s1
* - const polyveck *s2: pointer to vector s2
**************************************************/
void pack_sk(uint8_t sk[CRYPTO_SECRETKEYBYTES],
const uint8_t rho[SEEDBYTES],
const uint8_t tr[TRBYTES],
const uint8_t key[SEEDBYTES],
const polyveck *t0,
const polyvecl *s1,
const polyveck *s2)
{
unsigned int i;
for(i = 0; i < SEEDBYTES; ++i)
sk[i] = rho[i];
sk += SEEDBYTES;
for(i = 0; i < SEEDBYTES; ++i)
sk[i] = key[i];
sk += SEEDBYTES;
for(i = 0; i < TRBYTES; ++i)
sk[i] = tr[i];
sk += TRBYTES;
for(i = 0; i < L; ++i)
polyeta_pack(sk + i*POLYETA_PACKEDBYTES, &s1->vec[i]);
sk += L*POLYETA_PACKEDBYTES;
for(i = 0; i < K; ++i)
polyeta_pack(sk + i*POLYETA_PACKEDBYTES, &s2->vec[i]);
sk += K*POLYETA_PACKEDBYTES;
for(i = 0; i < K; ++i)
polyt0_pack(sk + i*POLYT0_PACKEDBYTES, &t0->vec[i]);
}
/*************************************************
* Name: unpack_sk
*
* Description: Unpack secret key sk = (rho, tr, key, t0, s1, s2).
*
* Arguments: - const uint8_t rho[]: output byte array for rho
* - const uint8_t tr[]: output byte array for tr
* - const uint8_t key[]: output byte array for key
* - const polyveck *t0: pointer to output vector t0
* - const polyvecl *s1: pointer to output vector s1
* - const polyveck *s2: pointer to output vector s2
* - uint8_t sk[]: byte array containing bit-packed sk
**************************************************/
void unpack_sk(uint8_t rho[SEEDBYTES],
uint8_t tr[TRBYTES],
uint8_t key[SEEDBYTES],
polyveck *t0,
polyvecl *s1,
polyveck *s2,
const uint8_t sk[CRYPTO_SECRETKEYBYTES])
{
unsigned int i;
for(i = 0; i < SEEDBYTES; ++i)
rho[i] = sk[i];
sk += SEEDBYTES;
for(i = 0; i < SEEDBYTES; ++i)
key[i] = sk[i];
sk += SEEDBYTES;
for(i = 0; i < TRBYTES; ++i)
tr[i] = sk[i];
sk += TRBYTES;
for(i=0; i < L; ++i)
polyeta_unpack(&s1->vec[i], sk + i*POLYETA_PACKEDBYTES);
sk += L*POLYETA_PACKEDBYTES;
for(i=0; i < K; ++i)
polyeta_unpack(&s2->vec[i], sk + i*POLYETA_PACKEDBYTES);
sk += K*POLYETA_PACKEDBYTES;
for(i=0; i < K; ++i)
polyt0_unpack(&t0->vec[i], sk + i*POLYT0_PACKEDBYTES);
}
/*************************************************
* Name: pack_sig
*
* Description: Bit-pack signature sig = (c, z, h).
*
* Arguments: - uint8_t sig[]: output byte array
* - const uint8_t *c: pointer to challenge hash length SEEDBYTES
* - const polyvecl *z: pointer to vector z
* - const polyveck *h: pointer to hint vector h
**************************************************/
void pack_sig(uint8_t sig[CRYPTO_BYTES],
const uint8_t c[CTILDEBYTES],
const polyvecl *z,
const polyveck *h)
{
unsigned int i, j, k;
for(i=0; i < CTILDEBYTES; ++i)
sig[i] = c[i];
sig += CTILDEBYTES;
for(i = 0; i < L; ++i)
polyz_pack(sig + i*POLYZ_PACKEDBYTES, &z->vec[i]);
sig += L*POLYZ_PACKEDBYTES;
/* Encode h */
for(i = 0; i < OMEGA + K; ++i)
sig[i] = 0;
k = 0;
for(i = 0; i < K; ++i) {
for(j = 0; j < N; ++j)
if(h->vec[i].coeffs[j] != 0)
sig[k++] = j;
sig[OMEGA + i] = k;
}
}
/*************************************************
* Name: unpack_sig
*
* Description: Unpack signature sig = (c, z, h).
*
* Arguments: - uint8_t *c: pointer to output challenge hash
* - polyvecl *z: pointer to output vector z
* - polyveck *h: pointer to output hint vector h
* - const uint8_t sig[]: byte array containing
* bit-packed signature
*
* Returns 1 in case of malformed signature; otherwise 0.
**************************************************/
int unpack_sig(uint8_t c[CTILDEBYTES],
polyvecl *z,
polyveck *h,
const uint8_t sig[CRYPTO_BYTES])
{
unsigned int i, j, k;
for(i = 0; i < CTILDEBYTES; ++i)
c[i] = sig[i];
sig += CTILDEBYTES;
for(i = 0; i < L; ++i)
polyz_unpack(&z->vec[i], sig + i*POLYZ_PACKEDBYTES);
sig += L*POLYZ_PACKEDBYTES;
/* Decode h */
k = 0;
for(i = 0; i < K; ++i) {
for(j = 0; j < N; ++j)
h->vec[i].coeffs[j] = 0;
if(sig[OMEGA + i] < k || sig[OMEGA + i] > OMEGA)
return 1;
for(j = k; j < sig[OMEGA + i]; ++j) {
/* Coefficients are ordered for strong unforgeability */
if(j > k && sig[j] <= sig[j-1]) return 1;
h->vec[i].coeffs[sig[j]] = 1;
}
k = sig[OMEGA + i];
}
/* Extra indices are zero for strong unforgeability */
for(j = k; j < OMEGA; ++j)
if(sig[j])
return 1;
return 0;
}
/*************** dilithium/ref/poly.c */
/*************************************************
* Name: challenge
*
* Description: Implementation of H. Samples polynomial with TAU nonzero
* coefficients in {-1,1} using the output stream of
* SHAKE256(seed).
*
* Arguments: - poly *c: pointer to output polynomial
* - const uint8_t mu[]: byte array containing seed of length CTILDEBYTES
**************************************************/
void poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]) {
unsigned int i, b, pos;
uint64_t signs;
uint8_t buf[SHAKE256_RATE];
keccak_state state;
shake256_init(&state);
shake256_absorb(&state, seed, CTILDEBYTES);
shake256_finalize(&state);
shake256_squeezeblocks(buf, 1, &state);
signs = 0;
for(i = 0; i < 8; ++i)
signs |= (uint64_t)buf[i] << 8*i;
pos = 8;
for(i = 0; i < N; ++i)
c->coeffs[i] = 0;
for(i = N-TAU; i < N; ++i) {
do {
if(pos >= SHAKE256_RATE) {
shake256_squeezeblocks(buf, 1, &state);
pos = 0;
}
b = buf[pos++];
} while(b > i);
c->coeffs[i] = c->coeffs[b];
c->coeffs[b] = 1 - 2*(signs & 1);
signs >>= 1;
}
shake256_close(&state);
}
/*************** dilithium/ref/polyvec.c */
/*************************************************
* Name: expand_mat
*
* Description: Implementation of ExpandA. Generates matrix A with uniformly
* random coefficients a_{i,j} by performing rejection
* sampling on the output stream of SHAKE128(rho|j|i)
*
* Arguments: - polyvecl mat[K]: output matrix
* - const uint8_t rho[]: byte array containing seed rho
**************************************************/
void polyvec_matrix_expand(polyvecl mat[K], const uint8_t rho[SEEDBYTES]) {
unsigned int i, j;
for(i = 0; i < K; ++i)
for(j = 0; j < L; ++j)
poly_uniform(&mat[i].vec[j], rho, (i << 8) + j);
}
void polyvec_matrix_pointwise_montgomery(polyveck *t, const polyvecl mat[K], const polyvecl *v) {
unsigned int i;
for(i = 0; i < K; ++i)
polyvecl_pointwise_acc_montgomery(&t->vec[i], &mat[i], v);
}
/**************************************************************/
/************ Vectors of polynomials of length L **************/
/**************************************************************/
void polyvecl_uniform_eta(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
unsigned int i;
for(i = 0; i < L; ++i)
poly_uniform_eta(&v->vec[i], seed, nonce++);
}
void polyvecl_uniform_gamma1(polyvecl *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
unsigned int i;
for(i = 0; i < L; ++i)
poly_uniform_gamma1(&v->vec[i], seed, L*nonce + i);
}
void polyvecl_reduce(polyvecl *v) {
unsigned int i;
for(i = 0; i < L; ++i)
poly_reduce(&v->vec[i]);
}
/*************************************************
* Name: polyvecl_add
*
* Description: Add vectors of polynomials of length L.
* No modular reduction is performed.
*
* Arguments: - polyvecl *w: pointer to output vector
* - const polyvecl *u: pointer to first summand
* - const polyvecl *v: pointer to second summand
**************************************************/
void polyvecl_add(polyvecl *w, const polyvecl *u, const polyvecl *v) {
unsigned int i;
for(i = 0; i < L; ++i)
poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
}
/*************************************************
* Name: polyvecl_ntt
*
* Description: Forward NTT of all polynomials in vector of length L. Output
* coefficients can be up to 16*Q larger than input coefficients.
*
* Arguments: - polyvecl *v: pointer to input/output vector
**************************************************/
void polyvecl_ntt(polyvecl *v) {
unsigned int i;
for(i = 0; i < L; ++i)
poly_ntt(&v->vec[i]);
}
void polyvecl_invntt_tomont(polyvecl *v) {
unsigned int i;
for(i = 0; i < L; ++i)
poly_invntt_tomont(&v->vec[i]);
}
void polyvecl_pointwise_poly_montgomery(polyvecl *r, const poly *a, const polyvecl *v) {
unsigned int i;
for(i = 0; i < L; ++i)
poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
}
/*************************************************
* Name: polyvecl_pointwise_acc_montgomery
*
* Description: Pointwise multiply vectors of polynomials of length L, multiply
* resulting vector by 2^{-32} and add (accumulate) polynomials
* in it. Input/output vectors are in NTT domain representation.
*
* Arguments: - poly *w: output polynomial
* - const polyvecl *u: pointer to first input vector
* - const polyvecl *v: pointer to second input vector
**************************************************/
void polyvecl_pointwise_acc_montgomery(poly *w,
const polyvecl *u,
const polyvecl *v)
{
unsigned int i;
poly t;
poly_pointwise_montgomery(w, &u->vec[0], &v->vec[0]);
for(i = 1; i < L; ++i) {
poly_pointwise_montgomery(&t, &u->vec[i], &v->vec[i]);
poly_add(w, w, &t);
}
}
/*************************************************
* Name: polyvecl_chknorm
*
* Description: Check infinity norm of polynomials in vector of length L.
* Assumes input polyvecl to be reduced by polyvecl_reduce().
*
* Arguments: - const polyvecl *v: pointer to vector
* - int32_t B: norm bound
*
* Returns 0 if norm of all polynomials is strictly smaller than B <= (Q-1)/8
* and 1 otherwise.
**************************************************/
int polyvecl_chknorm(const polyvecl *v, int32_t bound) {
unsigned int i;
for(i = 0; i < L; ++i)
if(poly_chknorm(&v->vec[i], bound))
return 1;
return 0;
}
/**************************************************************/
/************ Vectors of polynomials of length K **************/
/**************************************************************/
void polyveck_uniform_eta(polyveck *v, const uint8_t seed[CRHBYTES], uint16_t nonce) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_uniform_eta(&v->vec[i], seed, nonce++);
}
/*************************************************
* Name: polyveck_reduce
*
* Description: Reduce coefficients of polynomials in vector of length K
* to representatives in [-6283008,6283008].
*
* Arguments: - polyveck *v: pointer to input/output vector
**************************************************/
void polyveck_reduce(polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_reduce(&v->vec[i]);
}
/*************************************************
* Name: polyveck_caddq
*
* Description: For all coefficients of polynomials in vector of length K
* add Q if coefficient is negative.
*
* Arguments: - polyveck *v: pointer to input/output vector
**************************************************/
void polyveck_caddq(polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_caddq(&v->vec[i]);
}
/*************************************************
* Name: polyveck_add
*
* Description: Add vectors of polynomials of length K.
* No modular reduction is performed.
*
* Arguments: - polyveck *w: pointer to output vector
* - const polyveck *u: pointer to first summand
* - const polyveck *v: pointer to second summand
**************************************************/
void polyveck_add(polyveck *w, const polyveck *u, const polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_add(&w->vec[i], &u->vec[i], &v->vec[i]);
}
/*************************************************
* Name: polyveck_sub
*
* Description: Subtract vectors of polynomials of length K.
* No modular reduction is performed.
*
* Arguments: - polyveck *w: pointer to output vector
* - const polyveck *u: pointer to first input vector
* - const polyveck *v: pointer to second input vector to be
* subtracted from first input vector
**************************************************/
void polyveck_sub(polyveck *w, const polyveck *u, const polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_sub(&w->vec[i], &u->vec[i], &v->vec[i]);
}
/*************************************************
* Name: polyveck_shiftl
*
* Description: Multiply vector of polynomials of Length K by 2^D without modular
* reduction. Assumes input coefficients to be less than 2^{31-D}.
*
* Arguments: - polyveck *v: pointer to input/output vector
**************************************************/
void polyveck_shiftl(polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_shiftl(&v->vec[i]);
}
/*************************************************
* Name: polyveck_ntt
*
* Description: Forward NTT of all polynomials in vector of length K. Output
* coefficients can be up to 16*Q larger than input coefficients.
*
* Arguments: - polyveck *v: pointer to input/output vector
**************************************************/
void polyveck_ntt(polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_ntt(&v->vec[i]);
}
/*************************************************
* Name: polyveck_invntt_tomont
*
* Description: Inverse NTT and multiplication by 2^{32} of polynomials
* in vector of length K. Input coefficients need to be less
* than 2*Q.
*
* Arguments: - polyveck *v: pointer to input/output vector
**************************************************/
void polyveck_invntt_tomont(polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_invntt_tomont(&v->vec[i]);
}
void polyveck_pointwise_poly_montgomery(polyveck *r, const poly *a, const polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_pointwise_montgomery(&r->vec[i], a, &v->vec[i]);
}
/*************************************************
* Name: polyveck_chknorm
*
* Description: Check infinity norm of polynomials in vector of length K.
* Assumes input polyveck to be reduced by polyveck_reduce().
*
* Arguments: - const polyveck *v: pointer to vector
* - int32_t B: norm bound
*
* Returns 0 if norm of all polynomials are strictly smaller than B <= (Q-1)/8
* and 1 otherwise.
**************************************************/
int polyveck_chknorm(const polyveck *v, int32_t bound) {
unsigned int i;
for(i = 0; i < K; ++i)
if(poly_chknorm(&v->vec[i], bound))
return 1;
return 0;
}
/*************************************************
* Name: polyveck_power2round
*
* Description: For all coefficients a of polynomials in vector of length K,
* compute a0, a1 such that a mod^+ Q = a1*2^D + a0
* with -2^{D-1} < a0 <= 2^{D-1}. Assumes coefficients to be
* standard representatives.
*
* Arguments: - polyveck *v1: pointer to output vector of polynomials with
* coefficients a1
* - polyveck *v0: pointer to output vector of polynomials with
* coefficients a0
* - const polyveck *v: pointer to input vector
**************************************************/
void polyveck_power2round(polyveck *v1, polyveck *v0, const polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_power2round(&v1->vec[i], &v0->vec[i], &v->vec[i]);
}
/*************************************************
* Name: polyveck_decompose
*
* Description: For all coefficients a of polynomials in vector of length K,
* compute high and low bits a0, a1 such a mod^+ Q = a1*ALPHA + a0
* with -ALPHA/2 < a0 <= ALPHA/2 except a1 = (Q-1)/ALPHA where we
* set a1 = 0 and -ALPHA/2 <= a0 = a mod Q - Q < 0.
* Assumes coefficients to be standard representatives.
*
* Arguments: - polyveck *v1: pointer to output vector of polynomials with
* coefficients a1
* - polyveck *v0: pointer to output vector of polynomials with
* coefficients a0
* - const polyveck *v: pointer to input vector
**************************************************/
void polyveck_decompose(polyveck *v1, polyveck *v0, const polyveck *v) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_decompose(&v1->vec[i], &v0->vec[i], &v->vec[i]);
}
/*************************************************
* Name: polyveck_make_hint
*
* Description: Compute hint vector.
*
* Arguments: - polyveck *h: pointer to output vector
* - const polyveck *v0: pointer to low part of input vector
* - const polyveck *v1: pointer to high part of input vector
*
* Returns number of 1 bits.
**************************************************/
unsigned int polyveck_make_hint(polyveck *h,
const polyveck *v0,
const polyveck *v1)
{
unsigned int i, s = 0;
for(i = 0; i < K; ++i)
s += poly_make_hint(&h->vec[i], &v0->vec[i], &v1->vec[i]);
return s;
}
/*************************************************
* Name: polyveck_use_hint
*
* Description: Use hint vector to correct the high bits of input vector.
*
* Arguments: - polyveck *w: pointer to output vector of polynomials with
* corrected high bits
* - const polyveck *u: pointer to input vector
* - const polyveck *h: pointer to input hint vector
**************************************************/
void polyveck_use_hint(polyveck *w, const polyveck *u, const polyveck *h) {
unsigned int i;
for(i = 0; i < K; ++i)
poly_use_hint(&w->vec[i], &u->vec[i], &h->vec[i]);
}
void polyveck_pack_w1(uint8_t r[K*POLYW1_PACKEDBYTES], const polyveck *w1) {
unsigned int i;
for(i = 0; i < K; ++i)
polyw1_pack(&r[i*POLYW1_PACKEDBYTES], &w1->vec[i]);
}
/*************** dilithium/ref/sign.c */
/*************************************************
* Name: crypto_sign_keypair
*
* Description: Generates public and private key.
*
* Arguments: - uint8_t *pk: pointer to output public key (allocated
* array of CRYPTO_PUBLICKEYBYTES bytes)
* - uint8_t *sk: pointer to output private key (allocated
* array of CRYPTO_SECRETKEYBYTES bytes)
*
* Returns 0 (success)
**************************************************/
int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) {
uint8_t seedbuf[2*SEEDBYTES + CRHBYTES];
uint8_t tr[TRBYTES];
const uint8_t *rho, *rhoprime, *key;
polyvecl mat[K];
polyvecl s1, s1hat;
polyveck s2, t1, t0;
/* Get randomness for rho, rhoprime and key */
randombytes(seedbuf, SEEDBYTES);
seedbuf[SEEDBYTES+0] = K;
seedbuf[SEEDBYTES+1] = L;
shake256(seedbuf, 2*SEEDBYTES + CRHBYTES, seedbuf, SEEDBYTES+2);
rho = seedbuf;
rhoprime = rho + SEEDBYTES;
key = rhoprime + CRHBYTES;
/* Expand matrix */
polyvec_matrix_expand(mat, rho);
/* Sample short vectors s1 and s2 */
polyvecl_uniform_eta(&s1, rhoprime, 0);
polyveck_uniform_eta(&s2, rhoprime, L);
/* Matrix-vector multiplication */
s1hat = s1;
polyvecl_ntt(&s1hat);
polyvec_matrix_pointwise_montgomery(&t1, mat, &s1hat);
polyveck_reduce(&t1);
polyveck_invntt_tomont(&t1);
/* Add error vector s2 */
polyveck_add(&t1, &t1, &s2);
/* Extract t1 and write public key */
polyveck_caddq(&t1);
polyveck_power2round(&t1, &t0, &t1);
pack_pk(pk, rho, &t1);
/* Compute H(rho, t1) and write secret key */
shake256(tr, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES);
pack_sk(sk, rho, tr, key, &t0, &s1, &s2);
return 0;
}
/*************************************************
* Name: crypto_sign_signature_internal
*
* Description: Computes signature. Internal API.
*
* Arguments: - uint8_t *sig: pointer to output signature (of length CRYPTO_BYTES)
* - size_t *siglen: pointer to output length of signature
* - uint8_t *m: pointer to message to be signed
* - size_t mlen: length of message
* - uint8_t *pre: pointer to prefix string
* - size_t prelen: length of prefix string
* - uint8_t *rnd: pointer to random seed
* - uint8_t *sk: pointer to bit-packed secret key
*
* Returns 0 (success)
**************************************************/
int crypto_sign_signature_internal(uint8_t *sig,
size_t *siglen,
const uint8_t *m,
size_t mlen,
const uint8_t *pre,
size_t prelen,
const uint8_t rnd[RNDBYTES],
const uint8_t *sk)
{
unsigned int n;
uint8_t seedbuf[2*SEEDBYTES + TRBYTES + 2*CRHBYTES];
uint8_t *rho, *tr, *key, *mu, *rhoprime;
uint16_t nonce = 0;
polyvecl mat[K], s1, y, z;
polyveck t0, s2, w1, w0, h;
poly cp;
keccak_state state;
rho = seedbuf;
tr = rho + SEEDBYTES;
key = tr + TRBYTES;
mu = key + SEEDBYTES;
rhoprime = mu + CRHBYTES;
unpack_sk(rho, tr, key, &t0, &s1, &s2, sk);
/* Compute mu = CRH(tr, pre, msg) */
shake256_init(&state);
shake256_absorb(&state, tr, TRBYTES);
shake256_absorb(&state, pre, prelen);
shake256_absorb(&state, m, mlen);
shake256_finalize(&state);
shake256_squeeze(mu, CRHBYTES, &state);
shake256_close(&state);
/* Compute rhoprime = CRH(key, rnd, mu) */
shake256_init(&state);
shake256_absorb(&state, key, SEEDBYTES);
shake256_absorb(&state, rnd, RNDBYTES);
shake256_absorb(&state, mu, CRHBYTES);
shake256_finalize(&state);
shake256_squeeze(rhoprime, CRHBYTES, &state);
shake256_close(&state);
/* Expand matrix and transform vectors */
polyvec_matrix_expand(mat, rho);
polyvecl_ntt(&s1);
polyveck_ntt(&s2);
polyveck_ntt(&t0);
rej:
/* Sample intermediate vector y */
polyvecl_uniform_gamma1(&y, rhoprime, nonce++);
/* Matrix-vector multiplication */
z = y;
polyvecl_ntt(&z);
polyvec_matrix_pointwise_montgomery(&w1, mat, &z);
polyveck_reduce(&w1);
polyveck_invntt_tomont(&w1);
/* Decompose w and call the random oracle */
polyveck_caddq(&w1);
polyveck_decompose(&w1, &w0, &w1);
polyveck_pack_w1(sig, &w1);
shake256_init(&state);
shake256_absorb(&state, mu, CRHBYTES);
shake256_absorb(&state, sig, K*POLYW1_PACKEDBYTES);
shake256_finalize(&state);
shake256_squeeze(sig, CTILDEBYTES, &state);
shake256_close(&state);
poly_challenge(&cp, sig);
poly_ntt(&cp);
/* Compute z, reject if it reveals secret */
polyvecl_pointwise_poly_montgomery(&z, &cp, &s1);
polyvecl_invntt_tomont(&z);
polyvecl_add(&z, &z, &y);
polyvecl_reduce(&z);
if(polyvecl_chknorm(&z, GAMMA1 - BETA))
goto rej;
/* Check that subtracting cs2 does not change high bits of w and low bits
* do not reveal secret information */
polyveck_pointwise_poly_montgomery(&h, &cp, &s2);
polyveck_invntt_tomont(&h);
polyveck_sub(&w0, &w0, &h);
polyveck_reduce(&w0);
if(polyveck_chknorm(&w0, GAMMA2 - BETA))
goto rej;
/* Compute hints for w1 */
polyveck_pointwise_poly_montgomery(&h, &cp, &t0);
polyveck_invntt_tomont(&h);
polyveck_reduce(&h);
if(polyveck_chknorm(&h, GAMMA2))
goto rej;
polyveck_add(&w0, &w0, &h);
n = polyveck_make_hint(&h, &w0, &w1);
if(n > OMEGA)
goto rej;
/* Write signature */
pack_sig(sig, sig, &z, &h);
*siglen = CRYPTO_BYTES;
return 0;
}
/*************************************************
* Name: crypto_sign_signature
*
* Description: Computes signature.
*
* Arguments: - uint8_t *sig: pointer to output signature (of length CRYPTO_BYTES)
* - size_t *siglen: pointer to output length of signature
* - uint8_t *m: pointer to message to be signed
* - size_t mlen: length of message
* - uint8_t *ctx: pointer to contex string
* - size_t ctxlen: length of contex string
* - uint8_t *sk: pointer to bit-packed secret key
*
* Returns 0 (success) or -1 (context string too long)
**************************************************/
int crypto_sign_signature(uint8_t *sig,
size_t *siglen,
const uint8_t *m,
size_t mlen,
const uint8_t *ctx,
size_t ctxlen,
const uint8_t *sk)
{
size_t i;
uint8_t pre[257];
uint8_t rnd[RNDBYTES];
if(ctxlen > 255)
return -1;
/* Prepare pre = (0, ctxlen, ctx) */
pre[0] = 0;
pre[1] = ctxlen;
for(i = 0; i < ctxlen; i++)
pre[2 + i] = ctx[i];
#ifdef DILITHIUM_RANDOMIZED_SIGNING
randombytes(rnd, RNDBYTES);
#else
for(i=0;i<RNDBYTES;i++)
rnd[i] = 0;
#endif
crypto_sign_signature_internal(sig,siglen,m,mlen,pre,2+ctxlen,rnd,sk);
return 0;
}
/*************************************************
* Name: crypto_sign
*
* Description: Compute signed message.
*
* Arguments: - uint8_t *sm: pointer to output signed message (allocated
* array with CRYPTO_BYTES + mlen bytes),
* can be equal to m
* - size_t *smlen: pointer to output length of signed
* message
* - const uint8_t *m: pointer to message to be signed
* - size_t mlen: length of message
* - const uint8_t *ctx: pointer to context string
* - size_t ctxlen: length of context string
* - const uint8_t *sk: pointer to bit-packed secret key
*
* Returns 0 (success) or -1 (context string too long)
**************************************************/
int crypto_sign(uint8_t *sm,
size_t *smlen,
const uint8_t *m,
size_t mlen,
const uint8_t *ctx,
size_t ctxlen,
const uint8_t *sk)
{
int ret;
size_t i;
for(i = 0; i < mlen; ++i)
sm[CRYPTO_BYTES + mlen - 1 - i] = m[mlen - 1 - i];
ret = crypto_sign_signature(sm, smlen, sm + CRYPTO_BYTES, mlen, ctx, ctxlen, sk);
*smlen += mlen;
return ret;
}
/*************************************************
* Name: crypto_sign_verify_internal
*
* Description: Verifies signature. Internal API.
*
* Arguments: - uint8_t *m: pointer to input signature
* - size_t siglen: length of signature
* - const uint8_t *m: pointer to message
* - size_t mlen: length of message
* - const uint8_t *pre: pointer to prefix string
* - size_t prelen: length of prefix string
* - const uint8_t *pk: pointer to bit-packed public key
*
* Returns 0 if signature could be verified correctly and -1 otherwise
**************************************************/
int crypto_sign_verify_internal(const uint8_t *sig,
size_t siglen,
const uint8_t *m,
size_t mlen,
const uint8_t *pre,
size_t prelen,
const uint8_t *pk)
{
unsigned int i;
uint8_t buf[K*POLYW1_PACKEDBYTES];
uint8_t rho[SEEDBYTES];
uint8_t mu[CRHBYTES];
uint8_t c[CTILDEBYTES];
uint8_t c2[CTILDEBYTES];
poly cp;
polyvecl mat[K], z;
polyveck t1, w1, h;
keccak_state state;
if(siglen != CRYPTO_BYTES)
return -1;
unpack_pk(rho, &t1, pk);
if(unpack_sig(c, &z, &h, sig))
return -1;
if(polyvecl_chknorm(&z, GAMMA1 - BETA))
return -1;
/* Compute CRH(H(rho, t1), pre, msg) */
shake256(mu, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES);
shake256_init(&state);
shake256_absorb(&state, mu, TRBYTES);
shake256_absorb(&state, pre, prelen);
shake256_absorb(&state, m, mlen);
shake256_finalize(&state);
shake256_squeeze(mu, CRHBYTES, &state);
shake256_close(&state);
/* Matrix-vector multiplication; compute Az - c2^dt1 */
poly_challenge(&cp, c);
polyvec_matrix_expand(mat, rho);
polyvecl_ntt(&z);
polyvec_matrix_pointwise_montgomery(&w1, mat, &z);
poly_ntt(&cp);
polyveck_shiftl(&t1);
polyveck_ntt(&t1);
polyveck_pointwise_poly_montgomery(&t1, &cp, &t1);
polyveck_sub(&w1, &w1, &t1);
polyveck_reduce(&w1);
polyveck_invntt_tomont(&w1);
/* Reconstruct w1 */
polyveck_caddq(&w1);
polyveck_use_hint(&w1, &w1, &h);
polyveck_pack_w1(buf, &w1);
/* Call random oracle and verify challenge */
shake256_init(&state);
shake256_absorb(&state, mu, CRHBYTES);
shake256_absorb(&state, buf, K*POLYW1_PACKEDBYTES);
shake256_finalize(&state);
shake256_squeeze(c2, CTILDEBYTES, &state);
shake256_close(&state);
for(i = 0; i < CTILDEBYTES; ++i)
if(c[i] != c2[i])
return -1;
return 0;
}
/*************************************************
* Name: crypto_sign_verify
*
* Description: Verifies signature.
*
* Arguments: - uint8_t *m: pointer to input signature
* - size_t siglen: length of signature
* - const uint8_t *m: pointer to message
* - size_t mlen: length of message
* - const uint8_t *ctx: pointer to context string
* - size_t ctxlen: length of context string
* - const uint8_t *pk: pointer to bit-packed public key
*
* Returns 0 if signature could be verified correctly and -1 otherwise
**************************************************/
int crypto_sign_verify(const uint8_t *sig,
size_t siglen,
const uint8_t *m,
size_t mlen,
const uint8_t *ctx,
size_t ctxlen,
const uint8_t *pk)
{
size_t i;
uint8_t pre[257];
if(ctxlen > 255)
return -1;
pre[0] = 0;
pre[1] = ctxlen;
for(i = 0; i < ctxlen; i++)
pre[2 + i] = ctx[i];
return crypto_sign_verify_internal(sig,siglen,m,mlen,pre,2+ctxlen,pk);
}
/*************************************************
* Name: crypto_sign_open
*
* Description: Verify signed message.
*
* Arguments: - uint8_t *m: pointer to output message (allocated
* array with smlen bytes), can be equal to sm
* - size_t *mlen: pointer to output length of message
* - const uint8_t *sm: pointer to signed message
* - size_t smlen: length of signed message
* - const uint8_t *ctx: pointer to context tring
* - size_t ctxlen: length of context string
* - const uint8_t *pk: pointer to bit-packed public key
*
* Returns 0 if signed message could be verified correctly and -1 otherwise
**************************************************/
int crypto_sign_open(uint8_t *m,
size_t *mlen,
const uint8_t *sm,
size_t smlen,
const uint8_t *ctx,
size_t ctxlen,
const uint8_t *pk)
{
size_t i;
if(smlen < CRYPTO_BYTES)
goto badsig;
*mlen = smlen - CRYPTO_BYTES;
if(crypto_sign_verify(sm, CRYPTO_BYTES, sm + CRYPTO_BYTES, *mlen, ctx, ctxlen, pk))
goto badsig;
else {
/* All good, copy msg, return 0 */
for(i = 0; i < *mlen; ++i)
m[i] = sm[CRYPTO_BYTES + i];
return 0;
}
badsig:
/* Signature verification failed */
*mlen = 0;
for(i = 0; i < smlen; ++i)
m[i] = 0;
return -1;
}
+
+#undef DILITHIUM_MODE
+
+#undef CRYPTO_PUBLICKEYBYTES
+#undef CRYPTO_SECRETKEYBYTES
+#undef CRYPTO_BYTES
+#undef POLYZ_PACKEDBYTES
+#undef POLYW1_PACKEDBYTES
+#undef POLYETA_PACKEDBYTES
+
+#undef CRYPTO_ALGNAME
+#undef K
+#undef L
+#undef ETA
+#undef TAU
+#undef BETA
+#undef GAMMA1
+#undef GAMMA2
+#undef OMEGA
+#undef CTILDEBYTES
+
+#undef poly_decompose
+#undef poly_make_hint
+#undef poly_use_hint
+#undef poly_uniform_eta
+#undef poly_uniform_gamma1
+#undef polyz_pack
+#undef polyz_unpack
+#undef polyeta_pack
+#undef polyeta_unpack
+#undef polyw1_pack
+
+#undef polyvecl
+#undef polyveck
+#undef pack_pk
+#undef unpack_pk
+#undef pack_sk
+#undef unpack_sk
+#undef pack_sig
+#undef unpack_sig
+#undef poly_challenge
+#undef polyvec_matrix_expand
+#undef polyvec_matrix_pointwise_montgomery
+#undef polyveck_power2round
+#undef polyveck_make_hint
+#undef polyveck_use_hint
+#undef polyvecl_uniform_eta
+#undef polyvecl_uniform_gamma1
+#undef polyvecl_reduce
+#undef polyvecl_add
+#undef polyvecl_ntt
+#undef polyvecl_invntt_tomont
+#undef polyvecl_pointwise_poly_montgomery
+#undef polyvecl_pointwise_acc_montgomery
+#undef polyvecl_chknorm
+#undef polyveck_uniform_eta
+#undef polyveck_reduce
+#undef polyveck_caddq
+#undef polyveck_add
+#undef polyveck_sub
+#undef polyveck_shiftl
+#undef polyveck_ntt
+#undef polyveck_invntt_tomont
+#undef polyveck_pointwise_poly_montgomery
+#undef polyveck_chknorm
+#undef polyveck_pack_w1
+#undef polyveck_decompose
+#undef crypto_sign_keypair
+#undef crypto_sign_signature_internal
+#undef crypto_sign_signature
+#undef crypto_sign
+#undef crypto_sign_verify_internal
+#undef crypto_sign_verify
+#undef crypto_sign_open
diff --git a/cipher/dilithium.c b/cipher/dilithium.c
index d1b11c05..a85056e2 100644
--- a/cipher/dilithium.c
+++ b/cipher/dilithium.c
@@ -1,349 +1,610 @@
/* dilithium.c - the Dilithium (main part)
* Copyright (C) 2025 g10 Code GmbH
*
* This file was modified for use by Libgcrypt.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* You can also use this file under the same licence of original code.
* SPDX-License-Identifier: CC0 OR Apache-2.0
*
*/
/*
Original code from:
Repository: https://github.com/pq-crystals/dilithium.git
Branch: master
Commit: 444cdcc84eb36b66fe27b3a2529ee48f6d8150c2
Licence:
Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html).
Authors:
Léo Ducas
Eike Kiltz
Tancrède Lepoint
Vadim Lyubashevsky
Gregor Seiler
Peter Schwabe
Damien Stehlé
Dilithium Home: https://github.com/pq-crystals/dilithium.git
*/
/*
* This implementation consists of four files: dilithium.h (header),
* dilithium.c (this), dilithium-common.c (common part), and
* dilithium-dep.c (DILITHIUM_MODE dependent part).
*
* It is for inclusion in libgcrypt library. Also, standalone use of
* the implementation is possible. With DILITHIUM_MODE defined, it
* can offer the variant of that DILITHIUM_MODE specified. Otherwise,
* three variants are offered.
*
* From original code, following modification was made.
*
* - C++ style comments are changed to C-style.
*
* - No use of DILITHIUM_NAMESPACE and FIPS202_NAMESPACE. Don't export
* internal symbols.
*
* - Different external API for shake128 and shake256, having _init
* and _close.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#ifdef _GCRYPT_IN_LIBGCRYPT
#include <stdarg.h>
#include <gpg-error.h>
#include "types.h"
#include "g10lib.h"
#include "gcrypt-int.h"
#include "const-time.h"
-#define DILITHIUM_MODE 2
#include "dilithium.h"
static void
randombytes (uint8_t *out, size_t outlen)
{
_gcry_randomize (out, outlen, GCRY_VERY_STRONG_RANDOM);
}
typedef struct {
gcry_md_hd_t h;
} keccak_state;
static void
shake128_init (keccak_state *state)
{
gcry_err_code_t ec;
ec = _gcry_md_open (&state->h, GCRY_MD_SHAKE128, 0);
if (ec)
log_fatal ("internal md_open failed: %d\n", ec);
}
static void
shake128_absorb (keccak_state *state, const uint8_t *in, size_t inlen)
{
_gcry_md_write (state->h, in, inlen);
}
static void
shake128_finalize (keccak_state *state)
{
(void)state;
}
static void
shake128_squeeze (uint8_t *out, size_t outlen, keccak_state *state)
{
_gcry_md_extract (state->h, GCRY_MD_SHAKE128, out, outlen);
}
static void
shake128_close (keccak_state *state)
{
_gcry_md_close (state->h);
}
static void
shake256_init (keccak_state *state)
{
gcry_err_code_t ec;
ec = _gcry_md_open (&state->h, GCRY_MD_SHAKE256, 0);
if (ec)
log_fatal ("internal md_open failed: %d\n", ec);
}
static void
shake256_absorb (keccak_state *state, const uint8_t *in, size_t inlen)
{
_gcry_md_write (state->h, in, inlen);
}
static void
shake256_finalize (keccak_state *state)
{
(void)state;
}
static void
shake256_squeeze (uint8_t *out, size_t outlen, keccak_state *state)
{
_gcry_md_extract (state->h, GCRY_MD_SHAKE256, out, outlen);
}
static void
shake256_close (keccak_state *state)
{
_gcry_md_close (state->h);
}
static void
shake256 (uint8_t *out, size_t outlen, const uint8_t *in,
size_t inlen)
{
gcry_buffer_t iov[1];
iov[0].size = 0;
iov[0].data = (uint8_t *)in;
iov[0].off = 0;
iov[0].len = inlen;
_gcry_md_hash_buffers_extract (GCRY_MD_SHAKE256, 0, out, outlen,
iov, 1);
}
#else
/* to be filled soon... */
#endif
/*************** dilithium/ref/config.h */
#define DILITHIUM_RANDOMIZED_SIGNING
/*************** dilithium/ref/fips202.h */
#define SHAKE128_RATE 168
#define SHAKE256_RATE 136
#define SHA3_256_RATE 136
#define SHA3_512_RATE 72
/*************** dilithium/ref/params.h */
#define SEEDBYTES 32
#define CRHBYTES 64
#define TRBYTES 64
#define RNDBYTES 32
#define N 256
#define Q 8380417
#define D 13
#define ROOT_OF_UNITY 1753
-/* DILITHIUM_MODE dependent values (part 1) */
+/* DILITHIUM_MODE dependent values */
#define ETA2 2
#define ETA4 4
#define GAMMA1_17 (1 << 17)
#define GAMMA1_19 (1 << 19)
#define GAMMA2_32 ((Q-1)/32)
#define GAMMA2_88 ((Q-1)/88)
#define POLYZ_PACKEDBYTES_17 576
#define POLYZ_PACKEDBYTES_19 640
#define POLYW1_PACKEDBYTES_88 192
#define POLYW1_PACKEDBYTES_32 128
#define POLYETA_PACKEDBYTES_2 96
#define POLYETA_PACKEDBYTES_4 128
/*************** dilithium/ref/poly.h */
typedef struct {
int32_t coeffs[N];
} poly;
/*************** dilithium/ref/reduce.h */
#define MONT -4186625 /* 2^32 % Q */
#define QINV 58728449 /* q^(-1) mod 2^32 */
/*************** dilithium/ref/symmetric.h */
typedef keccak_state stream128_state;
typedef keccak_state stream256_state;
#define STREAM128_BLOCKBYTES SHAKE128_RATE
#define STREAM256_BLOCKBYTES SHAKE256_RATE
/*************** dilithium/ref/params.h */
#define POLYT1_PACKEDBYTES 320
#define POLYT0_PACKEDBYTES 416
#define POLYVECH_PACKEDBYTES (OMEGA + K)
/*************** */
/* Forward declarations */
int32_t montgomery_reduce(int64_t a);
int32_t reduce32(int32_t a);
int32_t caddq(int32_t a);
int32_t power2round(int32_t *a0, int32_t a);
-int32_t decompose(int32_t *a0, int32_t a);
-unsigned int make_hint(int32_t a0, int32_t a1);
-int32_t use_hint(int32_t a, unsigned int hint);
-void polyz_pack(uint8_t *r, const poly *a);
-void polyz_unpack(poly *r, const uint8_t *a);
/* Glue code */
#define stream128_squeezeblocks(OUT, OUTBLOCKS, STATE) \
shake128_squeeze(OUT, SHAKE128_RATE*OUTBLOCKS, STATE)
#define stream128_close(STATE) shake128_close(STATE)
#define stream256_squeezeblocks(OUT, OUTBLOCKS, STATE) \
shake256_squeeze(OUT, SHAKE256_RATE*OUTBLOCKS, STATE)
#define stream256_close(STATE) shake256_close(STATE)
#define shake256_squeezeblocks(OUT, OUTBLOCKS, STATE) \
shake256_squeeze(OUT, SHAKE256_RATE*OUTBLOCKS, STATE)
void stream128_init(keccak_state *state, const uint8_t seed[SEEDBYTES], uint16_t nonce)
{
uint8_t t[2];
t[0] = nonce;
t[1] = nonce >> 8;
shake128_init(state);
shake128_absorb(state, seed, SEEDBYTES);
shake128_absorb(state, t, 2);
shake128_finalize(state);
}
void stream256_init(keccak_state *state, const uint8_t seed[CRHBYTES], uint16_t nonce)
{
uint8_t t[2];
t[0] = nonce;
t[1] = nonce >> 8;
shake256_init(state);
shake256_absorb(state, seed, CRHBYTES);
shake256_absorb(state, t, 2);
shake256_finalize(state);
}
#include "dilithium-common.c"
#ifdef DILITHIUM_MODE
-#if DILITHIUM_MODE == 2
-#define K 4
-#define L 4
-#define ETA 2
-#define TAU 39
-#define BETA 78
-#define GAMMA1 (1 << 17)
-#define GAMMA2 ((Q-1)/88)
-#define OMEGA 80
-#define CTILDEBYTES 32
-
-#elif DILITHIUM_MODE == 3
-#define K 6
-#define L 5
-#define ETA 4
-#define TAU 49
-#define BETA 196
-#define GAMMA1 (1 << 19)
-#define GAMMA2 ((Q-1)/32)
-#define OMEGA 55
-#define CTILDEBYTES 48
-
-#elif DILITHIUM_MODE == 5
-#define K 8
-#define L 7
-#define ETA 2
-#define TAU 60
-#define BETA 120
-#define GAMMA1 (1 << 19)
-#define GAMMA2 ((Q-1)/32)
-#define OMEGA 75
-#define CTILDEBYTES 64
-
-#endif
-
-#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2 || DILITHIUM_MODE == 5
-#define POLYETA_PACKEDBYTES POLYETA_PACKEDBYTES_2
-#endif
-#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3
-#define POLYETA_PACKEDBYTES POLYETA_PACKEDBYTES_4
-#endif
-
-#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define POLYZ_PACKEDBYTES POLYZ_PACKEDBYTES_17
-#endif
-#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define POLYZ_PACKEDBYTES POLYZ_PACKEDBYTES_19
-#endif
+# if DILITHIUM_MODE == 2
+# define CRYPTO_ALGNAME "Dilithium2"
+# define K 4
+# define L 4
+# define ETA 2
+# define TAU 39
+# define BETA 78
+# define GAMMA1 (1 << 17)
+# define GAMMA2 ((Q-1)/88)
+# define OMEGA 80
+# define CTILDEBYTES 32
+
+# define poly_decompose poly_decompose_88
+# define poly_make_hint poly_make_hint_88
+# define poly_use_hint poly_use_hint_88
+# define poly_uniform_eta poly_uniform_eta_2
+# define poly_uniform_gamma1 poly_uniform_gamma1_17
+# define polyz_pack polyz_pack_17
+# define polyz_unpack polyz_unpack_17
+# define polyeta_pack polyeta_pack_2
+# define polyeta_unpack polyeta_unpack_2
+# define polyw1_pack polyw1_pack_88
+
+# elif DILITHIUM_MODE == 3
+# define CRYPTO_ALGNAME "Dilithium3"
+# define K 6
+# define L 5
+# define ETA 4
+# define TAU 49
+# define BETA 196
+# define GAMMA1 (1 << 19)
+# define GAMMA2 ((Q-1)/32)
+# define OMEGA 55
+# define CTILDEBYTES 48
+
+# define poly_decompose poly_decompose_32
+# define poly_make_hint poly_make_hint_32
+# define poly_use_hint poly_use_hint_32
+# define poly_uniform_eta poly_uniform_eta_4
+# define poly_uniform_gamma1 poly_uniform_gamma1_19
+# define polyz_pack polyz_pack_19
+# define polyz_unpack polyz_unpack_19
+# define polyeta_pack polyeta_pack_4
+# define polyeta_unpack polyeta_unpack_4
+# define polyw1_pack polyw1_pack_32
+
+# elif DILITHIUM_MODE == 5
+# define CRYPTO_ALGNAME "Dilithium5"
+# define K 8
+# define L 7
+# define ETA 2
+# define TAU 60
+# define BETA 120
+# define GAMMA1 (1 << 19)
+# define GAMMA2 ((Q-1)/32)
+# define OMEGA 75
+# define CTILDEBYTES 64
+
+# define poly_decompose poly_decompose_32
+# define poly_make_hint poly_make_hint_32
+# define poly_use_hint poly_use_hint_32
+# define poly_uniform_eta poly_uniform_eta_2
+# define poly_uniform_gamma1 poly_uniform_gamma1_19
+# define polyz_pack polyz_pack_19
+# define polyz_unpack polyz_unpack_19
+# define polyeta_pack polyeta_pack_2
+# define polyeta_unpack polyeta_unpack_2
+# define polyw1_pack polyw1_pack_32
+
+# endif
+
+# if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
+# define POLYZ_PACKEDBYTES POLYZ_PACKEDBYTES_17
+# endif
+# if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
+# define POLYZ_PACKEDBYTES POLYZ_PACKEDBYTES_19
+# endif
+
+# if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
+# define POLYW1_PACKEDBYTES POLYW1_PACKEDBYTES_88
+# endif
+# if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
+# define POLYW1_PACKEDBYTES POLYW1_PACKEDBYTES_32
+# endif
+
+# if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2 || DILITHIUM_MODE == 5
+# define POLYETA_PACKEDBYTES POLYETA_PACKEDBYTES_2
+# endif
+# if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3
+# define POLYETA_PACKEDBYTES POLYETA_PACKEDBYTES_4
+# endif
+
+# include "dilithium-dep.c"
+#else
-#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 2
-#define POLYW1_PACKEDBYTES POLYW1_PACKEDBYTES_88
-#endif
-#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3 || DILITHIUM_MODE == 5
-#define POLYW1_PACKEDBYTES POLYW1_PACKEDBYTES_32
-#endif
+# define CRYPTO_ALGNAME "Dilithium"
+
+# define VARIANT2(name) name ## _2
+# define VARIANT3(name) name ## _3
+# define VARIANT5(name) name ## _5
+
+# define DILITHIUM_MODE 2
+
+# define CRYPTO_PUBLICKEYBYTES CRYPTO_PUBLICKEYBYTES_2
+# define CRYPTO_SECRETKEYBYTES CRYPTO_SECRETKEYBYTES_2
+# define CRYPTO_BYTES CRYPTO_BYTES_2
+# define POLYZ_PACKEDBYTES POLYZ_PACKEDBYTES_17
+# define POLYW1_PACKEDBYTES POLYW1_PACKEDBYTES_88
+# define POLYETA_PACKEDBYTES POLYETA_PACKEDBYTES_2
+
+# define K 4
+# define L 4
+# define ETA 2
+# define TAU 39
+# define BETA 78
+# define GAMMA1 (1 << 17)
+# define GAMMA2 ((Q-1)/88)
+# define OMEGA 80
+# define CTILDEBYTES 32
+
+# define poly_decompose poly_decompose_88
+# define poly_make_hint poly_make_hint_88
+# define poly_use_hint poly_use_hint_88
+# define poly_uniform_eta poly_uniform_eta_2
+# define poly_uniform_gamma1 poly_uniform_gamma1_17
+# define polyz_pack polyz_pack_17
+# define polyz_unpack polyz_unpack_17
+# define polyeta_pack polyeta_pack_2
+# define polyeta_unpack polyeta_unpack_2
+# define polyw1_pack polyw1_pack_88
+
+# define polyvecl VARIANT2(polyvecl)
+# define polyveck VARIANT2(polyveck)
+# define pack_pk VARIANT2(pack_pk)
+# define unpack_pk VARIANT2(unpack_pk)
+# define pack_sk VARIANT2(pack_sk)
+# define unpack_sk VARIANT2(unpack_sk)
+# define pack_sig VARIANT2(pack_sig)
+# define unpack_sig VARIANT2(unpack_sig)
+# define poly_challenge VARIANT2(poly_challenge)
+# define polyvec_matrix_expand VARIANT2(polyvec_matrix_expand)
+# define polyvec_matrix_pointwise_montgomery VARIANT2(polyvec_matrix_pointwise_montgomery)
+# define polyveck_power2round VARIANT2(polyvec_power2round)
+# define polyveck_make_hint VARIANT2(polyvec_make_hint)
+# define polyveck_use_hint VARIANT2(polyvec_use_hint)
+# define polyvecl_uniform_eta VARIANT2(polyvecl_uniform_eta)
+# define polyvecl_uniform_gamma1 VARIANT2(polyvecl_uniform_gamma1)
+# define polyvecl_reduce VARIANT2(polyvecl_reduce)
+# define polyvecl_add VARIANT2(polyvecl_add)
+# define polyvecl_ntt VARIANT2(polyvecl_ntt)
+# define polyvecl_invntt_tomont VARIANT2(polyvecl_invntt_tomont)
+# define polyvecl_pointwise_poly_montgomery VARIANT2(polyvecl_pointwise_poly_montgomery)
+# define polyvecl_pointwise_acc_montgomery VARIANT2(polyvecl_pointwise_acc_montgomery)
+# define polyvecl_chknorm VARIANT2(polyvecl_chknorm)
+# define polyveck_uniform_eta VARIANT2(polyveck_uniform_eta)
+# define polyveck_reduce VARIANT2(polyveck_reduce)
+# define polyveck_caddq VARIANT2(polyveck_caddq)
+# define polyveck_add VARIANT2(polyveck_add)
+# define polyveck_sub VARIANT2(polyveck_sub)
+# define polyveck_shiftl VARIANT2(polyveck_shiftl)
+# define polyveck_ntt VARIANT2(polyveck_ntt)
+# define polyveck_invntt_tomont VARIANT2(polyveck_invntt_tomont)
+# define polyveck_pointwise_poly_montgomery VARIANT2(polyveck_pointwise_poly_montgomery)
+# define polyveck_chknorm VARIANT2(polyveck_chknorm)
+# define polyveck_pack_w1 VARIANT2(polyveck_pack_w1)
+# define polyveck_decompose VARIANT2(polyveck_decompose)
+# define crypto_sign_keypair VARIANT2(crypto_sign_keypair)
+# define crypto_sign_signature_internal VARIANT2(crypto_sign_signature_internal)
+# define crypto_sign_signature VARIANT2(crypto_sign_signature)
+# define crypto_sign VARIANT2(crypto_sign)
+# define crypto_sign_verify_internal VARIANT2(crypto_sign_verify_internal)
+# define crypto_sign_verify VARIANT2(crypto_sign_verify)
+# define crypto_sign_open VARIANT2(crypto_sign_open)
+
+# include "dilithium-dep.c"
+
+# define DILITHIUM_MODE 3
+
+# define CRYPTO_PUBLICKEYBYTES CRYPTO_PUBLICKEYBYTES_3
+# define CRYPTO_SECRETKEYBYTES CRYPTO_SECRETKEYBYTES_3
+# define CRYPTO_BYTES CRYPTO_BYTES_3
+# define POLYZ_PACKEDBYTES POLYZ_PACKEDBYTES_19
+# define POLYW1_PACKEDBYTES POLYW1_PACKEDBYTES_32
+# define POLYETA_PACKEDBYTES POLYETA_PACKEDBYTES_4
+
+# define K 6
+# define L 5
+# define ETA 4
+# define TAU 49
+# define BETA 196
+# define GAMMA1 (1 << 19)
+# define GAMMA2 ((Q-1)/32)
+# define OMEGA 55
+# define CTILDEBYTES 48
+
+# define poly_decompose poly_decompose_32
+# define poly_make_hint poly_make_hint_32
+# define poly_use_hint poly_use_hint_32
+# define poly_uniform_eta poly_uniform_eta_4
+# define poly_uniform_gamma1 poly_uniform_gamma1_19
+# define polyz_pack polyz_pack_19
+# define polyz_unpack polyz_unpack_19
+# define polyeta_pack polyeta_pack_4
+# define polyeta_unpack polyeta_unpack_4
+# define polyw1_pack polyw1_pack_32
+
+# define polyvecl VARIANT3(polyvecl)
+# define polyveck VARIANT3(polyveck)
+# define pack_pk VARIANT3(pack_pk)
+# define unpack_pk VARIANT3(unpack_pk)
+# define pack_sk VARIANT3(pack_sk)
+# define unpack_sk VARIANT3(unpack_sk)
+# define pack_sig VARIANT3(pack_sig)
+# define unpack_sig VARIANT3(unpack_sig)
+# define poly_challenge VARIANT3(poly_challenge)
+# define polyvec_matrix_expand VARIANT3(polyvec_matrix_expand)
+# define polyvec_matrix_pointwise_montgomery VARIANT3(polyvec_matrix_pointwise_montgomery)
+# define polyveck_power2round VARIANT3(polyvec_power2round)
+# define polyveck_make_hint VARIANT3(polyvec_make_hint)
+# define polyveck_use_hint VARIANT3(polyvec_use_hint)
+# define polyvecl_uniform_eta VARIANT3(polyvecl_uniform_eta)
+# define polyvecl_uniform_gamma1 VARIANT3(polyvecl_uniform_gamma1)
+# define polyvecl_reduce VARIANT3(polyvecl_reduce)
+# define polyvecl_add VARIANT3(polyvecl_add)
+# define polyvecl_ntt VARIANT3(polyvecl_ntt)
+# define polyvecl_invntt_tomont VARIANT3(polyvecl_invntt_tomont)
+# define polyvecl_pointwise_poly_montgomery VARIANT3(polyvecl_pointwise_poly_montgomery)
+# define polyvecl_pointwise_acc_montgomery VARIANT3(polyvecl_pointwise_acc_montgomery)
+# define polyvecl_chknorm VARIANT3(polyvecl_chknorm)
+# define polyveck_uniform_eta VARIANT3(polyveck_uniform_eta)
+# define polyveck_reduce VARIANT3(polyveck_reduce)
+# define polyveck_caddq VARIANT3(polyveck_caddq)
+# define polyveck_add VARIANT3(polyveck_add)
+# define polyveck_sub VARIANT3(polyveck_sub)
+# define polyveck_shiftl VARIANT3(polyveck_shiftl)
+# define polyveck_ntt VARIANT3(polyveck_ntt)
+# define polyveck_invntt_tomont VARIANT3(polyveck_invntt_tomont)
+# define polyveck_pointwise_poly_montgomery VARIANT3(polyveck_pointwise_poly_montgomery)
+# define polyveck_chknorm VARIANT3(polyveck_chknorm)
+# define polyveck_pack_w1 VARIANT3(polyveck_pack_w1)
+# define polyveck_decompose VARIANT3(polyveck_decompose)
+# define crypto_sign_keypair VARIANT3(crypto_sign_keypair)
+# define crypto_sign_signature_internal VARIANT3(crypto_sign_signature_internal)
+# define crypto_sign_signature VARIANT3(crypto_sign_signature)
+# define crypto_sign VARIANT3(crypto_sign)
+# define crypto_sign_verify_internal VARIANT3(crypto_sign_verify_internal)
+# define crypto_sign_verify VARIANT3(crypto_sign_verify)
+# define crypto_sign_open VARIANT3(crypto_sign_open)
+
+# include "dilithium-dep.c"
+
+# define DILITHIUM_MODE 5
+
+# define CRYPTO_PUBLICKEYBYTES CRYPTO_PUBLICKEYBYTES_5
+# define CRYPTO_SECRETKEYBYTES CRYPTO_SECRETKEYBYTES_5
+# define CRYPTO_BYTES CRYPTO_BYTES_5
+# define POLYZ_PACKEDBYTES POLYZ_PACKEDBYTES_19
+# define POLYW1_PACKEDBYTES POLYW1_PACKEDBYTES_32
+# define POLYETA_PACKEDBYTES POLYETA_PACKEDBYTES_4
+
+# define K 8
+# define L 7
+# define ETA 2
+# define TAU 60
+# define BETA 120
+# define GAMMA1 (1 << 19)
+# define GAMMA2 ((Q-1)/32)
+# define OMEGA 75
+# define CTILDEBYTES 64
+
+# define poly_decompose poly_decompose_32
+# define poly_make_hint poly_make_hint_32
+# define poly_use_hint poly_use_hint_32
+# define poly_uniform_eta poly_uniform_eta_2
+# define poly_uniform_gamma1 poly_uniform_gamma1_19
+# define polyz_pack polyz_pack_19
+# define polyz_unpack polyz_unpack_19
+# define polyeta_pack polyeta_pack_2
+# define polyeta_unpack polyeta_unpack_2
+# define polyw1_pack polyw1_pack_32
+
+# define polyvecl VARIANT5(polyvecl)
+# define polyveck VARIANT5(polyveck)
+# define pack_pk VARIANT5(pack_pk)
+# define unpack_pk VARIANT5(unpack_pk)
+# define pack_sk VARIANT5(pack_sk)
+# define unpack_sk VARIANT5(unpack_sk)
+# define pack_sig VARIANT5(pack_sig)
+# define unpack_sig VARIANT5(unpack_sig)
+# define poly_challenge VARIANT5(poly_challenge)
+# define polyvec_matrix_expand VARIANT5(polyvec_matrix_expand)
+# define polyvec_matrix_pointwise_montgomery VARIANT5(polyvec_matrix_pointwise_montgomery)
+# define polyveck_power2round VARIANT5(polyvec_power2round)
+# define polyveck_make_hint VARIANT5(polyvec_make_hint)
+# define polyveck_use_hint VARIANT5(polyvec_use_hint)
+# define polyvecl_uniform_eta VARIANT5(polyvecl_uniform_eta)
+# define polyvecl_uniform_gamma1 VARIANT5(polyvecl_uniform_gamma1)
+# define polyvecl_reduce VARIANT5(polyvecl_reduce)
+# define polyvecl_add VARIANT5(polyvecl_add)
+# define polyvecl_ntt VARIANT5(polyvecl_ntt)
+# define polyvecl_invntt_tomont VARIANT5(polyvecl_invntt_tomont)
+# define polyvecl_pointwise_poly_montgomery VARIANT5(polyvecl_pointwise_poly_montgomery)
+# define polyvecl_pointwise_acc_montgomery VARIANT5(polyvecl_pointwise_acc_montgomery)
+# define polyvecl_chknorm VARIANT5(polyvecl_chknorm)
+# define polyveck_uniform_eta VARIANT5(polyveck_uniform_eta)
+# define polyveck_reduce VARIANT5(polyveck_reduce)
+# define polyveck_caddq VARIANT5(polyveck_caddq)
+# define polyveck_add VARIANT5(polyveck_add)
+# define polyveck_sub VARIANT5(polyveck_sub)
+# define polyveck_shiftl VARIANT5(polyveck_shiftl)
+# define polyveck_ntt VARIANT5(polyveck_ntt)
+# define polyveck_invntt_tomont VARIANT5(polyveck_invntt_tomont)
+# define polyveck_pointwise_poly_montgomery VARIANT5(polyveck_pointwise_poly_montgomery)
+# define polyveck_chknorm VARIANT5(polyveck_chknorm)
+# define polyveck_pack_w1 VARIANT5(polyveck_pack_w1)
+# define polyveck_decompose VARIANT5(polyveck_decompose)
+# define crypto_sign_keypair VARIANT5(crypto_sign_keypair)
+# define crypto_sign_signature_internal VARIANT5(crypto_sign_signature_internal)
+# define crypto_sign_signature VARIANT5(crypto_sign_signature)
+# define crypto_sign VARIANT5(crypto_sign)
+# define crypto_sign_verify_internal VARIANT5(crypto_sign_verify_internal)
+# define crypto_sign_verify VARIANT5(crypto_sign_verify)
+# define crypto_sign_open VARIANT5(crypto_sign_open)
+
+# include "dilithium-dep.c"
-#include "dilithium-dep.c"
-#else
-/*TBD soon*/
#endif
diff --git a/cipher/dilithium.h b/cipher/dilithium.h
index 7b0f6120..414ed03e 100644
--- a/cipher/dilithium.h
+++ b/cipher/dilithium.h
@@ -1,110 +1,110 @@
/* dilithium.h - the Dilithium (header)
* Copyright (C) 2025 g10 Code GmbH
*
* This file was modified for use by Libgcrypt.
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1-or-later
*
* You can also use this file under the same licence of original code.
* SPDX-License-Identifier: CC0 OR Apache-2.0
*
*/
/*
Original code from:
Repository: https://github.com/pq-crystals/dilithium.git
Branch: master
Commit: 444cdcc84eb36b66fe27b3a2529ee48f6d8150c2
Licence:
Public Domain (https://creativecommons.org/share-your-work/public-domain/cc0/);
or Apache 2.0 License (https://www.apache.org/licenses/LICENSE-2.0.html).
Authors:
Léo Ducas
Eike Kiltz
Tancrède Lepoint
Vadim Lyubashevsky
Gregor Seiler
Peter Schwabe
Damien Stehlé
Dilithium Home: https://github.com/pq-crystals/dilithium.git
*/
/* Standalone use is possible either with DILITHIUM_MODE defined with
* the value (2, 3, or 5), or not defined. For the latter, routines
* for three variants are available.
*/
#ifndef DILITHIUM_H
#define DILITHIUM_H
#define SEEDBYTES 32
#define RNDBYTES 32
#if defined(DILITHIUM_MODE)
# if DILITHIUM_MODE == 2
# define CRYPTO_PUBLICKEYBYTES (SEEDBYTES + 4*320)
# define CRYPTO_SECRETKEYBYTES (2*SEEDBYTES \
+ 64 \
+ 4*96 \
+ 4*96 \
+ 4*416)
# define CRYPTO_BYTES (32 + L*576 + 80 + 4)
# elif DILITHIUM_MODE == 3
# define CRYPTO_PUBLICKEYBYTES (SEEDBYTES + 6*320)
# define CRYPTO_SECRETKEYBYTES (2*SEEDBYTES \
+ 64 \
+ 5*128 \
+ 6*128 \
+ 6*416)
# define CRYPTO_BYTES (48 + 5*640 + 55 + 6)
# elif DILITHIUM_MODE == 5
# define CRYPTO_PUBLICKEYBYTES (SEEDBYTES + 8*320)
# define CRYPTO_SECRETKEYBYTES (2*SEEDBYTES \
+ 64 \
+ 7*96 \
+ 8*96 \
+ 8*416)
# define CRYPTO_BYTES (64 + 7*640 + 75 + 8)
# else
# error "DILITHIUM_MODE should be either 2, 3 or 5"
# endif
#else
# define CRYPTO_PUBLICKEYBYTES_2 (SEEDBYTES + 4*320)
# define CRYPTO_SECRETKEYBYTES_2 (2*SEEDBYTES \
+ 64 \
+ 4*96 \
+ 4*96 \
+ 4*416)
-# define CRYPTO_BYTES_2 (32 + L*576 + 80 + 4))
+# define CRYPTO_BYTES_2 (32 + L*576 + 80 + 4)
# define CRYPTO_PUBLICKEYBYTES_3 (SEEDBYTES + 6*320)
# define CRYPTO_SECRETKEYBYTES_3 (2*SEEDBYTES \
+ 64 \
+ 5*128 \
+ 6*128 \
+ 6*416)
# define CRYPTO_BYTES_3 (48 + 5*640 + 55 + 6)
# define CRYPTO_PUBLICKEYBYTES_5 (SEEDBYTES + 8*320)
# define CRYPTO_SECRETKEYBYTES_5 (2*SEEDBYTES \
+ 64 \
+ 7*96 \
+ 8*96 \
+ 8*416)
# define CRYPTO_BYTES_5 (64 + 7*640 + 75 + 8)
#endif
#endif
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Jan 12, 11:42 PM (1 d, 5 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
75/27/28b73cc35b50fb8afe63547feeaf
Attached To
rC libgcrypt
Event Timeline
Log In to Comment