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