Skip to content

Commit 21a7359

Browse files
committed
specific dst and unit tests
1 parent d5604bb commit 21a7359

File tree

4 files changed

+255
-13
lines changed

4 files changed

+255
-13
lines changed

mithril-stm/src/signature_scheme/schnorr_signature/jubjub/poseidon_digest.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,13 @@ use dusk_poseidon::{Domain, Hash};
33

44
use super::{BaseFieldElement, ScalarFieldElement};
55

6-
/// A DST (Domain Separation Tag) to distinguish between use of Poseidon hash
7-
const DST_SIGNATURE: JubjubBase = JubjubBase::from_raw([0u64, 0, 0, 0]);
6+
/// Domain Separation Tag (DST) for the Poseidon hash used in signature contexts.
7+
const DST_SIGNATURE: JubjubBase = JubjubBase::from_raw([
8+
0x5349_474E_5F44_5354, // "SIGN_DST" (ASCII), little-endian u64
9+
0,
10+
0,
11+
0,
12+
]);
813

914
/// Computes a truncated Poseidon digest over the provided base field elements
1015
/// Returns a scalar field element as the digest

mithril-stm/src/signature_scheme/schnorr_signature/signature.rs

Lines changed: 74 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,21 @@ mod tests {
145145
use crate::signature_scheme::{SchnorrSignature, SchnorrSigningKey, SchnorrVerificationKey};
146146

147147
#[test]
148-
fn invalid_sig() {
148+
fn valid_signature_verification() {
149+
let msg = vec![0, 0, 0, 1];
150+
let seed = [0u8; 32];
151+
let mut rng = ChaCha20Rng::from_seed(seed);
152+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
153+
let vk = SchnorrVerificationKey::new_from_signing_key(sk.clone()).unwrap();
154+
155+
let sig = sk.sign(&msg, &mut rng).unwrap();
156+
157+
sig.verify(&msg, &vk)
158+
.expect("Valid signature should verify successfully");
159+
}
160+
161+
#[test]
162+
fn invalid_signature() {
149163
let msg = vec![0, 0, 0, 1];
150164
let msg2 = vec![0, 0, 0, 2];
151165
let seed = [0u8; 32];
@@ -168,26 +182,75 @@ mod tests {
168182
}
169183

170184
#[test]
171-
fn serialize_deserialize_signature() {
185+
fn from_bytes_signature_not_enough_bytes() {
186+
let msg = vec![0u8; 95];
187+
let result = SchnorrSignature::from_bytes(&msg);
188+
result.expect_err("Not enough bytes.");
189+
}
190+
191+
#[test]
192+
fn from_bytes_signature_exact_size() {
172193
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
194+
let msg = vec![1, 2, 3];
195+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
173196

174-
let msg = vec![0, 0, 0, 1];
197+
let sig = sk.sign(&msg, &mut rng).unwrap();
198+
let sig_bytes: [u8; 96] = sig.to_bytes();
199+
200+
let sig_restored = SchnorrSignature::from_bytes(&sig_bytes).unwrap();
201+
assert_eq!(sig, sig_restored);
202+
}
203+
204+
#[test]
205+
fn from_bytes_signature_extra_bytes() {
206+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
207+
let msg = vec![1, 2, 3];
175208
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
176209

177210
let sig = sk.sign(&msg, &mut rng).unwrap();
178211
let sig_bytes: [u8; 96] = sig.to_bytes();
179-
let sig2 = SchnorrSignature::from_bytes(&sig_bytes).unwrap();
180212

181-
assert_eq!(sig, sig2);
213+
let mut extended_bytes = sig_bytes.to_vec();
214+
extended_bytes.extend_from_slice(&[0xFF; 10]);
215+
216+
let sig_restored = SchnorrSignature::from_bytes(&extended_bytes).unwrap();
217+
assert_eq!(sig, sig_restored);
182218
}
183219

184220
#[test]
185-
fn from_bytes_signature_not_enough_bytes() {
186-
let msg = vec![0u8; 95];
221+
fn to_bytes_is_deterministic() {
222+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
223+
let msg = vec![1, 2, 3];
224+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
187225

188-
let result = SchnorrSignature::from_bytes(&msg);
226+
let sig = sk.sign(&msg, &mut rng).unwrap();
189227

190-
result.expect_err("Not enough bytes.");
228+
// Converting to bytes multiple times should give same result
229+
let bytes1 = sig.to_bytes();
230+
let bytes2 = sig.to_bytes();
231+
232+
assert_eq!(bytes1, bytes2);
233+
}
234+
235+
#[test]
236+
fn signature_roundtrip_preserves_verification() {
237+
let mut rng = ChaCha20Rng::from_seed([42u8; 32]);
238+
let msg = vec![5, 6, 7, 8, 9];
239+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
240+
let vk = SchnorrVerificationKey::new_from_signing_key(sk.clone()).unwrap();
241+
242+
// Create and verify original signature
243+
let sig = sk.sign(&msg, &mut rng).unwrap();
244+
sig.verify(&msg, &vk).expect("Original signature should verify");
245+
246+
// Roundtrip through bytes
247+
let sig_bytes = sig.to_bytes();
248+
let sig_restored = SchnorrSignature::from_bytes(&sig_bytes).unwrap();
249+
250+
// Restored signature should still verify
251+
sig_restored
252+
.verify(&msg, &vk)
253+
.expect("Restored signature should verify");
191254
}
192255

193256
mod golden {
@@ -200,8 +263,8 @@ mod tests {
200263
const GOLDEN_JSON: &str = r#"
201264
{
202265
"commitment_point": [143, 53, 198, 62, 178, 1, 88, 253, 21, 92, 100, 13, 72, 180, 198, 127, 39, 175, 102, 69, 147, 249, 244, 224, 122, 121, 248, 68, 217, 242, 158, 113],
203-
"response": [94, 57, 200, 241, 208, 145, 251, 8, 92, 119, 163, 38, 81, 85, 54, 36, 193, 221, 254, 242, 21, 129, 110, 161, 142, 184, 107, 156, 100, 34, 190, 9],
204-
"challenge": [200, 20, 178, 142, 61, 253, 193, 11, 5, 180, 97, 73, 125, 88, 162, 36, 30, 177, 225, 52, 136, 21, 138, 93, 81, 23, 19, 64, 82, 78, 229, 3]
266+
"response": [5, 81, 137, 228, 235, 18, 112, 76, 71, 127, 44, 47, 60, 55, 144, 204, 254, 50, 67, 167, 67, 133, 79, 168, 10, 153, 228, 114, 147, 64, 34, 9],
267+
"challenge": [12, 75, 91, 200, 29, 62, 12, 245, 185, 181, 67, 251, 210, 211, 37, 42, 204, 205, 133, 215, 235, 236, 193, 155, 2, 147, 83, 189, 148, 38, 71, 0]
205268
}"#;
206269

207270
fn golden_value() -> SchnorrSignature {

mithril-stm/src/signature_scheme/schnorr_signature/signing_key.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,72 @@ impl SchnorrSigningKey {
113113

114114
#[cfg(test)]
115115
mod tests {
116+
use rand_chacha::ChaCha20Rng;
117+
use rand_core::SeedableRng;
118+
119+
use crate::signature_scheme::SchnorrSigningKey;
120+
121+
#[test]
122+
fn generate_signing_key() {
123+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
124+
let sk = SchnorrSigningKey::generate(&mut rng);
125+
126+
assert!(sk.is_ok(), "Signing key generation should succeed");
127+
}
128+
129+
#[test]
130+
fn generate_different_keys() {
131+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
132+
let sk1 = SchnorrSigningKey::generate(&mut rng).unwrap();
133+
let sk2 = SchnorrSigningKey::generate(&mut rng).unwrap();
134+
135+
// Keys should be different
136+
assert_ne!(sk1, sk2, "Different keys should be generated");
137+
}
138+
139+
#[test]
140+
fn from_bytes_not_enough_bytes() {
141+
let bytes = vec![0u8; 31];
142+
let result = SchnorrSigningKey::from_bytes(&bytes);
143+
144+
result.expect_err("Should fail with insufficient bytes");
145+
}
146+
147+
#[test]
148+
fn from_bytes_exact_size() {
149+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
150+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
151+
let sk_bytes = sk.to_bytes();
152+
153+
let sk_restored = SchnorrSigningKey::from_bytes(&sk_bytes).unwrap();
154+
155+
assert_eq!(sk, sk_restored);
156+
}
157+
158+
#[test]
159+
fn from_bytes_extra_bytes() {
160+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
161+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
162+
let sk_bytes = sk.to_bytes();
163+
164+
let mut extended_bytes = sk_bytes.to_vec();
165+
extended_bytes.extend_from_slice(&[0xFF; 10]);
166+
167+
let sk_restored = SchnorrSigningKey::from_bytes(&extended_bytes).unwrap();
168+
169+
assert_eq!(sk, sk_restored);
170+
}
171+
172+
#[test]
173+
fn to_bytes_is_deterministic() {
174+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
175+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
176+
177+
let bytes1 = sk.to_bytes();
178+
let bytes2 = sk.to_bytes();
179+
180+
assert_eq!(bytes1, bytes2, "to_bytes should be deterministic");
181+
}
116182

117183
mod golden {
118184

mithril-stm/src/signature_scheme/schnorr_signature/verification_key.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,114 @@ impl SchnorrVerificationKey {
5959

6060
#[cfg(test)]
6161
mod tests {
62+
use rand_chacha::ChaCha20Rng;
63+
use rand_core::SeedableRng;
64+
65+
use crate::signature_scheme::{SchnorrSigningKey, SchnorrVerificationKey};
66+
67+
#[test]
68+
fn create_verification_key_from_signing_key() {
69+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
70+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
71+
72+
let vk = SchnorrVerificationKey::new_from_signing_key(sk);
73+
74+
assert!(
75+
vk.is_ok(),
76+
"Verification key creation should succeed for valid signing key"
77+
);
78+
}
79+
80+
#[test]
81+
fn different_signing_keys_produce_different_verification_keys() {
82+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
83+
let sk1 = SchnorrSigningKey::generate(&mut rng).unwrap();
84+
let sk2 = SchnorrSigningKey::generate(&mut rng).unwrap();
85+
86+
let vk1 = SchnorrVerificationKey::new_from_signing_key(sk1).unwrap();
87+
let vk2 = SchnorrVerificationKey::new_from_signing_key(sk2).unwrap();
88+
89+
assert_ne!(
90+
vk1, vk2,
91+
"Different signing keys should produce different verification keys"
92+
);
93+
}
94+
95+
#[test]
96+
fn same_signing_key_produces_same_verification_key() {
97+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
98+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
99+
100+
let vk1 = SchnorrVerificationKey::new_from_signing_key(sk.clone()).unwrap();
101+
let vk2 = SchnorrVerificationKey::new_from_signing_key(sk).unwrap();
102+
103+
assert_eq!(
104+
vk1, vk2,
105+
"Same signing key should produce same verification key"
106+
);
107+
}
108+
109+
#[test]
110+
fn valid_verification_key_passes_validation() {
111+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
112+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
113+
let vk = SchnorrVerificationKey::new_from_signing_key(sk).unwrap();
114+
115+
let result = vk.is_valid();
116+
117+
assert!(
118+
result.is_ok(),
119+
"Valid verification key should pass validation"
120+
);
121+
}
122+
123+
#[test]
124+
fn from_bytes_not_enough_bytes() {
125+
let bytes = vec![0u8; 31];
126+
let result = SchnorrVerificationKey::from_bytes(&bytes);
127+
128+
result.expect_err("Should fail with insufficient bytes");
129+
}
130+
131+
#[test]
132+
fn from_bytes_exact_size() {
133+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
134+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
135+
let vk = SchnorrVerificationKey::new_from_signing_key(sk).unwrap();
136+
let vk_bytes = vk.to_bytes();
137+
138+
let vk_restored = SchnorrVerificationKey::from_bytes(&vk_bytes).unwrap();
139+
140+
assert_eq!(vk, vk_restored);
141+
}
142+
143+
#[test]
144+
fn from_bytes_extra_bytes() {
145+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
146+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
147+
let vk = SchnorrVerificationKey::new_from_signing_key(sk).unwrap();
148+
let vk_bytes = vk.to_bytes();
149+
150+
let mut extended_bytes = vk_bytes.to_vec();
151+
extended_bytes.extend_from_slice(&[0xFF; 10]);
152+
153+
let vk_restored = SchnorrVerificationKey::from_bytes(&extended_bytes).unwrap();
154+
155+
assert_eq!(vk, vk_restored);
156+
}
157+
158+
#[test]
159+
fn to_bytes_is_deterministic() {
160+
let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
161+
let sk = SchnorrSigningKey::generate(&mut rng).unwrap();
162+
let vk = SchnorrVerificationKey::new_from_signing_key(sk).unwrap();
163+
164+
let bytes1 = vk.to_bytes();
165+
let bytes2 = vk.to_bytes();
166+
167+
assert_eq!(bytes1, bytes2, "to_bytes should be deterministic");
168+
}
169+
62170
mod golden {
63171

64172
use rand_chacha::ChaCha20Rng;

0 commit comments

Comments
 (0)