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

Added FIPS 204 documentation, cleanse intermediate values #2017

Merged
merged 8 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 2 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,8 @@ 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 `reduce.c` that outlines the algorithm specification (including algorithm number) in FIPS 204.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refers to reduce.c instead of rounding.c

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice spot! fixed 0f43f79

- `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.

**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
Loading