Skip to content

Commit

Permalink
v0.4.3 RC1
Browse files Browse the repository at this point in the history
  • Loading branch information
eschorn1 committed Oct 16, 2024
1 parent b398b68 commit abebea1
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 73 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.4.3 (2024-10-XX)
## 0.4.3 (2024-10-16)

- Adapted PrivateKey into PrivateKey and PublicKey into PublicKey, removed the former(s)
- Internal revision to align comments with released spec
- Adapted ExpandedPrivateKey into PrivateKey and ExpandedPublicKey into PublicKey, removed the former(s)
- Internal revision to align comments with released spec; added try_hash_sign (using OS rng)
- Revisit/revise supporting benchmarks, embedded target, dudect, fuzz and wasm functionality
- Fixed a bug in verify relating to non-empty contexts; asserts on all doctests

Expand Down
1 change: 0 additions & 1 deletion benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ pub fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("ml_dsa_44 pk verify", |b| b.iter(|| pk44.verify(&msg, &sig44, &[])));
c.bench_function("ml_dsa_65 pk verify", |b| b.iter(|| pk65.verify(&msg, &sig65, &[])));
c.bench_function("ml_dsa_87 pk verify", |b| b.iter(|| pk87.verify(&msg, &sig87, &[])));

}

criterion_group!(benches, criterion_benchmark);
Expand Down
2 changes: 1 addition & 1 deletion src/encodings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub(crate) fn pk_encode<const K: usize, const PK_LEN: usize>(
pk[32..]
.chunks_mut(32 * blqd)
.enumerate()
.take(K) // not strictly needed
.take(K) // not strictly needed
.for_each(|(i, chunk)| simple_bit_pack(&t1[i], (1 << blqd) - 1, chunk));

// 5: return pk
Expand Down
4 changes: 3 additions & 1 deletion src/hashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,8 @@ pub(crate) fn expand_mask<const L: usize>(gamma1: i32, rho: &[u8; 64], mu: u16)
xof.read(&mut v);

// 5: y[r] ← BitUnpack(v, γ_1 − 1, γ_1)
y[r as usize] = bit_unpack(&v[0..32 * c], gamma1 - 1, gamma1).expect("Alg 34: try_from2 fail");
y[r as usize] =
bit_unpack(&v[0..32 * c], gamma1 - 1, gamma1).expect("Alg 34: try_from2 fail");

// 6: end for
}
Expand All @@ -312,6 +313,7 @@ pub(crate) fn expand_mask<const L: usize>(gamma1: i32, rho: &[u8; 64], mu: u16)
y
}


/// See for example, Algorithm 4 lines 10-22
pub(crate) fn hash_message(message: &[u8], ph: &Ph, phm: &mut [u8; 64]) -> ([u8; 11], usize) {
match ph {
Expand Down
6 changes: 4 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@

// TODO Roadmap
// 1. Improve docs on first/last few algorithms
// 2. Always more testing...
// 2. Several outstanding refactors (mostly down below in this file)
// 3. Always more testing...


// Implements FIPS 204 Module-Lattice-Based Digital Signature Standard.
// See <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf>
Expand Down Expand Up @@ -74,7 +76,7 @@
// Algorithm 49 MontgomeryReduce(a) on page 50 --> helpers.rs
// Types are in types.rs, traits are in traits.rs...

// Note that debug! statements enforce correct program construction and are not involved
// Note that debug_assert! statements enforce correct program construction and are not involved
// in any operational dataflow (so are good fuzz targets). The ensure! statements implement
// conservative dataflow validation. Separately, functions are only generic over security
// parameters that are directly involved in memory allocation (on the stack). Some coding
Expand Down
32 changes: 16 additions & 16 deletions src/ml_dsa.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
// This file implements functionality from FIPS 204 sections 5/6: Key Generation, Signing, Verification

use crate::encodings::{
pk_decode, pk_encode, sig_decode, sig_encode, sk_decode, w1_encode,
};
use crate::encodings::{pk_decode, pk_encode, sig_decode, sig_encode, sk_decode, w1_encode};
use crate::hashing::{expand_a, expand_mask, expand_s, h256_xof, sample_in_ball};
use crate::helpers::{
center_mod, full_reduce32, infinity_norm, mat_vec_mul, mont_reduce, partial_reduce32, to_mont,
add_vector_ntt,
add_vector_ntt, center_mod, full_reduce32, infinity_norm, mat_vec_mul, mont_reduce,
partial_reduce32, to_mont,
};
use crate::high_low::{high_bits, low_bits, make_hint, power2round, use_hint};
use crate::ntt::{inv_ntt, ntt};
Expand All @@ -33,7 +31,7 @@ pub(crate) fn key_gen<
const SK_LEN: usize,
>(
rng: &mut impl CryptoRngCore, eta: i32,
) -> Result<(PublicKey::<K,L>, PrivateKey::<K,L>), &'static str> {
) -> Result<(PublicKey<K, L>, PrivateKey<K, L>), &'static str> {
//
// 1: ξ ← {0,1}^{256} ▷ Choose random seed
let mut xi = [0u8; 32];
Expand Down Expand Up @@ -258,8 +256,6 @@ pub(crate) fn sign<
}




/// Continuation of `verify_start()`. The `lib.rs` wrapper around this will convert `Error()` to false.
#[allow(clippy::too_many_arguments, clippy::similar_names)]
pub(crate) fn verify<
Expand All @@ -270,8 +266,8 @@ pub(crate) fn verify<
const SIG_LEN: usize,
const W1_LEN: usize,
>(
beta: i32, gamma1: i32, gamma2: i32, omega: i32, tau: i32, epk: &PublicKey<K, L>,
m: &[u8], sig: &[u8; SIG_LEN], ctx: &[u8], oid: &[u8], phm: &[u8], nist: bool,
beta: i32, gamma1: i32, gamma2: i32, omega: i32, tau: i32, epk: &PublicKey<K, L>, m: &[u8],
sig: &[u8; SIG_LEN], ctx: &[u8], oid: &[u8], phm: &[u8], nist: bool,
) -> Result<bool, &'static str> {
//
let PublicKey { rho: _, cap_a_hat, tr, t1_d2_hat_mont } = epk;
Expand Down Expand Up @@ -369,7 +365,7 @@ pub(crate) fn key_gen_internal<
const SK_LEN: usize,
>(
eta: i32, xi: &[u8; 32],
) -> (PublicKey::<K,L>, PrivateKey<K,L>) {
) -> (PublicKey<K, L>, PrivateKey<K, L>) {
//
// 1: (rho, rho′, 𝐾) ∈ 𝔹32 × 𝔹64 × 𝔹32 ← H(𝜉||IntegerToBytes(𝑘, 1)||IntegerToBytes(ℓ, 1), 128)
let mut h2 = h256_xof(&[xi, &[K.to_le_bytes()[0]], &[L.to_le_bytes()[0]]]);
Expand All @@ -393,7 +389,8 @@ pub(crate) fn key_gen_internal<
let s_1_hat: [T; L] = ntt(&s_1);
let as1_hat: [T; K] = mat_vec_mul(&cap_a_hat, &s_1_hat);
let t_not_reduced: [R; K] = add_vector_ntt(&inv_ntt(&as1_hat), &s_2);
let t: [R; K] = core::array::from_fn(|k| R(core::array::from_fn(|n| full_reduce32(t_not_reduced[k].0[n]))));
let t: [R; K] =
core::array::from_fn(|k| R(core::array::from_fn(|n| full_reduce32(t_not_reduced[k].0[n]))));

// 6: (t_1, t_0) ← Power2Round(t, d) ▷ Compress t
let (t_1, t_0): ([R; K], [R; K]) = power2round(&t);
Expand Down Expand Up @@ -421,7 +418,7 @@ pub(crate) fn key_gen_internal<

// 2: s_hat_1 ← NTT(s_1)
let s_hat_1_mont: [T; L] = to_mont(&s_1_hat); //ntt(&s_1));
// 3: s_hat_2 ← NTT(s_2)
// 3: s_hat_2 ← NTT(s_2)
let s_hat_2_mont: [T; K] = to_mont(&ntt(&s_2));
// 4: t_hat_0 ← NTT(t_0)
let t_hat_0_mont: [T; K] = to_mont(&ntt(&t_0));
Expand All @@ -440,13 +437,16 @@ pub(crate) fn key_gen_internal<
}




/// Expand the private/secret key by pre-calculating some constants used in the signing process.
/// This is only used in the `try_from_bytes()` deserialization functionality.
/// # Errors
/// Returns an error on malformed private key.
pub(crate) fn expand_private<const CTEST: bool, const K: usize, const L: usize, const SK_LEN: usize>(
pub(crate) fn expand_private<
const CTEST: bool,
const K: usize,
const L: usize,
const SK_LEN: usize,
>(
eta: i32, sk: &[u8; SK_LEN],
) -> Result<PrivateKey<K, L>, &'static str> {
//
Expand Down
31 changes: 2 additions & 29 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ use rand_core::OsRng;

/// The `KeyGen` trait is defined to allow trait objects for keygen.
pub trait KeyGen {
// /// A public key specific to the chosen security parameter set, e.g., ml-dsa-44,
// /// ml-dsa-65 or ml-dsa-87
// type PublicKey;
// /// A private (secret) key specific to the chosen security parameter set, e.g.,
// /// ml-dsa-44, ml-dsa-65 or ml-dsa-87
// type PrivateKey;
/// An expanded public key containing precomputed elements to increase (repeated)
/// verify performance. Derived from the public key.
type PublicKey;
Expand Down Expand Up @@ -108,28 +102,6 @@ pub trait KeyGen {
/// ```
#[must_use]
fn keygen_from_seed(xi: &[u8; 32]) -> (Self::PublicKey, Self::PrivateKey);


// /// Generates an expanded private key from the normal/compressed private key.
// /// This supports improved signing performance. This function operates in constant-time
// /// relative to secret data (which specifically excludes the provided random `rho`
// /// value as it is stored in the public key).
// /// # Errors
// /// This function operates on trusted data - either a private key directly from `keygen()`
// /// or one validated during deserialization. Nonetheless, a `Result<>` is returned for
// /// symmetry which can propagates internal errors.
// fn gen_expanded_private(
// sk: &Self::PrivateKey,
// ) -> Result<Self::PrivateKey, &'static str>;
//
// /// Generates an expanded public key from the normal/compressed public key.
// /// This supports improved verification performance. As this function operates on purely
// /// public data, it need not provide constant-time assurances.
// /// # Errors
// /// This function operates on trusted data - either a public key directly from `keygen()`
// /// or one validated during deserialization. Nonetheless, a `Result<>` is returned for
// /// symmetry which can propagates internal errors.
// fn gen_expanded_public(pk: &Self::PublicKey) -> Result<Self::PublicKey, &'static str>;
}


Expand Down Expand Up @@ -218,7 +190,8 @@ pub trait Signer {
/// Will return an error on rng failure
#[cfg(feature = "default-rng")]
fn try_hash_sign(
&self, message: &[u8], ctx: &[u8], ph: &Ph) -> Result<Self::Signature, &'static str> {
&self, message: &[u8], ctx: &[u8], ph: &Ph,
) -> Result<Self::Signature, &'static str> {
self.try_hash_sign_with_rng(&mut OsRng, message, ctx, ph)
}

Expand Down
28 changes: 8 additions & 20 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,10 @@ pub enum Ph {
}


// /// Correctly sized private key specific to the target security parameter set. <br>
// /// Implements the [`crate::traits::Signer`] and [`crate::traits::SerDes`] trait.
// #[derive(Clone, Zeroize, ZeroizeOnDrop)]
// #[repr(align(8))]
// pub struct PrivateKey<const SK_LEN: usize>(pub(crate) [u8; SK_LEN]);


/// Expanded private key, specific to the target security parameter set, that contains <br>
/// precomputed elements which increase (repeated) signature performance. Implements only
/// the [`crate::traits::Signer`] trait.
/// Private key specific to the target security parameter set that contains
/// precomputed elements which improve signature performance.
///
/// Implements the [`crate::traits::Signer`] and [`crate::traits::SerDes`] traits.
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
#[repr(align(8))]
pub struct PrivateKey<const K: usize, const L: usize> {
Expand All @@ -35,16 +29,10 @@ pub struct PrivateKey<const K: usize, const L: usize> {
}


// /// Correctly sized public key specific to the target security parameter set. <br>
// /// Implements the [`crate::traits::Verifier`] and [`crate::traits::SerDes`] traits.
// #[derive(Clone, Zeroize, ZeroizeOnDrop)]
// #[repr(align(8))]
// pub struct PublicKey<const PK_LEN: usize>(pub(crate) [u8; PK_LEN]);


/// Expanded public key, specific to the target security parameter set, that contains <br>
/// precomputed elements which increase (repeated) verification performance. Implements only
/// the [`crate::traits::Verifier`] traits.
/// Public key specific to the target security parameter set that contains
/// precomputed elements which improve verification performance.
///
/// Implements the [`crate::traits::Verifier`] and [`crate::traits::SerDes`] traits.
#[derive(Clone, Zeroize, ZeroizeOnDrop)]
#[repr(align(8))]
pub struct PublicKey<const K: usize, const L: usize> {
Expand Down

0 comments on commit abebea1

Please sign in to comment.