A Python port of the Invisible Internet Project (I2P)
at main 181 lines 7.4 kB view raw
1"""Tests for i2p_crypto DSA — SigType enum, KeyGenerator, DSAEngine dispatcher.""" 2 3import pytest 4 5 6class TestSigType: 7 def test_dsa_sha1_constants(self): 8 from i2p_crypto.dsa import SigType 9 st = SigType.DSA_SHA1 10 assert st.code == 0 11 assert st.pubkey_len == 128 12 assert st.privkey_len == 20 13 assert st.sig_len == 40 14 assert st.hash_algo == "sha1" 15 16 def test_ecdsa_sha256_p256(self): 17 from i2p_crypto.dsa import SigType 18 st = SigType.ECDSA_SHA256_P256 19 assert st.code == 1 20 assert st.pubkey_len == 64 21 assert st.privkey_len == 32 22 assert st.sig_len == 64 23 assert st.hash_algo == "sha256" 24 25 def test_ecdsa_sha384_p384(self): 26 from i2p_crypto.dsa import SigType 27 st = SigType.ECDSA_SHA384_P384 28 assert st.code == 2 29 assert st.pubkey_len == 96 30 assert st.privkey_len == 48 31 assert st.sig_len == 96 32 assert st.hash_algo == "sha384" 33 34 def test_ecdsa_sha512_p521(self): 35 from i2p_crypto.dsa import SigType 36 st = SigType.ECDSA_SHA512_P521 37 assert st.code == 3 38 assert st.pubkey_len == 132 39 assert st.privkey_len == 66 40 assert st.sig_len == 132 41 assert st.hash_algo == "sha512" 42 43 def test_eddsa_sha512_ed25519(self): 44 from i2p_crypto.dsa import SigType 45 st = SigType.EdDSA_SHA512_Ed25519 46 assert st.code == 7 47 assert st.pubkey_len == 32 48 assert st.privkey_len == 32 49 assert st.sig_len == 64 50 assert st.hash_algo == "sha512" 51 52 def test_reddsa_sha512_ed25519(self): 53 from i2p_crypto.dsa import SigType 54 st = SigType.RedDSA_SHA512_Ed25519 55 assert st.code == 11 56 assert st.pubkey_len == 32 57 assert st.privkey_len == 32 58 assert st.sig_len == 64 59 60 def test_by_code(self): 61 from i2p_crypto.dsa import SigType 62 assert SigType.by_code(0) is SigType.DSA_SHA1 63 assert SigType.by_code(7) is SigType.EdDSA_SHA512_Ed25519 64 assert SigType.by_code(999) is None 65 66 def test_all_codes_unique(self): 67 from i2p_crypto.dsa import SigType 68 codes = [st.code for st in SigType] 69 assert len(codes) == len(set(codes)) 70 71 def test_default_sig_type(self): 72 from i2p_crypto.dsa import SigType 73 # I2P default is EdDSA_SHA512_Ed25519 74 assert SigType.EdDSA_SHA512_Ed25519.code == 7 75 76 77class TestKeyGenerator: 78 def test_generate_eddsa_keypair(self): 79 from i2p_crypto.dsa import SigType, KeyGenerator 80 pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) 81 assert len(pub) == 32 82 assert len(priv) == 32 83 84 def test_generate_ecdsa_p256_keypair(self): 85 from i2p_crypto.dsa import SigType, KeyGenerator 86 pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA256_P256) 87 assert len(pub) == 64 88 assert len(priv) == 32 89 90 def test_generate_ecdsa_p384_keypair(self): 91 from i2p_crypto.dsa import SigType, KeyGenerator 92 pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA384_P384) 93 assert len(pub) == 96 94 assert len(priv) == 48 95 96 def test_generate_ecdsa_p521_keypair(self): 97 from i2p_crypto.dsa import SigType, KeyGenerator 98 pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA512_P521) 99 assert len(pub) == 132 100 assert len(priv) == 66 101 102 def test_generate_unique_keys(self): 103 from i2p_crypto.dsa import SigType, KeyGenerator 104 pub1, _ = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) 105 pub2, _ = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) 106 assert pub1 != pub2 107 108 109class TestDSAEngine: 110 def test_sign_verify_eddsa(self): 111 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 112 pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) 113 sig = DSAEngine.sign(b"hello", priv, SigType.EdDSA_SHA512_Ed25519) 114 assert len(sig) == 64 115 assert DSAEngine.verify(b"hello", sig, pub, SigType.EdDSA_SHA512_Ed25519) 116 117 def test_sign_verify_ecdsa_p256(self): 118 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 119 pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA256_P256) 120 sig = DSAEngine.sign(b"test data", priv, SigType.ECDSA_SHA256_P256) 121 assert len(sig) == 64 122 assert DSAEngine.verify(b"test data", sig, pub, SigType.ECDSA_SHA256_P256) 123 124 def test_sign_verify_ecdsa_p384(self): 125 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 126 pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA384_P384) 127 sig = DSAEngine.sign(b"test", priv, SigType.ECDSA_SHA384_P384) 128 assert len(sig) == 96 129 assert DSAEngine.verify(b"test", sig, pub, SigType.ECDSA_SHA384_P384) 130 131 def test_sign_verify_ecdsa_p521(self): 132 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 133 pub, priv = KeyGenerator.generate(SigType.ECDSA_SHA512_P521) 134 sig = DSAEngine.sign(b"test", priv, SigType.ECDSA_SHA512_P521) 135 assert len(sig) == 132 136 assert DSAEngine.verify(b"test", sig, pub, SigType.ECDSA_SHA512_P521) 137 138 def test_verify_wrong_data(self): 139 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 140 pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) 141 sig = DSAEngine.sign(b"correct", priv, SigType.EdDSA_SHA512_Ed25519) 142 assert not DSAEngine.verify(b"wrong", sig, pub, SigType.EdDSA_SHA512_Ed25519) 143 144 def test_verify_wrong_key(self): 145 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 146 st = SigType.EdDSA_SHA512_Ed25519 147 _, priv1 = KeyGenerator.generate(st) 148 pub2, _ = KeyGenerator.generate(st) 149 sig = DSAEngine.sign(b"data", priv1, st) 150 assert not DSAEngine.verify(b"data", sig, pub2, st) 151 152 def test_sign_empty_message(self): 153 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 154 pub, priv = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) 155 sig = DSAEngine.sign(b"", priv, SigType.EdDSA_SHA512_Ed25519) 156 assert DSAEngine.verify(b"", sig, pub, SigType.EdDSA_SHA512_Ed25519) 157 158 def test_corrupted_signature_rejected(self): 159 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 160 st = SigType.ECDSA_SHA256_P256 161 pub, priv = KeyGenerator.generate(st) 162 sig = bytearray(DSAEngine.sign(b"data", priv, st)) 163 sig[0] ^= 0xFF 164 assert not DSAEngine.verify(b"data", bytes(sig), pub, st) 165 166 def test_cross_type_verify_fails(self): 167 """Signature from one type should not verify under another.""" 168 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 169 pub_ed, priv_ed = KeyGenerator.generate(SigType.EdDSA_SHA512_Ed25519) 170 sig = DSAEngine.sign(b"data", priv_ed, SigType.EdDSA_SHA512_Ed25519) 171 pub_ec, _ = KeyGenerator.generate(SigType.ECDSA_SHA256_P256) 172 # Different type, different key — should fail gracefully 173 assert not DSAEngine.verify(b"data", sig, pub_ec, SigType.ECDSA_SHA256_P256) 174 175 def test_large_message(self): 176 from i2p_crypto.dsa import SigType, KeyGenerator, DSAEngine 177 st = SigType.ECDSA_SHA256_P256 178 pub, priv = KeyGenerator.generate(st) 179 data = bytes(range(256)) * 100 180 sig = DSAEngine.sign(data, priv, st) 181 assert DSAEngine.verify(data, sig, pub, st)