1pub mod aux;
2pub mod definitions;
3pub mod parameter;
4pub mod reference_impl_private_key;
5mod seed_derive;
6pub mod signing;
7pub mod verify;
8
9use core::{convert::TryFrom, marker::PhantomData};
10use tinyvec::ArrayVec;
11
12use crate::{
13 constants::{MAX_HSS_PUBLIC_KEY_LENGTH, REF_IMPL_MAX_PRIVATE_KEY_SIZE},
14 hss::{aux::hss_is_aux_data_used, reference_impl_private_key::Seed},
15 signature::{Error, SignerMut, Verifier},
16 HashChain, Signature, VerifierSignature,
17};
18
19use self::{
20 definitions::{HssPrivateKey, HssPublicKey, InMemoryHssPublicKey},
21 parameter::HssParameter,
22 reference_impl_private_key::ReferenceImplPrivateKey,
23 signing::{HssSignature, InMemoryHssSignature},
24};
25
26#[derive(Clone, Debug, PartialEq, Eq)]
30pub struct SigningKey<H: HashChain> {
31 pub bytes: ArrayVec<[u8; REF_IMPL_MAX_PRIVATE_KEY_SIZE]>,
32 phantom_data: PhantomData<H>,
33}
34
35impl<H: HashChain> SigningKey<H> {
36 pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
37 let bytes = ArrayVec::try_from(bytes).map_err(|_| Error::new())?;
38
39 Ok(Self {
40 bytes,
41 phantom_data: PhantomData,
42 })
43 }
44
45 pub fn as_slice(&self) -> &[u8] {
46 self.bytes.as_slice()
47 }
48
49 pub fn as_mut_slice(&mut self) -> &mut [u8] {
50 self.bytes.as_mut_slice()
51 }
52
53 pub fn get_lifetime(&self) -> Result<u64, Error> {
54 let rfc_sk = ReferenceImplPrivateKey::from_binary_representation(self.bytes.as_slice())
55 .map_err(|_| Error::new())?;
56
57 let parsed_sk = HssPrivateKey::<H>::from(&rfc_sk, &mut None).map_err(|_| Error::new())?;
58
59 Ok(parsed_sk.get_lifetime())
60 }
61
62 pub fn try_sign_with_aux(
63 &mut self,
64 msg: &[u8],
65 aux_data: Option<&mut &mut [u8]>,
66 ) -> Result<Signature, Error> {
67 let private_key = self.bytes;
68 let mut private_key_update_function = |new_key: &[u8]| {
69 self.bytes.as_mut_slice().copy_from_slice(new_key);
70 Ok(())
71 };
72
73 hss_sign::<H>(
74 msg,
75 private_key.as_slice(),
76 &mut private_key_update_function,
77 aux_data,
78 )
79 }
80}
81
82impl<H: HashChain> SignerMut<Signature> for SigningKey<H> {
83 fn try_sign(&mut self, msg: &[u8]) -> Result<Signature, Error> {
84 self.try_sign_with_aux(msg, None)
85 }
86}
87
88#[derive(Clone, Debug, PartialEq, Eq)]
92pub struct VerifyingKey<H: HashChain> {
93 pub bytes: ArrayVec<[u8; MAX_HSS_PUBLIC_KEY_LENGTH]>,
94 phantom_data: PhantomData<H>,
95}
96
97impl<H: HashChain> VerifyingKey<H> {
98 pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
99 let bytes = ArrayVec::try_from(bytes).map_err(|_| Error::new())?;
100
101 Ok(Self {
102 bytes,
103 phantom_data: PhantomData,
104 })
105 }
106
107 pub fn as_slice(&self) -> &[u8] {
108 self.bytes.as_slice()
109 }
110}
111
112impl<H: HashChain> Verifier<Signature> for VerifyingKey<H> {
113 fn verify(&self, msg: &[u8], signature: &Signature) -> Result<(), Error> {
114 hss_verify::<H>(msg, signature.as_ref(), &self.bytes)
115 }
116}
117
118impl<'a, H: HashChain> Verifier<VerifierSignature<'a>> for VerifyingKey<H> {
119 fn verify(&self, msg: &[u8], signature: &VerifierSignature) -> Result<(), Error> {
120 hss_verify::<H>(msg, signature.as_ref(), &self.bytes)
121 }
122}
123
124pub fn hss_verify<H: HashChain>(
134 message: &[u8],
135 signature: &[u8],
136 public_key: &[u8],
137) -> Result<(), Error> {
138 let signature = InMemoryHssSignature::<H>::new(signature).ok_or_else(Error::new)?;
139 let public_key = InMemoryHssPublicKey::<H>::new(public_key).ok_or_else(Error::new)?;
140
141 crate::hss::verify::verify(&signature, &public_key, message).map_err(|_| Error::new())
142}
143
144pub fn hss_sign<H: HashChain>(
156 message: &[u8],
157 private_key: &[u8],
158 private_key_update_function: &mut dyn FnMut(&[u8]) -> Result<(), ()>,
159 aux_data: Option<&mut &mut [u8]>,
160) -> Result<Signature, Error> {
161 hss_sign_core::<H>(
162 Some(message),
163 None,
164 private_key,
165 private_key_update_function,
166 aux_data,
167 )
168}
169
170#[cfg(feature = "fast_verify")]
171pub fn hss_sign_mut<H: HashChain>(
172 message_mut: &mut [u8],
173 private_key: &[u8],
174 private_key_update_function: &mut dyn FnMut(&[u8]) -> Result<(), ()>,
175 aux_data: Option<&mut &mut [u8]>,
176) -> Result<Signature, Error> {
177 if message_mut.len() <= H::OUTPUT_SIZE.into() {
178 return Err(Error::new());
179 }
180
181 let (_, message_randomizer) = message_mut.split_at(message_mut.len() - H::OUTPUT_SIZE as usize);
182 if !message_randomizer.iter().all(|&byte| byte == 0u8) {
183 return Err(Error::new());
184 }
185
186 hss_sign_core::<H>(
187 None,
188 Some(message_mut),
189 private_key,
190 private_key_update_function,
191 aux_data,
192 )
193}
194
195fn hss_sign_core<H: HashChain>(
196 message: Option<&[u8]>,
197 message_mut: Option<&mut [u8]>,
198 private_key: &[u8],
199 private_key_update_function: &mut dyn FnMut(&[u8]) -> Result<(), ()>,
200 aux_data: Option<&mut &mut [u8]>,
201) -> Result<Signature, Error> {
202 let mut rfc_private_key = ReferenceImplPrivateKey::from_binary_representation(private_key)
203 .map_err(|_| Error::new())?;
204
205 let is_aux_data_used = if let Some(ref aux_data) = aux_data {
206 hss_is_aux_data_used(aux_data)
207 } else {
208 false
209 };
210
211 let parameters = rfc_private_key
212 .compressed_parameter
213 .to::<H>()
214 .map_err(|_| Error::new())?;
215 let mut expanded_aux_data = HssPrivateKey::get_expanded_aux_data(
216 aux_data,
217 &rfc_private_key,
218 parameters[0].get_lms_parameter(),
219 is_aux_data_used,
220 );
221
222 let mut private_key = HssPrivateKey::<H>::from(&rfc_private_key, &mut expanded_aux_data)
223 .map_err(|_| Error::new())?;
224
225 let hss_signature = HssSignature::sign(
226 &mut private_key,
227 message,
228 message_mut,
229 &mut expanded_aux_data,
230 )
231 .map_err(|_| Error::new())?;
232
233 rfc_private_key.increment(&private_key);
235 private_key_update_function(&rfc_private_key.to_binary_representation())
236 .map_err(|_| Error::new())?;
237
238 let hash_iterations = {
239 let mut hash_iterations: u32 = 0;
240 for signed_public_key in hss_signature.signed_public_keys.iter() {
241 hash_iterations += signed_public_key.sig.lmots_signature.hash_iterations as u32;
242 }
243 hash_iterations + hss_signature.signature.lmots_signature.hash_iterations as u32
244 };
245
246 Signature::from_bytes_verbose(&hss_signature.to_binary_representation(), hash_iterations)
247}
248
249pub fn hss_keygen<H: HashChain>(
278 parameters: &[HssParameter<H>],
279 seed: &Seed<H>,
280 aux_data: Option<&mut &mut [u8]>,
281) -> Result<(SigningKey<H>, VerifyingKey<H>), Error> {
282 let private_key =
283 ReferenceImplPrivateKey::generate(parameters, seed).map_err(|_| Error::new())?;
284
285 let hss_public_key = HssPublicKey::from(&private_key, aux_data).map_err(|_| Error::new())?;
286
287 let signing_key = SigningKey::from_bytes(&private_key.to_binary_representation())?;
288 let verifying_key = VerifyingKey::from_bytes(&hss_public_key.to_binary_representation())?;
289 Ok((signing_key, verifying_key))
290}
291
292#[cfg(test)]
293mod tests {
294 use crate::util::helper::test_helper::gen_random_seed;
295 use crate::{
296 constants::{LMS_LEAF_IDENTIFIERS_SIZE, MAX_HASH_SIZE},
297 hasher::{
298 sha256::{Sha256_128, Sha256_192, Sha256_256},
299 shake256::{Shake256_128, Shake256_192, Shake256_256},
300 HashChain,
301 },
302 LmotsAlgorithm, LmsAlgorithm,
303 };
304
305 use super::*;
306
307 #[test]
308 fn update_keypair() {
309 let message = [
310 32u8, 48, 2, 1, 48, 58, 20, 57, 9, 83, 99, 255, 0, 34, 2, 1, 0,
311 ];
312 type H = Sha256_256;
313 let seed = gen_random_seed::<H>();
314
315 let lmots = LmotsAlgorithm::LmotsW4;
316 let lms = LmsAlgorithm::LmsH5;
317 let parameters = [HssParameter::new(lmots, lms)];
318
319 let (mut signing_key, verifying_key) =
320 hss_keygen::<H>(¶meters, &seed, None).expect("Should generate HSS keys");
321
322 let signing_key_const = signing_key.clone();
323
324 let mut update_private_key = |new_key: &[u8]| {
325 signing_key.as_mut_slice().copy_from_slice(new_key);
326 Ok(())
327 };
328
329 let signature = hss_sign::<H>(
330 &message,
331 signing_key_const.as_slice(),
332 &mut update_private_key,
333 None,
334 )
335 .expect("Signing should complete without error.");
336
337 assert!(hss_verify::<H>(&message, signature.as_ref(), verifying_key.as_slice()).is_ok());
338
339 assert_ne!(signing_key.as_slice(), signing_key_const.as_slice());
340 assert_eq!(
341 signing_key.as_slice()[LMS_LEAF_IDENTIFIERS_SIZE..],
342 signing_key_const.as_slice()[LMS_LEAF_IDENTIFIERS_SIZE..]
343 );
344 }
345
346 #[test]
347 fn exhaust_keypair() {
348 let message = [
349 32u8, 48, 2, 1, 48, 58, 20, 57, 9, 83, 99, 255, 0, 34, 2, 1, 0,
350 ];
351 type H = Sha256_256;
352 let seed = gen_random_seed::<H>();
353
354 let lmots = LmotsAlgorithm::LmotsW2;
355 let lms = LmsAlgorithm::LmsH2;
356 let parameters = [HssParameter::new(lmots, lms), HssParameter::new(lmots, lms)];
357
358 let (mut signing_key, verifying_key) =
359 hss_keygen::<H>(¶meters, &seed, None).expect("Should generate HSS keys");
360 let keypair_lifetime = signing_key.get_lifetime().unwrap();
361
362 assert_ne!(
363 signing_key.as_slice()[(REF_IMPL_MAX_PRIVATE_KEY_SIZE - H::OUTPUT_SIZE as usize)..],
364 [0u8; H::OUTPUT_SIZE as usize],
365 );
366
367 for index in 0..keypair_lifetime {
368 assert_eq!(
369 signing_key.as_slice()[..LMS_LEAF_IDENTIFIERS_SIZE],
370 index.to_be_bytes(),
371 );
372 assert_eq!(
373 keypair_lifetime - signing_key.get_lifetime().unwrap(),
374 index
375 );
376
377 let signing_key_const = signing_key.clone();
378
379 let mut update_private_key = |new_key: &[u8]| {
380 signing_key.as_mut_slice().copy_from_slice(new_key);
381 Ok(())
382 };
383
384 let signature = hss_sign::<H>(
385 &message,
386 signing_key_const.as_slice(),
387 &mut update_private_key,
388 None,
389 )
390 .expect("Signing should complete without error.");
391
392 assert!(
393 hss_verify::<H>(&message, signature.as_ref(), verifying_key.as_slice()).is_ok()
394 );
395 }
396 assert_eq!(
397 signing_key.as_slice()[(REF_IMPL_MAX_PRIVATE_KEY_SIZE - H::OUTPUT_SIZE as usize)..],
398 [0u8; H::OUTPUT_SIZE as usize],
399 );
400 }
401
402 #[test]
403 #[should_panic(expected = "Signing should panic!")]
404 fn use_exhausted_keypair() {
405 let message = [
406 32u8, 48, 2, 1, 48, 58, 20, 57, 9, 83, 99, 255, 0, 34, 2, 1, 0,
407 ];
408 type H = Sha256_256;
409 let seed = gen_random_seed::<H>();
410
411 let lmots = LmotsAlgorithm::LmotsW2;
412 let lms = LmsAlgorithm::LmsH2;
413 let parameters = [HssParameter::new(lmots, lms), HssParameter::new(lmots, lms)];
414
415 let (mut signing_key, verifying_key) =
416 hss_keygen::<H>(¶meters, &seed, None).expect("Should generate HSS keys");
417 let keypair_lifetime = signing_key.get_lifetime().unwrap();
418
419 for index in 0..(1u64 + keypair_lifetime) {
420 let signing_key_const = signing_key.clone();
421
422 let mut update_private_key = |new_key: &[u8]| {
423 signing_key.as_mut_slice().copy_from_slice(new_key);
424 Ok(())
425 };
426
427 let signature = hss_sign::<H>(
428 &message,
429 signing_key_const.as_slice(),
430 &mut update_private_key,
431 None,
432 )
433 .unwrap_or_else(|_| {
434 if index < keypair_lifetime {
435 panic!("Signing should complete without error.");
436 } else {
437 assert!(signing_key.get_lifetime().is_err());
438 panic!("Signing should panic!");
439 }
440 });
441
442 assert!(
443 hss_verify::<H>(&message, signature.as_ref(), verifying_key.as_slice()).is_ok()
444 );
445 }
446 }
447
448 #[test]
449 fn keygen_with_forged_aux_data() {
450 type H = Sha256_256;
451 let seed = gen_random_seed::<H>();
452
453 let lmots = LmotsAlgorithm::LmotsW2;
454 let lms = LmsAlgorithm::LmsH5;
455 let parameters = [HssParameter::new(lmots, lms), HssParameter::new(lmots, lms)];
456
457 let mut aux_data = [0u8; 1_000];
458 let aux_slice: &mut &mut [u8] = &mut &mut aux_data[..];
459
460 let (sk1, vk1) =
461 hss_keygen::<H>(¶meters, &seed, Some(aux_slice)).expect("Should generate HSS keys");
462
463 aux_slice[2 * MAX_HASH_SIZE - 1] ^= 0x1;
464
465 let (sk2, vk2) =
466 hss_keygen::<H>(¶meters, &seed, Some(aux_slice)).expect("Should generate HSS keys");
467
468 assert_eq!(sk1, sk2);
469 assert_eq!(vk1, vk2);
470 }
471
472 #[test]
473 fn test_signing_sha256_128() {
474 test_signing_core::<Sha256_128>();
475 }
476
477 #[test]
478 fn test_signing_sha256_192() {
479 test_signing_core::<Sha256_192>();
480 }
481
482 #[test]
483 fn test_signing_sha256_256() {
484 test_signing_core::<Sha256_256>();
485 }
486
487 #[test]
488 fn test_signing_shake256_128() {
489 test_signing_core::<Shake256_128>();
490 }
491
492 #[test]
493 fn test_signing_shake256_192() {
494 test_signing_core::<Shake256_192>();
495 }
496
497 #[test]
498 fn test_signing_shake256_256() {
499 test_signing_core::<Shake256_256>();
500 }
501
502 fn test_signing_core<H: HashChain>() {
503 let seed = gen_random_seed::<H>();
504 let (mut signing_key, verifying_key) = hss_keygen::<H>(
505 &[
506 HssParameter::construct_default_parameters(),
507 HssParameter::construct_default_parameters(),
508 HssParameter::construct_default_parameters(),
509 ],
510 &seed,
511 None,
512 )
513 .expect("Should generate HSS keys");
514
515 let message_values = [
516 32u8, 48, 2, 1, 48, 58, 20, 57, 9, 83, 99, 255, 0, 34, 2, 1, 0,
517 ];
518 let mut message = [0u8; 64];
519 message[..message_values.len()].copy_from_slice(&message_values);
520
521 let signing_key_const = signing_key.clone();
522
523 let mut update_private_key = |new_key: &[u8]| {
524 signing_key.as_mut_slice().copy_from_slice(new_key);
525 Ok(())
526 };
527
528 let signature = hss_sign::<H>(
529 &message,
530 signing_key_const.as_slice(),
531 &mut update_private_key,
532 None,
533 )
534 .expect("Signing should complete without error.");
535
536 assert!(hss_verify::<H>(&message, signature.as_ref(), verifying_key.as_slice(),).is_ok());
537
538 message[0] = 33;
539
540 assert!(hss_verify::<H>(&message, signature.as_ref(), verifying_key.as_slice(),).is_err());
541 }
542
543 #[cfg(feature = "fast_verify")]
544 #[test]
545 fn test_signing_fast_verify() {
546 type H = Sha256_256;
547 let seed = gen_random_seed::<H>();
548
549 let (mut signing_key, verifying_key) = hss_keygen::<H>(
550 &[
551 HssParameter::construct_default_parameters(),
552 HssParameter::construct_default_parameters(),
553 HssParameter::construct_default_parameters(),
554 ],
555 &seed,
556 None,
557 )
558 .expect("Should generate HSS keys");
559
560 let message_values = [
561 32u8, 48, 2, 1, 48, 58, 20, 57, 9, 83, 99, 255, 0, 34, 2, 1, 0,
562 ];
563 let mut message = [0u8; 64];
564 message[..message_values.len()].copy_from_slice(&message_values);
565
566 let signing_key_const = signing_key.clone();
567
568 let mut update_private_key = |new_key: &[u8]| {
569 signing_key.as_mut_slice().copy_from_slice(new_key);
570 Ok(())
571 };
572
573 let signature = hss_sign_mut::<H>(
574 &mut message,
575 signing_key_const.as_slice(),
576 &mut update_private_key,
577 None,
578 )
579 .expect("Signing should complete without error.");
580
581 assert!(H::OUTPUT_SIZE == MAX_HASH_SIZE as u16);
582 assert_ne!(
583 message[(message.len() - MAX_HASH_SIZE)..],
584 [0u8; MAX_HASH_SIZE]
585 );
586
587 assert!(hss_verify::<H>(&message, signature.as_ref(), verifying_key.as_slice()).is_ok());
588 }
589}