Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 3 additions & 2 deletions ml-dsa/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn use_hint<TwoGamma2: Unsigned>(h: bool, r: Elem) -> Elem {
}
}

#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, Debug)]
pub struct Hint<P>(pub Array<Array<bool, U256>, P::K>)
where
P: SignatureParams;
Expand Down Expand Up @@ -116,7 +116,7 @@ where
}

fn monotonic(a: &[usize]) -> bool {
a.iter().enumerate().all(|(i, x)| i == 0 || a[i - 1] < *x)
a.iter().enumerate().all(|(i, x)| i == 0 || a[i - 1] <= *x)
}

pub fn bit_unpack(y: &EncodedHint<P>) -> Option<Self> {
Expand All @@ -138,6 +138,7 @@ where
let indices = &indices[start..end];

if !Self::monotonic(indices) {
println!("indices not monotonic: {:?}", indices);
return None;
}

Expand Down
62 changes: 60 additions & 2 deletions ml-dsa/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![no_std]
// XXX #![no_std]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg",
Expand Down Expand Up @@ -89,7 +89,7 @@ pub use crate::util::B32;
pub use signature::Error;

/// An ML-DSA signature
#[derive(Clone, PartialEq)]
#[derive(Clone, PartialEq, Debug)]
pub struct Signature<P: MlDsaParams> {
c_tilde: Array<u8, P::Lambda>,
z: Vector<P::L>,
Expand Down Expand Up @@ -899,4 +899,62 @@ mod test {
sign_verify_round_trip_test::<MlDsa65>();
sign_verify_round_trip_test::<MlDsa87>();
}

fn many_round_trip_test<P>()
where
P: MlDsaParams,
{
use rand::Rng;

const ITERATIONS: usize = 1000;

let mut rng = rand::thread_rng();
let mut seed = B32::default();

for _i in 0..ITERATIONS {
let seed_data: &mut [u8] = seed.as_mut();
rng.fill(seed_data);

let kp = P::key_gen_internal(&seed);
let sk = kp.signing_key;
let vk = kp.verifying_key;

let M = b"Hello world";
let rnd = Array([0u8; 32]);
let sig = sk.sign_internal(&[M], &rnd);

let sig_enc = sig.encode();
let sig_dec = Signature::<P>::decode(&sig_enc).unwrap();

assert_eq!(sig_dec, sig);
assert!(vk.verify_internal(&[M], &sig));
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps consider proptest for these sorts of tests.

You can look at https://github.com/RustCrypto/crypto-bigint/tree/master/tests for some examples.

(Or I can try to convert them to proptests as a followup)

Copy link
Member

Choose a reason for hiding this comment

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

Note: tried doing this myself and it's a tad tricky due to the use of generics

Copy link
Member

Choose a reason for hiding this comment

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

Okay, found an okay enough solution and opened a PR to add proptests: #896

It also required adding a Debug impl for Signature as this PR does also.

It was able to find some failures right away, though I did see many_round_trip_test find failures with this PR's current state that the proptests did not (but perhaps they just need to be run more).


#[test]
fn many_round_trip() {
many_round_trip_test::<MlDsa44>();
many_round_trip_test::<MlDsa65>();
many_round_trip_test::<MlDsa87>();
}

#[test]
fn encode_decode_fail() {
use signature::Signer;

const SEED: [u8; 32] = [
197, 185, 159, 59, 216, 233, 208, 40, 244, 4, 182, 73, 109, 244, 205, 113, 116, 55,
206, 145, 214, 205, 247, 130, 41, 113, 93, 14, 140, 194, 191, 232,
];
const MESSAGE: &[u8] = b"There seems to be a round tripping issue somewhere in here";

let mut seed = B32::default();
seed.0.copy_from_slice(&SEED);

let seed = SEED.into();
let kp = MlDsa65::key_gen_internal(&seed);
let sig = kp.signing_key().sign(MESSAGE);
let sig_enc = sig.encode();
let _sig = Signature::<MlDsa65>::decode(&sig_enc).unwrap();
}
}
Loading