slh_dsa_sign_verify/
slh_dsa_sign_verify.rs1use quantica::slh_dsa::*;
27use std::time::Instant;
28
29fn hex(bytes: &[u8]) -> String {
31 bytes.iter().map(|b| format!("{:02x}", b)).collect()
32}
33
34fn main() {
35 println!("=== SLH-DSA (FIPS 205) Sign / Verify Example ===\n");
36
37 let mut rng = OsRng;
38
39 let t0 = Instant::now();
45 let (sk, pk) = SlhDsa::<Shake128f>::keygen(&mut rng).expect("keygen failed");
46 let keygen_us = t0.elapsed().as_micros();
47
48 println!("--- Key Generation (SLH-DSA-SHAKE-128f) ---");
49 println!(" secret key: {} bytes", sk.len());
50 println!(" public key: {} bytes", pk.len());
51 println!(" pk (hex): {}", hex(&pk));
52 println!(" time: {} us", keygen_us);
53 println!();
54
55 let message = b"Hash-based signatures: conservative post-quantum security.";
62
63 let t0 = Instant::now();
64 let sig = SlhDsa::<Shake128f>::sign(message, b"", &sk, &mut rng).expect("sign failed");
65 let sign_ms = t0.elapsed().as_millis();
66
67 println!("--- Signing ---");
68 println!(" message: {:?}", std::str::from_utf8(message).unwrap());
69 println!(" signature: {} bytes", sig.len());
70 println!(" sig[0..32]: {}", hex(&sig[..32]));
71 println!(" time: {} ms", sign_ms);
72 println!();
73
74 let t0 = Instant::now();
78 let valid = SlhDsa::<Shake128f>::verify(message, b"", &sig, &pk).expect("verify call failed");
79 let verify_ms = t0.elapsed().as_millis();
80
81 println!("--- Verification ---");
82 println!(" valid: {}", valid);
83 println!(" time: {} ms", verify_ms);
84 assert!(valid, "Signature should be valid!");
85 println!();
86
87 let mut tampered_bytes = sig.as_bytes().to_vec();
91 tampered_bytes[100] ^= 0x01;
92 let tampered_sig = quantica::slh_dsa::Signature::<Shake128f>::from_bytes(&tampered_bytes).expect("from_bytes");
93
94 let tampered_valid = SlhDsa::<Shake128f>::verify(message, b"", &tampered_sig, &pk).expect("verify call failed");
95
96 println!("--- Tamper Test ---");
97 println!(" flipped bit in sig[100]");
98 println!(" valid: {} (expected: false)", tampered_valid);
99 assert!(!tampered_valid, "Tampered signature should be rejected!");
100 println!();
101
102 println!("--- SLH-DSA Signature Sizes (SHAKE-based) ---");
106 println!(
107 " SHAKE-128f: sig={:>5} bytes, pk={:>2}, sk={:>3}",
108 SlhDsa::<Shake128f>::signature_size(),
109 SlhDsa::<Shake128f>::public_key_size(),
110 SlhDsa::<Shake128f>::secret_key_size(),
111 );
112 println!(
113 " SHAKE-128s: sig={:>5} bytes, pk={:>2}, sk={:>3}",
114 SlhDsa::<Shake128s>::signature_size(),
115 SlhDsa::<Shake128s>::public_key_size(),
116 SlhDsa::<Shake128s>::secret_key_size(),
117 );
118 println!(
119 " SHAKE-192f: sig={:>5} bytes, pk={:>2}, sk={:>3}",
120 SlhDsa::<Shake192f>::signature_size(),
121 SlhDsa::<Shake192f>::public_key_size(),
122 SlhDsa::<Shake192f>::secret_key_size(),
123 );
124 println!(
125 " SHAKE-192s: sig={:>5} bytes, pk={:>2}, sk={:>3}",
126 SlhDsa::<Shake192s>::signature_size(),
127 SlhDsa::<Shake192s>::public_key_size(),
128 SlhDsa::<Shake192s>::secret_key_size(),
129 );
130 println!(
131 " SHAKE-256f: sig={:>5} bytes, pk={:>2}, sk={:>3}",
132 SlhDsa::<Shake256f>::signature_size(),
133 SlhDsa::<Shake256f>::public_key_size(),
134 SlhDsa::<Shake256f>::secret_key_size(),
135 );
136 println!(
137 " SHAKE-256s: sig={:>5} bytes, pk={:>2}, sk={:>3}",
138 SlhDsa::<Shake256s>::signature_size(),
139 SlhDsa::<Shake256s>::public_key_size(),
140 SlhDsa::<Shake256s>::secret_key_size(),
141 );
142 println!();
143
144 println!("All checks passed.");
145}