#![allow(
clippy::too_many_arguments,
clippy::needless_range_loop,
clippy::uninlined_format_args,
clippy::must_use_candidate,
clippy::cast_precision_loss,
clippy::cast_lossless,
clippy::manual_clamp,
clippy::unused_self,
clippy::unnecessary_wraps,
clippy::let_and_return,
clippy::identity_op,
clippy::erasing_op,
clippy::struct_excessive_bools,
clippy::doc_markdown
)]
#![cfg_attr(not(feature = "std"), no_std)]
#![deny(unsafe_code)]
#![deny(unused_qualifications)]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::vec;
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::marker::PhantomData;
pub use fn_dsa::{
DOMAIN_NONE,
FN_DSA_LOGN_512,
FN_DSA_LOGN_1024,
HASH_ID_RAW,
KeyPairGenerator,
KeyPairGeneratorStandard,
SigningKey,
SigningKeyStandard,
VerifyingKey,
VerifyingKeyStandard,
sign_key_size,
signature_size,
vrfy_key_size,
};
pub use lib_q_core::{
Error,
Result,
SigKeypair,
SigPublicKey,
SigSecretKey,
Signature,
};
use rand_core::CryptoRng;
fn get_rng() -> impl CryptoRng {
lib_q_random::FnDsaRng::new()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FnDsaSecurityLevel {
Level1,
Level5,
}
impl FnDsaSecurityLevel {
pub fn logn(&self) -> u32 {
match self {
FnDsaSecurityLevel::Level1 => FN_DSA_LOGN_512,
FnDsaSecurityLevel::Level5 => FN_DSA_LOGN_1024,
}
}
pub fn key_sizes(&self) -> (usize, usize, usize) {
let logn = self.logn();
(
sign_key_size(logn),
vrfy_key_size(logn),
signature_size(logn),
)
}
}
pub trait FnDsaImpl {
fn security_level(&self) -> FnDsaSecurityLevel;
fn logn(&self) -> u32;
}
pub struct FnDsa512 {
_phantom: PhantomData<()>,
}
impl FnDsa512 {
pub fn new() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl FnDsaImpl for FnDsa512 {
fn security_level(&self) -> FnDsaSecurityLevel {
FnDsaSecurityLevel::Level1
}
fn logn(&self) -> u32 {
FN_DSA_LOGN_512
}
}
impl Signature for FnDsa512 {
fn generate_keypair(&self) -> Result<SigKeypair> {
let mut kg = KeyPairGeneratorStandard::default();
let mut sign_key = {
let v = vec![0; sign_key_size(self.logn())];
v
};
let mut vrfy_key = {
let v = vec![0; vrfy_key_size(self.logn())];
v
};
let mut rng = get_rng();
kg.keygen(self.logn(), &mut rng, &mut sign_key, &mut vrfy_key);
Ok(SigKeypair::new(vrfy_key, sign_key))
}
fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>> {
let mut sk = SigningKeyStandard::decode(secret_key.as_bytes()).ok_or_else(|| {
Error::InvalidKeySize {
expected: sign_key_size(self.logn()),
actual: secret_key.as_bytes().len(),
}
})?;
let mut signature = {
let v = vec![0; signature_size(self.logn())];
v
};
let mut rng = get_rng();
sk.sign(
&mut rng,
&DOMAIN_NONE,
&HASH_ID_RAW,
message,
&mut signature,
);
Ok(signature)
}
fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool> {
let expected_sig_size = signature_size(self.logn());
if signature.len() != expected_sig_size {
return Err(Error::InvalidSignatureSize {
expected: expected_sig_size,
actual: signature.len(),
});
}
let vk = VerifyingKeyStandard::decode(public_key.as_bytes()).ok_or_else(|| {
Error::InvalidKeySize {
expected: vrfy_key_size(self.logn()),
actual: public_key.as_bytes().len(),
}
})?;
let is_valid = vk.verify(signature, &DOMAIN_NONE, &HASH_ID_RAW, message);
Ok(is_valid)
}
}
impl Default for FnDsa512 {
fn default() -> Self {
Self::new()
}
}
pub struct FnDsa1024 {
_phantom: PhantomData<()>,
}
impl FnDsa1024 {
pub fn new() -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl FnDsaImpl for FnDsa1024 {
fn security_level(&self) -> FnDsaSecurityLevel {
FnDsaSecurityLevel::Level5
}
fn logn(&self) -> u32 {
FN_DSA_LOGN_1024
}
}
impl Signature for FnDsa1024 {
fn generate_keypair(&self) -> Result<SigKeypair> {
let mut kg = KeyPairGeneratorStandard::default();
let mut sign_key = {
let v = vec![0; sign_key_size(self.logn())];
v
};
let mut vrfy_key = {
let v = vec![0; vrfy_key_size(self.logn())];
v
};
let mut rng = get_rng();
kg.keygen(self.logn(), &mut rng, &mut sign_key, &mut vrfy_key);
Ok(SigKeypair::new(vrfy_key, sign_key))
}
fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>> {
let mut sk = SigningKeyStandard::decode(secret_key.as_bytes()).ok_or_else(|| {
Error::InvalidKeySize {
expected: sign_key_size(self.logn()),
actual: secret_key.as_bytes().len(),
}
})?;
let mut signature = {
let v = vec![0; signature_size(self.logn())];
v
};
let mut rng = get_rng();
sk.sign(
&mut rng,
&DOMAIN_NONE,
&HASH_ID_RAW,
message,
&mut signature,
);
Ok(signature)
}
fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool> {
let expected_sig_size = signature_size(self.logn());
if signature.len() != expected_sig_size {
return Err(Error::InvalidSignatureSize {
expected: expected_sig_size,
actual: signature.len(),
});
}
let vk = VerifyingKeyStandard::decode(public_key.as_bytes()).ok_or_else(|| {
Error::InvalidKeySize {
expected: vrfy_key_size(self.logn()),
actual: public_key.as_bytes().len(),
}
})?;
let is_valid = vk.verify(signature, &DOMAIN_NONE, &HASH_ID_RAW, message);
Ok(is_valid)
}
}
impl Default for FnDsa1024 {
fn default() -> Self {
Self::new()
}
}
pub struct FnDsa {
security_level: FnDsaSecurityLevel,
}
impl FnDsa {
pub fn new(security_level: FnDsaSecurityLevel) -> Self {
Self { security_level }
}
pub fn level1() -> Self {
Self::new(FnDsaSecurityLevel::Level1)
}
pub fn level5() -> Self {
Self::new(FnDsaSecurityLevel::Level5)
}
pub fn security_level(&self) -> FnDsaSecurityLevel {
self.security_level
}
pub fn logn(&self) -> u32 {
self.security_level.logn()
}
}
impl Signature for FnDsa {
fn generate_keypair(&self) -> Result<SigKeypair> {
let mut kg = KeyPairGeneratorStandard::default();
let mut sign_key = {
let v = vec![0; sign_key_size(self.logn())];
v
};
let mut vrfy_key = {
let v = vec![0; vrfy_key_size(self.logn())];
v
};
let mut rng = get_rng();
kg.keygen(self.logn(), &mut rng, &mut sign_key, &mut vrfy_key);
Ok(SigKeypair::new(vrfy_key, sign_key))
}
fn sign(&self, secret_key: &SigSecretKey, message: &[u8]) -> Result<Vec<u8>> {
let mut sk = SigningKeyStandard::decode(secret_key.as_bytes()).ok_or_else(|| {
Error::InvalidKeySize {
expected: sign_key_size(self.logn()),
actual: secret_key.as_bytes().len(),
}
})?;
let mut signature = {
let v = vec![0; signature_size(self.logn())];
v
};
let mut rng = get_rng();
sk.sign(
&mut rng,
&DOMAIN_NONE,
&HASH_ID_RAW,
message,
&mut signature,
);
Ok(signature)
}
fn verify(&self, public_key: &SigPublicKey, message: &[u8], signature: &[u8]) -> Result<bool> {
let expected_sig_size = signature_size(self.logn());
if signature.len() != expected_sig_size {
return Err(Error::InvalidSignatureSize {
expected: expected_sig_size,
actual: signature.len(),
});
}
let vk = VerifyingKeyStandard::decode(public_key.as_bytes()).ok_or_else(|| {
Error::InvalidKeySize {
expected: vrfy_key_size(self.logn()),
actual: public_key.as_bytes().len(),
}
})?;
let is_valid = vk.verify(signature, &DOMAIN_NONE, &HASH_ID_RAW, message);
Ok(is_valid)
}
}
impl Default for FnDsa {
fn default() -> Self {
Self::level1()
}
}
pub mod utils {
use super::*;
pub fn get_key_sizes(security_level: FnDsaSecurityLevel) -> (usize, usize, usize) {
security_level.key_sizes()
}
pub fn validate_key_sizes(
security_level: FnDsaSecurityLevel,
sign_key_size: usize,
vrfy_key_size: usize,
signature_size: usize,
) -> Result<()> {
let (expected_sign, expected_vrfy, expected_sig) = security_level.key_sizes();
if sign_key_size != expected_sign {
return Err(Error::InvalidKeySize {
expected: expected_sign,
actual: sign_key_size,
});
}
if vrfy_key_size != expected_vrfy {
return Err(Error::InvalidKeySize {
expected: expected_vrfy,
actual: vrfy_key_size,
});
}
if signature_size != expected_sig {
return Err(Error::InvalidKeySize {
expected: expected_sig,
actual: signature_size,
});
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
type TestResult = std::result::Result<(), Box<dyn std::error::Error>>;
#[test]
fn test_fn_dsa512_creation() {
let fn_dsa = FnDsa512::new();
assert_eq!(fn_dsa.security_level(), FnDsaSecurityLevel::Level1);
assert_eq!(fn_dsa.logn(), FN_DSA_LOGN_512);
}
#[test]
fn test_fn_dsa1024_creation() {
let fn_dsa = FnDsa1024::new();
assert_eq!(fn_dsa.security_level(), FnDsaSecurityLevel::Level5);
assert_eq!(fn_dsa.logn(), FN_DSA_LOGN_1024);
}
#[test]
fn test_fn_dsa_generic_creation() {
let fn_dsa1 = FnDsa::level1();
assert_eq!(fn_dsa1.security_level(), FnDsaSecurityLevel::Level1);
let fn_dsa5 = FnDsa::level5();
assert_eq!(fn_dsa5.security_level(), FnDsaSecurityLevel::Level5);
}
#[test]
fn test_key_sizes() {
let (sign_size_512, vrfy_size_512, sig_size_512) = FnDsaSecurityLevel::Level1.key_sizes();
let (sign_size_1024, vrfy_size_1024, sig_size_1024) =
FnDsaSecurityLevel::Level5.key_sizes();
assert!(sign_size_1024 > sign_size_512);
assert!(vrfy_size_1024 > vrfy_size_512);
assert!(sig_size_1024 > sig_size_512);
assert_eq!(sign_size_512, 1281);
assert_eq!(vrfy_size_512, 897);
assert_eq!(sig_size_512, 666);
assert_eq!(sign_size_1024, 2305);
assert_eq!(vrfy_size_1024, 1793);
assert_eq!(sig_size_1024, 1280);
}
#[test]
fn test_utils_validation() {
let result = utils::validate_key_sizes(FnDsaSecurityLevel::Level1, 1281, 897, 666);
assert!(result.is_ok());
let result = utils::validate_key_sizes(
FnDsaSecurityLevel::Level1,
1280,
897,
666, );
assert!(result.is_err());
}
#[test]
fn test_keypair_generation() -> TestResult {
let fn_dsa = FnDsa512::new();
let keypair = fn_dsa.generate_keypair()?;
assert_eq!(
keypair.public_key().as_bytes().len(),
vrfy_key_size(FN_DSA_LOGN_512)
);
assert_eq!(
keypair.secret_key().as_bytes().len(),
sign_key_size(FN_DSA_LOGN_512)
);
let message = b"coverage keypair generation message";
let signature = fn_dsa.sign(&keypair.secret_key, message)?;
assert_eq!(signature.len(), signature_size(FN_DSA_LOGN_512));
assert!(fn_dsa.verify(&keypair.public_key, message, &signature)?);
let invalid_signature = vec![0_u8; signature.len().saturating_sub(1)];
let verify_err = fn_dsa.verify(&keypair.public_key, message, &invalid_signature);
assert!(matches!(
verify_err,
Err(Error::InvalidSignatureSize {
expected,
actual
}) if expected == signature_size(FN_DSA_LOGN_512) && actual + 1 == expected
));
let invalid_secret_key = SigSecretKey::new(vec![0_u8; sign_key_size(FN_DSA_LOGN_512) - 1]);
let sign_err = fn_dsa.sign(&invalid_secret_key, b"invalid secret key");
assert!(matches!(
sign_err,
Err(Error::InvalidKeySize {
expected,
actual
}) if expected == sign_key_size(FN_DSA_LOGN_512)
&& actual == sign_key_size(FN_DSA_LOGN_512) - 1
));
let invalid_public_key = SigPublicKey::new(vec![0_u8; vrfy_key_size(FN_DSA_LOGN_512) - 1]);
let verify_key_err = fn_dsa.verify(&invalid_public_key, message, &signature);
assert!(matches!(
verify_key_err,
Err(Error::InvalidKeySize {
expected,
actual
}) if expected == vrfy_key_size(FN_DSA_LOGN_512)
&& actual == vrfy_key_size(FN_DSA_LOGN_512) - 1
));
Ok(())
}
#[test]
fn test_sign_and_verify() -> TestResult {
let fn_dsa = FnDsa512::new();
let keypair = fn_dsa.generate_keypair()?;
let message = b"Hello, FN-DSA!";
let signature = fn_dsa.sign(&keypair.secret_key, message)?;
let is_valid = fn_dsa.verify(&keypair.public_key, message, &signature)?;
assert!(is_valid, "Signature should be valid");
let wrong_message = b"Wrong message";
let is_valid = fn_dsa.verify(&keypair.public_key, wrong_message, &signature)?;
assert!(!is_valid, "Signature should be invalid for wrong message");
Ok(())
}
#[test]
fn test_sign_and_verify_1024() -> TestResult {
let fn_dsa = FnDsa1024::new();
let keypair = fn_dsa.generate_keypair()?;
let message = b"Hello, FN-DSA 1024!";
let signature = fn_dsa.sign(&keypair.secret_key, message)?;
let is_valid = fn_dsa.verify(&keypair.public_key, message, &signature)?;
assert!(is_valid, "Signature should be valid");
Ok(())
}
}