Skip to content
 
 

Repository files navigation

AuthKademlia

Build Status Docs Status

An extended Python implementation of the Kademlia Distributed Hash Table, built on top of bmuller/kademlia, with native support for signed records and Verifiable Data Registry (VDR) capabilities for Decentralized Identifiers (DIDs).

A Rust reimplementation of this library is available at fratrung/AuthKademlia-RS. (WIP)


Overview

AuthKademlia extends the standard Kademlia protocol — an asynchronous, UDP-based DHT communicating via RPC over UDP and capable of operating behind NAT — with a cryptographic record layer that turns the network into a trustless, decentralized identity registry.

Unlike conventional DHT implementations, every value stored in the network is a verifiable artifact: cryptographically bound to its author and independently verifiable by any peer without relying on a central authority.


Key Differentiators

Feature Standard Kademlia AuthKademlia
Record integrity None Cryptographic signature verification
Identity support None Native DID Document storage
Post-quantum cryptography None Dilithium & Kyber key support
Verifiable Data Registry None Built-in VDR semantics
NAT traversal Yes Yes

Installation

pip install git+https://github.com/fratrung/AuthKademlia

Signed Records and Verifiable Data Registry

Each value stored in the DHT is a structured signed record with the following layout:

algorithm (12 bytes) | signature | DID Document (canonical JSON)

This structure allows any peer to:

  • Verify the authenticity of stored data using the public key embedded in the DID Document
  • Verify the integrity of the record against its signature
  • Operate without trusting any single node or coordinator

How It Works

  1. When inserting data (e.g., a DID Document), the record is digitally signed by the data owner using their private key.
  2. The DHT node validates the signature automatically via the integrated DIDSignatureVerifierHandler.
  3. Retrieved records can be independently verified by any node using the public key contained in the DID Document itself.

DID:IIoT Integration

AuthKademlia is designed to interoperate with the did:iiot method, an open DID method targeting Industrial IoT environments.

DID Documents stored in the DHT embed post-quantum public keys (Dilithium for authentication, Kyber for key exchange), enabling:

  • Secure device authentication
  • Post-quantum key exchange
  • Verifiable credential issuance and resolution

A complete end-to-end integration example is available at fratrung/did-iiot-dht.


Example Usage

The following example demonstrates how to generate post-quantum key pairs, construct a did:iiot DID Document, sign it, and store it as a verifiable record in the DHT.

import asyncio
from AuthKademlia.modules import Server, DilithiumKeyManager, KyberKeyManager, DIDSignatureVerifierHandler, Dilithium2
from did_iiot.modules import DIDIndustrialIoT, DIDDocument, Service, VerificationMethod

def base64_encode_publickey(pk: bytes) -> str:
    """Encodes a public key in base64url format (without padding)."""
    return base64.urlsafe_b64encode(pk).decode('utf-8').rstrip("=")

def encode_did_document(did_document: dict) -> bytes:
    """Serializes a DID Document as canonical JSON bytes."""
    return json.dumps(did_document, sort_keys=True, separators=(",", ":")).encode('utf-8')

def get_dilithium_pub_key_for_did_doc(did, pk, security_level, kid="k0"):
    """Creates a Dilithium public key JWK for inclusion in a DID Document."""
    from did_iiot.did_iiot.publicjwk import DilithiumPublicJwkey
    x = base64_encode_publickey(pk)
    return DilithiumPublicJwkey(f"{did}#{kid}", security_level=security_level, x=x)

def get_kyber_pub_key_for_did_doc(did, pk, lat, kid="k1"):
    """Creates a Kyber public key JWK for inclusion in a DID Document."""
    from did_iiot.did_iiot.publicjwk import KyberPublicJwkey
    x = base64_encode_publickey(pk)
    return KyberPublicJwkey(lat, x)

def get_signed_did_document_record(did_document: dict, sk: bytes, algorithm: str):
    """Signs the DID Document and returns a structured record (alg + signature + document)."""
    raw_did_doc_encoded = encode_did_document(did_document)
    alg = algorithm.encode('utf-8')[:12].ljust(12, b'\0')
    signature = Dilithium2.sign(sk, raw_did_doc_encoded)
    return alg + signature + raw_did_doc_encoded

async def run():
    # Initialize DHT node with signature verification
    node = Server(signature_verifier_handler=DIDSignatureVerifierHandler())
    await node.listen(5678)

    # Bootstrap to an existing DHT node
    # Replace "127.0.0.1" and 5678 with a real bootstrap node address/port.
    await node.bootstrap([("127.0.0.1", 5678)])
    # NOTE: omit the bootstrap call if this is the first node in the network

    # Generate post-quantum key pairs
    dilith_mgr = DilithiumKeyManager("dilithium_keys")
    kyber_mgr = KyberKeyManager("kyber_keys")

    dilith_pk, dilith_sk = dilith_mgr.generate_keypair(2)
    kyber_pk, kyber_sk = kyber_mgr.generate_keypair(512)

    # Build the DID URI and DID Document
    did = DIDIndustrialIoT.generate_did_uri()

    dilith_jwk = get_dilithium_pub_key_for_did_doc(did, dilith_pk, 2)
    kyber_jwk = get_kyber_pub_key_for_did_doc(did, kyber_pk, "Kyber-512", "k1")

    vm_auth = VerificationMethod(f"{did}#k0", type="Authentication", public_jwkey=dilith_jwk)
    vm_session = VerificationMethod(f"{did}#k1", type="KeySessionExchange", public_jwkey=kyber_jwk)
    service = [Service(f"{did}#device", "DeviceAgent", "http://example.com/device")]

    did_doc = DIDDocument(id=did, verification_methods=[vm_auth, vm_session], service=service)

    # Sign and store the record in the DHT
    signed_record = get_signed_did_document_record(did_doc.get_dict(), dilith_sk, algorithm="Dilithium-2")
    key = did.split(":")[-1]
    await node.set(key, signed_record)

    # Retrieve and verify
    result = await node.get(key)
    print("Verified record:", result)

asyncio.run(run())

Logging

AuthKademlia uses the standard Python logging library. To enable debug output to stdout:

import logging

log = logging.getLogger('kademlia')
log.setLevel(logging.DEBUG)
log.addHandler(logging.StreamHandler())

Related Projects

About

A Python implementation of Kademlia, extended to store structured records that include a digital signature, making them verifiable by anyone

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages