This commit is contained in:
Alex Emmet 2026-06-24 20:25:56 +02:00
commit 29427d301b
6 changed files with 398 additions and 3 deletions

View file

@ -261,3 +261,218 @@ pub fn wasm_derive_encryption_key(
.map(|key| key.to_vec())
.map_err(|e| js_error(&format!("derive_encryption_key failed: {}", e)))
}
#[cfg(test)]
#[cfg(target_arch = "wasm32")]
mod tests {
use super::*;
use wasm_bindgen_test::*;
// ------------------------------------------------------------------
// Keyring
// ------------------------------------------------------------------
#[wasm_bindgen_test]
fn keyring_from_ed25519_roundtrip() {
let sk = vec![0xabu8; 32];
let pk = vec![0x42u8; 32];
let bytes = keyring_from_ed25519(&sk, &pk).expect("keyring_from_ed25519 failed");
let restored = WasmKeyring::from_bytes(&bytes).expect("from_bytes failed");
let bundle = restored.public_key_bundle();
assert_eq!(bundle.sig_cl_public_key(), pk);
}
#[wasm_bindgen_test]
fn keyring_from_ed25519_wrong_key_length() {
let short = vec![0u8; 16];
let ok = vec![0u8; 32];
assert!(keyring_from_ed25519(&short, &ok).is_err());
assert!(keyring_from_ed25519(&ok, &short).is_err());
}
// ------------------------------------------------------------------
// PublicKeyBundle
// ------------------------------------------------------------------
#[wasm_bindgen_test]
fn public_key_bundle_roundtrip() {
let pk = vec![0x99u8; 32];
let bundle = WasmPublicKeyBundle {
inner: PublicKeyBundle {
kem_public_key: KemPublicKey::new(vec![1, 2, 3]),
sig_cl_public_key: SignaturePublicKey::new(pk.clone()),
sig_pq_public_key: SignaturePqPublicKey::new(vec![4, 5, 6]),
},
};
let bytes = bundle.to_bytes();
let restored = WasmPublicKeyBundle::from_bytes(&bytes).expect("from_bytes failed");
assert_eq!(restored.sig_cl_public_key(), pk);
}
// ------------------------------------------------------------------
// ChaCha20-Poly1305
// ------------------------------------------------------------------
#[wasm_bindgen_test]
fn chacha20_encrypt_decrypt_roundtrip() {
let key = vec![0x42u8; 32];
let cipher = WasmChaCha20Poly1305::new(key).expect("new failed");
let plaintext = b"hello wasm crypto";
let aad = b"test-aad";
let encrypted = cipher.encrypt(plaintext, aad).expect("encrypt failed");
let decrypted = cipher.decrypt(&encrypted, aad).expect("decrypt failed");
assert_eq!(decrypted, plaintext);
}
#[wasm_bindgen_test]
fn chacha20_wrong_key_length() {
assert!(WasmChaCha20Poly1305::new(vec![0u8; 16]).is_err());
assert!(WasmChaCha20Poly1305::new(vec![0u8; 31]).is_err());
assert!(WasmChaCha20Poly1305::new(vec![0u8; 33]).is_err());
}
#[wasm_bindgen_test]
fn chacha20_decrypt_wrong_key_fails() {
let key1 = vec![0x42u8; 32];
let key2 = vec![0x43u8; 32];
let cipher1 = WasmChaCha20Poly1305::new(key1).expect("new failed");
let cipher2 = WasmChaCha20Poly1305::new(key2).expect("new failed");
let encrypted = cipher1.encrypt(b"secret", b"aad").expect("encrypt failed");
let result = cipher2.decrypt(&encrypted, b"aad");
assert!(result.is_err());
}
// ------------------------------------------------------------------
// Ed25519
// ------------------------------------------------------------------
#[wasm_bindgen_test]
fn ed25519_sign_verify() {
let (_signer, sk, _pk) = Ed25519Signer::generate();
let signer = WasmEd25519Signer::new(sk.as_bytes().to_vec()).expect("new failed");
let message = b"test message for ed25519";
let signature = signer.sign(message).expect("sign failed");
assert!(!signature.is_empty());
signer.verify(message, &signature).expect("verify failed");
}
#[wasm_bindgen_test]
fn ed25519_sign_wrong_message_fails_verify() {
let (_signer, sk, _pk) = Ed25519Signer::generate();
let signer = WasmEd25519Signer::new(sk.as_bytes().to_vec()).expect("new failed");
let signature = signer.sign(b"message A").expect("sign failed");
let result = signer.verify(b"message B", &signature);
assert!(result.is_err());
}
#[wasm_bindgen_test]
fn ed25519_generate_returns_valid() {
let result = ed25519_generate().expect("generate failed");
let has_signer = js_sys::Reflect::has(&result, &"signer".into()).unwrap_or(false);
let has_sk = js_sys::Reflect::has(&result, &"secretKey".into()).unwrap_or(false);
let has_pk = js_sys::Reflect::has(&result, &"publicKey".into()).unwrap_or(false);
assert!(has_signer);
assert!(has_sk);
assert!(has_pk);
}
#[wasm_bindgen_test]
fn ed25519_verify_standalone() {
let (_signer, sk, pk) = Ed25519Signer::generate();
let signer = WasmEd25519Signer::new(sk.as_bytes().to_vec()).expect("new failed");
let msg = b"standalone verify test";
let sig = signer.sign(msg).expect("sign failed");
ed25519_verify(pk.as_bytes().to_vec(), msg, &sig).expect("verify failed");
}
#[wasm_bindgen_test]
fn ed25519_verify_bad_signature_fails() {
let pk = vec![0x42u8; 32];
let msg = b"test";
let bad_sig = vec![0x00u8; 64];
let result = ed25519_verify(pk, msg, &bad_sig);
assert!(result.is_err());
}
// ------------------------------------------------------------------
// Hashing
// ------------------------------------------------------------------
#[wasm_bindgen_test]
fn sha256_empty() {
let result = wasm_sha256(b"");
// SHA-256 of empty string
let expected = hex::decode("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
.expect("hex decode");
assert_eq!(result, expected);
}
#[wasm_bindgen_test]
fn sha256_hello() {
let result = wasm_sha256(b"hello");
let expected = hex::decode("2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824")
.expect("hex decode");
assert_eq!(result, expected);
}
#[wasm_bindgen_test]
fn sha256_double() {
let single = wasm_sha256(b"test");
let double = wasm_sha256_double(b"test");
let expected = wasm_sha256(&single);
assert_eq!(double, expected);
}
// ------------------------------------------------------------------
// HKDF / KDF
// ------------------------------------------------------------------
#[wasm_bindgen_test]
fn hkdf_expand_produces_correct_length() {
let result = wasm_hkdf_expand(b"ikm", b"salt", b"info", 32)
.expect("hkdf_expand failed");
assert_eq!(result.len(), 32);
}
#[wasm_bindgen_test]
fn hkdf_expand_different_info() {
let r1 = wasm_hkdf_expand(b"ikm", b"salt", b"info1", 16).expect("hkdf failed");
let r2 = wasm_hkdf_expand(b"ikm", b"salt", b"info2", 16).expect("hkdf failed");
assert_ne!(r1, r2);
}
#[wasm_bindgen_test]
fn derive_encryption_key_roundtrip() {
let key = wasm_derive_encryption_key(b"password", b"salt", b"context")
.expect("derive failed");
assert_eq!(key.len(), 32);
// Deterministic: same inputs = same key
let key2 = wasm_derive_encryption_key(b"password", b"salt", b"context")
.expect("derive failed");
assert_eq!(key, key2);
}
#[wasm_bindgen_test]
fn derive_encryption_key_different_inputs_different_key() {
let key = wasm_derive_encryption_key(b"pass1", b"salt", b"context")
.expect("derive failed");
let key2 = wasm_derive_encryption_key(b"pass2", b"salt", b"context")
.expect("derive failed");
assert_ne!(key, key2);
}
}