Skip to content

Commit 24179cc

Browse files
committed
Add proptests for Signature encoding
Ensures encoded signatures can be round tripped successfully, i.e. encoded and then decoded again without errors or panics.
1 parent e7c698a commit 24179cc

File tree

6 files changed

+60
-5
lines changed

6 files changed

+60
-5
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ml-dsa/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ criterion = "0.5.1"
3737
hex = { version = "0.4.3", features = ["serde"] }
3838
hex-literal = "0.4.1"
3939
pkcs8 = { version = "=0.11.0-rc.1", features = ["pem"] }
40+
proptest = "1"
4041
rand = "0.8.5"
4142
serde = { version = "1.0.215", features = ["derive"] }
4243
serde_json = "1.0.132"

ml-dsa/src/hint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ fn use_hint<TwoGamma2: Unsigned>(h: bool, r: Elem) -> Elem {
3333
}
3434
}
3535

36-
#[derive(Clone, PartialEq)]
36+
#[derive(Clone, PartialEq, Debug)]
3737
pub struct Hint<P>(pub Array<Array<bool, U256>, P::K>)
3838
where
3939
P: SignatureParams;

ml-dsa/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@
1717
//! # Quickstart
1818
//!
1919
//! ```
20-
//! use ml_dsa::{MlDsa65, KeyGen};
21-
//! use signature::{Keypair, Signer, Verifier};
20+
//! use ml_dsa::{MlDsa65, KeyGen, signature::{Keypair, Signer, Verifier}};
2221
//!
2322
//! let mut rng = rand::thread_rng();
2423
//! let kp = MlDsa65::key_gen(&mut rng);
@@ -86,10 +85,10 @@ use crate::util::B64;
8685

8786
pub use crate::param::{EncodedSignature, EncodedSigningKey, EncodedVerifyingKey, MlDsaParams};
8887
pub use crate::util::B32;
89-
pub use signature::Error;
88+
pub use signature::{self, Error};
9089

9190
/// An ML-DSA signature
92-
#[derive(Clone, PartialEq)]
91+
#[derive(Clone, PartialEq, Debug)]
9392
pub struct Signature<P: MlDsaParams> {
9493
c_tilde: Array<u8, P::Lambda>,
9594
z: Vector<P::L>,

ml-dsa/tests/sig-encoding.proptest-regressions

Lines changed: 8 additions & 0 deletions
Large diffs are not rendered by default.

ml-dsa/tests/sig-encoding.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use ml_dsa::{signature::Signer, KeyGen, MlDsa44, MlDsa65, MlDsa87, MlDsaParams, Signature, B32};
2+
use proptest::prelude::*;
3+
4+
fn example_signature<P: MlDsaParams>(seed_bytes: &B32) -> Signature<P> {
5+
let keypair = P::key_gen_internal(seed_bytes);
6+
let msg = b"";
7+
keypair.signing_key().sign(msg)
8+
}
9+
10+
prop_compose! {
11+
fn mldsa44_signature()(seed_bytes in any::<[u8; 32]>()) -> Signature<MlDsa44> {
12+
example_signature::<MlDsa44>(seed_bytes.as_ref())
13+
}
14+
}
15+
16+
prop_compose! {
17+
fn mldsa65_signature()(seed_bytes in any::<[u8; 32]>()) -> Signature<MlDsa65> {
18+
example_signature::<MlDsa65>(seed_bytes.as_ref())
19+
}
20+
}
21+
22+
prop_compose! {
23+
fn mldsa87_signature()(seed_bytes in any::<[u8; 32]>()) -> Signature<MlDsa87> {
24+
example_signature::<MlDsa87>(seed_bytes.as_ref())
25+
}
26+
}
27+
28+
proptest! {
29+
#[test]
30+
fn mldsa44_round_trip(sig in mldsa44_signature()) {
31+
let sig_decoded = Signature::<MlDsa44>::decode(&sig.encode());
32+
prop_assert_eq!(Some(sig), sig_decoded);
33+
}
34+
35+
#[test]
36+
fn mldsa65_round_trip(sig in mldsa65_signature()) {
37+
let sig_decoded = Signature::<MlDsa65>::decode(&sig.encode());
38+
prop_assert_eq!(Some(sig), sig_decoded);
39+
}
40+
41+
#[test]
42+
fn mldsa87_round_trip(sig in mldsa87_signature()) {
43+
let sig_decoded = Signature::<MlDsa87>::decode(&sig.encode());
44+
prop_assert_eq!(Some(sig), sig_decoded);
45+
}
46+
}

0 commit comments

Comments
 (0)