Skip to content

jodobear/tack

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tack — Key Rotation for Nostr

Tack is a reference implementation of NIP-41 — pre-rotation key migration for Nostr, anchored to Bitcoin via OpenTimestamps.

Your Nostr key gets compromised. What now? NIP-41 lets you pre-register a recovery key so you can reclaim your identity — even if the attacker races you.

How It Works

1. BEFORE anything goes wrong:
   Chuck publishes kind:1776 → "Not-Chuck is my recovery key"
   Timestamped to Bitcoin via OpenTimestamps (kind:1040)

2. Key compromised!
   Not-Chuck publishes kind:1777 → "I'm claiming Chuck's identity"
   21-day dispute period starts

3. Attacker tries to counter-claim?
   Client compares Bitcoin-anchored timestamps on the kind:1776 whitelists
   Earliest timestamp wins — attacker can't forge a past Bitcoin block

4. Dispute period expires, no successful challenge
   → Migration accepted. Not-Chuck is now Chuck.

Key insight: OTS timestamps are immutable. If you set up recovery first, no attacker can produce an earlier timestamp — even with your compromised key.

What's Here

tack/
├── specs/              NIP-41 specification
├── docs/research/      Protocol analysis and design decisions
├── prototype/
│   ├── src/            Core library (events, OTS, verification, state machine)
│   ├── test/           48 tests covering 14 scenarios
│   ├── web/            Interactive demo UI (6 scenarios, live relay publishing)
│   ├── client.ts       CLI daemon (relay subscription, dispute resolution)
│   └── demo.ts         Terminal demo with real OTS proofs

Quick Start

cd prototype
bun install
bun test              # 48 tests, 14 scenarios
bun run web           # interactive demo on :3041

The web demo walks through 6 scenarios with live Nostr relay publishing:

  1. Happy Migration — clean, uncontested key rotation
  2. Attacker Defeated — competing claims, OTS resolves in favor of legitimate owner
  3. Attacker Wins — what happens when the attacker had access first (why pre-rotation timing matters)
  4. Withholding Defense — attacker holds events and dumps later, firstSeenAt + OTS still wins
  5. Chain Migration — A→B→C, identity follows the chain
  6. Free Play — sandbox mode

The Protocol

NIP-41 implements two complementary NIPs:

NIP Author Mechanism Use Case
PR #829 pablof7z Pre-rotation + OTS Cryptographic recovery (requires setup before compromise)
PR #1056 vitorpamplona Social WoT migration Social recovery (no prior setup needed)

Event Kinds

  • kind:1776 — Whitelist: "this pubkey can recover my identity"
  • kind:1040 — OTS attestation: Bitcoin timestamp proof for the whitelist
  • kind:1777 — Migration claim: "I'm activating recovery"

Acceptance Requires Two Gates

Both must be true before a client accepts a migration:

  1. OTS verified — the whitelist's Bitcoin timestamp is confirmed
  2. Dispute period expired — 21 days (21 seconds in demo) with no successful challenge

Design Principles

  1. KISS. Minimal complexity.
  2. As-is. Honor the original NIP proposals.
  3. Build, don't discuss. Ship working software.
  4. Relays stay dumb. All validation is client-side.
  5. Trade-offs stated, not hidden. (See Scenario 3.)

License

MIT

About

NIP-41 Key Rotation Implementation per PR#829

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors