"""Tests for act.crypto module.""" import pytest from act.crypto import ( ACTKeyResolver, KeyRegistry, X509TrustStore, b64url_sha256, compute_sha256, did_key_from_ed25519, generate_ed25519_keypair, generate_p256_keypair, resolve_did_key, sign, verify, ) from act.errors import ACTKeyResolutionError, ACTSignatureError class TestEd25519: def test_generate_keypair(self): priv, pub = generate_ed25519_keypair() assert priv is not None assert pub is not None def test_sign_verify(self): priv, pub = generate_ed25519_keypair() data = b"test data" sig = sign(priv, data) verify(pub, sig, data) def test_verify_wrong_data(self): priv, pub = generate_ed25519_keypair() sig = sign(priv, b"correct data") with pytest.raises(ACTSignatureError): verify(pub, sig, b"wrong data") def test_verify_wrong_key(self): priv1, pub1 = generate_ed25519_keypair() _, pub2 = generate_ed25519_keypair() sig = sign(priv1, b"data") with pytest.raises(ACTSignatureError): verify(pub2, sig, b"data") class TestP256: def test_generate_keypair(self): priv, pub = generate_p256_keypair() assert priv is not None assert pub is not None def test_sign_verify(self): priv, pub = generate_p256_keypair() data = b"test data for p256" sig = sign(priv, data) assert len(sig) == 64 # r||s, 32 bytes each verify(pub, sig, data) def test_verify_wrong_data(self): priv, pub = generate_p256_keypair() sig = sign(priv, b"correct") with pytest.raises(ACTSignatureError): verify(pub, sig, b"wrong") class TestSHA256: def test_compute(self): h = compute_sha256(b"hello") assert len(h) == 32 def test_b64url(self): result = b64url_sha256(b"hello world") assert "=" not in result assert isinstance(result, str) class TestKeyRegistry: def test_register_and_get(self): reg = KeyRegistry() _, pub = generate_ed25519_keypair() reg.register("key-1", pub) assert reg.get("key-1") is pub assert "key-1" in reg assert len(reg) == 1 def test_missing_key(self): reg = KeyRegistry() assert reg.get("missing") is None assert "missing" not in reg class TestDIDKey: def test_ed25519_roundtrip(self): _, pub = generate_ed25519_keypair() did = did_key_from_ed25519(pub) assert did.startswith("did:key:z6Mk") resolved = resolve_did_key(did) # Verify same key by signing/verifying from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat original_bytes = pub.public_bytes(Encoding.Raw, PublicFormat.Raw) resolved_bytes = resolved.public_bytes(Encoding.Raw, PublicFormat.Raw) assert original_bytes == resolved_bytes def test_invalid_prefix(self): with pytest.raises(ACTKeyResolutionError): resolve_did_key("did:web:example.com") def test_with_fragment(self): _, pub = generate_ed25519_keypair() did = did_key_from_ed25519(pub) did_with_fragment = f"{did}#{did.split(':')[2]}" resolved = resolve_did_key(did_with_fragment) assert resolved is not None class TestACTKeyResolver: def test_tier1_resolution(self): reg = KeyRegistry() _, pub = generate_ed25519_keypair() reg.register("my-key", pub) resolver = ACTKeyResolver(registry=reg) assert resolver.resolve("my-key") is pub def test_tier3_did_key(self): _, pub = generate_ed25519_keypair() did = did_key_from_ed25519(pub) resolver = ACTKeyResolver() resolved = resolver.resolve(did) assert resolved is not None def test_unresolvable(self): resolver = ACTKeyResolver() with pytest.raises(ACTKeyResolutionError): resolver.resolve("unknown-kid") def test_did_web_resolver_callback(self): _, pub = generate_ed25519_keypair() def resolver_cb(did: str): if did == "did:web:example.com": return pub return None resolver = ACTKeyResolver(did_web_resolver=resolver_cb) result = resolver.resolve("did:web:example.com") assert result is pub