Values, Cleaning, Docs, Tests, Example (Current Example is Wrong)
This commit is contained in:
parent
775282caf4
commit
c2a7afe6c1
37 changed files with 1693 additions and 520 deletions
|
|
@ -57,15 +57,14 @@ impl MultiEncryptedMessage {
|
|||
pub fn from_bytes(bytes: &[u8]) -> Result<Self, CryptoError> {
|
||||
let mut offset = 0;
|
||||
let read_u16 = |off: &mut usize| -> Result<u16, CryptoError> {
|
||||
let v = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(*off..*off + 2)
|
||||
.ok_or(CryptoError::DecryptionFailed)?
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
);
|
||||
let slice = bytes
|
||||
.get(*off..*off + 2)
|
||||
.ok_or(CryptoError::DecryptionFailed)?;
|
||||
let arr: [u8; 2] = slice
|
||||
.try_into()
|
||||
.map_err(|_| CryptoError::DecryptionFailed)?;
|
||||
*off += 2;
|
||||
Ok(v)
|
||||
Ok(u16::from_be_bytes(arr))
|
||||
};
|
||||
|
||||
let num = read_u16(&mut offset)? as usize;
|
||||
|
|
@ -198,36 +197,4 @@ pub fn decrypt_multi(
|
|||
Err(CryptoError::DecryptionFailed)
|
||||
}
|
||||
|
||||
#[cfg(feature = "ed25519-dalek")]
|
||||
pub fn verify_ed25519_sig(
|
||||
public_key: &crate::keypair::SignaturePublicKey,
|
||||
msg: &[u8],
|
||||
signature: &[u8],
|
||||
) -> Result<(), CryptoError> {
|
||||
crate::sign::verify_ed25519(public_key, msg, signature)
|
||||
}
|
||||
|
||||
#[cfg(feature = "ml-dsa")]
|
||||
pub fn verify_ml_dsa_sig(
|
||||
public_key: &crate::keypair::SignaturePqPublicKey,
|
||||
msg: &[u8],
|
||||
signature: &[u8],
|
||||
) -> Result<(), CryptoError> {
|
||||
crate::sign::verify_ml_dsa(public_key, msg, signature)
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify both an Ed25519 and ML-DSA signature (dual) against
|
||||
* the public keys in a `PublicKeyBundle`.
|
||||
*/
|
||||
#[cfg(all(feature = "ed25519-dalek", feature = "ml-dsa"))]
|
||||
pub fn verify_dual_sig(
|
||||
public_keys: &crate::keypair::PublicKeyBundle,
|
||||
msg: &[u8],
|
||||
ed25519_sig: &[u8],
|
||||
mldsa_sig: &[u8],
|
||||
) -> Result<(), CryptoError> {
|
||||
verify_ed25519_sig(&public_keys.sig_cl_public_key, msg, ed25519_sig)?;
|
||||
verify_ml_dsa_sig(&public_keys.sig_pq_public_key, msg, mldsa_sig)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ pub struct HybridKem;
|
|||
#[cfg(feature = "mlkem-tls")]
|
||||
impl HybridKem {
|
||||
pub fn generate_keypair() -> (KemPrivateKey, KemPublicKey) {
|
||||
let (dk, ek) =
|
||||
let (ek, dk) =
|
||||
mlkem_tls::X25519MlKem768::keygen(&mut rand_core::OsRng);
|
||||
(
|
||||
KemPrivateKey::new(dk.as_bytes().to_vec()),
|
||||
|
|
|
|||
|
|
@ -287,14 +287,18 @@ impl PublicKeyBundle {
|
|||
use crate::error::CryptoError;
|
||||
let mut offset = 0;
|
||||
|
||||
let kem_len = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(offset..offset + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
let read_u16 = |off: &mut usize| -> Result<u16, CryptoError> {
|
||||
let slice = bytes
|
||||
.get(*off..*off + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?;
|
||||
let arr: [u8; 2] = slice
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
) as usize;
|
||||
offset += 2;
|
||||
.map_err(|_| CryptoError::InvalidKeyLength)?;
|
||||
*off += 2;
|
||||
Ok(u16::from_be_bytes(arr))
|
||||
};
|
||||
|
||||
let kem_len = read_u16(&mut offset)? as usize;
|
||||
let kem = KemPublicKey::new(
|
||||
bytes
|
||||
.get(offset..offset + kem_len)
|
||||
|
|
@ -303,14 +307,7 @@ impl PublicKeyBundle {
|
|||
);
|
||||
offset += kem_len;
|
||||
|
||||
let pq_len = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(offset..offset + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
) as usize;
|
||||
offset += 2;
|
||||
let pq_len = read_u16(&mut offset)? as usize;
|
||||
let pq = SignaturePqPublicKey::new(
|
||||
bytes
|
||||
.get(offset..offset + pq_len)
|
||||
|
|
@ -319,14 +316,7 @@ impl PublicKeyBundle {
|
|||
);
|
||||
offset += pq_len;
|
||||
|
||||
let cl_len = u16::from_be_bytes(
|
||||
bytes
|
||||
.get(offset..offset + 2)
|
||||
.ok_or(CryptoError::InvalidKeyLength)?
|
||||
.try_into()
|
||||
.unwrap(),
|
||||
) as usize;
|
||||
offset += 2;
|
||||
let cl_len = read_u16(&mut offset)? as usize;
|
||||
let cl = SignaturePublicKey::new(
|
||||
bytes
|
||||
.get(offset..offset + cl_len)
|
||||
|
|
|
|||
|
|
@ -46,16 +46,248 @@ pub use hash::{sha256, sha256_double, Sha256Hasher};
|
|||
pub use kdf::{derive_encryption_key, hkdf_expand, hkdf_extract};
|
||||
|
||||
#[cfg(feature = "mlkem-tls")]
|
||||
pub use kem::HybridKem;
|
||||
pub use kem::{Encapsulated, HybridKem};
|
||||
|
||||
#[cfg(all(feature = "mlkem-tls", feature = "chacha20poly1305", feature = "hkdf"))]
|
||||
pub use helper::{decrypt_multi, encrypt_multi, MultiEncryptedMessage, RecipientEntry};
|
||||
|
||||
#[cfg(feature = "ed25519-dalek")]
|
||||
pub use helper::verify_ed25519_sig;
|
||||
/* ================================ TESTS ================================ */
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[cfg(feature = "ml-dsa")]
|
||||
pub use helper::verify_ml_dsa_sig;
|
||||
#[cfg(feature = "chacha20poly1305")]
|
||||
#[test]
|
||||
fn aead_encrypt_decrypt() {
|
||||
use crate::aead::{AeadDecrypt, AeadEncrypt, ChaCha20Poly1305};
|
||||
let key = [0xAB; 32];
|
||||
let cipher = ChaCha20Poly1305::new(key);
|
||||
let ct = cipher.encrypt(b"hello world", b"aad").unwrap();
|
||||
let pt = cipher.decrypt(&ct, b"aad").unwrap();
|
||||
assert_eq!(pt, b"hello world");
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "ed25519-dalek", feature = "ml-dsa"))]
|
||||
pub use helper::verify_dual_sig;
|
||||
#[cfg(feature = "chacha20poly1305")]
|
||||
#[test]
|
||||
fn aead_wrong_key_fails() {
|
||||
use crate::aead::{AeadDecrypt, AeadEncrypt, ChaCha20Poly1305};
|
||||
let cipher_a = ChaCha20Poly1305::new([0xAB; 32]);
|
||||
let cipher_b = ChaCha20Poly1305::new([0xCD; 32]);
|
||||
let ct = cipher_a.encrypt(b"hello", b"").unwrap();
|
||||
assert!(cipher_b.decrypt(&ct, b"").is_err());
|
||||
}
|
||||
|
||||
#[cfg(feature = "chacha20poly1305")]
|
||||
#[test]
|
||||
fn aead_wrong_aad_fails() {
|
||||
use crate::aead::{AeadDecrypt, AeadEncrypt, ChaCha20Poly1305};
|
||||
let cipher = ChaCha20Poly1305::new([0xAB; 32]);
|
||||
let ct = cipher.encrypt(b"hello", b"correct-aad").unwrap();
|
||||
assert!(cipher.decrypt(&ct, b"wrong-aad").is_err());
|
||||
}
|
||||
|
||||
#[cfg(feature = "ed25519-dalek")]
|
||||
#[test]
|
||||
fn ed25519_sign_verify() {
|
||||
let (signer, sk, pk) = Ed25519Signer::generate();
|
||||
let msg = b"test message";
|
||||
let sig = signer.sign(msg).unwrap();
|
||||
signer.verify(msg, &sig).unwrap();
|
||||
verify_ed25519(&pk, msg, &sig).unwrap();
|
||||
|
||||
let loaded = Ed25519Signer::new(&sk).unwrap();
|
||||
loaded.verify(msg, &sig).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(feature = "ed25519-dalek")]
|
||||
#[test]
|
||||
fn ed25519_wrong_sig_fails() {
|
||||
let (signer, _, pk) = Ed25519Signer::generate();
|
||||
let msg = b"test message";
|
||||
let sig = signer.sign(msg).unwrap();
|
||||
assert!(verify_ed25519(&pk, b"wrong message", &sig).is_err());
|
||||
}
|
||||
|
||||
#[cfg(feature = "ml-dsa")]
|
||||
#[test]
|
||||
fn mldsa_sign_verify() {
|
||||
let (signer, sk, pk) = MlDsaSigner::generate();
|
||||
let msg = b"test message";
|
||||
let sig = signer.sign(msg).unwrap();
|
||||
signer.verify(msg, &sig).unwrap();
|
||||
verify_ml_dsa(&pk, msg, &sig).unwrap();
|
||||
|
||||
let loaded = MlDsaSigner::new(&sk, &pk).unwrap();
|
||||
loaded.verify(msg, &sig).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(feature = "ml-dsa")]
|
||||
#[test]
|
||||
fn mldsa_wrong_sig_fails() {
|
||||
let (signer, _, pk) = MlDsaSigner::generate();
|
||||
let msg = b"test message";
|
||||
let sig = signer.sign(msg).unwrap();
|
||||
assert!(verify_ml_dsa(&pk, b"wrong message", &sig).is_err());
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "ed25519-dalek", feature = "ml-dsa"))]
|
||||
#[test]
|
||||
fn dual_sign_verify() {
|
||||
use crate::sign::sign_dual;
|
||||
|
||||
let (ed_signer, _, _) = Ed25519Signer::generate();
|
||||
let (ml_signer, _, _) = MlDsaSigner::generate();
|
||||
let dual = sign_dual(ed_signer.signing_key(), ml_signer.signing_key(), b"msg");
|
||||
dual
|
||||
.verify(
|
||||
ed_signer.verifying_key(),
|
||||
ml_signer.verifying_key(),
|
||||
b"msg",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "ed25519-dalek", feature = "ml-dsa"))]
|
||||
#[test]
|
||||
fn dual_wrong_message_fails() {
|
||||
use crate::sign::sign_dual;
|
||||
|
||||
let (ed_signer, _, _) = Ed25519Signer::generate();
|
||||
let (ml_signer, _, _) = MlDsaSigner::generate();
|
||||
let dual = sign_dual(ed_signer.signing_key(), ml_signer.signing_key(), b"msg");
|
||||
assert!(dual
|
||||
.verify(ed_signer.verifying_key(), ml_signer.verifying_key(), b"wrong")
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[cfg(feature = "hkdf")]
|
||||
#[test]
|
||||
fn hkdf_expand_produces_key() {
|
||||
let key = derive_encryption_key(b"ikm", b"salt", b"context").unwrap();
|
||||
assert_eq!(key.len(), 32);
|
||||
|
||||
let expanded = hkdf_expand(b"ikm", b"salt", b"info", 64).unwrap();
|
||||
assert_eq!(expanded.len(), 64);
|
||||
}
|
||||
|
||||
#[cfg(feature = "hkdf")]
|
||||
#[test]
|
||||
fn hkdf_different_info_different_key() {
|
||||
let a = derive_encryption_key(b"ikm", b"salt", b"info-a").unwrap();
|
||||
let b = derive_encryption_key(b"ikm", b"salt", b"info-b").unwrap();
|
||||
assert_ne!(a, b);
|
||||
}
|
||||
|
||||
#[cfg(feature = "sha2")]
|
||||
#[test]
|
||||
fn sha256_hashes() {
|
||||
let h = sha256(b"hello");
|
||||
assert_eq!(h.len(), 32);
|
||||
|
||||
let h2 = sha256_double(b"hello");
|
||||
assert_eq!(h2.len(), 32);
|
||||
assert_ne!(h, h2);
|
||||
}
|
||||
|
||||
#[cfg(feature = "sha2")]
|
||||
#[test]
|
||||
fn sha256_deterministic() {
|
||||
assert_eq!(sha256(b"hello"), sha256(b"hello"));
|
||||
}
|
||||
|
||||
#[cfg(feature = "sha2")]
|
||||
#[test]
|
||||
fn sha256_hasher_incremental() {
|
||||
let mut hasher = Sha256Hasher::new();
|
||||
hasher.update(b"hel");
|
||||
hasher.update(b"lo");
|
||||
let h = hasher.finalize();
|
||||
assert_eq!(h, sha256(b"hello"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn key_types_roundtrip() {
|
||||
let data = vec![1u8, 2, 3, 4];
|
||||
let enc_pk = EncryptionPublicKey::new(data.clone());
|
||||
assert_eq!(enc_pk.as_bytes(), &data);
|
||||
let enc_sk = EncryptionPrivateKey::new(data.clone());
|
||||
assert_eq!(enc_sk.as_bytes(), &data);
|
||||
|
||||
let sig_pk = SignaturePublicKey::new(data.clone());
|
||||
assert_eq!(sig_pk.as_bytes(), &data);
|
||||
let sig_sk = SignaturePrivateKey::new(data.clone());
|
||||
assert_eq!(sig_sk.as_bytes(), &data);
|
||||
|
||||
let kem_pk = KemPublicKey::new(data.clone());
|
||||
assert_eq!(kem_pk.as_bytes(), &data);
|
||||
let kem_sk = KemPrivateKey::new(data.clone());
|
||||
assert_eq!(kem_sk.as_bytes(), &data);
|
||||
|
||||
let sig_pq_pk = SignaturePqPublicKey::new(data.clone());
|
||||
assert_eq!(sig_pq_pk.as_bytes(), &data);
|
||||
let sig_pq_sk = SignaturePqPrivateKey::new(data.clone());
|
||||
assert_eq!(sig_pq_sk.as_bytes(), &data);
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mlkem-tls", feature = "ml-dsa", feature = "ed25519-dalek"))]
|
||||
#[test]
|
||||
fn keyring_generate_and_bundle() {
|
||||
let kr = Keyring::generate();
|
||||
let bundle = kr.public_key_bundle();
|
||||
assert!(!bundle.kem_public_key.as_bytes().is_empty());
|
||||
assert!(!bundle.sig_pq_public_key.as_bytes().is_empty());
|
||||
assert!(!bundle.sig_cl_public_key.as_bytes().is_empty());
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mlkem-tls", feature = "ml-dsa", feature = "ed25519-dalek"))]
|
||||
#[test]
|
||||
fn keyring_serialize_roundtrip() {
|
||||
let kr = Keyring::generate();
|
||||
let bytes = kr.to_bytes();
|
||||
let loaded = Keyring::from_bytes(&bytes).unwrap();
|
||||
assert_eq!(kr.kem_public_key.as_bytes(), loaded.kem_public_key.as_bytes());
|
||||
assert_eq!(kr.sig_pq_public_key.as_bytes(), loaded.sig_pq_public_key.as_bytes());
|
||||
assert_eq!(kr.sig_cl_public_key.as_bytes(), loaded.sig_cl_public_key.as_bytes());
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mlkem-tls", feature = "ml-dsa", feature = "ed25519-dalek"))]
|
||||
#[test]
|
||||
fn public_key_bundle_serialize_roundtrip() {
|
||||
let kr = Keyring::generate();
|
||||
let bundle = kr.public_key_bundle();
|
||||
let bytes = bundle.as_bytes();
|
||||
let loaded = PublicKeyBundle::from_bytes(&bytes).unwrap();
|
||||
assert_eq!(bundle.kem_public_key.as_bytes(), loaded.kem_public_key.as_bytes());
|
||||
assert_eq!(
|
||||
bundle.sig_pq_public_key.as_bytes(),
|
||||
loaded.sig_pq_public_key.as_bytes()
|
||||
);
|
||||
assert_eq!(
|
||||
bundle.sig_cl_public_key.as_bytes(),
|
||||
loaded.sig_cl_public_key.as_bytes()
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "mlkem-tls")]
|
||||
#[test]
|
||||
fn hybrid_kem_roundtrip() {
|
||||
let (sk, pk) = HybridKem::generate_keypair();
|
||||
let enc = HybridKem::encapsulate(&pk).unwrap();
|
||||
let ss = HybridKem::decapsulate(&sk, &enc.ciphertext).unwrap();
|
||||
assert_eq!(enc.shared_secret, ss);
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mlkem-tls", feature = "chacha20poly1305", feature = "hkdf"))]
|
||||
#[test]
|
||||
fn encrypt_multi_roundtrip() {
|
||||
use crate::keypair::Keyring;
|
||||
use crate::helper::{encrypt_multi, decrypt_multi};
|
||||
|
||||
let kr = Keyring::generate();
|
||||
let entities = vec![kr.public_key_bundle()];
|
||||
let msg = b"secret data";
|
||||
let ct = encrypt_multi(msg, b"aad", &entities).unwrap();
|
||||
let pt = decrypt_multi(&ct, b"aad", &kr).unwrap();
|
||||
assert_eq!(pt, msg);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,14 @@ impl Ed25519Signer {
|
|||
pub fn public_key(&self) -> SignaturePublicKey {
|
||||
SignaturePublicKey::new(self.public.to_bytes().to_vec())
|
||||
}
|
||||
|
||||
pub fn signing_key(&self) -> &ed25519_dalek::SigningKey {
|
||||
&self.secret
|
||||
}
|
||||
|
||||
pub fn verifying_key(&self) -> &ed25519_dalek::VerifyingKey {
|
||||
&self.public
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "ed25519-dalek")]
|
||||
|
|
@ -104,23 +112,26 @@ impl MlDsaSigner {
|
|||
secret_key: &SignaturePqPrivateKey,
|
||||
public_key: &SignaturePqPublicKey,
|
||||
) -> Result<Self, CryptoError> {
|
||||
let encoded_sk =
|
||||
ml_dsa::EncodedSigningKey::<ml_dsa::MlDsa65>::try_from(secret_key.as_bytes())
|
||||
.map_err(|_| CryptoError::KeyGenerationFailed)?;
|
||||
let secret = ml_dsa::SigningKey::<ml_dsa::MlDsa65>::decode(&encoded_sk);
|
||||
let seed_bytes: [u8; 32] = secret_key
|
||||
.as_bytes()
|
||||
.try_into()
|
||||
.map_err(|_| CryptoError::KeyGenerationFailed)?;
|
||||
let seed = ml_dsa::Seed::from(seed_bytes);
|
||||
let secret = ml_dsa::SigningKey::<ml_dsa::MlDsa65>::from_seed(&seed);
|
||||
|
||||
let encoded_pk =
|
||||
ml_dsa::EncodedVerifyingKey::<ml_dsa::MlDsa65>::try_from(public_key.as_bytes())
|
||||
.map_err(|_| CryptoError::KeyGenerationFailed)?;
|
||||
let public = ml_dsa::VerifyingKey::<ml_dsa::MlDsa65>::decode(&encoded_pk);
|
||||
|
||||
Ok(Self { secret, public })
|
||||
}
|
||||
|
||||
pub fn generate() -> (Self, SignaturePqPrivateKey, SignaturePqPublicKey) {
|
||||
use ml_dsa::KeyGen;
|
||||
let kp = ml_dsa::MlDsa65::key_gen(&mut rand_core::OsRng);
|
||||
let secret = kp.signing_key().clone();
|
||||
let public = kp.verifying_key().clone();
|
||||
let priv_key = SignaturePqPrivateKey::new(secret.encode().to_vec());
|
||||
use ml_dsa::{Generate, Keypair};
|
||||
let secret = ml_dsa::SigningKey::<ml_dsa::MlDsa65>::generate();
|
||||
let public = secret.verifying_key();
|
||||
let priv_key = SignaturePqPrivateKey::new(secret.to_seed().to_vec());
|
||||
let pub_key = SignaturePqPublicKey::new(public.encode().to_vec());
|
||||
let signer = Self { secret, public };
|
||||
(signer, priv_key, pub_key)
|
||||
|
|
@ -142,20 +153,17 @@ impl MlDsaSigner {
|
|||
#[cfg(feature = "ml-dsa")]
|
||||
impl SignatureScheme for MlDsaSigner {
|
||||
fn sign(&self, msg: &[u8]) -> Result<Vec<u8>, CryptoError> {
|
||||
use ml_dsa::signature::Signer;
|
||||
let signature = self.secret.sign(msg);
|
||||
use ml_dsa::Signer;
|
||||
let signature = self.secret.try_sign(msg)
|
||||
.map_err(|_| CryptoError::SigningFailed)?;
|
||||
Ok(signature.encode().to_vec())
|
||||
}
|
||||
|
||||
fn verify(&self, msg: &[u8], signature: &[u8]) -> Result<(), CryptoError> {
|
||||
use ml_dsa::signature::Verifier;
|
||||
let encoded_sig =
|
||||
ml_dsa::EncodedSignature::<ml_dsa::MlDsa65>::try_from(signature)
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
let sig = ml_dsa::Signature::<ml_dsa::MlDsa65>::decode(&encoded_sig)
|
||||
.ok_or(CryptoError::InvalidSignature)?;
|
||||
self.public
|
||||
.verify(msg, &sig)
|
||||
use ml_dsa::Verifier;
|
||||
let sig = ml_dsa::Signature::<ml_dsa::MlDsa65>::try_from(signature)
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
self.public.verify(msg, &sig)
|
||||
.map_err(|_| CryptoError::VerificationFailed)
|
||||
}
|
||||
}
|
||||
|
|
@ -166,23 +174,22 @@ pub fn verify_ml_dsa(
|
|||
msg: &[u8],
|
||||
signature: &[u8],
|
||||
) -> Result<(), CryptoError> {
|
||||
use ml_dsa::signature::Verifier;
|
||||
use ml_dsa::Verifier;
|
||||
|
||||
let encoded_pk =
|
||||
ml_dsa::EncodedVerifyingKey::<ml_dsa::MlDsa65>::try_from(public_key.as_bytes())
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
let public = ml_dsa::VerifyingKey::<ml_dsa::MlDsa65>::decode(&encoded_pk);
|
||||
let encoded_sig =
|
||||
ml_dsa::EncodedSignature::<ml_dsa::MlDsa65>::try_from(signature)
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
let sig = ml_dsa::Signature::<ml_dsa::MlDsa65>::decode(&encoded_sig)
|
||||
.ok_or(CryptoError::InvalidSignature)?;
|
||||
|
||||
let sig = ml_dsa::Signature::<ml_dsa::MlDsa65>::try_from(signature)
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
|
||||
public
|
||||
.verify(msg, &sig)
|
||||
.map_err(|_| CryptoError::VerificationFailed)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct DualSignature {
|
||||
pub ed25519: Vec<u8>,
|
||||
pub mldsa: Vec<u8>,
|
||||
|
|
@ -194,12 +201,18 @@ pub fn sign_dual(
|
|||
mldsa_sk: &ml_dsa::SigningKey<ml_dsa::MlDsa65>,
|
||||
message: &[u8],
|
||||
) -> DualSignature {
|
||||
use ed25519_dalek::Signer;
|
||||
|
||||
DualSignature {
|
||||
ed25519: ed25519_sk.sign(message).to_bytes().to_vec(),
|
||||
mldsa: mldsa_sk.sign(message).encode().to_vec(),
|
||||
}
|
||||
let ed25519 = {
|
||||
use ed25519_dalek::Signer;
|
||||
ed25519_sk.sign(message).to_bytes().to_vec()
|
||||
};
|
||||
let mldsa = {
|
||||
use ml_dsa::Signer;
|
||||
mldsa_sk.try_sign(message)
|
||||
.expect("ML-DSA signing failed")
|
||||
.encode()
|
||||
.to_vec()
|
||||
};
|
||||
DualSignature { ed25519, mldsa }
|
||||
}
|
||||
|
||||
impl DualSignature {
|
||||
|
|
@ -210,22 +223,23 @@ impl DualSignature {
|
|||
mldsa_vk: &ml_dsa::VerifyingKey<ml_dsa::MlDsa65>,
|
||||
message: &[u8],
|
||||
) -> Result<(), CryptoError> {
|
||||
use ed25519_dalek::Verifier;
|
||||
|
||||
let ed_sig = ed25519_dalek::Signature::from_slice(&self.ed25519)
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
ed25519_vk
|
||||
.verify(message, &ed_sig)
|
||||
.map_err(|_| CryptoError::VerificationFailed)?;
|
||||
{
|
||||
use ed25519_dalek::Verifier;
|
||||
ed25519_vk
|
||||
.verify(message, &ed_sig)
|
||||
.map_err(|_| CryptoError::VerificationFailed)?;
|
||||
}
|
||||
|
||||
let encoded_sig =
|
||||
ml_dsa::EncodedSignature::<ml_dsa::MlDsa65>::try_from(self.mldsa.as_slice())
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
let ml_sig = ml_dsa::Signature::<ml_dsa::MlDsa65>::decode(&encoded_sig)
|
||||
.ok_or(CryptoError::InvalidSignature)?;
|
||||
mldsa_vk
|
||||
.verify(message, &ml_sig)
|
||||
.map_err(|_| CryptoError::VerificationFailed)?;
|
||||
let ml_sig = ml_dsa::Signature::<ml_dsa::MlDsa65>::try_from(self.mldsa.as_slice())
|
||||
.map_err(|_| CryptoError::InvalidSignature)?;
|
||||
{
|
||||
use ml_dsa::Verifier;
|
||||
mldsa_vk
|
||||
.verify(message, &ml_sig)
|
||||
.map_err(|_| CryptoError::VerificationFailed)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue