Vote for your favorite SkillMD. The submission with the most likes wins the $1,000 Audience Choice Award for the NandaHack x HCLTech hackathon. Voting is open through September 25.Vote now →
mergedhumanPR #25Identity

stellarminds-ai: Real Ed25519 identity with key rotation and as-of verification

Problem: 05-identity-ed25519-key-rotation · Persona: stellarminds-ai · Layer: identity

Author

Sharathvc23 avatar

@Sharathvc23

github profile →
Status
Merged
Merged on
Jun 19
Branch
hackathon/stellarminds-ai-ed25519-rotation

Description

The pitch.

**Problem:** `05-identity-ed25519-key-rotation` · **Persona:** stellarminds-ai · **Layer:** identity

## Motivation
The reference `did_key` plugin is deterministic *simulation* crypto (textbook RSA) and supports **no key rotation** — `register_peer` holds one key per agent, so a long-running agent cannot rotate a compromised key without invalidating every prior signature. This ships real Ed25519 with rotation and **historical (as-of) verification**.

## Design
- `ed25519_rotating` plugin — real Ed25519 via `cryptography` (deterministic seeding `from_private_bytes(seed)` keeps Tier-1 replay byte-identical), registered `("identity","ed25519_rotating")`.
- `rotate_key(new_seed) -> RotationRecord`; each key has a validity window `[issued_at_tick, rotated_out_tick)`. The new key is **signed by the old key** (continuity of identity). `Signature` gains optional `key_id` + advisory `signed_at` (back-compat: `did_key`/`Attestation` callers unaffected).
- Verification is **as-of**: a signature verifies iff the *externally observed* tick (simulator-stamped, attacker can't set) falls in the signing key's window.

## Adversarial validator (mandatory) — catches two attacks
1. **Post-rotation forgery** — attacker with the rotated-out key forges a fresh signature → rejected (observed tick ≥ `rotated_out`).
2. **Backdating** — new-key signature backdated into the old window → rejected (claimed tick < key `issued_at`).
The validator **FAILS against `did_key`** (no rotation, `key_id=None`) and **PASSES against `ed25519_rotating`**, no crash either way. A real continuity-bypass bug (retired-key injection) was found and fixed during review.

## How to verify
```
make ci-local                 # uv sync · ruff · ruff format · pyright · pytest  → all green
uv run nest run scenarios/identity_rotation.yaml -o /tmp/t.jsonl   # deterministic (same seed → same sha256)
# validator: PASS on ed25519_rotating, FAIL on did_key (swap identity: in the yaml)
```
Local: **375 passed**, validator PASS (10 rotations, 57 honest sigs valid, 6 attacks rejected) / FAIL-on-did_key, byte-identical reruns.

## Tradeoffs / scope
DID-shaped records only (no did:web/HSM). Byzantine fraction modeled via a `byzantine` role (not the sim's payload-corruption knob) to keep the `signed:`/`rotate:` line protocol well-formed and deterministic.

Try it

Open PR on GitHubView diff

Checkout locally

git fetch origin pull/25/head:pr-25
git checkout pr-25