"""Tests for i2p_crypto DSA — SigType enum, KeyGenerator, DSAEngine dispatcher.""" import pytest class TestSigType: def test_dsa_sha1_constants(self): from i2p_crypto.dsa import SigType st = SigType.DSA_SHA1 assert st.code == 0 assert st.pubkey_len == 128 assert st.privkey_len == 20 assert st.sig_len == 40 assert st.hash_algo == "sha1" def test_ecdsa_sha256_p256(self): from i2p_crypto.dsa import SigType st = SigType.ECDSA_SHA256_P256 assert st.code == 1 assert st.pubkey_len == 64 assert st.privkey_len == 32 assert st.sig_len == 64 assert st.hash_algo == "sha256" def test_ecdsa_sha384_p384(self): from i2p_crypto.dsa import SigType st = SigType.ECDSA_SHA384_P384 assert st.code == 2 assert st.pubkey_len == 96 assert st.privkey_len == 48 assert st.sig_len == 96 assert st.hash_algo == "sha384" def test_ecdsa_sha512_p521(self): from i2p_crypto.dsa import SigType st = SigType.ECDSA_SHA512_P521 assert st.code == 3 assert st.pubkey_len == 132 assert st.privkey_len == 66 assert st.sig_len == 132 assert st.hash_algo == "sha512" def test_eddsa_sha512_ed25519(self): from i2p_crypto.dsa import SigType st = SigType.EdDSA_SHA512_Ed25519 assert st.code == 7 assert st.pubkey_len == 32 assert st.privkey_len == 32 assert st.sig_len == 64 assert st.hash_algo == "sha512" def test_reddsa_sha512_ed25519(self): from i2p_crypto.dsa import SigType st = SigType.RedDSA_SHA512_Ed25519 assert st.code == 11 assert st.pubkey_len == 32 assert st.privkey_len == 32 assert st.sig_len == 64 def test_by_code(self): from i2p_crypto.dsa import SigType assert SigType.by_code(0) is SigType.DSA_SHA1 assert SigType.by_code(7) is SigType.EdDSA_SHA512_Ed25519 assert SigType.by_code(999) is None def test_all_codes_unique(self): from i2p_crypto.dsa import SigType codes = [st.code for st in SigType] assert len(codes) == len(set(codes)) def test_default_sig_type(self): from i2p_crypto.dsa import SigType # I2P default is EdDSA_SHA512_Ed25519 assert SigType.EdDSA_SHA512_Ed25519.code == 7 class TestKeyGenerator: def test_generate_eddsa_keypair(self): from i2p_crypto.dsa import SigType, KeyGenerator pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) assert len(pub) == 32 assert len(priv) == 32 def test_generate_ecdsa_p256_keypair(self): from i2p_crypto.dsa import SigType, KeyGenerator pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA256_P256) assert len(pub) == 64 assert len(priv) == 32 def test_generate_ecdsa_p384_keypair(self): from i2p_crypto.dsa import SigType, KeyGenerator pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA384_P384) assert len(pub) == 96 assert len(priv) == 48 def test_generate_ecdsa_p521_keypair(self): from i2p_crypto.dsa import SigType, KeyGenerator pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA512_P521) assert len(pub) == 132 assert len(priv) == 66 def test_generate_unique_keys(self): from i2p_crypto.dsa import SigType, KeyGenerator pub1, _ = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) pub2, _ = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) assert pub1 != pub2 class TestDSAEngine: def test_sign_verify_eddsa(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) sig = DSAEngine.sign(b"hello", priv, SigType.EdDSA_SHA512_Ed25519) assert len(sig) == 64 assert DSAEngine.verify(b"hello", sig, pub, SigType.EdDSA_SHA512_Ed25519) def test_sign_verify_ecdsa_p256(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA256_P256) sig = DSAEngine.sign(b"test data", priv, SigType.ECDSA_SHA256_P256) assert len(sig) == 64 assert DSAEngine.verify(b"test data", sig, pub, SigType.ECDSA_SHA256_P256) def test_sign_verify_ecdsa_p384(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA384_P384) sig = DSAEngine.sign(b"test", priv, SigType.ECDSA_SHA384_P384) assert len(sig) == 96 assert DSAEngine.verify(b"test", sig, pub, SigType.ECDSA_SHA384_P384) def test_sign_verify_ecdsa_p521(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA512_P521) sig = DSAEngine.sign(b"test", priv, SigType.ECDSA_SHA512_P521) assert len(sig) == 132 assert DSAEngine.verify(b"test", sig, pub, SigType.ECDSA_SHA512_P521) def test_verify_wrong_data(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) sig = DSAEngine.sign(b"correct", priv, SigType.EdDSA_SHA512_Ed25519) assert not DSAEngine.verify(b"wrong", sig, pub, SigType.EdDSA_SHA512_Ed25519) def test_verify_wrong_key(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine st = SigType.EdDSA_SHA512_Ed25519 _, priv1 = KeyGenerator.generate(st) pub2, _ = KeyGenerator.generate(st) sig = DSAEngine.sign(b"data", priv1, st) assert not DSAEngine.verify(b"data", sig, pub2, st) def test_sign_empty_message(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) sig = DSAEngine.sign(b"", priv, SigType.EdDSA_SHA512_Ed25519) assert DSAEngine.verify(b"", sig, pub, SigType.EdDSA_SHA512_Ed25519) def test_corrupted_signature_rejected(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine st = SigType.ECDSA_SHA256_P256 pub, priv = KeyGenerator.generate(st) sig = bytearray(DSAEngine.sign(b"data", priv, st)) sig[0] ^= 0xFF assert not DSAEngine.verify(b"data", bytes(sig), pub, st) def test_cross_type_verify_fails(self): """Signature from one type should not verify under another.""" from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine pub_ed, priv_ed = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) sig = DSAEngine.sign(b"data", priv_ed, SigType.EdDSA_SHA512_Ed25519) pub_ec, _ = KeyGenerator.generate(SigType.ECDSA_SHA256_P256) # Different type, different key — should fail gracefully assert not DSAEngine.verify(b"data", sig, pub_ec, SigType.ECDSA_SHA256_P256) def test_large_message(self): from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine st = SigType.ECDSA_SHA256_P256 pub, priv = KeyGenerator.generate(st) data = bytes(range(256)) * 100 sig = DSAEngine.sign(data, priv, st) assert DSAEngine.verify(data, sig, pub, st)