Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding internal functions for ML-DSA #1977

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 160 additions & 55 deletions crypto/dilithium/pqcrystals_dilithium_ref_common/sign.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdint.h>
#include "../../internal.h"
#include "params.h"
#include "sign.h"
#include "packing.h"
Expand All @@ -9,28 +10,31 @@
#include "fips202.h"

/*************************************************
* Name: crypto_sign_keypair
* Name: crypto_sign_keypair_internal
*
* Description: Generates public and private key.
* Description: Generates public and private key. Internal API.
*
* Arguments: - ml_dsa_params: parameter struct
* - 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)
* - const uint8_t *rnd: pointer to random seed
*
* Returns 0 (success)
**************************************************/
int crypto_sign_keypair(ml_dsa_params *params, uint8_t *pk, uint8_t *sk) {
int crypto_sign_keypair_internal(ml_dsa_params *params,
uint8_t *pk,
uint8_t *sk,
const uint8_t *seed) {
uint8_t seedbuf[2*SEEDBYTES + CRHBYTES];
uint8_t tr[TRBYTES];
const uint8_t *rho, *rhoprime, *key;
polyvecl mat[DILITHIUM_K_MAX];
polyvecl s1, s1hat;
polyveck s2, t1, t0;

/* Get randomness for rho, rhoprime and key */
pq_custom_randombytes(seedbuf, SEEDBYTES);
OPENSSL_memcpy(seedbuf, seed, SEEDBYTES);
seedbuf[SEEDBYTES+0] = params->k;
seedbuf[SEEDBYTES+1] = params->l;
shake256(seedbuf, 2*SEEDBYTES + CRHBYTES, seedbuf, SEEDBYTES+2);
Expand Down Expand Up @@ -68,68 +72,84 @@ int crypto_sign_keypair(ml_dsa_params *params, uint8_t *pk, uint8_t *sk) {
}

/*************************************************
* Name: crypto_sign_signature
* Name: crypto_sign_keypair
*
* Description: Computes signature.
* Description: Generates public and private key.
*
* Arguments: - ml_dsa_params: parameter struct
* - 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(ml_dsa_params *params, uint8_t *pk, uint8_t *sk) {
uint8_t seedbuf[2*SEEDBYTES + CRHBYTES];
/* Get randomness for rho, rhoprime and key */
pq_custom_randombytes(seedbuf, SEEDBYTES);
crypto_sign_keypair_internal(params, pk, sk, seedbuf);
return 0;
}

/*************************************************
* Name: crypto_sign_signature_internal
*
* Description: Computes signature. Internal API.
*
* Arguments: - ml_dsa_params: parameter struct
* - 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)
**************************************************/
int crypto_sign_signature(ml_dsa_params *params,
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(ml_dsa_params *params,
uint8_t *sig,
size_t *siglen,
const uint8_t *m,
size_t mlen,
const uint8_t *pre,
size_t prelen,
const uint8_t *rnd,
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[DILITHIUM_K_MAX], 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(params, 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
pq_custom_randombytes(rnd, RNDBYTES);
#else
for(n=0;n<RNDBYTES;n++)
rnd[n] = 0;
#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(params, mat, rho);
Expand All @@ -155,7 +175,7 @@ int crypto_sign_signature(ml_dsa_params *params,

shake256_init(&state);
shake256_absorb(&state, mu, CRHBYTES);
shake256_absorb(&state, sig, params->k*params->poly_w1_packed_bytes);
shake256_absorb(&state, sig, params->k * params->poly_w1_packed_bytes);
shake256_finalize(&state);
shake256_squeeze(sig, params->c_tilde_bytes, &state);
poly_challenge(params, &cp, sig);
Expand Down Expand Up @@ -196,6 +216,55 @@ int crypto_sign_signature(ml_dsa_params *params,
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(ml_dsa_params *params,
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
if (!pq_custom_randombytes(rnd, RNDBYTES))
return -1;
#else
for(i=0;i<RNDBYTES;i++)
rnd[i] = 0;
#endif

crypto_sign_signature_internal(params, sig, siglen, m, mlen, pre, 2 + ctxlen, rnd, sk);
return 0;
}

/*************************************************
* Name: crypto_sign
*
Expand Down Expand Up @@ -235,29 +304,29 @@ int crypto_sign(ml_dsa_params *params,
}

/*************************************************
* Name: crypto_sign_verify
* Name: crypto_sign_verify_internal
*
* Description: Verifies signature.
* Description: Verifies signature. Internal API.
*
* Arguments: - ml_dsa_params: parameter struct
* - 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(ml_dsa_params *params,
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(ml_dsa_params *params,
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[DILITHIUM_K_MAX*DILITHIUM_POLYW1_PACKEDBYTES_MAX];
Expand All @@ -270,7 +339,7 @@ int crypto_sign_verify(ml_dsa_params *params,
polyveck t1, w1, h;
keccak_state state;

if(ctxlen > 255 || siglen != params->bytes)
if(siglen != params->bytes)
return -1;

unpack_pk(params, rho, &t1, pk);
Expand All @@ -283,10 +352,7 @@ int crypto_sign_verify(ml_dsa_params *params,
shake256(mu, TRBYTES, pk, params->public_key_bytes);
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);
Expand Down Expand Up @@ -315,7 +381,7 @@ int crypto_sign_verify(ml_dsa_params *params,
/* Call random oracle and verify challenge */
shake256_init(&state);
shake256_absorb(&state, mu, CRHBYTES);
shake256_absorb(&state, buf, params->k*params->poly_w1_packed_bytes);
shake256_absorb(&state, buf, params->k * params->poly_w1_packed_bytes);
shake256_finalize(&state);
shake256_squeeze(c2, params->c_tilde_bytes, &state);
for(i = 0; i < params->c_tilde_bytes; ++i)
Expand All @@ -325,6 +391,45 @@ int crypto_sign_verify(ml_dsa_params *params,
return 0;
}

/*************************************************
* Name: crypto_sign_verify
*
* Description: Verifies signature.
*
* Arguments: - ml_dsa_params: parameter struct
* - 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(ml_dsa_params *params,
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(params, sig, siglen, m, mlen, pre, 2 + ctxlen, pk);
}

/*************************************************
* Name: crypto_sign_open
*
Expand Down
24 changes: 24 additions & 0 deletions crypto/dilithium/pqcrystals_dilithium_ref_common/sign.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,27 @@

int crypto_sign_keypair(ml_dsa_params *params, uint8_t *pk, uint8_t *sk);

int crypto_sign_keypair_internal(ml_dsa_params *params,
uint8_t *pk,
uint8_t *sk,
const uint8_t *seed);

int crypto_sign_signature(ml_dsa_params *params,
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(ml_dsa_params *params,
uint8_t *sig,
size_t *siglen,
const uint8_t *m,
size_t mlen,
const uint8_t *pre,
size_t prelen,
const uint8_t *rnd,
const uint8_t *sk);

int crypto_sign(ml_dsa_params *params,
uint8_t *sm, size_t *smlen,
const uint8_t *m, size_t mlen,
Expand All @@ -27,6 +42,15 @@ int crypto_sign_verify(ml_dsa_params *params,
const uint8_t *ctx, size_t ctxlen,
const uint8_t *pk);

int crypto_sign_verify_internal(ml_dsa_params *params,
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);

int crypto_sign_open(ml_dsa_params *params,
uint8_t *m, size_t *mlen,
const uint8_t *sm, size_t smlen,
Expand Down
Loading