#[cfg(test)]
mod sumrec;
#[cfg(not(feature = "with-bench"))]
mod common;
#[cfg(not(feature = "with-bench"))]
mod sum;
#[cfg(feature = "with-bench")]
pub mod common;
#[cfg(feature = "with-bench")]
pub mod sum;
use crate::evolving::{EvolvingStatus, KeyEvolvingAlgorithm};
use crate::kes::KeyEvolvingSignatureAlgorithm;
use crate::key::{
AsymmetricKey, AsymmetricPublicKey, PublicKeyError, SecretKeyError, SecretKeySizeStatic,
};
use crate::sign::{SignatureError, SigningAlgorithm, Verification, VerificationAlgorithm};
use rand_core::{CryptoRng, RngCore};
#[cfg_attr(
any(test, feature = "property-test-api"),
derive(test_strategy::Arbitrary, Debug)
)]
pub struct SumEd25519_12;
const DEPTH: common::Depth = common::Depth(12);
impl AsymmetricPublicKey for SumEd25519_12 {
type Public = sum::PublicKey;
const PUBLIC_BECH32_HRP: &'static str = "kes25519-12-pk";
const PUBLIC_KEY_SIZE: usize = 32;
fn public_from_binary(data: &[u8]) -> Result<Self::Public, PublicKeyError> {
sum::PublicKey::from_bytes(data).map_err(|e| match e {
sum::Error::InvalidPublicKeySize(_) => PublicKeyError::SizeInvalid,
_ => PublicKeyError::StructureInvalid,
})
}
}
impl AsymmetricKey for SumEd25519_12 {
type Secret = sum::SecretKey;
type PubAlg = SumEd25519_12;
const SECRET_BECH32_HRP: &'static str = "kes25519-12-sk";
fn generate<T: RngCore + CryptoRng>(mut rng: T) -> Self::Secret {
let mut priv_bytes = [0u8; common::Seed::SIZE];
rng.fill_bytes(&mut priv_bytes);
let seed = common::Seed::from_bytes(priv_bytes);
let (sk, _) = sum::keygen(DEPTH, &seed);
sk
}
fn compute_public(key: &Self::Secret) -> sum::PublicKey {
key.compute_public()
}
fn secret_from_binary(data: &[u8]) -> Result<Self::Secret, SecretKeyError> {
sum::SecretKey::from_bytes(DEPTH, data).map_err(|e| match e {
sum::Error::InvalidSecretKeySize(_) => SecretKeyError::SizeInvalid,
_ => SecretKeyError::StructureInvalid,
})
}
}
impl SecretKeySizeStatic for SumEd25519_12 {
const SECRET_KEY_SIZE: usize = sum::maximum_secret_key_size(DEPTH);
}
impl VerificationAlgorithm for SumEd25519_12 {
type Signature = sum::Signature;
const SIGNATURE_SIZE: usize = sum::signature_size(DEPTH);
const SIGNATURE_BECH32_HRP: &'static str = "kes25519-12-sig";
fn signature_from_bytes(data: &[u8]) -> Result<Self::Signature, SignatureError> {
sum::Signature::from_bytes(DEPTH, data).map_err(|e| match e {
sum::Error::InvalidSignatureSize(_) => SignatureError::SizeInvalid {
expected: Self::SIGNATURE_SIZE,
got: data.len(),
},
_ => SignatureError::StructureInvalid,
})
}
fn verify_bytes(
pubkey: &Self::Public,
signature: &Self::Signature,
msg: &[u8],
) -> Verification {
if sum::verify(pubkey, msg, signature) {
Verification::Success
} else {
Verification::Failed
}
}
}
impl SigningAlgorithm for SumEd25519_12 {
fn sign(key: &Self::Secret, msg: &[u8]) -> sum::Signature {
sum::sign(key, msg)
}
}
impl KeyEvolvingAlgorithm for SumEd25519_12 {
fn get_period(sec: &Self::Secret) -> u32 {
sec.t() as u32
}
fn update(key: &mut Self::Secret) -> EvolvingStatus {
if sum::update(key).is_ok() {
EvolvingStatus::Success
} else {
EvolvingStatus::Failed
}
}
}
impl KeyEvolvingSignatureAlgorithm for SumEd25519_12 {
fn get_period(sig: &Self::Signature) -> u32 {
sig.t() as u32
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
use test_strategy::proptest;
#[test]
fn public_from_binary_correct_size() {
SumEd25519_12::public_from_binary(&[0; SumEd25519_12::PUBLIC_KEY_SIZE]).unwrap();
}
#[test]
fn public_from_binary_empty_slice() {
assert!(matches!(
SumEd25519_12::public_from_binary(&[]),
Err(PublicKeyError::SizeInvalid)
))
}
#[proptest]
fn public_from_binary_size_check(#[strategy(..SumEd25519_12::PUBLIC_KEY_SIZE * 10)] n: usize) {
let public_key = SumEd25519_12::public_from_binary(&vec![0; n]);
prop_assert_eq!(
n != SumEd25519_12::PUBLIC_KEY_SIZE,
matches!(public_key, Err(PublicKeyError::SizeInvalid))
);
}
#[test]
fn signature_from_binary_correct_size() {
SumEd25519_12::signature_from_bytes(&vec![0; SumEd25519_12::SIGNATURE_SIZE]).unwrap();
}
#[test]
fn signature_from_binary_empty_slice() {
assert!(matches!(
SumEd25519_12::signature_from_bytes(&[]),
Err(SignatureError::SizeInvalid { .. })
))
}
#[proptest]
fn signature_from_binary_size_check(
#[strategy(..SumEd25519_12::SIGNATURE_SIZE * 10)] n: usize,
) {
let signature = SumEd25519_12::signature_from_bytes(&vec![0; n]);
prop_assert_eq!(
n != SumEd25519_12::SIGNATURE_SIZE,
matches!(signature, Err(SignatureError::SizeInvalid { .. }))
);
}
#[proptest]
fn secret_from_binary_size_check(#[strategy(..SumEd25519_12::SECRET_KEY_SIZE * 10)] n: usize) {
let private_key = SumEd25519_12::secret_from_binary(&vec![0; n]);
assert_eq!(
n != SumEd25519_12::SECRET_KEY_SIZE,
private_key.err() == Some(SecretKeyError::SizeInvalid)
);
}
}