sdata Decentralized Identifier (DID) Implementation: Technical Guide and Use Cases
sdata provides a lightweight, pure-Python implementation of Decentralized Identifiers (DIDs) supporting peer:4 and did:github methods with Ed25519 cryptography for secure, dependency-free identity management.
The lepy/sdata repository delivers a complete, self-contained toolkit for generating, resolving, and utilizing DIDs in Python applications without requiring external dependencies. This implementation focuses on practical interoperability through standard cryptographic primitives and emerging DID methods optimized for both offline peer-to-peer interactions and repository-based resolution.
Core Architecture of sdata's DID Stack
The sdata DID implementation consists of three integrated components that work together to provide end-to-end decentralized identity functionality.
Cryptographic Primitives in sdata/did/ed25519.py
The foundation of sdata's security model resides in sdata/did/ed25519.py, which supplies pure-Python Ed25519 key generation, signing, and verification. These low-level cryptographic operations support the DID-Comm JWS (JSON Web Signature) flow and enable DID methods that embed public keys directly within identifiers. The module exposes functions including keypair_from_seed, sign, and verify, which handle the raw cryptographic operations required for message authentication and document validation.
DID Method Modules
Each supported DID method maintains its own dedicated module under sdata/did/, implementing method-specific encoding, resolution, and validation logic.
sdata/did/did_peer4.py implements the peer:4 method for self-contained, hash-anchored DIDs. This method encodes JSON DID Documents using multicodec framing, hashes them with SHA-256, and generates multibase-encoded identifiers. The implementation distinguishes between long-form DIDs (containing both the hash and the encoded document) and short-form DIDs (containing only the hash), enabling offline resolution without external registries.
sdata/did/did_github.py implements the did:github method for repository-based identity resolution. This module parses identifiers following the pattern did:github:<user>:<repo>[:<ref>[:<subpath>]], constructs candidate raw-GitHub URLs targeting .well-known/did.json or did.json files, and fetches documents via HTTP with optional GITHUB_TOKEN authentication. Resolution includes minimal DID-Core validation to ensure document integrity.
JWS Helper for DID-Comm Messaging
The sdata/did/diddoc.py module demonstrates practical application of the cryptographic layer through DID-Comm message signing. It implements functions for creating flattened JWS structures using Ed25519 signatures, including base64url_encode and base64url_decode helpers. The JWS headers declare alg: "EdDSA" with a kid (key identifier) pointing to a DID fragment, enabling authentication of decentralized messages using keys referenced in DID Documents.
Implementing did:peer:4 Self-Contained Identifiers
The peer:4 method enables offline-capable DIDs ideal for ad-hoc, peer-to-peer interactions where no centralized registry exists. In sdata/did/did_peer4.py, the did_peer4_from_payload function generates both long-form and short-form identifiers from a JSON DID Document payload.
The encoding process applies multicodec framing to the document, computes a SHA-256 hash, and produces multibase-encoded identifiers. The resolve_long_form function validates the embedded multihash against the encoded document and reconstructs a contextualized DID Document with populated id and alsoKnownAs fields.
from sdata.did.did_peer4 import did_peer4_from_payload, resolve_long_form
payload = {
"@context": ["https://www.w3.org/ns/did/v1"],
"verificationMethod": [{
"id": "#key-0",
"type": "JsonWebKey2020",
"publicKeyJwk": {
"kty": "OKP",
"crv": "Ed25519",
"x": "qhqVmPevNBx1W-amRiTzOizsqtVHiOVGQMRMBM29cE0"
}
}],
"authentication": ["#key-0"]
}
long_did, short_did, did_doc = did_peer4_from_payload(payload)
print("Long‑form DID :", long_did)
print("Short‑form DID:", short_did)
# Resolve the long-form DID with hash validation
resolved_doc = resolve_long_form(long_did)
assert resolved_doc["id"] == long_did
assert short_did in resolved_doc["alsoKnownAs"]
Resolving did:github Repository-Based Identities
For scenarios requiring public, auditable identity records, sdata/did/did_github.py provides decentralized resolution through GitHub repositories. The resolve_did_github function parses the DID identifier to extract user, repository, reference, and subpath components, then attempts resolution against standard DID document locations within the repository.
This method supports optional authentication via GITHUB_TOKEN environment variables for accessing private repositories or avoiding rate limits, making it suitable for both open-source projects and private organizational deployments.
from sdata.did.did_github import resolve_did_github
github_did = "did:github:lepy:cudi2:main"
doc = resolve_did_github(github_did)
print("Fetched DID Document from GitHub:")
print(doc)
Secure Message Exchange with Ed25519 JWS
The sdata toolkit enables DID-Comm compatible messaging through Ed25519-signed JWS envelopes. Using functions from sdata/did/ed25519.py and sdata/did/diddoc.py, applications can sign and verify messages using keys referenced in DID Documents.
The signing process generates a protected header declaring the EdDSA algorithm and key identifier, base64url-encodes the payload, and creates a signature over the concatenated protected header and payload. The resulting flattened JWS JSON structure is ready for transport across any messaging protocol.
from sdata.did.ed25519 import keypair_from_seed, sign, verify
from sdata.did.diddoc import base64url_encode, base64url_decode
import json
# Generate deterministic key pair for demonstration
kp = keypair_from_seed(b"0"*32)
# Prepare DID-Comm message
message = {
"id": "123",
"type": "http://example.com/protocol/1.0/request",
"from": "did:example:alice",
"to": ["did:example:bob"],
"body": {"msg": "Hello"}
}
payload_bytes = json.dumps(message, separators=(',', ':')).encode()
# Construct JWS protected header
header = {"typ": "JWM", "alg": "EdDSA", "kid": "did:example:alice#key-0"}
protected = base64url_encode(json.dumps(header, separators=(',', ':')).encode())
payload = base64url_encode(payload_bytes)
# Sign the message
signing_input = protected + b"." + payload
sig = sign(signing_input, kp.sk, kp.pk)
jws = {
"payload": payload.decode(),
"signatures": [{
"protected": protected.decode(),
"signature": base64url_encode(sig).decode(),
"header": {"kid": header["kid"]}
}]
}
# Verify on receipt
sig_bytes = base64url_decode(jws["signatures"][0]["signature"])
assert verify(sig_bytes, signing_input, kp.pk)
Summary
The sdata Decentralized Identifier implementation provides a complete, dependency-free toolkit for Python developers building decentralized identity solutions:
- Pure-Python cryptography via
sdata/did/ed25519.pyeliminates external dependency requirements while providing standard Ed25519 operations - Self-contained peer DIDs through
did:peer:4enable offline-capable, hash-anchored identities using multicodec and multibase encoding - Repository-based resolution via
did:githubleverages existing GitHub infrastructure for public DID document hosting - DID-Comm compatibility through JWS signing utilities enables secure message exchange between identified parties
Frequently Asked Questions
How does sdata's DID implementation differ from other Python DID libraries?
Unlike libraries that rely on external cryptographic dependencies or cloud-based resolution services, sdata implements all core functionality—including Ed25519 cryptography—in pure Python within the lepy/sdata repository. This design enables deployment in constrained environments while supporting both self-contained peer DIDs and repository-based resolution without additional infrastructure.
What is the difference between long-form and short-form peer:4 DIDs?
According to the implementation in sdata/did/did_peer4.py, the long-form DID contains both the SHA-256 multihash and the complete encoded DID Document, enabling immediate local resolution without external lookup. The short-form DID contains only the hash, suitable for compact referencing once the document has been shared through other channels. The did_peer4_from_payload function generates both forms simultaneously.
Can did:github resolution work with private repositories?
Yes. The resolve_did_github function in sdata/did/did_github.py checks for a GITHUB_TOKEN environment variable and includes it in HTTP request headers when present. This allows authentication against GitHub's API for accessing private repository content, though the resolved DID Documents themselves must follow standard DID-Core formatting regardless of repository visibility.
What cryptographic standards does sdata use for DID signing?
The implementation relies on Ed25519 for digital signatures as implemented in sdata/did/ed25519.py, with SHA-256 for hashing in the peer:4 method. For DID-Comm messaging, it produces JWS (JSON Web Signature) envelopes using the EdDSA algorithm identifier, with keys referenced via kid (key identifier) headers pointing to verification methods within DID Documents.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →