#![forbid(unsafe_code)]
#![cfg_attr(not(feature = "std"), no_std)]
extern crate core;
mod constants;
mod hasher;
mod hss;
mod lm_ots;
mod lms;
mod util;
pub use signature::{self};
#[doc(hidden)]
pub use crate::constants::MAX_HASH_SIZE;
#[doc(hidden)]
pub use crate::hss::reference_impl_private_key::Seed;
pub use crate::hasher::{
sha256::{Sha256_128, Sha256_192, Sha256_256},
shake256::{Shake256_128, Shake256_192, Shake256_256},
HashChain, HashChainData,
};
pub use crate::hss::parameter::HssParameter;
pub use crate::lm_ots::parameters::LmotsAlgorithm;
pub use crate::lms::parameters::LmsAlgorithm;
pub use crate::hss::hss_keygen as keygen;
pub use crate::hss::hss_sign as sign;
#[cfg(feature = "fast_verify")]
pub use crate::hss::hss_sign_mut as sign_mut;
pub use crate::hss::hss_verify as verify;
pub use crate::hss::{SigningKey, VerifyingKey};
use core::convert::TryFrom;
use signature::Error;
use tinyvec::ArrayVec;
use constants::MAX_HSS_SIGNATURE_LENGTH;
#[derive(Debug)]
pub struct Signature {
bytes: ArrayVec<[u8; MAX_HSS_SIGNATURE_LENGTH]>,
#[cfg(feature = "verbose")]
pub hash_iterations: u32,
}
impl Signature {
pub(crate) fn from_bytes_verbose(bytes: &[u8], _hash_iterations: u32) -> Result<Self, Error> {
let bytes = ArrayVec::try_from(bytes).map_err(|_| Error::new())?;
Ok(Self {
bytes,
#[cfg(feature = "verbose")]
hash_iterations: _hash_iterations,
})
}
}
impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
self.bytes.as_ref()
}
}
impl signature::Signature for Signature {
fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
Signature::from_bytes_verbose(bytes, 0)
}
}
#[derive(Debug)]
pub struct VerifierSignature<'a> {
bytes: &'a [u8],
}
#[allow(dead_code)]
impl<'a> VerifierSignature<'a> {
pub fn from_ref(bytes: &'a [u8]) -> Result<Self, Error> {
Ok(Self { bytes })
}
}
impl<'a> AsRef<[u8]> for VerifierSignature<'a> {
fn as_ref(&self) -> &'a [u8] {
self.bytes
}
}
impl<'a> signature::Signature for VerifierSignature<'a> {
fn from_bytes(_bytes: &[u8]) -> Result<Self, Error> {
Err(Error::new())
}
}
#[cfg(test)]
mod tests {
use crate::{keygen, HssParameter, LmotsAlgorithm, LmsAlgorithm, Sha256_256};
use crate::{
signature::{SignerMut, Verifier},
SigningKey, VerifierSignature, VerifyingKey,
};
use crate::util::helper::test_helper::gen_random_seed;
#[test]
fn get_signing_and_verifying_key() {
type H = Sha256_256;
let seed = gen_random_seed::<H>();
let (signing_key, verifying_key) = keygen::<H>(
&[HssParameter::new(
LmotsAlgorithm::LmotsW2,
LmsAlgorithm::LmsH5,
)],
&seed,
None,
)
.unwrap();
let _: SigningKey<H> = signing_key;
let _: VerifyingKey<H> = verifying_key;
}
#[test]
fn signature_trait() {
let message = [
32u8, 48, 2, 1, 48, 58, 20, 57, 9, 83, 99, 255, 0, 34, 2, 1, 0,
];
type H = Sha256_256;
let seed = gen_random_seed::<H>();
let (mut signing_key, verifying_key) = keygen::<H>(
&[
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
HssParameter::new(LmotsAlgorithm::LmotsW2, LmsAlgorithm::LmsH5),
],
&seed,
None,
)
.unwrap();
let signature = signing_key.try_sign(&message).unwrap();
assert!(verifying_key.verify(&message, &signature).is_ok());
let ref_signature = VerifierSignature::from_ref(signature.as_ref()).unwrap();
assert!(verifying_key.verify(&message, &ref_signature).is_ok());
}
}