Skip to content

Commit

Permalink
Added FIPS 204 documentation, cleanse intermediate values (#2017)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakemas authored Dec 10, 2024
1 parent 5c43438 commit 18cc07d
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 221 deletions.
3 changes: 3 additions & 0 deletions crypto/dilithium/pqcrystals_dilithium_ref_common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ that initialize a given structure with values corresponding to a parameter set.
- `reduce.c`: a small fix to documentation has been made on the bounds of `reduce32`.
- `poly.c`: a small fix to documentation has been made on the bounds of `poly_reduce`.
- `polyvec.c`: a small fix to documentation has been made on the bounds of `polyveck_reduce`.
- Documentation has been added to `ntt.c`, `packing.c`, `poly.c`, `polyvec.c`, and `rounding.c` that outlines the algorithm specification (including algorithm number) in FIPS 204.
- `poly.c` and `sign.c` have been modified to cleanse intermediate data as soon as it is no longer needed as defined in FIPS 204 Section 3.6.3.
- Intermediate values are cleansed within `crypto_sign_keypair_internal`, `crypto_sign_keypair`, `crypto_sign_signature_internal`, `crypto_sign_verify_internal`, `crypto_sign_verify`, `poly_uniform_eta`, `poly_uniform_gamma1`, and `poly_challenge` as per FIPS 204 Section 3.6.3.

**Testing**

Expand Down
6 changes: 4 additions & 2 deletions crypto/dilithium/pqcrystals_dilithium_ref_common/ntt.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ static const int32_t zetas[N] = {
/*************************************************
* Name: ntt
*
* Description: Forward NTT, in-place. No modular reduction is performed after
* Description: FIPS 204: Algorithm 41.
* 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
Expand All @@ -66,7 +67,8 @@ void ntt(int32_t a[N]) {
/*************************************************
* Name: invntt_tomont
*
* Description: Inverse NTT and multiplication by Montgomery factor 2^32.
* Description: FIPS 204: Algorithm 42.
* 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
Expand Down
105 changes: 69 additions & 36 deletions crypto/dilithium/pqcrystals_dilithium_ref_common/packing.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
/*************************************************
* Name: pack_pk
*
* Description: Bit-pack public key pk = (rho, t1).
* Description: FIPS 204: Algorithm 22 pkEncode.
* Bit-pack public key pk = (rho, t1).
*
* Arguments: - ml_dsa_params: parameter struct
* - uint8_t pk[]: pointer to output byte array
Expand All @@ -20,18 +21,21 @@ void pack_pk(ml_dsa_params *params,
{
unsigned int i;

for(i = 0; i < SEEDBYTES; ++i)
for(i = 0; i < SEEDBYTES; ++i) {
pk[i] = rho[i];
}
pk += SEEDBYTES;

for(i = 0; i < params->k; ++i)
for(i = 0; i < params->k; ++i) {
polyt1_pack(pk + i*POLYT1_PACKEDBYTES, &t1->vec[i]);
}
}

/*************************************************
* Name: unpack_pk
*
* Description: Unpack public key pk = (rho, t1).
* Description: FIPS 204: Algorithm 23 pkDecode.
* Unpack public key pk = (rho, t1).
*
* Arguments: - ml_dsa_params: parameter struct
* - const uint8_t rho[]: output byte array for rho
Expand All @@ -45,18 +49,21 @@ void unpack_pk(ml_dsa_params *params,
{
unsigned int i;

for(i = 0; i < SEEDBYTES; ++i)
for(i = 0; i < SEEDBYTES; ++i) {
rho[i] = pk[i];
}
pk += SEEDBYTES;

for(i = 0; i < params->k; ++i)
for(i = 0; i < params->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).
* Description: FIPS 204: Algorithm 24 skEncode.
* Bit-pack secret key sk = (rho, tr, key, t0, s1, s2).
*
* Arguments: - ml_dsa_params: parameter struct
* - uint8_t sk[]: pointer to output byte array
Expand All @@ -78,35 +85,41 @@ void pack_sk(ml_dsa_params *params,
{
unsigned int i;

for(i = 0; i < SEEDBYTES; ++i)
for(i = 0; i < SEEDBYTES; ++i) {
sk[i] = rho[i];
}
sk += SEEDBYTES;

for(i = 0; i < SEEDBYTES; ++i)
for(i = 0; i < SEEDBYTES; ++i) {
sk[i] = key[i];
}
sk += SEEDBYTES;

for(i = 0; i < TRBYTES; ++i)
for(i = 0; i < TRBYTES; ++i) {
sk[i] = tr[i];
}
sk += TRBYTES;

for(i = 0; i < params->l; ++i)
for(i = 0; i < params->l; ++i) {
polyeta_pack(params, sk + i * params->poly_eta_packed_bytes, &s1->vec[i]);
}
sk += params->l * params->poly_eta_packed_bytes;


for(i = 0; i < params->k; ++i)
for(i = 0; i < params->k; ++i) {
polyeta_pack(params,sk + i * params->poly_eta_packed_bytes, &s2->vec[i]);
}
sk += params->k * params->poly_eta_packed_bytes;

for(i = 0; i < params->k; ++i)
for(i = 0; i < params->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).
* Description: FIPS 204: Algorithm 25 skDecode.
* Unpack secret key sk = (rho, tr, key, t0, s1, s2).
*
* Arguments: - ml_dsa_params: parameter struct
* - const uint8_t rho[]: output byte array for rho
Expand All @@ -128,34 +141,41 @@ void unpack_sk(ml_dsa_params *params,
{
unsigned int i;

for(i = 0; i < SEEDBYTES; ++i)
for(i = 0; i < SEEDBYTES; ++i) {
rho[i] = sk[i];
}
sk += SEEDBYTES;

for(i = 0; i < SEEDBYTES; ++i)
for(i = 0; i < SEEDBYTES; ++i) {
key[i] = sk[i];
}
sk += SEEDBYTES;

for(i = 0; i < TRBYTES; ++i)
for(i = 0; i < TRBYTES; ++i) {
tr[i] = sk[i];
}
sk += TRBYTES;

for(i=0; i < params->l; ++i)
for(i=0; i < params->l; ++i) {
polyeta_unpack(params, &s1->vec[i], sk + i * params->poly_eta_packed_bytes);
}
sk += params->l * params->poly_eta_packed_bytes;

for(i=0; i < params->k; ++i)
for(i=0; i < params->k; ++i) {
polyeta_unpack(params, &s2->vec[i], sk + i * params->poly_eta_packed_bytes);
}
sk += params->k * params->poly_eta_packed_bytes;

for(i=0; i < params->k; ++i)
for(i=0; i < params->k; ++i) {
polyt0_unpack(&t0->vec[i], sk + i * POLYT0_PACKEDBYTES);
}
}

/*************************************************
* Name: pack_sig
*
* Description: Bit-pack signature sig = (c, z, h).
* Description: FIPS 204: Algorithm 26 sigEncode.
* Bit-pack signature sig = (c, z, h).
*
* Arguments: - ml_dsa_params: parameter struct
* - uint8_t sig[]: pointer to output byte array
Expand All @@ -171,23 +191,28 @@ void pack_sig(ml_dsa_params *params,
{
unsigned int i, j, k;

for(i=0; i < params->c_tilde_bytes; ++i)
for(i=0; i < params->c_tilde_bytes; ++i) {
sig[i] = c[i];
}
sig += params->c_tilde_bytes;

for(i = 0; i < params->l; ++i)
for(i = 0; i < params->l; ++i) {
polyz_pack(params, sig + i * params->poly_z_packed_bytes, &z->vec[i]);
}
sig += params->l * params->poly_z_packed_bytes;

/* Encode h */
for(i = 0; i < params->omega + params->k; ++i)
for(i = 0; i < params->omega + params->k; ++i) {
sig[i] = 0;
}

k = 0;
for(i = 0; i < params->k; ++i) {
for(j = 0; j < N; ++j)
if(h->vec[i].coeffs[j] != 0)
for(j = 0; j < N; ++j) {
if(h->vec[i].coeffs[j] != 0) {
sig[k++] = j;
}
}

sig[params->omega + i] = k;
}
Expand All @@ -196,7 +221,8 @@ void pack_sig(ml_dsa_params *params,
/*************************************************
* Name: unpack_sig
*
* Description: Unpack signature sig = (c, z, h).
* Description: FIPS 204: Algorithm 27 sigDecode.
* Unpack signature sig = (c, z, h).
*
* Arguments: - ml_dsa_params: parameter struct
* - uint8_t *c: pointer to output challenge hash
Expand All @@ -215,36 +241,43 @@ int unpack_sig(ml_dsa_params *params,
{
unsigned int i, j, k;

for(i = 0; i < params->c_tilde_bytes; ++i)
for(i = 0; i < params->c_tilde_bytes; ++i) {
c[i] = sig[i];
}
sig += params->c_tilde_bytes;

for(i = 0; i < params->l; ++i)
for(i = 0; i < params->l; ++i) {
polyz_unpack(params, &z->vec[i], sig + i * params->poly_z_packed_bytes);
}
sig += params->l * params->poly_z_packed_bytes;

/* Decode h */
k = 0;
for(i = 0; i < params->k; ++i) {
for(j = 0; j < N; ++j)
for(j = 0; j < N; ++j) {
h->vec[i].coeffs[j] = 0;
}

if(sig[params->omega + i] < k || sig[params->omega + i] > params->omega)
if(sig[params->omega + i] < k || sig[params->omega + i] > params->omega) {
return 1;
}

for(j = k; j < sig[params->omega + i]; ++j) {
/* Coefficients are ordered for strong unforgeability */
if(j > k && sig[j] <= sig[j-1]) return 1;
if(j > k && sig[j] <= sig[j-1]) {
return 1;
}
h->vec[i].coeffs[sig[j]] = 1;
}

k = sig[params->omega + i];
}

/* Extra indices are zero for strong unforgeability */
for(j = k; j < params->omega; ++j)
if(sig[j])
for(j = k; j < params->omega; ++j) {
if(sig[j]) {
return 1;

}
}
return 0;
}
Loading

0 comments on commit 18cc07d

Please sign in to comment.