[PATCH 09/17] cipher:dilithium: For _GCRYPT_IN_LIBGCRYPT, add *_close function.
NIIBE Yutaka via Gcrypt-devel <[email protected]> Sat, 28 Jun 2025 12:44:46 +0900
| Newsgroups | gmane.comp.encryption.gpg.libgcrypt.devel |
|---|---|
| Message-ID | <479085097a97fc1eb750d65ae4403ae44022c326.1751080340.git.gniibe@fsij.org> |
* cipher/dilithium-common.c (poly_uniform): Add stream128_close. (poly_uniform_eta_2, poly_uniform_eta_4): Add stream256_close. (poly_uniform_gamma1_17, poly_uniform_gamma1_19): Likewise. * cipher/dilithium-dep.c (poly_challenge): Add shake256_close. (crypto_sign_signature_internal): Likewise. (crypto_sign_verify_internal): Likewise. * cipher/dilithium.c [_GCRYPT_IN_LIBGCRYPT]: Add glue code for shake128_* and shake256_*. -- GnuPG-bug-id: 7640 Signed-off-by: NIIBE Yutaka <[email protected]> --- cipher/dilithium-common.c | 5 ++ cipher/dilithium-dep.c | 6 ++ cipher/dilithium.c | 181 ++++++++++++++++++++++++++++++++++---- 3 files changed, 175 insertions(+), 17 deletions(-) _______________________________________________ Gcrypt-devel mailing list [email protected] https://lists.gnupg.org/mailman/listinfo/gcrypt-devel
0009-cipher-dilithium-For-_GCRYPT_IN_LIBGCRYPT-add-_close.patch
(text/x-patch, 10.6 KB)
diff --git a/cipher/dilithium-common.c b/cipher/dilithium-common.c
index 2dfc4ba0..47d5f7d6 100644
--- a/cipher/dilithium-common.c
+++ b/cipher/dilithium-common.c
@@ -674,6 +674,7 @@ void poly_uniform(poly *a,
buflen = STREAM128_BLOCKBYTES + off;
ctr += rej_uniform(a->coeffs + ctr, N - ctr, buf, buflen);
}
+ stream128_close(&state);
}
/*************************************************
@@ -776,6 +777,7 @@ void poly_uniform_eta_2(poly *a,
stream256_squeezeblocks(buf, 1, &state);
ctr += rej_eta_2(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
}
+ stream256_close(&state);
}
#endif
#if !defined(DILITHIUM_MODE) || DILITHIUM_MODE == 3
@@ -798,6 +800,7 @@ void poly_uniform_eta_4(poly *a,
stream256_squeezeblocks(buf, 1, &state);
ctr += rej_eta_4(a->coeffs + ctr, N - ctr, buf, STREAM256_BLOCKBYTES);
}
+ stream256_close(&state);
}
#endif
@@ -825,6 +828,7 @@ void poly_uniform_gamma1_17(poly *a,
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
@@ -840,6 +844,7 @@ void poly_uniform_gamma1_19(poly *a,
stream256_init(&state, seed, nonce);
stream256_squeezeblocks(buf, POLY_UNIFORM_GAMMA1_NBLOCKS_19, &state);
polyz_unpack_19(a, buf);
+ stream256_close(&state);
}
#endif
diff --git a/cipher/dilithium-dep.c b/cipher/dilithium-dep.c
index e59cad55..569ffd5f 100644
--- a/cipher/dilithium-dep.c
+++ b/cipher/dilithium-dep.c
@@ -404,6 +404,7 @@ void poly_challenge(poly *c, const uint8_t seed[CTILDEBYTES]) {
c->coeffs[b] = 1 - 2*(signs & 1);
signs >>= 1;
}
+ shake256_close(&state);
}
/*************** dilithium/ref/polyvec.c */
@@ -899,6 +900,7 @@ int crypto_sign_signature_internal(uint8_t *sig,
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);
@@ -907,6 +909,7 @@ int crypto_sign_signature_internal(uint8_t *sig,
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);
@@ -935,6 +938,7 @@ rej:
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);
@@ -1107,6 +1111,7 @@ int crypto_sign_verify_internal(const uint8_t *sig,
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);
@@ -1135,6 +1140,7 @@ int crypto_sign_verify_internal(const uint8_t *sig,
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;
diff --git a/cipher/dilithium.c b/cipher/dilithium.c
index b9a16459..165b1117 100644
--- a/cipher/dilithium.c
+++ b/cipher/dilithium.c
@@ -43,37 +43,175 @@
Dilithium Home: https://github.com/pq-crystals/dilithium.git
*/
-/*************** dilithium/ref/fips202.h */
-#define SHAKE128_RATE 168
-#define SHAKE256_RATE 136
-#define SHA3_256_RATE 136
+#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"
+
+#include "dilithium.h"
+
+static int crypto_sign_keypair_internal_2 (uint8_t *pk, uint8_t *sk,
+ const uint8_t seed[SEEDBYTES]);
+static int crypto_sign_keypair_internal_3 (uint8_t *pk, uint8_t *sk,
+ const uint8_t seed[SEEDBYTES]);
+static int crypto_sign_keypair_internal_5 (uint8_t *pk, uint8_t *sk,
+ const uint8_t seed[SEEDBYTES]);
+static int crypto_sign_signature_internal_2 (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);
+static int crypto_sign_signature_internal_3 (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);
+static int crypto_sign_signature_internal_5 (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);
+static int crypto_sign_verify_internal_2 (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);
+static int crypto_sign_verify_internal_3 (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);
+static int crypto_sign_verify_internal_5 (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);
+
+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
+#include "dilithium.h"
+
+#define DILITHIUM_RANDOMIZED_SIGNING
+/*************** dilithium/ref/randombytes.h */
+void randombytes (uint8_t *out, size_t outlen);
+/*************** dilithium/ref/fips202.h */
typedef struct {
uint64_t s[25];
unsigned int pos;
} keccak_state;
-extern const uint64_t KeccakF_RoundConstants[];
-
void shake128_init(keccak_state *state);
void shake128_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
void shake128_finalize(keccak_state *state);
void shake128_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
-void shake128_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
-void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
void shake256_init(keccak_state *state);
void shake256_absorb(keccak_state *state, const uint8_t *in, size_t inlen);
void shake256_finalize(keccak_state *state);
void shake256_squeeze(uint8_t *out, size_t outlen, keccak_state *state);
-void shake256_absorb_once(keccak_state *state, const uint8_t *in, size_t inlen);
-void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state);
-
-void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen);
-void sha3_256(uint8_t h[32], const uint8_t *in, size_t inlen);
-void sha3_512(uint8_t h[64], const uint8_t *in, size_t inlen);
+#endif /* _GCRYPT_IN_LIBGCRYPT */
+
+/*************** dilithium/ref/fips202.h */
+#define SHAKE128_RATE 168
+#define SHAKE256_RATE 136
+#define SHA3_256_RATE 136
/*************** dilithium/ref/params.h */
#define SEEDBYTES 32
@@ -197,9 +335,6 @@ static void polyz_unpack(poly *r, const uint8_t *a);
static void polyw1_pack(uint8_t *r, const poly *a);
-/*************** dilithium/ref/randombytes.h */
-void randombytes(uint8_t *out, size_t outlen);
-
/*************** dilithium/ref/reduce.h */
#define MONT -4186625 /* 2^32 % Q */
#define QINV 58728449 /* q^(-1) mod 2^32 */
@@ -311,5 +446,17 @@ void dilithium_shake256_stream_init(keccak_state *state, const uint8_t seed[CRHB
shake256_finalize(state);
}
+/* Glue code */
+#define shake128_squeezeblocks(OUT, OUTBLOCKS, STATE) \
+ shake128_squeeze(OUT, SHAKE128_RATE*OUTBLOCKS, STATE)
+#define stream128_close(STATE) shake128_close(STATE)
+#define shake256_squeezeblocks(OUT, OUTBLOCKS, STATE) \
+ shake256_squeeze(OUT, SHAKE256_RATE*OUTBLOCKS, STATE)
+#define stream256_close(STATE) shake256_close(STATE)
+#ifndef _GCRYPT_IN_LIBGCRYPT
+static void shake256_close (keccak_state *state) { (void)state; }
+static void shake128_close (keccak_state *state) { (void)state; }
+#endif
+
#include "dilithium-common.c"
#include "dilithium-dep.c"