Files
spec/python/tests/test_identity.py
zeekay dd8e16745b feat: ZAP v0.2.1 - Zero-copy Agent Protocol
Initial release of ZAP (Zero-copy Agent Protocol) for high-performance
AI agent communication with post-quantum security.

## Features

### Core Protocol
- Cap'n Proto RPC for zero-copy serialization
- Client/Server/Gateway architecture
- Multi-transport support (TCP, Unix sockets, WebSocket)

### Post-Quantum Cryptography
- ML-KEM-768 key encapsulation (NIST FIPS 203)
- ML-DSA-65 digital signatures (NIST FIPS 204)
- Hybrid X25519 + ML-KEM handshake

### W3C DID Identity
- did:lux - Blockchain-anchored DIDs for Lux network
- did:key - Self-certifying DIDs from ML-DSA-65 keys
- did:web - DNS-based DIDs
- DID Document generation with verification methods

### Agentic Consensus
- Query/Response/Vote model for agent decisions
- Configurable consensus threshold (default 50% majority)
- Stake-weighted voting support
- Finality proofs with post-quantum signatures

### Lux Integration
- LuxConsensusBridge for Quasar finality
- Ringtail threshold signature support
- BLS + Ringtail hybrid signatures

## SDKs

- Rust: Full native implementation with async support
- Python: hanzo-zap package with asyncio
- TypeScript: @hanzo/zap package with full type safety

## Testing

- Rust: 38 tests
- Python: 48 tests
- TypeScript: 60 tests
- CI: GitHub Actions with 80%+ coverage gates
2026-01-23 09:18:37 -08:00

159 lines
4.9 KiB
Python

"""Tests for hanzo_zap.identity module."""
import pytest
from hanzo_zap.identity import (
Did,
DidDocument,
DidMethod,
VerificationMethod,
VerificationMethodType,
parse_did,
create_did_from_key,
create_did_from_web,
base58_encode,
base58_decode,
IdentityError,
)
class TestDid:
"""Tests for Did class."""
def test_create_lux_did(self):
"""Test creating a did:lux DID."""
did = Did(method=DidMethod.LUX, id="z6MkTest123")
assert did.method == DidMethod.LUX
assert did.id == "z6MkTest123"
def test_create_key_did(self):
"""Test creating a did:key DID."""
did = Did(method=DidMethod.KEY, id="z6MkTestKey456")
assert did.method == DidMethod.KEY
assert did.id == "z6MkTestKey456"
def test_create_web_did(self):
"""Test creating a did:web DID."""
did = Did(method=DidMethod.WEB, id="example.com:user:alice")
assert did.method == DidMethod.WEB
assert did.id == "example.com:user:alice"
def test_did_uri(self):
"""Test DID URI formatting."""
did = Did(method=DidMethod.LUX, id="z6MkTest123")
assert did.uri() == "did:lux:z6MkTest123"
def test_did_equality(self):
"""Test DID equality comparison."""
did1 = Did(method=DidMethod.LUX, id="z6MkTest123")
did2 = Did(method=DidMethod.LUX, id="z6MkTest123")
did3 = Did(method=DidMethod.LUX, id="z6MkDifferent")
assert did1.uri() == did2.uri()
assert did1.uri() != did3.uri()
class TestParseDid:
"""Tests for parse_did function."""
def test_parse_lux_did(self):
"""Test parsing did:lux DID."""
did = parse_did("did:lux:z6MkTest123")
assert did.method == DidMethod.LUX
assert did.id == "z6MkTest123"
def test_parse_key_did(self):
"""Test parsing did:key DID."""
did = parse_did("did:key:z6MkTestKey456")
assert did.method == DidMethod.KEY
assert did.id == "z6MkTestKey456"
def test_parse_web_did(self):
"""Test parsing did:web DID."""
did = parse_did("did:web:example.com:user:alice")
assert did.method == DidMethod.WEB
assert did.id == "example.com:user:alice"
def test_parse_invalid(self):
"""Test parsing invalid DID."""
with pytest.raises((ValueError, IdentityError)):
parse_did("invalid")
def test_parse_missing_method(self):
"""Test parsing DID without method."""
with pytest.raises((ValueError, IdentityError)):
parse_did("did:")
class TestDidDocument:
"""Tests for DidDocument class."""
def test_create_did_document(self):
"""Test creating a DID document."""
did = Did(method=DidMethod.LUX, id="z6MkTest123")
doc = did.document()
assert doc.id == "did:lux:z6MkTest123"
def test_did_document_to_json(self):
"""Test converting DID document to JSON."""
did = Did(method=DidMethod.LUX, id="z6MkTest123")
doc = did.document()
json_str = doc.to_json()
assert '"id": "did:lux:z6MkTest123"' in json_str or '"id":"did:lux:z6MkTest123"' in json_str
class TestBase58:
"""Tests for base58 encoding/decoding."""
def test_base58_encode(self):
"""Test base58 encoding."""
data = b"hello"
encoded = base58_encode(data)
assert len(encoded) > 0
def test_base58_decode(self):
"""Test base58 decoding."""
data = b"hello"
encoded = base58_encode(data)
decoded = base58_decode(encoded)
assert decoded == data
def test_base58_roundtrip(self):
"""Test base58 encode/decode roundtrip."""
test_cases = [
b"a",
b"hello world",
bytes(range(1, 256)), # Skip leading zeros for this test
]
for data in test_cases:
encoded = base58_encode(data)
decoded = base58_decode(encoded)
assert decoded == data
class TestCreateDidFromKey:
"""Tests for create_did_from_key function."""
def test_create_did_from_key(self):
"""Test creating did:key from bytes."""
# 1952-byte fake ML-DSA public key (exact size required)
public_key = bytes([i % 256 for i in range(1952)])
did = create_did_from_key(public_key)
assert did.method == DidMethod.KEY
assert did.id.startswith("z")
class TestCreateDidFromWeb:
"""Tests for create_did_from_web function."""
def test_create_did_from_web(self):
"""Test creating did:web from domain."""
did = create_did_from_web("example.com")
assert did.method == DidMethod.WEB
assert did.id == "example.com"
def test_create_did_from_web_with_path(self):
"""Test creating did:web with path."""
did = create_did_from_web("example.com", "users/alice")
assert did.method == DidMethod.WEB
assert "example.com" in did.id