Completes the parallel tutorial set across all three implementations.
Python now has the same friendly step-by-step walkthrough that the
Rust and Node sides have had since the original tutorial commits.
Python tutorial content mirrors the others 1:1, adapted for the
Python invocation style (.venv/bin/python kez_cli.py …), plus:
• Programmatic section uses Python imports (NostrSecret.from_nsec,
sign_claim, default_registry, etc.) instead of the TS imports
from the Node tutorial.
• Same "Recovery phrases" mini-chapter as rust/nodejs — both 12-word
AND 24-word are explained, with the entropy table, picking guide,
hardware-wallet-incompatibility callout, concrete backup advice
("pencil + paper, numbered words, fireproof, don't split,
don't permute"), and "Working with phrases later" examples
(`identity mnemonic`, `identity from-mnemonic`).
• Notes that `sigchain publish` isn't in the Python CLI yet (only
add/revoke/show/export) — match the actual current surface; the
JSONL the Python CLI produces is byte-compatible with Rust/Node,
so users can build the chain in Python and publish via either
of the other CLIs in the meantime.
• Troubleshooting includes ModuleNotFoundError: kez (a Python-
specific footgun when running outside the venv).
• Links to ../rust/TUTORIAL.md and ../nodejs/TUTORIAL.md as parallel
references throughout.
python/README.md now opens with the same "New to KEZ? Read TUTORIAL.md"
callout as the rust and nodejs READMEs do.
Root README's quick-start blocks for each implementation now reference
BOTH the impl README (reference) AND the impl TUTORIAL (step-by-step,
on-ramp) instead of just the README.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
114 lines
4.3 KiB
Markdown
114 lines
4.3 KiB
Markdown
# KEZ — Python Implementation
|
|
|
|
KEZ is a portable, decentralized identity graph. It lets one person say:
|
|
|
|
> "These accounts, keys, domains, and identities are all me."
|
|
|
|
…without depending on any central authority. Every connection is proven by a
|
|
signature against a key the user already controls. The protocol is specified in
|
|
[`../SPEC.md`](../SPEC.md); this directory is the Python implementation of that
|
|
spec.
|
|
|
|
It is **wire-compatible** with the [Rust](../rust/) and [Node](../nodejs/)
|
|
implementations: a claim signed here verifies there and vice versa, in every
|
|
direction. The repo-root [`crosstest.sh`](../crosstest.sh) proves it.
|
|
|
|
---
|
|
|
|
## What's in this directory
|
|
|
|
```
|
|
python/
|
|
├── pyproject.toml Package metadata + entry point (`kez`)
|
|
├── requirements.txt Runtime deps (cryptography, zstandard)
|
|
├── kez_cli.py Standalone launcher (used by ../crosstest.sh)
|
|
└── kez/
|
|
├── jcs.py RFC 8785 JSON canonicalization
|
|
├── bech32.py Bech32 (nsec/npub) encode/decode
|
|
├── schnorr.py Pure-Python BIP-340 Schnorr over secp256k1
|
|
├── identity.py `system:identifier` parsing + normalization
|
|
├── keys.py NostrSecret / Ed25519Secret signers + verification
|
|
├── envelope.py Envelope, claim & sigchain-event payloads, sign/verify
|
|
├── encodings.py JSON / compact (kez:z1:) / markdown / DNS / JSONL bundle
|
|
├── sigchain.py Append-only signed sigchain + on-disk storage
|
|
├── channels.py parse_proof across all four wire encodings
|
|
└── cli.py The `kez` command-line interface
|
|
```
|
|
|
|
---
|
|
|
|
## Setup
|
|
|
|
> **New to KEZ?** Read [**`TUTORIAL.md`**](TUTORIAL.md) — a friendly
|
|
> step-by-step walkthrough that takes you from "I have a nostr `nsec`"
|
|
> to "I have a verified, published sigchain," including the BIP-39
|
|
> recovery-phrase backup (12 or 24 words). It assumes nothing.
|
|
>
|
|
> This README is the reference; the tutorial is the on-ramp.
|
|
|
|
```sh
|
|
cd python
|
|
python3 -m venv .venv
|
|
.venv/bin/pip install -r requirements.txt
|
|
```
|
|
|
|
Then run the CLI either through the launcher or the installed entry point:
|
|
|
|
```sh
|
|
.venv/bin/python kez_cli.py identity new
|
|
# or, after `.venv/bin/pip install -e .`:
|
|
.venv/bin/kez identity new
|
|
```
|
|
|
|
---
|
|
|
|
## Crypto stack
|
|
|
|
| Concern | Choice | Why |
|
|
|---|---|---|
|
|
| JCS (RFC 8785) | hand-rolled (`jcs.py`) | KEZ payloads are strings/ints/objects only; a tiny dependency-free canonicalizer guarantees byte-identical output |
|
|
| secp256k1 Schnorr (BIP-340) | pure-Python reference (`schnorr.py`) | the native `coincurve`/`secp256k1` bindings fail to build on recent CPython; signing fixed-size digests is fast enough for a CLI. Signs with zero aux-rand to match Rust/Node exactly |
|
|
| Ed25519 (RFC 8032) | [`cryptography`](https://cryptography.io) | well-maintained, ships wheels |
|
|
| zstd | [`zstandard`](https://pypi.org/project/zstandard/) | level 3, matching the other impls; `decompressobj` handles frames without a content-size header |
|
|
| Bech32 | hand-rolled (`bech32.py`) | the BIP-173 reference is small and avoids a dependency |
|
|
|
|
All signing is **deterministic**, so the same claim signs identically every
|
|
time.
|
|
|
|
---
|
|
|
|
## CLI reference
|
|
|
|
```
|
|
kez identity new [--key-type nostr|ed25519]
|
|
|
|
kez claim create <subject> (--nsec <nsec> | --ed25519-seed <hex>)
|
|
[--format json|compact|markdown] [--out <path>]
|
|
kez claim dns <domain> (--nsec <nsec> | --ed25519-seed <hex>)
|
|
|
|
kez verify file <path>
|
|
|
|
kez sigchain add <subject> (--nsec | --ed25519-seed) [--proof-url <url>]
|
|
kez sigchain revoke <subject> (--nsec | --ed25519-seed)
|
|
kez sigchain show [--primary <id> | --nsec | --ed25519-seed]
|
|
kez sigchain export [--primary <id> | --nsec | --ed25519-seed]
|
|
[--format jsonl|compact] [--out <path>]
|
|
```
|
|
|
|
Sigchain state lives in `~/.kez/sigchains/<primary-with-colons-as-underscores>.jsonl`
|
|
— the same paths the Rust and Node CLIs use, so chains built by one are
|
|
readable by the others.
|
|
|
|
---
|
|
|
|
## What's not done yet
|
|
|
|
Matching the gap list in [`../rust/README.md`](../rust/README.md), the Python
|
|
CLI implements `claim`, `verify file`, and `sigchain add/revoke/show/export`.
|
|
Not yet ported: `verify id` channel resolution (network fetch), `sigchain
|
|
publish`, and the `rotate`/`add_device` ops.
|
|
|
|
## License
|
|
|
|
Dual-licensed under MIT or Apache-2.0.
|