Skip to content

Commit e6b7aa0

Browse files
test: Add example test suite for AIDAS components
This commit adds tests/test_example.py with comprehensive test cases for: - PUF simulator functionality and uniqueness - Chaotic map cryptography and sensitivity - Cryptographic engine operations (AES, SHA256, HMAC) - Entity creation and management - Integration tests for the complete protocol These tests demonstrate the testing structure and provide a foundation for expanding test coverage as outlined in CLAUDE.md.
1 parent 8aeafa7 commit e6b7aa0

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

tests/test_example.py

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Example test file for AIDAS protocol components
4+
This demonstrates the testing structure for the project
5+
"""
6+
7+
import pytest
8+
import sys
9+
import os
10+
11+
# Add parent directory to path for imports
12+
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
13+
14+
from aidas_protocol import (
15+
PUFSimulator, ChaoticMap, CryptographicEngine,
16+
Entity, Operator, AutonomousVehicle, ChargingStation,
17+
ElectricServiceProvider, AIDASimulator
18+
)
19+
import secrets
20+
21+
22+
class TestPUFSimulator:
23+
"""Test Physical Unclonable Function simulator"""
24+
25+
def test_puf_creation(self):
26+
"""Test PUF simulator creation"""
27+
puf = PUFSimulator("test_device")
28+
assert puf.device_id == "test_device"
29+
assert puf.noise_level == 0.03
30+
31+
def test_response_generation(self):
32+
"""Test PUF response generation"""
33+
puf = PUFSimulator("test_device")
34+
challenge = secrets.token_bytes(16)
35+
response = puf.generate_response(challenge)
36+
37+
assert isinstance(response, bytes)
38+
assert len(response) == 16
39+
40+
def test_response_uniqueness(self):
41+
"""Test that different devices generate different responses"""
42+
puf1 = PUFSimulator("device1")
43+
puf2 = PUFSimulator("device2")
44+
challenge = secrets.token_bytes(16)
45+
46+
response1 = puf1.generate_response(challenge)
47+
response2 = puf2.generate_response(challenge)
48+
49+
assert response1 != response2
50+
51+
def test_response_verification(self):
52+
"""Test PUF response verification with fuzzy matching"""
53+
puf = PUFSimulator("test_device")
54+
challenge = secrets.token_bytes(16)
55+
response = puf.generate_response(challenge)
56+
57+
# Same response should verify
58+
assert puf.verify_response(challenge, response, threshold=0.9)
59+
60+
# Completely different response should fail
61+
wrong_response = secrets.token_bytes(16)
62+
assert not puf.verify_response(challenge, wrong_response, threshold=0.9)
63+
64+
65+
class TestChaoticMap:
66+
"""Test Chaotic Map cryptography"""
67+
68+
def test_chaotic_map_creation(self):
69+
"""Test chaotic map initialization"""
70+
cm = ChaoticMap(r=3.99, x0=0.5)
71+
assert cm.r == 3.99
72+
assert cm.x == 0.5
73+
74+
def test_chaotic_map_iteration(self):
75+
"""Test chaotic map iteration"""
76+
cm = ChaoticMap(r=3.99, x0=0.5)
77+
initial_value = cm.x
78+
79+
# Iterate once
80+
new_value = cm.iterate()
81+
assert new_value != initial_value
82+
assert 0 <= new_value <= 1
83+
84+
def test_key_generation(self):
85+
"""Test cryptographic key generation"""
86+
cm = ChaoticMap()
87+
key16 = cm.generate_key(16)
88+
key32 = cm.generate_key(32)
89+
90+
assert len(key16) == 16
91+
assert len(key32) == 32
92+
assert key16 != key32[:16] # Keys should be different
93+
94+
def test_sensitivity_to_initial_conditions(self):
95+
"""Test butterfly effect in chaotic maps"""
96+
cm1 = ChaoticMap(r=3.99, x0=0.5)
97+
cm2 = ChaoticMap(r=3.99, x0=0.50001) # Slightly different
98+
99+
# After several iterations, values should diverge
100+
for _ in range(10):
101+
cm1.iterate()
102+
cm2.iterate()
103+
104+
assert abs(cm1.x - cm2.x) > 0.1 # Significant divergence
105+
106+
107+
class TestCryptographicEngine:
108+
"""Test cryptographic operations"""
109+
110+
def test_sha256_hash(self):
111+
"""Test SHA-256 hashing"""
112+
crypto = CryptographicEngine()
113+
data = b"test data"
114+
hash_result = crypto.sha256_hash(data)
115+
116+
assert len(hash_result) == 32 # SHA-256 produces 32 bytes
117+
# Hash should be deterministic
118+
assert hash_result == crypto.sha256_hash(data)
119+
120+
def test_aes_encryption_decryption(self):
121+
"""Test AES encryption and decryption"""
122+
crypto = CryptographicEngine()
123+
key = secrets.token_bytes(32)
124+
plaintext = b"This is a secret message for AIDAS testing"
125+
126+
# Encrypt
127+
ciphertext, iv = crypto.aes_encrypt(key, plaintext)
128+
assert ciphertext != plaintext
129+
assert len(iv) == 16
130+
131+
# Decrypt
132+
decrypted = crypto.aes_decrypt(key, ciphertext, iv)
133+
assert decrypted == plaintext
134+
135+
def test_hmac_hash(self):
136+
"""Test HMAC-SHA256"""
137+
crypto = CryptographicEngine()
138+
key = secrets.token_bytes(32)
139+
data = b"test data"
140+
141+
hmac_result = crypto.hmac_hash(key, data)
142+
assert len(hmac_result) == 32
143+
144+
# HMAC should be deterministic for same key and data
145+
assert hmac_result == crypto.hmac_hash(key, data)
146+
147+
# Different key should produce different HMAC
148+
different_key = secrets.token_bytes(32)
149+
assert hmac_result != crypto.hmac_hash(different_key, data)
150+
151+
152+
class TestEntities:
153+
"""Test entity creation and management"""
154+
155+
def test_operator_creation(self):
156+
"""Test operator entity creation"""
157+
bio_data = secrets.token_bytes(32)
158+
operator = Operator("OP001", "secure_password", bio_data)
159+
160+
assert operator.entity_id == "OP001"
161+
assert operator.entity_type == "Operator"
162+
assert operator.password == "secure_password"
163+
assert operator.biometric_data == bio_data
164+
165+
def test_vehicle_creation(self):
166+
"""Test autonomous vehicle creation"""
167+
vehicle = AutonomousVehicle("AV001")
168+
169+
assert vehicle.entity_id == "AV001"
170+
assert vehicle.entity_type == "AV"
171+
assert vehicle.puf is not None
172+
assert vehicle.chaotic_map is not None
173+
174+
def test_charging_station_creation(self):
175+
"""Test charging station creation"""
176+
station = ChargingStation("CS001")
177+
178+
assert station.entity_id == "CS001"
179+
assert station.entity_type == "CS"
180+
181+
def test_esp_creation(self):
182+
"""Test ESP creation"""
183+
esp = ElectricServiceProvider("ESP001")
184+
185+
assert esp.entity_id == "ESP001"
186+
assert esp.entity_type == "ESP"
187+
assert len(esp.secret_key) == 32
188+
189+
190+
class TestProtocolIntegration:
191+
"""Test complete protocol flows"""
192+
193+
@pytest.fixture
194+
def simulator(self):
195+
"""Create a simulator instance for testing"""
196+
return AIDASimulator()
197+
198+
def test_entity_registration(self, simulator):
199+
"""Test entity registration with ESP"""
200+
# Create and register operator
201+
bio_data = secrets.token_bytes(32)
202+
operator = simulator.create_operator("TEST_OP", "password123", bio_data)
203+
assert operator is not None
204+
assert "TEST_OP" in simulator.entities
205+
206+
# Create and register vehicle
207+
vehicle = simulator.create_vehicle("TEST_AV")
208+
assert vehicle is not None
209+
assert "TEST_AV" in simulator.entities
210+
211+
# Create and register charging station
212+
station = simulator.create_charging_station("TEST_CS")
213+
assert station is not None
214+
assert "TEST_CS" in simulator.entities
215+
216+
def test_authentication_session(self, simulator):
217+
"""Test complete authentication session"""
218+
# Create entities
219+
bio_data = secrets.token_bytes(32)
220+
operator = simulator.create_operator("AUTH_OP", "password", bio_data)
221+
vehicle = simulator.create_vehicle("AUTH_AV")
222+
station = simulator.create_charging_station("AUTH_CS")
223+
224+
# Run authentication session
225+
try:
226+
simulator.simulate_authentication_session("AUTH_OP", "AUTH_AV", "AUTH_CS")
227+
228+
# Check if session was established
229+
assert "AUTH_AV" in operator.sessions
230+
session_info = operator.sessions["AUTH_AV"]
231+
assert "session_key" in session_info
232+
assert len(session_info["session_key"]) == 32
233+
234+
except Exception as e:
235+
pytest.fail(f"Authentication session failed: {e}")
236+
237+
238+
if __name__ == "__main__":
239+
pytest.main([__file__, "-v"])

0 commit comments

Comments
 (0)