# sdata Decentralized Identifier (DID) Implementation: Technical Guide and Use Cases

> Explore sdata's Decentralized Identifier DID implementation in Python. Learn about peer:4 and did:github methods with Ed25519 for secure identity management. Get the technical guide and use cases.

- Repository: [lepy/sdata](https://github.com/lepy/sdata)
- Tags: technical-guide
- Published: 2026-03-05

---

**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`](https://github.com/lepy/sdata/blob/main/sdata/did/ed25519.py)

The foundation of sdata's security model resides in [`sdata/did/ed25519.py`](https://github.com/lepy/sdata/blob/main/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`](https://github.com/lepy/sdata/blob/main/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`](https://github.com/lepy/sdata/blob/main/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`](https://github.com/lepy/sdata/blob/main/.well-known/did.json) or [`did.json`](https://github.com/lepy/sdata/blob/main/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`](https://github.com/lepy/sdata/blob/main/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`](https://github.com/lepy/sdata/blob/main/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.

```python
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`](https://github.com/lepy/sdata/blob/main/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.

```python
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`](https://github.com/lepy/sdata/blob/main/sdata/did/ed25519.py) and [`sdata/did/diddoc.py`](https://github.com/lepy/sdata/blob/main/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.

```python
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.py`](https://github.com/lepy/sdata/blob/main/sdata/did/ed25519.py) eliminates external dependency requirements while providing standard Ed25519 operations
- **Self-contained peer DIDs** through `did:peer:4` enable offline-capable, hash-anchored identities using multicodec and multibase encoding
- **Repository-based resolution** via `did:github` leverages 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`](https://github.com/lepy/sdata/blob/main/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`](https://github.com/lepy/sdata/blob/main/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`](https://github.com/lepy/sdata/blob/main/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.