use crate::{
PrivateKey,
PrivateKeyGenerator,
PublicKey,
RecoverableSignature,
Signature,
};
use iota_crypto_preview::Sponge;
use iota_ternary_preview::{
TritBuf,
Trits,
};
use std::marker::PhantomData;
#[derive(Default)]
pub struct MssPrivateKeyGeneratorBuilder<S, G> {
depth: Option<u8>,
generator: Option<G>,
_sponge: PhantomData<S>,
}
pub struct MssPrivateKeyGenerator<S, G> {
depth: u8,
generator: G,
_sponge: PhantomData<S>,
}
pub struct MssPrivateKey<S, K> {
depth: u8,
index: u64,
keys: Vec<K>,
tree: TritBuf,
_sponge: PhantomData<S>,
}
pub struct MssPublicKey<S, K> {
state: TritBuf,
depth: u8,
_sponge: PhantomData<S>,
_key: PhantomData<K>,
}
pub struct MssSignature<S> {
state: TritBuf,
index: u64,
_sponge: PhantomData<S>,
}
#[derive(Debug, PartialEq)]
pub enum MssError {
InvalidDepth(u8),
MissingDepth,
MissingGenerator,
FailedUnderlyingPrivateKeyGeneration,
FailedUnderlyingPublicKeyGeneration,
FailedUnderlyingSignatureGeneration,
FailedUnderlyingPublicKeyRecovery,
FailedSpongeOperation,
}
impl<S, G> MssPrivateKeyGeneratorBuilder<S, G>
where
S: Sponge + Default,
G: PrivateKeyGenerator,
{
pub fn depth(mut self, depth: u8) -> Self {
self.depth = Some(depth);
self
}
pub fn generator(mut self, generator: G) -> Self {
self.generator = Some(generator);
self
}
pub fn build(self) -> Result<MssPrivateKeyGenerator<S, G>, MssError> {
let depth = match self.depth {
Some(depth) => match depth {
0..=20 => depth,
_ => Err(MssError::InvalidDepth(depth))?,
},
None => Err(MssError::MissingDepth)?,
};
let generator = self.generator.ok_or(MssError::MissingGenerator)?;
Ok(MssPrivateKeyGenerator {
depth: depth,
generator: generator,
_sponge: PhantomData,
})
}
}
impl<S, G> PrivateKeyGenerator for MssPrivateKeyGenerator<S, G>
where
S: Sponge + Default,
G: PrivateKeyGenerator,
<<<G as PrivateKeyGenerator>::PrivateKey as PrivateKey>::PublicKey as PublicKey>::Signature: RecoverableSignature,
{
type Seed = G::Seed;
type PrivateKey = MssPrivateKey<S, G::PrivateKey>;
type Error = MssError;
fn generate(&self, seed: &Self::Seed, _: u64) -> Result<Self::PrivateKey, Self::Error> {
let mut sponge = S::default();
let mut keys = Vec::new();
let mut tree = TritBuf::zeros(((1 << self.depth) - 1) * 243);
for key_index in 0..(1 << (self.depth - 1)) {
let ots_private_key = self
.generator
.generate(seed, key_index)
.map_err(|_| Self::Error::FailedUnderlyingPrivateKeyGeneration)?;
let ots_public_key = ots_private_key
.generate_public_key()
.map_err(|_| Self::Error::FailedUnderlyingPublicKeyGeneration)?;
let tree_index = ((1 << (self.depth - 1)) + key_index - 1) as usize;
keys.push(ots_private_key);
tree[tree_index * 243..(tree_index + 1) * 243].copy_from(ots_public_key.trits());
}
for depth in (0..self.depth - 1).rev() {
for i in 0..(1 << depth) {
let index = (1 << depth) + i - 1;
let left_index = index * 2 + 1;
let right_index = left_index + 1;
sponge
.absorb(&tree[left_index * 243..(left_index + 1) * 243])
.map_err(|_| Self::Error::FailedSpongeOperation)?;
sponge
.absorb(&tree[right_index * 243..(right_index + 1) * 243])
.map_err(|_| Self::Error::FailedSpongeOperation)?;
sponge
.squeeze_into(&mut tree[index * 243..(index + 1) * 243])
.map_err(|_| Self::Error::FailedSpongeOperation)?;
sponge.reset();
}
}
Ok(MssPrivateKey {
depth: self.depth,
index: 0,
keys: keys,
tree: tree,
_sponge: PhantomData,
})
}
}
impl<S, K> PrivateKey for MssPrivateKey<S, K>
where
S: Sponge + Default,
K: PrivateKey,
<<K as PrivateKey>::PublicKey as PublicKey>::Signature: RecoverableSignature,
{
type PublicKey = MssPublicKey<S, K::PublicKey>;
type Signature = MssSignature<S>;
type Error = MssError;
fn generate_public_key(&self) -> Result<Self::PublicKey, Self::Error> {
Ok(Self::PublicKey::from_buf(self.tree[0..243].to_buf()).depth(self.depth))
}
fn sign(&mut self, message: &[i8]) -> Result<Self::Signature, Self::Error> {
let ots_private_key = &mut self.keys[self.index as usize];
let ots_signature = ots_private_key
.sign(message)
.map_err(|_| Self::Error::FailedUnderlyingSignatureGeneration)?;
let mut state: TritBuf = TritBuf::zeros(ots_signature.size() + 6561);
let mut tree_index = ((1 << (self.depth - 1)) + self.index - 1) as usize;
let mut sibling_index;
let mut i = 0;
state[0..ots_signature.size()].copy_from(ots_signature.trits());
while tree_index != 0 {
if tree_index % 2 != 0 {
sibling_index = tree_index + 1;
tree_index = tree_index / 2;
} else {
sibling_index = tree_index - 1;
tree_index = (tree_index - 1) / 2;
}
state[ots_signature.size() + i * 243..ots_signature.size() + (i + 1) * 243]
.copy_from(&self.tree[sibling_index * 243..(sibling_index + 1) * 243]);
i = i + 1;
}
self.index = self.index + 1;
Ok(Self::Signature::from_buf(state).index(self.index - 1))
}
}
impl<S, K> MssPublicKey<S, K>
where
S: Sponge + Default,
K: PublicKey,
{
pub fn depth(mut self, depth: u8) -> Self {
self.depth = depth;
self
}
}
impl<S, K> PublicKey for MssPublicKey<S, K>
where
S: Sponge + Default,
K: PublicKey,
<K as PublicKey>::Signature: RecoverableSignature,
{
type Signature = MssSignature<S>;
type Error = MssError;
fn verify(&self, message: &[i8], signature: &Self::Signature) -> Result<bool, Self::Error> {
let mut sponge = S::default();
let ots_signature =
K::Signature::from_buf(signature.state[0..((signature.state.len() / 6561) - 1) * 6561].to_buf());
let siblings: TritBuf = signature.state.chunks(6561).last().unwrap().to_buf();
let ots_public_key = ots_signature
.recover_public_key(message)
.map_err(|_| Self::Error::FailedUnderlyingPublicKeyRecovery)?;
let mut hash: TritBuf = TritBuf::zeros(243);
hash.copy_from(ots_public_key.trits());
let mut j = 1;
for (i, sibling) in siblings.chunks(243).enumerate() {
if self.depth - 1 == i as u8 {
break;
}
if signature.index & j != 0 {
sponge.absorb(sibling).map_err(|_| Self::Error::FailedSpongeOperation)?;
sponge.absorb(&hash).map_err(|_| Self::Error::FailedSpongeOperation)?;
} else {
sponge.absorb(&hash).map_err(|_| Self::Error::FailedSpongeOperation)?;
sponge
.absorb(&sibling)
.map_err(|_| Self::Error::FailedSpongeOperation)?;
}
sponge
.squeeze_into(&mut hash)
.map_err(|_| Self::Error::FailedSpongeOperation)?;
sponge.reset();
j <<= 1;
}
Ok(hash == self.state)
}
fn from_buf(state: TritBuf) -> Self {
Self {
state,
depth: 0,
_sponge: PhantomData,
_key: PhantomData,
}
}
fn as_bytes(&self) -> &[i8] {
&self.state.as_i8_slice()
}
fn trits(&self) -> &Trits {
&self.state
}
}
impl<S: Sponge + Default> MssSignature<S> {
pub fn index(mut self, index: u64) -> Self {
self.index = index;
self
}
}
impl<S: Sponge + Default> Signature for MssSignature<S> {
fn size(&self) -> usize {
self.state.len()
}
fn from_buf(state: TritBuf) -> Self {
Self {
state,
index: 0,
_sponge: PhantomData,
}
}
fn as_bytes(&self) -> &[i8] {
self.state.as_i8_slice()
}
fn trits(&self) -> &Trits {
&self.state
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
seed::Seed,
wots::{
WotsPrivateKeyGenerator,
WotsPrivateKeyGeneratorBuilder,
WotsPublicKey,
WotsSecurityLevel,
},
};
use iota_crypto_preview::{
CurlP27,
CurlP81,
Kerl,
};
use iota_ternary_preview::{
T1B1Buf,
TryteBuf,
};
#[test]
fn mss_generator_missing_depth_test() {
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<Kerl>::default()
.security_level(WotsSecurityLevel::Low)
.build()
.unwrap();
match MssPrivateKeyGeneratorBuilder::<Kerl, WotsPrivateKeyGenerator<Kerl>>::default()
.generator(wots_private_key_generator)
.build()
{
Ok(_) => unreachable!(),
Err(err) => assert_eq!(err, MssError::MissingDepth),
}
}
#[test]
fn mss_generator_invalid_depth_test() {
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<Kerl>::default()
.security_level(WotsSecurityLevel::Low)
.build()
.unwrap();
match MssPrivateKeyGeneratorBuilder::<Kerl, WotsPrivateKeyGenerator<Kerl>>::default()
.generator(wots_private_key_generator)
.depth(21)
.build()
{
Err(MssError::InvalidDepth(depth)) => assert_eq!(depth, 21),
_ => unreachable!(),
}
}
#[test]
fn mss_generator_missing_generator_test() {
match MssPrivateKeyGeneratorBuilder::<Kerl, WotsPrivateKeyGenerator<Kerl>>::default()
.depth(5)
.build()
{
Ok(_) => unreachable!(),
Err(err) => assert_eq!(err, MssError::MissingGenerator),
}
}
fn mss_wots_generic_signature_verify<S>(public_key: &str, message: &str, signature: &str, depth: u8, index: u64)
where
S: Sponge + Default,
{
let public_key_trits = TryteBuf::try_from_str(public_key)
.unwrap()
.as_trits()
.encode::<T1B1Buf>();
let message_trits = TryteBuf::try_from_str(message).unwrap().as_trits().encode::<T1B1Buf>();
let signature_trits = TryteBuf::try_from_str(signature)
.unwrap()
.as_trits()
.encode::<T1B1Buf>();
let public_key = MssPublicKey::<S, WotsPublicKey<S>>::from_buf(public_key_trits).depth(depth);
let signature = MssSignature::<S>::from_buf(signature_trits).index(index);
let valid = public_key.verify(message_trits.as_i8_slice(), &signature).unwrap();
assert!(valid);
}
#[test]
fn mss_wots_kerl_sec_1_signature_verify_test() {
const PUBLIC_KEY: &str = "ECRGOIGKMFCNJPILB9GRUN9WIFOXY9GPKLSJV9UUQINIOHWKYJRZEQ9IHTS9HMFCMQBGRNODBIWTPILGC";
const MESSAGE: &str = "KEWPSJHHGOICFXVGNUNRUDSKDUKNWGADKUFOFYVTZVGBVLWGIQBOICNNZIMWAXMV9RRMWSYGIABIBZUZ9";
const SIGNATURE: &str = "DJ9WGAKRZOMH9KVRCHGCDCREXZVDKY9FXAXVSLELYADXHQCQQSMQYAEEBTEIWTQDUZIOFSFLBQQA9RUPXZ9THOGJIBPKN9XLYMNYMWHWRKJMDTGM9BNFDZQH9IVIOGSOMNUBDAGUMWECIQX9YVLNIXPXYTAACLZRIYPFVDVVDGQXCROYORAPAWIOQGHRVWNBXKAAGBGGYOORIUDBMYYZXTCUHDYFDZOHOERAOP9VCNKEULPU9ZCVKOMSYNCOPXTKTTFLWHQKEVNIAKLPKJ9YHBZDBQZDSAJYGVVSKMQZ9OJNBDUDJTGAE9OLPACMMX9WLVC9TWJRRGNLQJPJMEPBAFBNYJ9CWMTLTWIHISDMKRMUUHSPLIXMWYIMBAUOFTKMQSSBZOXTKKBADHUJFCQVYJJCAUGAEJJPJWWFWCZNHRFZZLMQLDVRQAVNHJBOXGZCWQZCLKDIDXSAHYOCSOUIHMIRTM9PHPTTGWUCJWNYPSIGTRQSUWQMFCXAKNJZZUCMGQUDJWZJRSLTHPIPVLMKZRTDJBGHQOSUXAENIGPKRBSZPAPFAGNPBXXHZR9SEWVCRSGUXIJLKSAJVCJDBJXJY9M9LVLWJAMHHNGAIVZ9DFGOFGPHLVDSDEGPNJZWVNGHKWEUFQRCMEGNLJMAFJKIAZBRPUDZTFLGRLADIBRNNIGWAKCCZD9KCFRX9ENNXGR9MBCDFJWUCZUMPOFW9GWF9GRBDVHWOLSXVWDIVKBOARUPCZSLVD9UNSKLDLJGLPHZR9KFSSGLRCHMESLBYUDIJTGPARIZFQROWSRZOZAJW9TPYIA9YHECNANSTMNLBUWJZVLTYAILPGJLCUNGXQNGBRXCBFCONWEIDXD9OQIWNCJZDFXOAVOVOUMGTOYB9ATJLKPVRHWPHGZSBPMEUWNDZGVMZYVAFQT9YGBGXDBDCTLTHBJEYDOZPLAAZCMFKHAQ9CAXVGZUTJYDMPL9DIMAUATSIOSHWJWAVPWIQIMXOLAYEIUGDISTOCIGGPA9WNVOSDDXVPOMFZKNKMSNIMXKCTGPNCRO9NQFYXVRTPSXHRRDGHMKNLFEPKAXDZLOCSFCVMIBEIQMJTBHWUHXNH9WGSKVCRBDRXRWAURDMNSKFLGMPXQEBXKKENSUKRZMQZUMNHJYWEZXIRPEPSKPC9JRGNYWAJFPN9AZKGYZCHVBCHHPTLXOURSVUHCM9QDACGWBDVTMNZKNVTOJSINYRDYNRPCMEBDUMUXFRCPYRHXOHDFGJFXOETGT9TOJVNWBEYXSK9PVVYZAS9WOSWJAH9UFXFFNWKWEUKXZM9BJDRXFFTQYRIVKWVFKCMSRDVNWVDPXWT9KOEBIDUKBE9MNKENKVABUSUDMIKZLCSBS9ZDTZNXRKCMIQTDEHYKEBPJUIGFZNCTSGOCQAVZIBFXKCREXDLWRBUDXWPHPYEDFLMSUBODJPSUIHCAHGLQZZHRQCMHRCSTKWCRRJHEVYXKGKIXRXSFREXRKQHHOIETURROFUTKYIDSQFAKZYWJKZESEYXIPKXCJLIPFCORSVH9WKFHJLUAQ9NSTRYBIFZIWZXMV9ZCCPTELAFRAMRFCOQHNOTLAXVTKLHEILANKBOTOQDACLYWXXKVFDIODLYNUIXQXPRFZTELIBDJUXJFPIQ9FRTGEXHOLOIVKCVTGLGHQNTONFRLAHDLHVSWDKBNH9ILD9IKJPNCBNAOASMFZVLUSOMPAHNIXRAKQDNTUZSCVNUOORADATIBHLHXTAADAUTPFTQEIRGWHMNBGSWPGMHAXNEUWVPETBYQKKTLBKVCEDYUSZ9KYMWMRYKDYWMFKJYEGHUSGDIVZWFFFQXAHSJYTRIAVQNXG9WXRIZFCZPWMOXZQRFAFMVRUCDSACJ9FRATCGNOPJRSGGTOCJIZIQNYOFKZWHBCRKLERIECSBLQND9ATPIFCSNPONGMI9LMRMKDHIFEGYRWPHBYHLS9ZXVE9JLJNIMCTGVTTCWQOYPREFLBJUAVBOE9JKHTWHKZPKCMPAGPFIVRWIBEXNPTEKCNDZOIOHLVWEGWSEKRSW9DUIXDKPQLQNZWGFMMCTGYKZWYHNRLQRDTIDFZRBVOQFCRMURK9CZS9IZPUSCIEPPCCTFKBS9FYXSPIKTNWXYENQDUNXLJWVBJBSQTUHIGDFRWEJEXPZYZTJAPZR99TTEXIIPGTIFRSLZKAKAAPACWEKAIAWVQRODDVMHOGGMSXEDAACFPSTWKARTNLZCBDISLZSJPAGCRZEDQBWIMQIUASDWYTZRZMYGZDEQLWCIJY9ULUIYQWWIFKEBZAIINGPMWCEFYWXQAPCYNOTL9HMYDNQMUEJJVDAQ9HRHZMI9NRJWLFM9SQIOFYXDBGCCBEWDQWUHIGFZKHJNRWMFSEFAWPM9AYNEQVUDKPPLK9WPLDFQBHLWWWGRTL9QCFMMMFKIEAORYLUEHFZMMSVVUHVNEJVTWKNUVOLSFEIFSZIDGOKPUXJADTAKWCYZZVQE9LWEDDRRKEFDHUUUPVTZHGBTBAAY9EQYGTNUFETRJBPPUP9HBJHXTPEUWDFDACXRQCAKGLBIK9GPGCVHUMRW9CCKMKJIAZEAWP9GMVRWQFTGDRGHZHPRSJTBRRPJQHMIDFJKSKKVVZWASKJG9FVWUGARVWXRBUFBSWNHPPXAKKX9MBGZUBRYCXWVSWWAEMTFGMMLYMGXSAWWQNJCGAXDVSKZTHW9NFKJHAQTKAOWHXBTLIUDLCQX9GPW999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999";
const DEPTH: u8 = 8;
const INDEX: u64 = 0;
mss_wots_generic_signature_verify::<Kerl>(PUBLIC_KEY, MESSAGE, SIGNATURE, DEPTH, INDEX);
}
#[test]
fn mss_wots_kerl_sec_3_signature_verify_test() {
const PUBLIC_KEY: &str = "IDSWNWLGPFLAQADAEYUINRS9MBEMCYARHXHVSBOZDOBHPIPNVYUFFTQLNYGDZKKTEBHYOQXVQVHXBGXH9";
const MESSAGE: &str = "NNZLXQKRAQBEUKNGVTKAHIIJUGSNNNNCASGGPNBJHKGTH9EGEAJZPKYL9WTNVYHFKDSQYERI9AYUFHYB9";
const SIGNATURE: &str = "PGCWBHJEXWRBTMSIWGIDRXWNFTYGTTXPEAHWEFXKXGH9VA9JARHWUHUYEOOYENBHKNF9WLIFOH9HGQJVDOMSJ9XWTOVUDVDJBDCSKOYHM9QQFEHHMGUMXNBTWVBDCBBCAGEAKCWMHUUGBIXURKNMUSQTWQVRYGQAS9SJFAXLWXALFRWJUFNS9LDMOVUFVPHBZPDLYD9DKSWDY9TUOCCQQM9JXMTJRLRWEUBAQLJCOYJTASG9QBXKKGDTRWHQGATGSWDEEZUU9EJQACNU9CHIUIQRGLWGHFF9ABGE9SGYFRANEOZJLRHCYRWI9IT9FGYMKYGYMYDWRUOFMDGIR9EYNMIHWDBAJRBBYBBRL9YAWDGWUVGWLMKKVJQAAFVOTYMQNBAGZZFLVP9HHENEFZC9DPLOABBV9FKJCYJ9OH9BTBNEQTJSJICBWHUQVHSOISVIIRCUUEVJLJNLZUGBQUDXTUNS9HQYXHNAQWTQIWYYERXQKFZBEJGRDJJLZUNNTZDDEIYZBFWFF9ENLLS9TNPFXJARPBMYFOAQEP9GYBRNAAFOPBRSTOKPCUZQLQAMNWHVKZHVPHDLDRORAUTLQKZNPTIAERPPMDD99WTVZGGJWCLVOWXIJHEKAKINBSQQEBFIWTFIZINBGEOI9IRNCVY9QBQECCDCTOTAOEUCLJCM9MSNXJMHHNFGIBLT9KDMASEGKFPOAQQ9ZFXUSRCNZTGPOXHDWTGUAL9JYLMOOKLWCTNC9UKMEFSBZSV9DXBYTOHNMUEAJTHJNVBMCYIEDOICPHROXUVMA9UREPMUCPBPJDELBJEBZYOR9D9TKLEQ9G9GXRXPSDBDZXTTUAKJSAIRCFTCTQFRLUDQBPRXIYCDAXCUOZIGZKCZRWXSLLZLAJTCDCEUIPYASTQOLMSEYEIMVBEGKOBAPYJZMHPGSXPFUGYLWGZZPBVCBKZBBCSPGEGBZAJQUCHSMSNW9HFEDYHOJAUJBJSKYFSMTWTTF9HGERJZIYMMLYBRVLJLCQFMXNXUPILZSERKSNMVTLMSKJZRIAVN9IRIBNBYLU9MW9EVPBEESKHOWTETUTZRHKM9BKWRFLZGIREKNC9KSKHBPRLCHCIEXPZEXILOYXBOPFLMWHSCN9JWUGZPWCWFSBNFFOKBQKPIJSUXNN9UZQQDKKEWZQDRXPDYQJHPBZJTOLQEFDWCKFPQELRFWTVBZVVZTAXDRQIGJVFNBM9TZCKRE9WDFTFVPV9RYIIUDIOIPYUG9UZCSVTJCLLSAFQJKPZGTTQLQYIAYGWJUMARKHSXKGCOXKKBBVUSPZZETMAGQBPAH9WUXLUJQGZKQUYUWMPCFCHMNGNQL9XNMFVEKMIPVTBXLBNKGDFVLLHNAREIC9HLZHNZYMBJHWAGESNDANOLPXHE9CVDQPVJBQHLTZLOEBSHZPMTAMLDTTNVYJWGOXCSGUEFIMLY9CNCLJSAUDLMRRFXSESMPMXDZRVTHZGLKJCHUYHNBNGBUOPISW9TAGGJY9FUQVLX9BRDJGRQ9BHCMLCZPJZFLCFBPDCIHAGJNNT9OKHSRBHPPNPNFFKYBUTXKUOTHH9ASBNDCYTUQOJWMYUDFDGBRPRSKKHQIOERZPWZWWZQLSORYDOU9QV9UW9NZFVBGUCFBNGGJSPYDVPXO9ZBDR9WYJIYDRNKIJQTJCJOOAEQT9OTADGBDAZACMTWKWFDMSS9BGLSNKZVFTKDQDNSGBACUVFCQBJXMVNPIY9RUR9IUWTDUJFQWTJTWUQYNSSZB9QWGDPXJWNUSKWUYBVIC9BSMNHQVKXSOUSJUBZDOUOMEXAX9KDEWZSWRJZNQDBCXQZFEZJMCMPMOA9ZVCHLQDUCMFDNIFCHOSIJIPCKTFOPVUTZCTZWAWBIGMQRRQGCNQYMAYZXDPXBFAKVDEPMJUXPMRLEMXUMFNSMGHZ9MSEWKYPWOUPSIOZTEJYUFLRVHXCMCTQX9IVNKMTQYQCHW9VSSSXJBOJPBGBIDIIKNRUQBDZUSOMOSWRZCGBLZZWNJQFRUWPBPXHMPVGOEZATZSDRLULE9ECFUMNPWELRL9AAJCONHTXMXSSIXNQBCNNLGREGDPRDWBNOVCOJVTKDPVRAYLXMFMZHABVZXZAIKUJGHYGYQWTBIDFHLBCLRASI9MTFFFHLJOYSIOSGPFKPUDYAXVRVXGDERBTZIAEG9UFXMWDGOCMXZSOHSCAPPYKWUJQLXJCIKJOP9NJJXRLCDEBUWMAKTNLVSJEZNTDVRPXWWKEZXIKBWEQRIR9RDIKXNPTIKNQWWOMIAECGNCYWY9LDSZQBVAOIJFWBYFYKXPLWPNWGDVMOVTNYMH9ZLYUBXPCOWOHJEHBTWEX9XNBWKOTGKWYCTIIKTZSUJPPXNXZOS9USOUIPOAZFWZRMQKKOWSSRMMTIVYQHRIODKXAKPH9FSJNQ9ZUEJNUMHPOPINIUZGNAIDBWEDSGPDPXRWLNKCMJCGYQBDWIGULQKYKLPHQQDDHBWNRVEBXJDSBGWSXEJFBYVVNOIOOQOTKLJYVDVRQUZCVKFBPROB9VVSHLAEKEEJLQHHNZDQLNAKEHBVPDSKGNHXTZNA9WUXBTK99SZXZYRHHHGRZIRLRQEVQSGPVHIOPKP9T9AGGJBTFASXWMKAOFUUZYMRHBUXRBZAO9SGMACE9CXLXCQADLITOI9AWXSUXUPAYFVNIMUZAGCJLZGCKX9IFJQKSNAAG9YBZRJBGJFWBSYCYV99GOSLLMSAXJNQWMCCQWBARLWDDRXUYBUIKHTAOGWWXLTZKOCBYIGBKVFCHDAPQIBBMJFPCQMQCWZYAMGWRBTMBJNDCXP9ADBXSUBAROQYODUWKDSXFMPKANYEJYESWNCHVDKCDBCQXXCRRENIIABYT9WUMDWRVRPSLLS99HYAACBKEWJQXXEWMHXFAEPVQD9KTDZFIWTGBLEBWAYAHVRNLGKPHXFNFLSFWRIKX99OTIUQVFYA9YPJAJJEYGXFSINSXDGNPUKPERLCCSCPHU9WKCGNWMCQRXBTWRRXACOVLKPWSHOXKLRIRWBDMEEUJOOALMYZLIWPHSCWXHV9RNHTFAUSPRHZMR9OAJWFWQENFOFCPMVJEPBQAS9LJWDUP9WKFDWOZRREWX9TSNCCDCHNMVBYGCIF9VVVBWRKDRGJNQQLIP9CABUZRISLUJIZTWIEXGDLMBVIFVEUWSDGTRVLGOPTEUOWUY99G9OEKUFIORYCXXQMTSL9MCVUQJWMVTSVSEMXREZHBIETUVNNUACCVFUECTCKWMUUCLXOEY9LQFAYGUKWGFZWXTTVCXVYJYCRCCARSKWMIGBZONSJIAACSNZUFBVBASXEXHXIJEQTEANIDZSREFIUOEVRSKUGFHMNV9ZQDUFBZAXNHZLZTH9YSVRWNEXAZVXPYIPRSNRHNZUJPALZQHUO9QLAS9RX9QBIXMAGIRNM9GUUYOGUBQOXXLKQEZPZMHKNCITFOYBEUKAXHJLRRMMVF9SLJZDGQAM9UXQ9VMVLIHFUVSNLBVVMDLYULLELHMTFTWCNUEXXQFDIJSNWUDWYLWAXEUSVOJFCCCYZFLQNFFRTPOTVVUALPYZCTUSEQOKVHCTZETMDMFSNSNGDTUCEGJYYZTXGRMUZJTWCULIZWUIBOVJAISLCGJ9MFOJIDZROGYYXHEXAIIWOAVEJWXVVQEKZXVIT99LBOIKGZWNX9OPTPLSOQPEAOIRKYIMLXHYLPVPXG9AKFIOFBFEBLASXYENQ9WXIMKILNNJOAJHWODVRBGNCBGWT9BHZZYDPJXQQHSO9CNDSPNZZEIPVIMNAPVCSXTTFGJSRVDYTMIQAKFPUEZAT9AKAQDBMP9FKXLQZUDDSMKVK9ZKVWDAPAINQYCYHOFGOUCFRBLUYB9HGVWJPKQXLXF9JKQJLNMROEGCPFGXUSAIJNQ9YLVCCPUDJNJPNWLMYVDQPQXBTDEWMQVZYWDVKBTVEF9VOKDVHVZDZRWFK9WTMYU9ATRQJSKFDWXNPRDHQAYNGWXYFDKSIHFNA9UGGMVNCDMTZPEFBJAHGHMMDHEQLA9IGVDUGBQHJQORJ9ZWNEUJPVWVFDXKWDWLUHEVE9PYVYSMYPSYU9ZSMACZUAXCSAEJNVHOJGBRFYARSFZMYESXLNQOAB9HOH9VGQJTSAURKCMPYUFWZGEPHP9PUVFNHSCCHVVTGWYHLLVKIZCROMYQIYOCAHPONKRPEGJPKWTNQ9LIKTSHMKPESEZEPJETUUO99JDHXAUJIFEZCJLDGDTKZNLNEUSFYBWXHJILLHILNRXZKYAJDYYPNIJHIYXZ9RJKAGYLEVKVQDAIOCHGEKPQPCZOLSDXNFVFBDVCKKN9ZXJDSXGC9MMLCZGOBGDACJAHCOKJBDSTGANCAKNEVVTKARLTCPFRSGPPFPDIEDMCUEEFOGWUUXXQEPULAIFOEINWPDCMFXOJXCLQITCCMAUUDLGXDJDLVMOFEADOWJDVIXBBSINQMLGXGILLMHWIVHDBDTIHWOEETQZPJOSSWNWJYYGEDGMSNNJUDYTOATBYCACKRICFQALDFLDZGKFKCCLWZIKGWOGMEVKOITUUDCZCBQEDXWYGV9XARB9CKWNLCKVOZBWZAKAMAWNMLVGYDFQOARCUN9CA9YAKIZDBSFZXZRZJABWZLZGGNAXVOHZMXXMTCQZWIMSYYGS9QA9KLXYHLUFEGIFUVLAHKOINTMFMJZFUUWZKRT9GZZGSAWWCFUZUYNJXPWPKKYYZVUBCWSMWZFJEFZHDTLVACXIYPPFYWCFUDHZGTSOJPKNOADZPQPMYCJGSZRKANUOZRGKD9UAFAKUSDDPPPJORELCGTNZZQDBKZYWUBKM9GKGIBOJANBZFQMZKNVMLNZPQFFFVXYYUBHXQPBQZHCCZIP9Y99PIHURWQTJIJMA9L9UQIOMCWJLVCFTRQ9DNOWJKBEAANBCMLXX9DFYVDLVIYWAYPISVVYSMHYHHQMOVHMHLWPDWWMFYBUHNVSDU9BP9CSZVCLU9MEBETEJRNEQ9XPNGRPCMQSRNBZA9HUWBRCLEJEJZYVVFWGY9QMGCLYRVC9YBBKVDQNZDBTJGS9YZOH9XLNQFKPVWHEFPWOWOEPMRVBATFBOZAWIYVTPJMBCCBVSLBZTCXWQNGWLPCYXWHHHVUAAMABPWGIXMPIRPCWMKRPY9VYEGAHSIKDJT9GEXSPKFGUZWJBKRIGQSYUFFIRXWXFENFFHDHYROGHPVFHUXMMQETAHWJGJSVUUV9Z9CPWUTRDE9OYZAJXGXEJONLEUNSACYMXQBIBGELXFULFBU9AISG9IQSPASNHU9OWHILBVGYJAMEYMZOKMNFDBPMMORLENRVUOVZEBETIASNTBOHXUWAPAVJCZZGJUYAPTPREPLJOEW9OTD9DMALQOGUDZAKOYHEFALMNKGCKWECEQMSGDA9VPVHFEMYEVVHC9HVXQKQJABAYEGLFJVDWNCSOOPURHMYPGSWKSDFMCGTSZRYVQAKMATIRRGVIYHHTXATCXQHEJWOJMEVDXV9QCRGTGYQYDWCEJMRGSCHZOTERVNBDNCKZWUDZPXOOWDUXZ9GYQKNVUNZKUGOMPWDWGTTXGJIQ9XUOGKCEWMDKFYXIBUSAUGYJYJYUVEMAIKEXPLEBKMUEBECVIGYXJUQLISTYSXLQ9RNIHWVDWLXCXCYCUK9TAGBBFXCIYLOPRKZCKTDSMQVCUXU9WQCQ9GKPCN9PKUQYUAJDIAJKNTDWJH9PPGYGN9PVRKRMUBZZCW9SVGPLRRZDRADYMWGXWMWAFWLVGKVRI9WQGZIUHOXQJUCIBXQBB9VZNXDKT9ONCYCFZMTNHPJMJPUJZDWSPQLRAZNGV9QTKNYBZDSUQIPLVSQZHEOLUPFPRAXRHJSXADGQDBEVNPMVEC9TCYAGZSZASMGJLRZYWOKLUZULZZXTCBLZUQND9VPFJJHEDLOTRINEBFMPWSGDHKEOQACITVNPNTXKKQWCZLC9PYUHGSQEATWZRGZPELGOWUYVIHDYQPGJXAL9O9XNODA9GLDBYXXVPURQTQSWXZRWYRHOIQUUCRBZYTKSGSOMAXHRZSTUP9HRIMHNIBQJFCUBIWHIXHUWXATPHSVIFXMWJKKOBFMICGJGFJKLDPCVLFGHILHLIKFSDOPYFHEWVPGQISJQHKV9HBLKWX9JGDSUZWBUTPOHAINLBFNMUTEQ9NFFBKFSCZELK9XIXFTDZFQIYVIEULYEOEWMQWHZJZQR9SDBIOCXEPHXMCWCQSFCSDWY9QTJRDJDRFVJUCPBMRHIADTC9KZNDNUVDYSKQEDUX9BLFFNPNS9OCQHCHNMDYBRTOJNWAGWKLSTEAQHYCYEEYPKRUFPTWEWXMOQE9UKZYXHBFBHOHNDRYVTW9JKBIUZFF9OOFKFHPVCFYAEDUYSRMKKDCEOGNIJQYCYKVVUHUZRWMJFHVGTYFVFNXOIRXXZHBGMFQJEBUPSBKLAY9QTJZNIWMHYIQLVWF9TQMM9ZEDDKCCPEKDMJCJCKGDICZKINBYZGBCEUXAFMGWZTF9TUMVAEELCKMBESECIMAAVDRJWJBYEWDVB9HPVWNYUPUMOEFJETRHKD9N9KOAZRBFOQCXXMUBFPAVWZEEJ9FPOTLMLEMZ9EEJWKYMHDVXYFTKLRRCHWDWSCJTODJWIHWMFUTKGFLPDTFEYGCFAATPX9MTX9YCFWXWRMLZBNAAFOZMYUQZ9JYUXFQUXI9XKYVCTL9BIKJJPSVILKNDOHZWQQBG9QINKZPVG9EDU9WFVUZZQXZTCWWLHWIFQW9ECOJVGNYZFPXQAMKTVPEMAVLBQKUCBCQVFQFBDKATSOZGOQZJUKMOYZYHKECFQCR9NFEYCLFKFUMTSFZVYZYBFZQC9SAYIXTIPQJSKHTFEZ9NKPOYGRSOXROPRPGEJH9JPTLSI9VWQODQQZMAABCN9NNDUNO9WGWBSHLOXMTFWNTAFXAAMXBS9IHOPEPBRIBGDLKFCTEPSQWOZVKWJKZNGSTVYVJYKPCBUSIOY9FRPXCVBPCFMSKYDDXKYJJWMXMXDPZNAUNCKRCWDIHWGZUMUPMRBZKHSXEZSWWLXXVLLQBSVJFQWNSJZIA999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999";
const DEPTH: u8 = 8;
const INDEX: u64 = 4;
mss_wots_generic_signature_verify::<Kerl>(PUBLIC_KEY, MESSAGE, SIGNATURE, DEPTH, INDEX);
}
#[test]
fn mss_wots_curl27_sec_1_signature_verify_test() {
const PUBLIC_KEY: &str = "ECFTA9SVHYH9MRRKJHQCBXNQKDBNGCWWDUAVILCOF9LMJNDPZLLTRYPKNHPVLXJYGGAXGOBYHZHGLNXKE";
const MESSAGE: &str = "MMMMBNKRJWVAYO9ZCXYAODVATBOZPAQVLUH9FBCMQQOKTHKXOLIASYMMMMVRNNIQQAPVCUTMUVZAMYJA9";
const SIGNATURE: &str = "XERUGTJZGCCJDUFSKVTNSZAENGJ9XBGRVVPVDVVWZMLQERHXNTSE9UPP99AIHZRUATYJUAVLEGAXVFVDRSFLQGSLWSNKKPBVSYXEMNAU9W9NLKYVSN9OLXS9URJFCR9GHINRIHDEOJNUDHADUWDFCAIESB9LJHOHFGWYYX9DDNPSQEXKGLJLKGALKTEZWOLIKJLWVTYVLUHYNON9UYKBXDKUTYJMQWHEZTNYNGXO9OMBLAPBDUCVWWVVAOQKNVLMZFMEFAX9MRZHEAFOPVBQEFHFEHXILKPJWVHZJUGGPQVHWYCRGJXMQOSNEHOZBKCCAHMRGZKBDDFSHJRNFSLXHVO9RQWJCPOBV9JUFZHAEQAEBIAQWNZNXHRIFKCVKOJSYTSACRIWJKLVIPYHGS9CGXFPTBBOCIV99O9GXZJAENKGLAOMKFBTXJRZOTWSMITMMI9GQFJQNYRHWDO9KUHHKDCRA9Z9MUBMLLPBOFSIGLAQAMHSSJTZSPTYJKPRJDVZLWGHFNRXSKOLVJLCOSLMBAVDMIUJCHOOAKJMHNRPHCFYTRPGIPIMNAYTAAKOJKFSXUMOYEZPWMXUGFJIOJVXQMGIXYKLOQWOCIOLIZTTOKVXVDRQAMBJVOQBDQHAAKDJKFRHXAFMPGXNLBKQIZUCTBBAZCKGCGOPXJHQSKGRZWTFTGALKESETAQKSXZWWKGFMGPTQFWHCXPJUN9MBTAVSAQSLNKVZHUKDDCEKLIEZJTOMBSPWIFUBTYCKOPKITSOEXENX9OHACHEH9WXBYMVSTYSAHEDWGTMGF9YKNFNJZUKJPYFEQ9HKIWNELFBBIHNGPUQQTCNAMZBZTRVDMQYJHV9LMRZZVVVKNTCJMDEEGQFXHRDHB9DMJDXEQWXLPPWJRIBYYXTAZNZSHL9RLFASMDLNVCZDEFIRDMEMAXQZMTPRWRWCZERT9EWUNBI9QRCHICMJEWVBHHRVDGSZCATFSHP9WFBQFMNPDDH9KYDVXIBVTOEMVTHZLDNASLKFDNQRXUNADCYOZOHBDQQPCHRHSNCAEANGSJVFUYLEJWCBF9OHM9GFRGKAO9VCJLDGXRCPECEOIKZPPFMDZCXDPCMNTHVELWLMIVAVZCZUGLFAZTLUYZKOIRPCPORDI9TCZZJU9XKZTCFVUGGFSCPKTKUGF9FJWBGQFJZQUT9FALIOJVEULADRINQHUQWNPWXSDHTPISNMHVHVSRZSTOIJUGOZBVPAGPBJVRLSABLMAH9OXG9CCTMRX9AYNUKBWZVNCINUYNZNJPUCJGQCQJHMHZOYFDWQEWRRYMOLUCBCHQMCVTPWZASBYQZUFUUKCYNVXNVHHAVVYBQPKHHKQWIJBRKZDZZFUDU9GJXUCKLXVVNEONUQSXNA9XUVCHOLIPHWQ9KBVIIGAXRHJBMTLGHQQSMMACAJSMHKZXECJPG9ELQIHTPUXDGAFYQTZACZMNUMDPSNSYUOKIUAOXNSJDTTZVAWJUQZITPTWSETMWXKEGDOKXVFUPSGUDMZZKRFPFWIPDFAJFFELZOXMZVJRGDFJAKCXQYPKVPNCENWJZVDOKNKJPXNGOP9KBP9RJEWTNCOABFJEOKONQSCCQRR9XCSXKTDJXVYJAVNUODHOXBZEUDFFTVCWHUPYV9RJZNVBAWCAL9XSGSMNFNADOAGFVEOXIAFRVEEFQKWEVTUVJHYINOSCHDWFSHJDATPUKJNBVFGKUQNUJLTHVNGVMXZWF9OCYKVJPKLME9EIWCIUBDBNHQJUMVXQJDJJDPJWHMVN9UCYKALOUSXZPZOGKVTGVAODHUTYVLEECAGNBRHBTQVOIMRGEHD9YJZITIEGRTDOA9FURPNRBDQAEPMLLUIHULV9AE99EADNBUYLDUKIBAIZHKFYJKGDQRKYTDZKOPCXG9WWBYOBZZBAHBOZVKXLPDZJRHBCSTCHMKSHGGYAXEVC9LWMZQISIJXAWOUVOULIHLAVTATZTZX9CRWJDYSGRPQVEBSDFVL9OAJLAHEISSYAKXKRTTSNHZPP9MDRCCPAIHWUYTKKJN9MZNGDJBDKJDEXYORFFJHXKK9MNGHPLYETLYGYBCJTFDPZGZTGICNEY9PFLWGIIGJ9CUOFAEXLHJNLHCTUYINWOHXAYJT9BTPDTFXIYEXBOWILI9AIDSQUVINLQMLEGLIGDYLWSRVCSRDCI9JTVKFYZXXVUPRXXCSPOLCHXQOBDCTBAGSGVVHANITAKBBMSWMWJ9TTTNF9HGMYXQEEDLDKXTDCFYXYLJJALBRJ9WMBYDBFGBHBUWYVDAHES9VSKVW9OXMOXMKNHAQPGRLFQRRGXRTTFPLYRZIYCDDJAHGTOLCUGHEHODTMKWUUAL9VFCISRXUKUTSZBPKPJEFSODZIBATZRPVFPGHDVXKOMIGTWTNYQKENYQKJFDCCRALOPQKCNZGQPRXQCAEYPZYZFSQMOCSLRTNTQWRYVFGPWMYKSUMKMMXCHPWRMF9QWKQJYYPKGJUJMBIAOQRII9PWKXUQOLNPCNKBCRDYM9FCGQ9BCMLIRHLIUANSYXBLZTLWGVIGJLWDWEQVLATWF9VJSQAKYEAZ9AAJMYEMXPXZDRXOOFRG9GGKARKNZZRTNOKZUBLPYNLPPLZMQPKACCHYNSQOBFXUYVWDGINAMIEODYZ9JTZQNRWCLGKCUBEGTKRIMESUPGYXQMIT9WWKQRVJNBOMXDOHBIOCNHWAICO9PQADCIEWLMFVZK9LXXMFWLWZ999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999";
const DEPTH: u8 = 8;
const INDEX: u64 = 4;
mss_wots_generic_signature_verify::<CurlP27>(PUBLIC_KEY, MESSAGE, SIGNATURE, DEPTH, INDEX);
}
#[test]
fn mss_wots_curl27_sec_3_signature_verify_test() {
const PUBLIC_KEY: &str = "ROLHKXFNMSN9WWAWLWYKWXJUQ9BREXTKOMCZFT99JOLWNWBPUYSCZPLSOSOPICLKXXSDRAYEYRNTTKTNI";
const MESSAGE: &str = "NKWSPOYLCE9NMZEWZBRLMZISBYBMMMKCOAUU9PQRHZYZPFVXPQHILAUQLHYKRPMTTIXGMSCTJWFVNMQX9";
const SIGNATURE: &str = "JYIDCZPR9QNEUDENZCQQLBQNWPMQ9O9VOTTZNO9RWIDRQRUWZNURKZWLMHZRXUEYHUFCKUUCVMWMGBTEIAMPXQYYTB9S9YRHBEDWJRVPYCMFWTLUP9NWGSYQDYJAJMOGXERUYSGKFDKTFRWSRPGXUOAEPOFN9FURIJADBRKEZWQNDNJALFAQAZL9QJVGDK9KNIFHVLQI9ARIC9ZBRARPHFDGZGNU9SHCFWWCYUPXQRQADWBYMHNEZXXNDJYY9QTPXATBKHXBNHUNWCPARKWIJ9OLWVHJVU9SLVVUGECSZH9VDSCZJRJEIZVTSUVRLMJPKLQSJW9XUTAAXXCQ9FZVHKKFBXFDHUXUCAUGKIOWL9ZFQCPQT9WRWKWRPXRYXCJCNOKGRNBWBVYXISEIW9FLZBAVQ9SQNIXWZEVBEJSFD9LEGOYJMMGKWC9AESFF9HXETEHTXT9TULC9LIATTEVRVWRFKCUNJOOOAOMBZOMUYDUHVFWSPOTJACZAFCPGSZXRHPUCCNHEHHIFJMOCV9CXEPDT9G9DPWEH9LIDZKAYBXKFLTJQSUMBBJV9HHQQCX9TADOIVW9TBYGXSPDIATJEUBJK9OXBMIJWIMOC9OFUNIBEYSTGZCMNWZDKCPALIGEUAIQLSDEDUOXKJJWXXGEC9DTXWYRQPPGOUGYTSBXVOXUJIILLNLLSVRSJCFNUKEBINRLBFBOXUWPXYETMIWSGXXZMOJJMHLHHDQXZETJSPUBBQMDEVRQAUTLNLTNFEUURRGVUDJFESHKRJMKACUPPIYGQCZQVWZUOAYAAIOZVPRCYUFTMMIEUCCJZRQJDCWLUQIJYYSGTGJEESLME9DTTFJL9XHYDDSLBIEXYYQZ9BMSZMLIN9ANJXWOT9LHMCID9LIFKJZSAQOCWPBDCHI9BYF9SGKZFXZDXIPGDMEUDDRIRQUSYDVEYEEEWBAHJZKNZXVTTPGYVQWFSRBWZEVGYFWEQJONFGBWTLKKVPZ9CNHEYDKPK9YW9JBRXMMYQVHMHRUPPQQGZQRPLKPXRGSX9LQMETBEWAZKSVLKJFYTBZXVLDCKS9TZTZJFZQJPTB9RZJYJGACMFDPCOBSDMXEPFJDJXGEMLZKRLXMOQUYQACLMSUALGDGEFTRIYZBNYWKGKWTVXQXCXVDYRBZHMANNYATAPQKXEALVFEGS9MJZCTXOUCBNHKRWJNTKFMPFOI9LGEI9YEYAFYA9GRCTCBUP9ABJUABWZQKV9WETMQACUQKYSRXJWNUYZKDZQISRQPZOEUQFYYOTPWMZGYFQPTIW9ZEGKSBQYUUNBTFM9PGRKBPPV99TEXQAREHRUCWJ9ETABXDTBJDHPCCLEFSHKHMZPENXNQVHMHJAZVIAWR99UMFYGNBFMKIDVBMSBXANIXMEIPOUHPWBBXDMCETESPCB9AOQNGZVGKJHSSJFIRHJEKWLSCNYTIQXXZCGSYECRIGITGYIRRZRE9YGUTTSQARCCZBKBDJVZQLQDOVESVCXRSFXAAJAZPNURMOEUGMCRWBXNIFKKSOCPUMWP9UICRSZKZJNRUAV9VEJMOLLP9TECFBPINGTUZBZ9ARZIJTIQ9MTQOPNUNVIUHIXSDCFOJEWYJUAYJSKEVDQYXGH9IDMZDDHOBQ9NYUTPDRDPSTEIHXST9MPEQUGGMHTHECPLSH9CPPZHRDWPHVZGHCYFT9ESHTTPGRUBELXKOZHTG9LKLTPFGZAAGQKPEEOPZFKOWMPMAUSGBDYOZCHHFZZENDFVSFSKNCT9RQZXIIKTBP9MKRJYYMUDIPGVPFOXVFRKMBNRRTKO9STAAXVBHHQAWUGGYBUSSRKVMLLVBNLJOW99MJOUPZFXOPAMJFQLBURBWYIZLICWCNKJBCLQAAOSEGKCHJTYXMAFSRECUR9RKJW99NNHMOHWAEOJKTQCOENF9ROEYBSEAYFYNVEWEL9DTTAATCKVHEBMFMZPXWILAIEFNXRIWCSJRLYGZXFLVASNGSGKMQZFQJYDJUBOETECNGUQQXJXZYLMQCYKWXGIZTOPCIPYCVHAII9PTJLWAHHXORFQATHMTYLRTFFIS9WMNSLNET99QSCPLKXOGYMLEHRQQGFDRLHBRPKTUJGLKYENBIJGCTOSBYQ9GRYXB9OULPJHYTBIJPUL9YJNQVOGFZQZGIVKUYGOCVZDIDUIFKHDFXGMESJHRPNKSKJNJZLJNXUEKJGQZXWSYBGPEHPSFB9BXFHMMSLUPAHD9KAEMASLVNBOQ9NANOKHQBLFHIUIKKVBROGBYVABWEGRBYOPYPOJXYEKMEFGYBEPUTKBJWALHRIZILHATXXENUPQNQDOCBGFKEXNAYBHOQXF9WZUUPADXGRIRHLTZZBDFOGH9ADOY9QSMWOUARWMPJJEJZZNXAGGKWYBNQNZBFJFDIJKJTHBPRHI9UUGDVBPNTDXVIDGAEFBADUQRHVLEGZOTWBQIDVUVZYOOHXNTVOUUEMG9YTTSAXSINFPBIONVZSEFZNHZCXNZADLXXHNBTSEPHUA9IPUXESBXDLFLJWKJBXOX9HKQIOFKFQYJIMTQYJSBBHGVGTMTSQUTOPYVGSJPDIRRPIXLYASBAJWJIDTTTJYOXVSHASCFOTBCZYCTCCYAZB9TDLHFL9BJB9TGBEQRVJXVWSNNVJGYQXUJLCB9ZVRWCUVNFMNZZ9SBAVGENHMKJO9MGNKYRQTPFCETOLPDCPTWGMZJHKRKI9QWMBTQMLHI9FVHSYWGZQUIDA9C9NDAKGKXBIRZGMSSZAFPEOKDPNNUQIDDOBMSF9HHARDEGAHSDHFGSECSVTIGKKUJRCNGQNIYWMMULPNHZNJX9MWDIESXPTCGAAZQPKUPSLZGCFBXRUYSDYTQDJXPYBZVAWCXJTOVA9EJZG9XN9RAXAW9PBVTGMYJUOWLHMZNUXCJP9URUGJJYHKKFVZNNKPSXNSYIS9STBETRFKUM9QABQHFPFKTQLONWINQEYEJKWQASOBWBRCZRV9VDQJKMOTYLPYRBZANWFERYMPBOTDFWHFZJKFMOPVWABJWZDAFTIZNCZO99UBGHGFTXHZSMDVCXIX9UBPTYQYPEIHFXBONHHZHLYRCNVAEVTCZIHZVZZCCDMCPUFZEZVBWH9HSBFJATDLAGVOCGLBIVWJSRCLQQWTWNQSXHKRIQLLG9BCRSHNTSYRYWJJXVZDOHFSBXTOSFTNKSVEVPOTDYFYGHVAMUITVDSXDAARRFYETDRW9NW9CTOFNOFURWWTFDWNKVHRODCCPRFGIFPZBBFSZZHDAEZ9BOFTVFMUASHFRCVFHSDKQKILHUUMUK9ZZIHZTREQGXLLPHDNUOGOVNUEGYDHQYNQ9XWHCRJ9IWXJUKQYPDSHWCAVVWZNYSVGBPIGFFMT9PGHKXYCAZVCUOQVFWPOXES9SHNZSEBQAHHZRJHMBGJ9EJAMZKFQEIFTSTCOFBWEVMXGGJZYNFOAAFFVRXIMFCBRNFHIXMDKLRJIOJGXQABDVXKKICKXMNDWIQOPGFYSRNVWWKMZTC9CQCCPAJIMAWQYTSS9SAFOWNLAOSXGR9WI9PYHBKGTTQFBSSZEW9FHTMBGFIWFCEBH9ZPU9YARCLGLIDDKPIHHUDOSE9YINTJHWAZOWACAJHXXV9ZWDKQRHXDKFCLGBT9TNIKYKNGEIJEKRRI9SHKL9TFVTOHMKRVVWSZIJWFLDLJHKDWPQVOEDZU9DF9JXNFVNUBI9JUBTTAKKR9WAF9AGTPVFDPSOCPXVSYJMHGGWLUBQQTJVJGPAFBWVYQTEBTENKJARVSJ9VCYVCLSHIRVOQVHDRLR9FSOWJ9FAKCULBQYXARKPGVPXFCCDTZEYPMI9OZUBNNDPLLKQW9COFNAKLUTJQBCWAPYICQAVGYAQOYRSWVHKDJQVPGFZWGDFMTPUIOTKDB9FSJSXPFYYNWRICNKUROBQHLYLPJIQBJFGHIUVQYKDMQNHHRXNVWXE9TZKRFNNVHCKZNVICCSSMGSQZTPVTCWRASVCNMIH9S9VGUPAHMSB9ZPUOVAFDPIHIRHMXKFDHJXUGDFP9IGGL9CRNNMVAL99HXZB9KIVUYMKAUSLNPBMMX9VEBGAKXFTURHKGYR9LQRAPGJZQAJKAAQTFEYXDFNLZKJKHCDPEOKNIRXKZIMPSTGKWWVYREWXUEAPPHLSVGSJTCBZWCCMXRSAKWBQTDDSWUKKQBSKANV9R9BAXEPMNRH9MLSQLZWPTUMD9SDTWPIXEGLYDWFJILKJFZE9EHXSFWWDUWWMCIOPXMFSPHBCYOTUWPDLQOFU9EUT9FXSCQJBFKZIJMKYYQGVVGGBPCJHKPLBYSCZJDEUKK9YIXESUEVJTUB9UGFMXTUVIUUKAMTRJXHUSIIBVAYPY9RBQAKFADROQYRJVSTWZMVPQ99EFXFIBRBGSOMPQFSO9PNEXNOTJEOI9F9VQJF9QHZUTLJJDBSEMBKVUPBEVLDIGBQIKYIPDBARIMCEYTW9LVW9PQMVIRRCIPOE9TMCCVPUO9MIAHHBVZEBHRUASOSSCKFJIKLLNGRTYGLYCMU9FPLPOUCHQEYYUPQXCMZWHXCYLFAVPWHXFYYKQVLSCHESVDUBSRHPPOOOVRSVQFCMBUYIAFNBERKQVXWLBKHDKYNWXLAAOCSKBIHHXZ9XRCJZELNCEXFWUKSHZLRXJAHFBXNEJOTSYPSTVHECBWKHDTRENPCDGPAHIQJMQKJPDNGUUPYPQRHJORGYRMAAKPVYZBP9CUBIJQQRQPSPCCVRJZCUJZQNQCKNPAWIXZHMWTCWDGPLAHRUNVS9QVOLYXEDZRMNDSCRLISGHI9SNCAGPICRAIBQNDILYQIAZO9RBKBYIDOAGKFOEJNUSEUECREDOYPH9EZIQVFKGVJPOHGLXCFUKJWDCKEQAZIKKKIHAUSFNNHOFZLMVSFDJPZYNTWLHLFBTASMFQGTODHYPKGUKRAHAZNRILYEBSYEFEUJWOYIAACENBHGJFACRWDZXOTOOBYFOZS9YSPSRMYZMKBMYSBMWCHJV9LXQQEASTNPVC9USWEQBWHDGXNNYMCMUIHWANCPSRLWPXNHDOLMTMXBLRWXWK9ASDQNGFAJJPNFMTPQERZF9FY9ENZSKDQXXSBABCNK9FSMTEFLXHHXIWSKEXY9EU9QYZOHXGHAYDVDZJH9YWAXXBSUURBBIXYSIEAOAGBVP9F9NJBPN9AJAYONVNRIWOUHAZDGZ9NKXHOIWBTQLXRRQCHG9DQNZYXPXKPPOHMNMWTVEETFLKIMKUDOKMKCW99T9OTNTXBYYHUKUQUYJPRCPDMWIRHYMTXHQWVDHUBXYXKAFU9ZDODFXAZCTVJPTZALFKIEEX9KFNQXORIVYSNQDXEDTQ9LCCSWGSVGJADOZWVXYPVYGV9MSKWWHQFSWSQNOUWVWIKAVDOCTVNTXNGRAO9TLMPRUR9FFZWTAGANOTKNG9OPINIYDNAOPYNLGQMDUSGYEZZWAEYE99ZWVDJHBYSOOXFYFCGISWCTMFUOG9OJVDXEDIOOEF9HVZWQVWANYKNJIYARMDHNDWTZMNFOFGUVVETUBPIDRRZCGYDEKVJQVUHWJSQLBN9VMWONIBABYFLHDNYSNJMLEZKBAVRXYWAYQIWXBTSMUINPOLKNAWNDEWPTAQFYRCLABXL9GLSJBNBWXYDLYOLYVNV9UAFLDHNAELXBYQXERGHAYDRDHAYEUXXTXHQYTOIHDLRROCFJCR9CVWJPLXKAEFPPHWWQPKNZWSWI9WWYGWKUKXMPLZSWDJGRRGANQF9YVNFGIYRCIDHSIU9TUGNHRRTCXVQFNVMUM9GRJFQKDPKCTVQRBIYVIVFBPLVBNIBTKBMGRDDPEYQNNWYFBZEHWCLNZMKZUXQTGOXRPNWYHCWSCHUUNYCTRWBZXVJECIMWTAUAJFTC99AUNEZIRJEPYADMYNW9HFQHGX9QYMGRCLUTQLIHOGAYWRVJVOJZERUPFTOOXQCFEEIXHFBVDITQCPMCVXDNWHIBESNGDBUJHZALMVOOTH9YLFMEZQTPUQBVD9JPKUVBDDMNLRZOFTNLNWKEMRRYCHCXGRSPWMRISRUHOTOJPUCXJZZMZRSBDNVDNWZQLAZWTVJPFUARURHHGOZPBOICYQHY9EIBSZFZSEVDUGKETNVLTKYCGGHNYQYBF9OWDHMOVT9FPYWCVSMBDRTGTBVGPRMVFVWLAZISLEJWLHZWDGYWRZBEHBMNOELYKIMGHGBISMKNLLISNOA9RMFBLXDKNEVVSARAZUDYPVMGOKMPWOIKDHWCFTOMEGPPCALOE9NC9DEFVMUOFFQQJDIPAXOESW9LOYANYLHTVYQBAOCJYDWJKAMPTVRRXAJPPMFFMYNXHBBLLQ9IMMRSCSQXPAGR9BSRZXGZJYVNCWPADSHXITMPBBVMDUEYIMKPJOWBFIUZJYWHFCKRPEU9FZIYNSRZJP9ECGKSYLV9LEFPPEFA9VYBV9TZUXXVUYMGDBTCDHIUTWMCB9NGJBPXGTPNIOHLWNTQIKINRKCOAWYDIQLPYPQDSSSLQDIDMKZDRFHZZACOPWAQJLQXSCAJXNAUPPNLH9XYYUFRNXZS9XKXWUVVYVB9YRSGOLHFGPBKVYMVHCNKPBEAGWWUE9ROVFYHXAUZAOPLNNQQTQXNBXWJMJVQZEQWSZAQYUQHKQGJTSHLXBR9PUVQUWSG9GUMVVXDKZOZEJTAEJHMTOOWUWTO9NUOKL9MIJDSW9HZMLWEJYJTKHRDVBPWUTKJI9GBQZUQRMNDMFTDHJJKPGZVMNYAKXGHQIQPLPSMJOGIIMVHXMYNPTFYKEFWYHBIEASGBYUD9GFIBUIJBKNJCOAGNDDKHGMNWFBRDXUVIZBBENU9QQAZU9SRLVADEWUIHKKOCERSDEGVFKDXYAQDKGLVKVNWXJ9PVIUD9RYYATRM9AAKSPVMDGBNIAMZPWXALNDBHWUBNQWVMIAJIFCAEOSETTEAZ9GBCXP9EPSKBQMZPDPQXOKVRBIWJTMRLWJAJJFPICRQFKGXYYIERERVKRDYTLUNLQNJYHFEDRRQJHYSGLANFGBVAZJLKOYJMJHPJACMMMCQNPZJEHGRYLXSTADGKLVXKSD999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999";
const DEPTH: u8 = 8;
const INDEX: u64 = 4;
mss_wots_generic_signature_verify::<CurlP27>(PUBLIC_KEY, MESSAGE, SIGNATURE, DEPTH, INDEX);
}
fn mss_wots_generic_roundtrip_test<S, G>(generator: G)
where
S: Sponge + Default,
G: PrivateKeyGenerator + Default,
<<<G as PrivateKeyGenerator>::PrivateKey as PrivateKey>::PublicKey as PublicKey>::Signature:
RecoverableSignature,
<<G as PrivateKeyGenerator>::Seed as Seed>::Error: std::fmt::Debug,
{
const SEED: &str = "NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN";
const MESSAGE: &str = "CHXHLHQLOPYP9NSUXTMWWABIBSBLUFXFRNWOZXJPVJPBCIDI99YBSCFYILCHPXHTSEYSYWIGQFERCRVDD";
const DEPTH: u8 = 4;
let seed_trits = TryteBuf::try_from_str(SEED).unwrap().as_trits().encode::<T1B1Buf>();
let seed = G::Seed::from_buf(seed_trits).unwrap();
let message_trits = TryteBuf::try_from_str(MESSAGE).unwrap().as_trits().encode::<T1B1Buf>();
let mss_private_key_generator = MssPrivateKeyGeneratorBuilder::<S, G>::default()
.depth(DEPTH)
.generator(generator)
.build()
.unwrap();
let mut mss_private_key = mss_private_key_generator.generate(&seed, 0).unwrap();
let mss_public_key = mss_private_key.generate_public_key().unwrap();
for _ in 0..(1 << DEPTH - 1) {
let mss_signature = mss_private_key.sign(message_trits.as_i8_slice()).unwrap();
let valid = mss_public_key
.verify(message_trits.as_i8_slice(), &mss_signature)
.unwrap();
assert!(valid);
}
}
#[test]
fn mss_kerl_wots_kerl_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<Kerl>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<Kerl, WotsPrivateKeyGenerator<Kerl>>(wots_private_key_generator);
}
}
#[test]
fn mss_kerl_wots_curl27_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<CurlP27>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<Kerl, WotsPrivateKeyGenerator<CurlP27>>(wots_private_key_generator);
}
}
#[test]
fn mss_kerl_wots_curl81_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<CurlP81>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<Kerl, WotsPrivateKeyGenerator<CurlP81>>(wots_private_key_generator);
}
}
#[test]
fn mss_curl27_wots_kerl_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<Kerl>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<CurlP27, WotsPrivateKeyGenerator<Kerl>>(wots_private_key_generator);
}
}
#[test]
fn mss_curl27_wots_curl27_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<CurlP27>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<CurlP27, WotsPrivateKeyGenerator<CurlP27>>(wots_private_key_generator);
}
}
#[test]
fn mss_curl27_wots_curl81_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<CurlP81>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<CurlP27, WotsPrivateKeyGenerator<CurlP81>>(wots_private_key_generator);
}
}
#[test]
fn mss_curl81_wots_kerl_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<Kerl>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<CurlP81, WotsPrivateKeyGenerator<Kerl>>(wots_private_key_generator);
}
}
#[test]
fn mss_curl81_wots_curl27_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<CurlP27>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<CurlP81, WotsPrivateKeyGenerator<CurlP27>>(wots_private_key_generator);
}
}
#[test]
fn mss_curl81_wots_curl81_roundtrip_test() {
for s in [
WotsSecurityLevel::Low,
WotsSecurityLevel::Medium,
WotsSecurityLevel::High,
]
.to_vec()
.into_iter()
{
let wots_private_key_generator = WotsPrivateKeyGeneratorBuilder::<CurlP81>::default()
.security_level(s)
.build()
.unwrap();
mss_wots_generic_roundtrip_test::<CurlP81, WotsPrivateKeyGenerator<CurlP81>>(wots_private_key_generator);
}
}
}