From 444cdcc84eb36b66fe27b3a2529ee48f6d8150c2 Mon Sep 17 00:00:00 2001 From: Gregor Seiler Date: Fri, 1 Nov 2024 16:21:46 +0100 Subject: [PATCH] Add internal functions --- Dilithium2_META.yml | 1 + Dilithium3_META.yml | 1 + Dilithium5_META.yml | 1 + avx2/sign.c | 134 ++++++++++++++++++++++++---------- ref/sign.c | 172 +++++++++++++++++++++++++++++++------------- ref/sign.h | 19 +++++ 6 files changed, 243 insertions(+), 85 deletions(-) diff --git a/Dilithium2_META.yml b/Dilithium2_META.yml index 425606f..122b3ca 100644 --- a/Dilithium2_META.yml +++ b/Dilithium2_META.yml @@ -4,6 +4,7 @@ claimed-nist-level: 2 length-public-key: 1312 length-secret-key: 2560 length-signature: 2420 +nistkat-sha256: 9a196e7fb32fbc93757dc2d8dc1924460eab66303c0c08aeb8b798fb8d8f8cf3 testvectors-sha256: 5f0d135c0f7fd43f3fb9727265fcd6ec3651eb8c67c04ea5f3d8dfa1d99740d2 principal-submitters: - Vadim Lyubashevsky diff --git a/Dilithium3_META.yml b/Dilithium3_META.yml index 94b60c0..b108b4f 100644 --- a/Dilithium3_META.yml +++ b/Dilithium3_META.yml @@ -4,6 +4,7 @@ claimed-nist-level: 3 length-public-key: 1952 length-secret-key: 4032 length-signature: 3309 +nistkat-sha256: 7cb96242eac9907a55b5c84c202f0ebd552419c50b2e986dc2e28f07ecebf072 testvectors-sha256: 14bf84918ee90e7afbd580191d3eb890d4557e0900b1145e39a8399ef7dd3fba principal-submitters: - Vadim Lyubashevsky diff --git a/Dilithium5_META.yml b/Dilithium5_META.yml index 69e1c01..5163526 100644 --- a/Dilithium5_META.yml +++ b/Dilithium5_META.yml @@ -4,6 +4,7 @@ claimed-nist-level: 5 length-public-key: 2592 length-secret-key: 4896 length-signature: 4627 +nistkat-sha256: 4537905d2aabcf302fab2f242baed293459ecda7c230e6a67063b02c7e2840ed testvectors-sha256: 759a3ba35210c7e27ff90a7ce5e399295533b82ef125e6ec98af158e00268e44 principal-submitters: - Vadim Lyubashevsky diff --git a/avx2/sign.c b/avx2/sign.c index 7d70257..efb6ea3 100644 --- a/avx2/sign.c +++ b/avx2/sign.c @@ -137,26 +137,27 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_signature +* Name: crypto_sign_signature_internal * -* Description: Computes signature. +* 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 *ctx: pointer to context string -* - size_t ctxlen: length of context string +* - 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) or -1 (context string too long) +* Returns 0 (success) **************************************************/ -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) +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 i, n, pos; - uint8_t seedbuf[2*SEEDBYTES + TRBYTES + RNDBYTES + 2*CRHBYTES]; - uint8_t *rho, *tr, *key, *rnd, *mu, *rhoprime; + uint8_t seedbuf[2*SEEDBYTES + TRBYTES + 2*CRHBYTES]; + uint8_t *rho, *tr, *key, *mu, *rhoprime; uint8_t hintbuf[N]; uint8_t *hint = sig + CTILDEBYTES + L*POLYZ_PACKEDBYTES; uint64_t nonce = 0; @@ -169,34 +170,28 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t } tmpv; keccak_state state; - if(ctxlen > 255) - return -1; - rho = seedbuf; tr = rho + SEEDBYTES; key = tr + TRBYTES; - rnd = key + SEEDBYTES; - mu = rnd + RNDBYTES; + mu = key + SEEDBYTES; rhoprime = mu + CRHBYTES; unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); - /* Compute CRH(tr, 0, ctxlen, ctx, msg) */ + /* Compute mu = CRH(tr, pre, msg) */ shake256_init(&state); shake256_absorb(&state, tr, TRBYTES); - mu[0] = 0; - mu[1] = ctxlen; - shake256_absorb(&state, mu, 2); - shake256_absorb(&state, ctx, ctxlen); + shake256_absorb(&state, pre, prelen); shake256_absorb(&state, m, mlen); shake256_finalize(&state); shake256_squeeze(mu, CRHBYTES, &state); -#ifdef DILITHIUM_RANDOMIZED_SIGNING - randombytes(rnd, RNDBYTES); -#else - memset(rnd, 0, RNDBYTES); -#endif - shake256(rhoprime, CRHBYTES, key, SEEDBYTES + RNDBYTES + CRHBYTES); + /* 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); /* Expand matrix and transform vectors */ polyvec_matrix_expand(mat, rho); @@ -293,6 +288,45 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t 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 context string +* - size_t ctxlen: length of context 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) +{ + uint8_t pre[257]; + uint8_t rnd[RNDBYTES]; + + if(ctxlen > 255) + return -1; + + /* Prepare pre = (0, ctxlen, ctx) */ + pre[0] = 0; + pre[1] = ctxlen; + memcpy(&pre[2], ctx, ctxlen); + +#ifdef DILITHIUM_RANDOMIZED_SIGNING + randombytes(rnd, RNDBYTES); +#else + memset(rnd, 0, RNDBYTES); +#endif + + crypto_sign_signature_internal(sig,siglen,m,mlen,pre,2+ctxlen,rnd,sk); + return 0; +} + /************************************************* * Name: crypto_sign * @@ -325,22 +359,22 @@ int crypto_sign(uint8_t *sm, size_t *smlen, const uint8_t *m, size_t mlen, const } /************************************************* -* Name: crypto_sign_verify +* Name: crypto_sign_verify_internal * -* Description: Verifies signature. +* 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 *ctx: pointer to context string -* - size_t ctxlen: length of context string +* - 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(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) { +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, j, pos = 0; /* polyw1_pack writes additional 14 bytes */ ALIGNED_UINT8(K*POLYW1_PACKEDBYTES+14) buf; @@ -352,17 +386,14 @@ int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size poly c, w1, h; keccak_state state; - if(ctxlen > 255 || siglen != CRYPTO_BYTES) + if(siglen != CRYPTO_BYTES) return -1; - /* Compute CRH(H(rho, t1), msg) */ + /* Compute CRH(H(rho, t1), pre, msg) */ shake256(mu, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES); shake256_init(&state); shake256_absorb(&state, mu, CRHBYTES); - mu[0] = 0; - mu[1] = ctxlen; - shake256_absorb(&state, mu, 2); - shake256_absorb(&state, ctx, ctxlen); + shake256_absorb(&state, pre, prelen); shake256_absorb(&state, m, mlen); shake256_finalize(&state); shake256_squeeze(mu, CRHBYTES, &state); @@ -427,6 +458,35 @@ int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size 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) +{ + uint8_t pre[257]; + + if(ctxlen > 255) + return -1; + + pre[0] = 0; + pre[1] = ctxlen; + memcpy(&pre[2], ctx, ctxlen); + return crypto_sign_verify_internal(sig,siglen,m,mlen,pre,2+ctxlen,pk); +} + /************************************************* * Name: crypto_sign_open * diff --git a/ref/sign.c b/ref/sign.c index b130da9..7d3f882 100644 --- a/ref/sign.c +++ b/ref/sign.c @@ -67,66 +67,61 @@ int crypto_sign_keypair(uint8_t *pk, uint8_t *sk) { } /************************************************* -* Name: crypto_sign_signature +* Name: crypto_sign_signature_internal * -* Description: Computes signature. +* 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 *ctx: pointer to context string -* - size_t ctxlen: length of context string +* - 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) or -1 (context string too long) +* Returns 0 (success) **************************************************/ -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) +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 + RNDBYTES + 2*CRHBYTES]; - uint8_t *rho, *tr, *key, *mu, *rhoprime, *rnd; + 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; - if(ctxlen > 255) - return -1; - rho = seedbuf; tr = rho + SEEDBYTES; key = tr + TRBYTES; - rnd = key + SEEDBYTES; - mu = rnd + RNDBYTES; + mu = key + SEEDBYTES; rhoprime = mu + CRHBYTES; unpack_sk(rho, tr, key, &t0, &s1, &s2, sk); - /* Compute mu = CRH(tr, 0, ctxlen, ctx, msg) */ - mu[0] = 0; - mu[1] = ctxlen; + /* Compute mu = CRH(tr, pre, msg) */ shake256_init(&state); shake256_absorb(&state, tr, TRBYTES); - shake256_absorb(&state, mu, 2); - shake256_absorb(&state, ctx, ctxlen); + shake256_absorb(&state, pre, prelen); shake256_absorb(&state, m, mlen); shake256_finalize(&state); shake256_squeeze(mu, CRHBYTES, &state); -#ifdef DILITHIUM_RANDOMIZED_SIGNING - randombytes(rnd, RNDBYTES); -#else - for(n=0;n 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 255 || siglen != CRYPTO_BYTES) + if(siglen != CRYPTO_BYTES) return -1; unpack_pk(rho, &t1, pk); @@ -272,14 +314,11 @@ int crypto_sign_verify(const uint8_t *sig, if(polyvecl_chknorm(&z, GAMMA1 - BETA)) return -1; - /* Compute CRH(H(rho, t1), msg) */ + /* Compute CRH(H(rho, t1), pre, msg) */ shake256(mu, TRBYTES, pk, CRYPTO_PUBLICKEYBYTES); shake256_init(&state); shake256_absorb(&state, mu, TRBYTES); - mu[0] = 0; - mu[1] = ctxlen; - shake256_absorb(&state, mu, 2); - shake256_absorb(&state, ctx, ctxlen); + shake256_absorb(&state, pre, prelen); shake256_absorb(&state, m, mlen); shake256_finalize(&state); shake256_squeeze(mu, CRHBYTES, &state); @@ -318,6 +357,43 @@ int crypto_sign_verify(const uint8_t *sig, 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 * diff --git a/ref/sign.h b/ref/sign.h index 91d2001..2741e8f 100644 --- a/ref/sign.h +++ b/ref/sign.h @@ -10,6 +10,16 @@ #define crypto_sign_keypair DILITHIUM_NAMESPACE(keypair) int crypto_sign_keypair(uint8_t *pk, uint8_t *sk); +#define crypto_sign_signature_internal DILITHIUM_NAMESPACE(signature_internal) +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); + #define crypto_sign_signature DILITHIUM_NAMESPACE(signature) int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen, @@ -22,6 +32,15 @@ int crypto_sign(uint8_t *sm, size_t *smlen, const uint8_t *ctx, size_t ctxlen, const uint8_t *sk); +#define crypto_sign_verify_internal DILITHIUM_NAMESPACE(verify_internal) +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); + #define crypto_sign_verify DILITHIUM_NAMESPACE(verify) int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,