Skip to content

Commit

Permalink
v0.4.0 RC1
Browse files Browse the repository at this point in the history
  • Loading branch information
eschorn1 committed Sep 29, 2024
1 parent 39803c9 commit 27de0e0
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 26 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ 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.0 (2024-09-32)
## 0.4.0 (2024-09-29)

- Now aligned with **released** FIPS 204 including hash sig/verif and keygen with seed.

Expand Down
25 changes: 14 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
![Apache2/MIT licensed][license-image]
![Rust Version][rustc-image]

[FIPS 204] Module-Lattice-Based Digital Signature Standard written in pure Rust for server,
[FIPS 204] Module-Lattice-Based Digital Signature Standard written in pure/safe Rust for server,
desktop, browser and embedded applications. The source repository includes examples demonstrating benchmarking,
an embedded target, constant-time statistical measurements, fuzzing, and WASM execution.

This crate implements the FIPS 204 **released** standard in pure Rust with minimal and mainstream dependencies, **and
without any unsafe code**. All three security parameter sets are fully functional and tested. The implementation's
key generation and signature functionality operates in constant-time, does not require the standard library, e.g.
This crate implements the FIPS 204 **released** standard in pure Rust with minimal and mainstream dependencies, and
without any unsafe code. All three security parameter sets are fully functional and tested. The implementation's
key- and signature-generation functionality operates in constant-time, does not require the standard library, e.g.
`#[no_std]`, has no heap allocations, e.g. no `alloc` needed, and exposes the `RNG` so it is suitable for the full
range of applications down to the bare-metal. The API is stabilized and the code is heavily biased towards safety
and correctness; further performance optimizations will be implemented as the standard matures. This crate will
Expand All @@ -34,16 +34,19 @@ let message = [0u8, 1, 2, 3, 4, 5, 6, 7];

// Generate key pair and signature
let (pk1, sk) = ml_dsa_44::try_keygen()?; // Generate both public and secret keys
let sig = sk.try_sign(&message, &[0])?; // Use the secret key to generate a message signature
let sig = sk.try_sign(&message, &[])?; // Use the secret key to generate a message signature

// Serialize then send the public key, message and signature
let (pk_send, msg_send, sig_send) = (pk1.into_bytes(), message, sig);
let (pk_recv, msg_recv, sig_recv) = (pk_send, msg_send, sig_send);

// Deserialize the public key and signature, then verify the message
let pk2 = ml_dsa_44::PublicKey::try_from_bytes(pk_recv)?;
let v = pk2.verify(&msg_recv, &sig_recv, &[0]); // Use the public to verify message signature
let v = pk2.verify(&msg_recv, &sig_recv, &[]); // Use the public to verify message signature
assert!(v);

// Note that the last argument to sign() and verify() is the (NIST specified) context
// value which is typically empty for basic signature generation and verification.
# }
# Ok(())
# }
Expand All @@ -54,13 +57,13 @@ The Rust [Documentation][docs-link] lives under each **Module** corresponding to

## Notes

* This crate is fully functional and corresponds to FIPS 204 (August 13, 2024).
* This crate is fully functional and corresponds to the final released FIPS 204 (August 13, 2024).
* **BEWARE:** As of September 27, 2024 NIST has not released external/hash test vectors!
* Constant-time assurances target the source-code level only on MSRV, with confirmation via
* Constant-time assurances target the source-code level only, with confirmation via
manual review/inspection, the embedded target, and the `dudect` dynamic tests.
* Note that FIPS 204 places specific requirements on randomness per section 3.5.1, hence the exposed `RNG`.
* Requires Rust **1.70** or higher. The minimum supported Rust version may be changed in the future, but
it will be done with a minor version bump (when the major version is larger than 0)..
it will be done with a minor version bump (when the major version is larger than 0).
* All on-by-default features of this library are covered by `SemVer`.
* The FIPS 204 standard and this software should be considered experimental -- USE AT YOUR OWN RISK!

Expand All @@ -76,7 +79,7 @@ defined in the Apache-2.0 license, shall be dual licensed as above, without any

[//]: # (badges)

[crate-image]: https://buildstats.info/crate/fips204
[crate-image]: https://img.shields.io/crates/v/fips204
[crate-link]: https://crates.io/crates/fips204
[docs-image]: https://docs.rs/fips204/badge.svg
[docs-link]: https://docs.rs/fips204/
Expand All @@ -88,4 +91,4 @@ defined in the Apache-2.0 license, shall be dual licensed as above, without any
[//]: # (general links)

[IntegrityChain]: https://github.com/integritychain/
[FIPS 204]: https://csrc.nist.gov/pubs/fips/204/ipd
[FIPS 204]: https://csrc.nist.gov/pubs/fips/204/final
8 changes: 5 additions & 3 deletions src/hashing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@ pub(crate) fn sample_in_ball<const CTEST: bool>(tau: i32, rho: &[u8]) -> R {

// 6: for 𝑖 from 256 − 𝜏 to 255 do
for i in (256 - tau)..=255 {
//
// 7: (ctx, 𝑗) ← H.Squeeze(ctx, 1)
let mut j = [i.to_le_bytes()[0]]; // remove timing variability
if !CTEST { h_ctx.read(&mut j) }; // ..
let mut j = [i.to_le_bytes()[0]]; // remove timing variability
if !CTEST {
h_ctx.read(&mut j);
};

// 8: while 𝑗 > 𝑖 do
while usize::from(j[0]) > i {
Expand Down Expand Up @@ -286,7 +289,6 @@ pub(crate) fn expand_mask<const L: usize>(gamma1: i32, rho: &[u8; 64], mu: u16)
for r in 0..u16::try_from(L).expect("cannot fail") {
//
// 3: n ← IntegerToBits(µ + r, 16)
// debug_assert!((mu + r < 1024), "Alg 28: mu + r out of range"); // arbitrary limit not needed
let n = mu + r; // This will perform overflow check in debug, which removes need for above assert

// 4: v ← (H(ρ || n)[[32rc]], H(ρ || n)[[32rc+1]], ..., H(ρ || n)[[32rc+32c − 1]])
Expand Down
4 changes: 1 addition & 3 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,7 @@ pub(crate) const fn full_reduce32(a: i32) -> i32 {

// Note: this is only used on 'fixed' security parameters (not secret values), so as not to impact CT
/// Bit length required to express `a` in bits
pub(crate) const fn bit_length(x: i32) -> usize {
x.ilog2() as usize + 1
}
pub(crate) const fn bit_length(x: i32) -> usize { x.ilog2() as usize + 1 }


/// Mod +/- see definition on page 6.
Expand Down
8 changes: 5 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
//
#![doc = include_str!("../README.md")]

// TODO: Internal code comment alignment with release spec is underway...

// Implements FIPS 204 Module-Lattice-Based Digital Signature Standard.
// See <https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.204.pdf>

Expand Down Expand Up @@ -453,9 +455,9 @@ macro_rules! functionality {

#[deprecated = "Temporary function to allow application of internal nist vectors; will be removed"]
/// As of Sep 22 2024, the NIST test vectors are applied to the **internal** functions rather than
/// the external API. T
/// the external API.
///
/// he primary difference pertains to the prepending of domain, context, OID and
/// The primary difference pertains to the prepending of domain, context, OID and
/// hash information to the message in the `sign_finish()` and `verify_finish()` functions (follow
/// the last `nist=true` function argument). This is expected to change such that the full API can
/// be robustly tested - when this happens, this function will no longer be needed.
Expand Down Expand Up @@ -510,7 +512,7 @@ macro_rules! functionality {
/// [`ml_dsa_44::PrivateKey`] struct implements the [`traits::Signer`] trait which supplies a variety of
/// functions to sign byte-array messages, such as [`traits::Signer::try_sign()`].
///
/// **2)** Both of the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait
/// **2)** Both of the `PrivateKey` and `PublicKey` structs implement the [`traits::SerDes`] trait.
/// The originator utilizes the [`traits::SerDes::into_bytes()`] functions to serialize the structs
/// into byte-arrays for storage and/or transmission, similar to the message. Upon retrieval and/or receipt,
/// the remote party utilizes the [`traits::SerDes::try_from_bytes()`] functions to deserialize the
Expand Down
18 changes: 13 additions & 5 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ pub trait KeyGen {
/// # Ok(())}
/// ```
#[must_use]
fn keygen_from_seed(_xi: &[u8; 32]) -> (Self::PublicKey, Self::PrivateKey);
fn keygen_from_seed(xi: &[u8; 32]) -> (Self::PublicKey, Self::PrivateKey);


/// Generates an expanded private key from the normal/compressed private key.
Expand Down Expand Up @@ -202,7 +202,14 @@ pub trait Signer {
&self, rng: &mut impl CryptoRngCore, message: &[u8], ctx: &[u8],
) -> Result<Self::Signature, &'static str>;

/// TKTKT placeholder
/// Attempt to sign the hash of the given message, returning a digital signature on success,
/// or an error if something went wrong. This function utilizes the **provided** random number
/// generator and allows for several hash algorithms. This function operates in constant-time
/// relative to secret data (which specifically excludes the provided random number generator
/// internals, the `rho` value (also) stored in the public key, the hash-derived `rho_prime`
/// value that is rejection-sampled/expanded into the internal `s_1` and `s_2` values, and the
/// main signing rejection loop as noted in section 5.5 of
/// <https://pq-crystals.org/dilithium/data/dilithium-specification-round3-20210208.pdf>.
/// # Errors
/// Will return an error on rng failure
fn try_hash_sign_with_rng(
Expand All @@ -217,8 +224,8 @@ pub trait Verifier {
/// or ml-dsa-87
type Signature;

/// Verifies a digital signature with respect to a `PublicKey`. As this function operates on
/// purely public data, it need/does not provide constant-time assurances.
/// Verifies a digital signature on a message with respect to a `PublicKey`. As this function
/// operates on purely public data, it need/does not provide constant-time assurances.
/// # Examples
/// ```rust
/// # use std::error::Error;
Expand All @@ -238,7 +245,8 @@ pub trait Verifier {
/// ```
fn verify(&self, message: &[u8], signature: &Self::Signature, ctx: &[u8]) -> bool;

/// TKTK placeholder
/// Verifies a digital signature on the hash of a message with respect to a `PublicKey`. As this
/// function operates on purely public data, it need/does not provide constant-time assurances.
fn hash_verify(&self, message: &[u8], sig: &Self::Signature, ctx: &[u8], ph: &Ph) -> bool;
}

Expand Down

0 comments on commit 27de0e0

Please sign in to comment.