use affinidi_secrets_resolver::secrets::KeyType;
use crate::DataIntegrityError;
use crate::crypto_suites::CryptoSuite;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum Canonicalization {
Jcs,
Rdfc,
Custom,
}
pub trait CryptoSuiteOps: Send + Sync + 'static {
fn name(&self) -> &'static str;
fn canonicalization(&self) -> Canonicalization;
fn compatible_key_types(&self) -> &'static [KeyType];
fn verify(&self, key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError>;
}
pub struct EddsaJcs2022;
pub struct EddsaRdfc2022;
fn eddsa_verify(key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError> {
use crate::SignatureFailure;
use ed25519_dalek::{Signature, VerifyingKey};
let verifying_key =
VerifyingKey::try_from(key).map_err(|_| DataIntegrityError::InvalidPublicKey {
codec: None,
len: key.len(),
reason: "invalid Ed25519 public key bytes".to_string(),
})?;
let signature =
Signature::from_slice(sig).map_err(|_| DataIntegrityError::InvalidSignature {
suite: CryptoSuite::EddsaJcs2022,
reason: SignatureFailure::Malformed,
})?;
verifying_key.verify_strict(data, &signature).map_err(|_| {
DataIntegrityError::InvalidSignature {
suite: CryptoSuite::EddsaJcs2022,
reason: SignatureFailure::Invalid,
}
})
}
impl CryptoSuiteOps for EddsaJcs2022 {
fn name(&self) -> &'static str {
"eddsa-jcs-2022"
}
fn canonicalization(&self) -> Canonicalization {
Canonicalization::Jcs
}
fn compatible_key_types(&self) -> &'static [KeyType] {
&[KeyType::Ed25519]
}
fn verify(&self, key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError> {
eddsa_verify(key, data, sig)
}
}
impl CryptoSuiteOps for EddsaRdfc2022 {
fn name(&self) -> &'static str {
"eddsa-rdfc-2022"
}
fn canonicalization(&self) -> Canonicalization {
Canonicalization::Rdfc
}
fn compatible_key_types(&self) -> &'static [KeyType] {
&[KeyType::Ed25519]
}
fn verify(&self, key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError> {
eddsa_verify(key, data, sig)
}
}
#[cfg(feature = "bbs-2023")]
pub struct Bbs2023;
#[cfg(feature = "bbs-2023")]
impl CryptoSuiteOps for Bbs2023 {
fn name(&self) -> &'static str {
"bbs-2023"
}
fn canonicalization(&self) -> Canonicalization {
Canonicalization::Custom
}
fn compatible_key_types(&self) -> &'static [KeyType] {
&[]
}
fn verify(&self, _key: &[u8], _data: &[u8], _sig: &[u8]) -> Result<(), DataIntegrityError> {
Err(DataIntegrityError::UnsupportedCryptoSuite {
name: "bbs-2023 verification uses bbs_2023::verify_proof, not CryptoSuiteOps::verify"
.to_string(),
})
}
}
#[cfg(feature = "ml-dsa")]
pub struct MlDsa44Jcs2024;
#[cfg(feature = "ml-dsa")]
pub struct MlDsa44Rdfc2024;
#[cfg(feature = "ml-dsa")]
fn ml_dsa_44_verify(
suite: CryptoSuite,
key: &[u8],
data: &[u8],
sig: &[u8],
) -> Result<(), DataIntegrityError> {
use crate::SignatureFailure;
affinidi_crypto::ml_dsa::verify_ml_dsa_44(key, data, sig).map_err(|_| {
DataIntegrityError::InvalidSignature {
suite,
reason: SignatureFailure::Invalid,
}
})
}
#[cfg(feature = "ml-dsa")]
impl CryptoSuiteOps for MlDsa44Jcs2024 {
fn name(&self) -> &'static str {
"mldsa44-jcs-2024"
}
fn canonicalization(&self) -> Canonicalization {
Canonicalization::Jcs
}
fn compatible_key_types(&self) -> &'static [KeyType] {
&[KeyType::MlDsa44]
}
fn verify(&self, key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError> {
ml_dsa_44_verify(CryptoSuite::MlDsa44Jcs2024, key, data, sig)
}
}
#[cfg(feature = "ml-dsa")]
impl CryptoSuiteOps for MlDsa44Rdfc2024 {
fn name(&self) -> &'static str {
"mldsa44-rdfc-2024"
}
fn canonicalization(&self) -> Canonicalization {
Canonicalization::Rdfc
}
fn compatible_key_types(&self) -> &'static [KeyType] {
&[KeyType::MlDsa44]
}
fn verify(&self, key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError> {
ml_dsa_44_verify(CryptoSuite::MlDsa44Rdfc2024, key, data, sig)
}
}
#[cfg(feature = "slh-dsa")]
pub struct SlhDsa128Jcs2024;
#[cfg(feature = "slh-dsa")]
pub struct SlhDsa128Rdfc2024;
#[cfg(feature = "slh-dsa")]
fn slh_dsa_verify(
suite: CryptoSuite,
key: &[u8],
data: &[u8],
sig: &[u8],
) -> Result<(), DataIntegrityError> {
use crate::SignatureFailure;
affinidi_crypto::slh_dsa::verify_slh_dsa_sha2_128s(key, data, sig).map_err(|_| {
DataIntegrityError::InvalidSignature {
suite,
reason: SignatureFailure::Invalid,
}
})
}
#[cfg(feature = "slh-dsa")]
impl CryptoSuiteOps for SlhDsa128Jcs2024 {
fn name(&self) -> &'static str {
"slhdsa128-jcs-2024"
}
fn canonicalization(&self) -> Canonicalization {
Canonicalization::Jcs
}
fn compatible_key_types(&self) -> &'static [KeyType] {
&[KeyType::SlhDsaSha2_128s]
}
fn verify(&self, key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError> {
slh_dsa_verify(CryptoSuite::SlhDsa128Jcs2024, key, data, sig)
}
}
#[cfg(feature = "slh-dsa")]
impl CryptoSuiteOps for SlhDsa128Rdfc2024 {
fn name(&self) -> &'static str {
"slhdsa128-rdfc-2024"
}
fn canonicalization(&self) -> Canonicalization {
Canonicalization::Rdfc
}
fn compatible_key_types(&self) -> &'static [KeyType] {
&[KeyType::SlhDsaSha2_128s]
}
fn verify(&self, key: &[u8], data: &[u8], sig: &[u8]) -> Result<(), DataIntegrityError> {
slh_dsa_verify(CryptoSuite::SlhDsa128Rdfc2024, key, data, sig)
}
}