-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathllms-full.txt
More file actions
3039 lines (2171 loc) · 158 KB
/
llms-full.txt
File metadata and controls
3039 lines (2171 loc) · 158 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Signet Protocol
> Nostr has no identity layer — anyone can impersonate anyone, and there's no way to verify age for child safety. Signet is a decentralised identity verification protocol for Nostr that lets users prove claims about their identity (age, profession, parenthood) using zero-knowledge proofs, without revealing personal data or relying on a central authority.
Signet is for Nostr client developers, relay operators, and anyone building identity-aware applications on Nostr. It provides a TypeScript library (`signet-protocol`) that handles credentials, vouches, trust scoring, and ZKP age proofs. Unlike centralised identity services, Signet anchors trust to professional bodies (law societies, medical boards, notary commissions) and uses cryptographic proofs instead of data collection.
## Getting Started
```bash
npm install signet-protocol
```
Display a verification badge for any Nostr pubkey (Level 1 integration — a weekend):
```typescript
import { computeBadge, buildBadgeFilters, meetsMinimumTier } from 'signet-protocol';
// Build relay filters and fetch events
const filters = buildBadgeFilters(['<hex-pubkey>']);
const events = await fetchFromRelay(filters);
// Compute badge
const badge = computeBadge('<hex-pubkey>', events, { verifySignatures: true });
// badge.tier => 3, badge.score => 106, badge.displayLabel => "Verified (Tier 3)"
// Gate features on verification level
if (meetsMinimumTier(badge, 2)) {
// allow posting in verified-only community
}
```
## Key Concepts
- **4 verification tiers**: Self-declared (Tier 1) → Web-of-trust via peer vouches (Tier 2) → Professional verification with ZKP age proof (Tier 3) → Professional + child safety (Tier 4)
- **Signet IQ** (0–200): A continuous identity quality score measuring statistical confidence that an identity is real, not fabricated. Weighted by professional verification, in-person vouches, online vouches, account age, and identity bridges. 100 represents the current government standard. IQ is not reputation — it measures identity quality, not trustworthiness.
- **Zero-knowledge age proofs**: Bulletproofs on secp256k1 prove age ranges (e.g. "adult" or "child aged 8–12") without revealing date of birth.
- **Document nullifiers**: SHA-256 of document fields prevents duplicate identity registration without storing any personal data.
- **Event kinds**: Single attestation kind 31000 (NIP-VA, differentiated by `type` tag) for credentials, vouches, verifier registration, challenges, revocations, identity bridges, and delegation; kind 30078 (NIP-78) for community policies; and kinds 30482–30484 for elections, ballots, and results.
## API Surface
### Credentials (kind 31000, type: credential)
- `createSelfDeclaredCredential(privateKey)` — Tier 1
- `createPeerVouchedCredential(issuerKey, subjectPubkey)` — Tier 2
- `createProfessionalCredential(verifierKey, subjectPubkey, opts)` — Tier 3
- `createChildSafetyCredential(verifierKey, parentPubkey, opts)` — Tier 4
- `verifyCredential(event)` — verify signature and structure
- `parseCredential(event)` — extract structured fields
### Vouches (kind 31000, type: vouch)
- `createVouch(privateKey, params)` — vouch for another user
- `hasEnoughVouches(vouches, pubkey)` — check Tier 2 threshold
### Trust & Badges
- `computeBadge(pubkey, events, opts)` — Level 1 badge display
- `computeTrustScore(pubkey, credentials, vouches, accountCreatedAt)` — full Signet IQ
### Policies (kind 30078)
- `createPolicy(privateKey, params)` — community verification requirements
- `PolicyChecker` — check users against a policy
### Verifiers (kind 31000, type: verifier)
- `createVerifierCredential(privateKey, params)` — register as professional verifier
- `checkCrossVerification(pubkey, vouches, verifiers)` — activation check
### Identity Bridge (kind 31000, type: identity-bridge)
- `createIdentityBridge(anonKey, realKey, ring, signerIndex, minTier)` — link anonymous account to verified identity via ring signature
### ZKP Age Proofs
- `createAgeRangeProof(age, ageRange, subjectPubkey?)` — create an age-range proof
- `verifyAgeRangeProof(proof, expectedAgeRange, expectedSubjectPubkey?)` — verify against an expected age policy
### Voting Extension (kinds 30482–30484)
- `createElection(privateKey, params)` — define an election
- `castBallot(privateKey, params)` — anonymous ballot via LSAG
- `tallyElection(election, ballots, decryptionKey)` — tally results
## Optional
- [Full protocol specification](spec/protocol.md)
- [Voting extension specification](spec/voting.md)
- [Signet in 5 Minutes — developer overview](docs/signet-in-5-minutes.md)
- [Implementation levels guide](docs/implementation-levels.md)
- [Full flow example](examples/full-flow.ts)
- [Jurisdiction-specific examples](examples/jurisdictions/)
- [Regulatory compatibility](README.md#regulatory-compatibility)
---
# The Signet Protocol
**Decentralised Identity Verification for Nostr**
**Version:** 0.1.0 (Draft)
**Date:** 2026-03-02
**Status:** Draft specification — seeking community feedback
**Licence:** MIT
---
## Abstract
Signet is an open protocol for decentralised identity verification on Nostr. It enables users to prove claims about their identity — age, parenthood, professional status — using zero-knowledge proofs, without revealing personal data or relying on a central authority.
The protocol defines four verification tiers, nine entity types, a continuous Signet IQ score (Identification Quotient), and a verifier accountability framework. All attestations use a single NIP-VA kind 31000 event, differentiated by `type` tag; community policies use NIP-78 kind 30078; and the voting extension adds kinds 30482–30484. Every professionally verified person receives two credentials — a Natural Person (real identity with Merkle-bound attributes and document nullifier) and a Persona (anonymous alias with age-range proof only). This two-credential model makes privacy a first-class design goal.
Any Nostr client can implement Signet. Any community can set verification policies. Any licensed professional can become a verifier.
**Child safety is the killer app. Social proof (blue checkmarks) drives adoption across all of Nostr.**
---
## Table of Contents
1. [Motivation](#1-motivation)
2. [Design Principles](#2-design-principles)
3. [Credential Tiers](#3-credential-tiers)
4. [Signet IQ (Identification Quotient)](#4-signet-iq-identification-quotient)
5. [Service Policies](#5-service-policies)
6. [Verifier Network](#6-verifier-network)
7. [Anti-Corruption Framework](#7-anti-corruption-framework)
8. [Event Kinds](#8-event-kinds)
9. [Cryptographic Stack](#9-cryptographic-stack)
10. [Social Proof — The Blue Checkmark](#10-social-proof--the-blue-checkmark)
11. [Alignment with Existing Standards](#11-alignment-with-existing-standards)
12. [Regulatory Compatibility](#12-regulatory-compatibility)
13. [Limitations](#13-limitations)
14. [Reference Implementation](#14-reference-implementation)
15. [Identity Management & Peer Verification](#15-identity-management--peer-verification)
16. [Identity Bridge](#16-identity-bridge)
17. [Entity Type Classification](#17-entity-type-classification)
18. [Adversarial Resilience](#18-adversarial-resilience)
19. [Civic Identity](#19-civic-identity)
20. [Two-Credential Verification](#20-two-credential-verification)
21. [Credential Lifecycle](#21-credential-lifecycle)
22. [Child Online Safety](#22-child-online-safety)
23. [Inclusivity](#23-inclusivity)
24. [Jurisdiction Confidence](#24-jurisdiction-confidence)
25. [Implementation Levels](#25-implementation-levels)
---
## 1. Motivation
### The Identity Gap on Nostr
Nostr has no identity verification. Anyone can claim to be anyone. There is no blue checkmark, no web-of-trust scoring, no way to prove "I met this person" or "a professional verified this person's identity." The result: spam, impersonation, and zero basis for trust beyond "I recognise this pubkey."
### For Children
Every kids' social platform that failed (Club Penguin, Messenger Kids, Wizz, Yubo) collapsed because safety was policy-based, not cryptographic. Adults could create child accounts to impersonate children. Age verification was self-declaration or nonexistent. No platform could prove:
- This parent is a real person
- This child is a real child
- This parent actually has this child
### For Everyone
Nostr needs a trust layer that:
- Proves claims without revealing personal data
- Works without a central authority
- Starts with nothing (any account can get verified retroactively)
- Scales from casual peer vouching to professional identity verification
- Lets communities set their own policies
### The Regulatory Landscape
The world is moving to mandatory age verification:
- **EU eIDAS 2.0** (December 2026): Every Member State must offer a digital identity wallet with selective disclosure
- **France SREN law** (April 2025): Adult sites must implement ZKP-based age verification
- **UK Online Safety Act** (2023): Platforms liable for children's exposure; Ofcom requires "highly effective age assurance"
- **US COPPA 2.0** (pending): Extends protections to under-17
- **US FTC COPPA flexibility** (March 2026): FTC will not enforce against data collected solely for age verification — but requires robust deletion and clear notice. Signet exceeds this: no personal data is collected at all.
- **Australia under-16 ban** (2024): $50M AUD fines on platforms
- **ISO/IEC 27566-1:2025**: New global age assurance standard
Nobody has built this for the decentralised world. Signet fills that gap.
---
## 2. Design Principles
1. **The credential states facts, the service sets policy.** Credentials say "here's what was verified and how." Communities decide "here's what we require." Separation of attestation and enforcement.
2. **Privacy by default.** ZKP means proving a claim without revealing the underlying data. "This parent has a child aged 8-12" without revealing which parent, which child, or the exact age.
3. **No central authority.** Professional bodies (Law Society, Medical Board, notary commissions) are the trust anchors. No single entity approves verifiers. No DAO. No token.
4. **Progressive — more than nothing is better than nothing.** Users who refuse to show documents can still accumulate peer vouches. Less trust weight, but more than zero, which is what everyone has today.
5. **Retroactive.** Verification attaches to existing accounts. Any active Nostr identity — adult or child — can get verified at any time. Not tied to account creation.
6. **Composable.** Discrete tiers for policy gates + continuous score for identity quality. Simple for end users, nuanced for power users.
7. **Nostr-native.** Built on secp256k1. Uses existing Nostr event infrastructure. Zero new dependencies for basic functionality.
---
## 3. Credential Tiers
Four tiers of verification, each declaring what was proven and by whom.
### Tier 1 — Self-Declared
| Aspect | Detail |
|--------|--------|
| **What's proven** | Nothing — a signed claim: "I say I'm X" |
| **Issuer** | Self |
| **ZKP hides** | N/A |
| **Use case** | Baseline. What every Nostr account has today. |
| **Trust weight** | Minimal |
### Tier 2 — Web-of-Trust Vouched
| Aspect | Detail |
|--------|--------|
| **What's proven** | N verified people (Tier 2+) attest: "I know this person/family" |
| **Issuer** | Peers |
| **ZKP hides** | Who vouched (proves count and minimum tier of vouchers without revealing identities) |
| **Use case** | Local communities, meetup groups, conferences. People who know each other. |
| **Trust weight** | Moderate. In-person vouches carry more weight than online vouches. |
| **Threshold** | Configurable per community. Default: 3 vouches from Tier 2+ accounts. |
### Tier 3 — Professional Verified (Adult)
| Aspect | Detail |
|--------|--------|
| **What's proven** | A licensed professional verified this adult's government-issued ID in person |
| **Issuer** | Professional (lawyer, doctor, notary) |
| **ZKP hides** | Which professional, the adult's real name, ID number, address — everything except "a professional verified this person" |
| **Use case** | High-trust communities. Adults who want strong verification without publishing their identity. |
| **Trust weight** | High |
### Tier 4 — Professional Verified (Adult + Child)
| Aspect | Detail |
|--------|--------|
| **What's proven** | A licensed professional verified the adult's ID AND confirmed a child exists in a specific age range |
| **Issuer** | Professional |
| **ZKP hides** | Everything in Tier 3 + child's identity, exact age, which documents were shown |
| **Evidence the professional sees** | Parent's ID (passport, driving licence) + child evidence (birth certificate, passport, school record) |
| **Use case** | Maximum safety spaces. Proves the child is real and the parent is real. |
| **Trust weight** | Maximum |
### Why Tier 4 Stops Predators
A predator who is a verified real adult (Tier 3) could still create a fake child account. Tier 4 prevents this because:
- A professional independently confirms the child exists
- The professional sees evidence of the child (birth cert, passport)
- The professional's licence is on the line — fraudulent attestation = professional misconduct
- The ZKP cryptographically binds the parent's identity to the child's verified age range
- An adult pretending to have a child cannot produce a child's birth certificate to a lawyer
---
## 4. Signet IQ (Identification Quotient)
On top of discrete tiers, a continuous Signet IQ score (0-200) measures identity quality — the statistical confidence that an identity is real, not fabricated. A score of 100 represents the current UK/US standard that governments deem acceptable (a human checking a passport face-to-face). Scores above 100 indicate multiple verifications from diverse independent sources, making the identity harder to fabricate than a government-issued passport.
### Score Components
| Signal | Weight | Notes |
|--------|--------|-------|
| Professional verification (Tier 3/4) | Heavy | Single event, large impact |
| Identity bridge (kind 31000, type: identity-bridge) | Medium | Ring-sig proof linking anon account to verified identity, scaled by ring min tier |
| In-person peer signature | Strong | Met in person, signed keys face-to-face |
| Online vouch from verified user | Light | Accumulates — many light vouches add up |
| Account age | Passive | Time on the network adds weight gradually |
| Voucher's own Signet IQ | Multiplier | A vouch from someone at IQ 150 carries more than from someone at IQ 40 |
### Score Algorithm
The exact algorithm is implementation-defined (clients can weight signals differently), but the protocol specifies the **signal types and their relative ordering**:
```
professional verification > identity bridge > in-person vouch > online vouch > account age
```
Clients MUST respect this ordering. A single professional verification always outweighs any number of online vouches. This prevents gaming through vouch farms.
### Display
```
┌───────────────────────────────────┐
│ Alice ✓✓ Tier 3 │
│ Signet IQ: 106 │
│ │
│ ● Prof verified (lawyer) │
│ ● 4 in-person vouches │
│ ● 12 online vouches │
│ ● Account age: 2 years │
└───────────────────────────────────┘
```
- **Tier** = the gate (can you enter this space?)
- **Signet IQ** = identity quality (how confident are we that this identity is real?)
- End users see a simple tier badge. Power users can drill into the score breakdown.
---
## 5. Service Policies
Each community, circle, relay, or client sets a minimum verification requirement.
### Policy Matrix
| Community Type | Adult Minimum | Child Minimum | Example |
|----------------|---------------|---------------|---------|
| Open | Tier 1 | Tier 1 | Public Nostr feed |
| Casual group | Tier 2 | Tier 2 | Local meetup group |
| Curated circle | Tier 3 | Tier 3 | Trusted community |
| Max safety | Tier 3 | Tier 4 | Children's learning space |
### Policy Options
Services can also set:
- **Minimum Signet IQ**: "Tier 2 AND iq > 100"
- **Per-role requirements**: "moderators need Tier 3, members need Tier 2"
- **Child-specific overrides**: "adults can be Tier 2, child accounts must be Tier 4"
### Policy Enforcement
Policy is enforced at the **client level** and optionally at the **relay level**:
- **Client-side**: Clients check Signet credentials before displaying content or allowing interaction.
- **Relay-side** (optional): AUTH-gated relays can require minimum verification tier before accepting events. This prevents unverified accounts from even publishing to protected spaces.
---
## 6. Verifier Network
### Open With Credentials — No Central Authority
Anyone can become a verifier if they meet the criteria. No single entity approves verifiers. No DAO. No token.
### Professional Verifiers (Issue Tier 3/4)
**Becoming a professional verifier:**
1. Publish a verifier credential (kind 31000, type: verifier) containing your professional licence information (bar number, medical licence number, notary commission ID)
2. Get cross-verified by other professional verifiers (prevents fraudulent licence claims)
3. You can now issue Tier 3 and Tier 4 attestations
4. Your professional body is your accountability — fraudulent attestations = professional misconduct, loss of licence, potential criminal liability
**Professional bodies as trust anchors:**
The system doesn't create a new trust hierarchy. It uses the ones that already exist: the Law Society, medical licensing boards, notary commissions. These bodies already:
- Verify practitioners' identities
- Hold them to ethical standards
- Have disciplinary procedures
- Can revoke licences
Signet gives these existing trust relationships a cryptographic expression.
**Cross-verification prevents gaming:**
A fake lawyer can't just publish a credential claiming to be a lawyer. Other verified lawyers in the network must vouch for the credential. This creates a self-policing professional network — the same professionals who risk their licences have every incentive to call out fakes.
### Peer Verifiers (Contribute to Tier 2 and Score)
**Becoming a peer verifier:**
1. Reach Tier 2+ yourself
2. You can vouch for others you know
3. In-person vouches (key signing at meetups, conferences) carry more weight than online vouches
4. Your vouches' weight scales with your own Signet IQ
**The already-doxed advantage:**
People who are already public figures (conference speakers, known community members) can vouch freely for people they meet in person. Their public identity IS their credential. When they sign someone's key at a meetup, that signature carries real weight because the voucher is already publicly accountable.
### Verification Flow
```
Professional Verification (Tier 3/4):
User ──── meets in person ────► Lawyer/Doctor/Notary
│
sees passport
(+ child evidence for Tier 4)
│
issues Signet credential
│
publishes to Nostr relay
│
User's account ◄──── credential attached ────┘
Peer Verification (Tier 2 / score):
User A ──── meets User B in person ────► key signing
│
mutual vouch events
published to relay
│
Both users' scores increase ◄───────────────┘
Online Vouching (score only):
Verified User ──── "I vouch for this person" ────► vouch event
│
Target user's score increases ◄───────────────────────┘
(weight depends on voucher's own score)
```
---
## 7. Anti-Corruption Framework
A registered professional can still be corrupt — doctors sell black market prescriptions, lawyers take bribes. No single measure prevents this. The defence is layered: make corruption expensive, detectable, and permanently traceable.
### Layer 1 — Public Registry Verification
Every verifier credential (kind 31000, type: verifier) includes a licence number and jurisdiction. Any client can link directly to the relevant public register for users to verify:
| Jurisdiction | Register | URL |
|-------------|----------|-----|
| UK solicitors | SRA | sra.org.uk/consumers/register |
| UK doctors | GMC | gmc-uk.org/registration-and-licensing |
| US lawyers | State bar (per state) | Varies by state |
| Notaries | State/county register | Varies by jurisdiction |
A fake professional is caught immediately — anyone can look up whether the licence number corresponds to a real, active practitioner. Clients can automate this check where registers expose APIs.
### Layer 2 — Cross-Professional Verification
A new verifier needs vouches from verified professionals in **other** fields. A corrupt doctor needs corrupt friends who are lawyers, notaries, or accountants. Cross-profession collusion rings are exponentially harder to build than single-profession ones.
Minimum requirement for verifier activation:
- At least 2 vouches from verified professionals
- At least 2 different professions represented
- Vouchers must themselves be active, non-revoked verifiers
### Layer 3 — Rate Limiting / Anomaly Detection
All credentials are public Nostr events. Issuance volume is visible to the entire network.
Clients perform statistical anomaly detection:
- **Volume flags:** A doctor issuing 200 verifications/week vs. the network average of 5/week is automatically flagged.
- **Geographic flags:** A solicitor in Manchester verifying 50 families in Tokyo is suspicious.
- **Temporal flags:** 30 verifications in one hour suggests rubber-stamping, not in-person ID checks.
- **Display:** Clients show a warning badge on credentials from flagged verifiers: "This verifier's issuance pattern is unusual."
This is purely client-side — no central authority decides what's suspicious. Each client applies its own heuristics. The transparency of Nostr events makes this possible without surveillance.
### Layer 4 — Lightning Bond (Skin in the Game)
Professional verifiers stake sats via Lightning when registering as a verifier. The bond is:
- **Locked** when the verifier credential (kind 31000, type: verifier) is published
- **Slashed** (burned or redistributed to reporters) if the verifier is found fraudulent and revoked
- **Returned** if the verifier deactivates cleanly (retires, leaves the network)
Bond amount is configurable per community policy. A casual group might require 100,000 sats. A high-security community might require 1,000,000 sats. The bond makes corruption financially costly — a corrupt verifier doesn't just lose their reputation, they lose money.
Implementation: NWC (Nostr Wallet Connect) for bond locking. The bond mechanism is optional — communities that don't require it simply don't set a bond threshold in their policy (kind 30078).
### Layer 5 — Community Reporting and Revocation
Anyone can publish a **challenge event** (kind 31000, type: challenge) against a verifier, presenting evidence of fraudulent behaviour.
Challenge flow:
```
Reporter ──── publishes kind 31000 (type: challenge) ────► challenge event
│
includes evidence
(screenshots, registry status,
anomaly data, testimony)
│
◄──── community reviews ─────────────────────────┘
│
If N trusted accounts (Tier 3+) confirm:
│
├─ Verifier's kind 31000 (type: verifier) is superseded
│ by a revocation event (kind 31000, type: revocation)
│
├─ Lightning bond is slashed
│
└─ All credentials issued by this verifier
are flagged in clients
```
The threshold for revocation (how many confirmations needed) is set per community policy. Default: 5 confirmations from Tier 3+ accounts.
### Layer 6 — Credential Provenance Trail
Every credential (kind 31000, type: credential) traces back to its issuer via the `pubkey` field. This is an immutable, public audit trail on Nostr relays.
If a verifier is revoked:
- Clients display a warning on all credentials they issued: "This verification was issued by a now-revoked verifier. Re-verification recommended."
- The credentials are not automatically invalidated — the community policy decides whether to require re-verification or grandfather existing credentials.
- The subject can get re-verified by a different professional. The old credential remains as a historical record.
### The Cumulative Cost of Corruption
A corrupt professional in this system must:
1. Be genuinely registered with a professional body (or be caught instantly by registry check)
2. Convince professionals in *other* fields to vouch for them (cross-profession requirement)
3. Keep issuance volume low enough to avoid anomaly detection (limits the profit from corruption)
4. Risk losing their Lightning bond (direct financial cost)
5. Risk community reporting, public revocation, and permanent reputation damage on Nostr
6. Accept that every fake credential they ever issued is permanently traceable back to them
Compare this to centralised identity verification: a company scans your ID, stores it in a database that gets breached, and has no accountability when it fails. Signet doesn't prevent all corruption — nothing does — but it makes corruption more expensive and more detectable than any centralised alternative.
---
## 8. Event Kinds
All identity attestations use a single NIP-VA kind 31000 event, differentiated by the `type` tag (e.g. `["type", "credential"]`). Community policies use NIP-78 kind 30078. Voting kinds (30482–30484) remain unchanged.
### Kind 31000 — Verification Credential (type: credential)
A replaceable NIP-VA event published by a verifier attesting to a subject's verification status.
```jsonc
{
"kind": 31000,
"pubkey": "<verifier_pubkey>",
"tags": [
["d", "<subject_pubkey>"], // who is being verified
["type", "credential"], // NIP-VA type tag
["p", "<subject_pubkey>"], // for queryability
["tier", "3"], // 1, 2, 3, or 4
["credential-type", "professional"], // "self", "peer", "professional"
["scope", "adult"], // "adult" or "adult+child"
["age-range", "8-12"], // only for tier 4 (child age range)
["method", "in-person-id"], // verification method
["profession", "solicitor"], // verifier's profession
["jurisdiction", "UK"], // legal jurisdiction
["expires", "<unix_timestamp>"], // credential expiry
["algo", "secp256k1"], // cryptographic algorithm (§9.5)
["L", "signet"], // protocol namespace label
["l", "verification", "signet"] // protocol label
],
"content": "<zkp_proof_blob>" // the actual zero-knowledge proof
}
```
### Kind 31000 — Vouch Attestation (type: vouch)
A replaceable NIP-VA event published by a peer vouching for another user.
```jsonc
{
"kind": 31000,
"pubkey": "<voucher_pubkey>",
"tags": [
["d", "<subject_pubkey>"], // who is being vouched for
["type", "vouch"], // NIP-VA type tag
["p", "<subject_pubkey>"],
["method", "in-person"], // "in-person" or "online"
["context", "bitcoin-meetup"], // optional: where/how they met
["voucher-tier", "3"], // voucher's own tier at time of vouch
["voucher-score", "87"], // voucher's own score at time of vouch
["algo", "secp256k1"], // cryptographic algorithm (§9.5)
["L", "signet"],
["l", "vouch", "signet"]
],
"content": "" // no personal data
}
```
### Kind 30078 — Community Verification Policy (NIP-78)
A NIP-78 app-specific data event published by a community operator defining minimum verification requirements.
```jsonc
{
"kind": 30078,
"pubkey": "<community_operator_pubkey>",
"tags": [
["d", "<community_identifier>"],
["adult-min-tier", "2"],
["child-min-tier", "3"],
["min-score", "50"], // optional minimum score
["mod-min-tier", "3"], // optional moderator requirement
["enforcement", "client"], // "client", "relay", or "both"
["verifier-bond", "100000"], // optional: min sats bond for verifiers
["revocation-threshold", "5"], // optional: confirmations needed to revoke
["algo", "secp256k1"], // cryptographic algorithm (§9.5)
["L", "signet"],
["l", "policy", "signet"]
],
"content": "<human-readable policy description>"
}
```
### Kind 31000 — Verifier Credential (type: verifier)
A replaceable NIP-VA event published by a professional declaring their verifier status.
```jsonc
{
"kind": 31000,
"pubkey": "<verifier_pubkey>",
"tags": [
["d", "verifier-credential"],
["type", "verifier"], // NIP-VA type tag
["profession", "solicitor"],
["jurisdiction", "UK"],
["licence", "<encrypted_or_hashed_licence_number>"],
["body", "Law Society of England and Wales"],
["algo", "secp256k1"], // cryptographic algorithm (§9.5)
["L", "signet"],
["l", "verifier", "signet"]
// Cross-verification vouches from other professionals
// are separate kind 31000 (type: vouch) events pointing at this pubkey
],
"content": "<optional: public statement about verification services>"
}
```
### Kind 31000 — Verifier Challenge (type: challenge)
A NIP-VA event published by anyone challenging a verifier's legitimacy. Triggers community review.
```jsonc
{
"kind": 31000,
"pubkey": "<reporter_pubkey>",
"tags": [
["d", "<verifier_pubkey>"], // who is being challenged
["type", "challenge"], // NIP-VA type tag
["p", "<verifier_pubkey>"],
["reason", "anomalous-volume"], // "anomalous-volume", "registry-mismatch",
// "fraudulent-attestation", "licence-revoked",
// "other"
["evidence-type", "registry-screenshot"], // type of evidence provided
["reporter-tier", "3"], // reporter's own tier
["algo", "secp256k1"], // cryptographic algorithm (§9.5)
["L", "signet"],
["l", "challenge", "signet"]
],
"content": "<detailed evidence and explanation>"
}
```
### Kind 31000 — Verifier Revocation (type: revocation)
A replaceable NIP-VA event published when a community confirms a challenge. Supersedes the verifier's kind 31000 (type: verifier) credential.
```jsonc
{
"kind": 31000,
"pubkey": "<revoking_authority_pubkey>", // community operator or threshold of Tier 3+ accounts
"tags": [
["d", "<verifier_pubkey>"], // whose credential is revoked
["type", "revocation"], // NIP-VA type tag
["p", "<verifier_pubkey>"],
["challenge", "<challenge_event_id>"], // the kind 31000 (type: challenge) that triggered this
["confirmations", "7"], // number of Tier 3+ accounts that confirmed
["bond-action", "slashed"], // "slashed", "returned", "held"
["scope", "full"], // "full" = all credentials flagged,
// "partial" = specific credentials flagged
["effective", "<unix_timestamp>"], // when revocation takes effect
["algo", "secp256k1"], // cryptographic algorithm (§9.5)
["L", "signet"],
["l", "revocation", "signet"]
],
"content": "<summary of findings>"
}
```
**Client behaviour on a revocation (kind 31000, type: revocation):**
1. Display a warning on all kind 31000 (type: credential) events issued by the revoked verifier
2. Reduce the Signet IQ contribution of those credentials to zero
3. Notify affected users that re-verification is recommended
4. Do not automatically invalidate credentials — the community policy decides whether to require re-verification or grandfather existing ones
### Kind 31000 — Identity Bridge (type: identity-bridge)
A replaceable NIP-VA event published by an anonymous account to prove it is controlled by a verified identity, without revealing which one. Uses SAG ring signatures over secp256k1.
**Use case:** A user has a real-name account (verified at Tier 3 by a professional) and an anonymous account. The identity bridge lets the anonymous account prove "I am a real verified person" without revealing which verified person. This enables anonymous participation with trust.
```jsonc
{
"kind": 31000,
"pubkey": "<anon_pubkey>", // the anonymous account publishing this
"tags": [
["d", "identity-bridge"],
["type", "identity-bridge"], // NIP-VA type tag
["ring-min-tier", "3"], // minimum verification tier of ring members
["ring-size", "10"], // number of pubkeys in the ring
["algo", "secp256k1"], // cryptographic algorithm (§9.5)
["L", "signet"],
["l", "identity-bridge", "signet"]
],
"content": "{\"ringSig\":{\"ring\":[...],\"c0\":\"...\",\"responses\":[...],\"message\":\"signet:identity-bridge:<anon_pubkey>:<timestamp>\"},\"timestamp\":...}"
}
```
**Ring signature construction:**
1. The real verified account's pubkey is placed at a random position in a ring of N verified pubkeys (minimum N=5).
2. The binding message is `signet:identity-bridge:<anon_pubkey>:<timestamp>`.
3. The real account's private key signs this message using a SAG ring signature, proving one of the N ring members also controls the anon account.
4. The Nostr event itself is signed by the anonymous account's private key.
**Verification:**
1. Verify the Nostr event signature (anon account signed the event).
2. Parse the ring signature from content.
3. Verify the binding message format matches `signet:identity-bridge:<event.pubkey>:<timestamp>`.
4. Verify the ring signature (one of the ring members signed the binding message).
5. Verify ring size >= 5 (anonymity threshold).
**Signet IQ contribution:**
- Base weight: 50 points (between professional verification and in-person vouch).
- Scaled by ring minimum tier: `weight = 50 × (ringMinTier / 4)`.
- Tier 3 ring → 37.5 points. Tier 4 ring → 50 points.
- Only one bridge per account is counted.
**Trust compounding:** When bridged anonymous accounts vouch for each other, each vouch is weighted by the voucher's score (which includes bridge points). This creates natural trust compounding without a special mechanism.
**Privacy guarantees:**
- The ring signature reveals only that *one of N* verified accounts controls the anon account, not which one.
- Minimum ring size of 5 provides meaningful anonymity (1-in-5 or better).
- Larger rings provide stronger anonymity at no additional cost to the verifier.
- The binding message prevents ring signature reuse across different anon accounts.
---
## 9. Cryptographic Stack
The protocol design (tiers, scores, event kinds, policies) is specified independently of the ZKP implementation. The credential format works regardless of which cryptographic library backs the proofs. This section specifies the recommended architecture.
### Recommended Architecture: Hybrid Layers
```
Layer 1: Schnorr — the base (zero new dependencies)
│
├─ Credential issuance & verification
│ Verifier signs kind 31000 (type: credential) event with their Nostr key.
│ Any client verifies with schnorr.verify().
│
├─ Selective disclosure via Merkle trees
│ Credential attributes as Merkle leaves, sign root.
│ Holder reveals chosen attributes + sibling paths.
│ @noble/secp256k1 + @noble/hashes (already in every Nostr client).
│
├─ Ring signatures for issuer privacy (Tier 3/4)
│ SAG: "one of these N professionals verified this"
│ without revealing which one.
│ Stays on secp256k1.
│
├─ MuSig2 for multi-verifier co-signing
│ Multiple professionals co-sign → single aggregated Schnorr sig.
│
└─ Signet IQ computation
Pure client-side math. Count vouches, weight by voucher score.
No crypto needed.
Layer 2: Bulletproofs — targeted addition (for Tier 4 age proofs)
│
└─ Age range proofs
"This child is in age range [8, 12]" without revealing exact age.
Pedersen commitment + Bulletproof range proof on secp256k1.
~700 byte proofs. No trusted setup. No new curve.
Layer 3: General-purpose ZK (future, if needed)
│
├─ Complex threshold proofs
│ "I have N vouches from tier 2+ accounts" via recursive composition.
│
├─ Credential binding proofs
│ Prove credential ownership + attribute predicate in one proof.
│
└─ Unlinkable presentations (if required)
Re-randomisable proofs. For when threat model evolves.
```
### What Each Tier Needs
| Tier | Crypto Required | New Dependencies |
|------|----------------|------------------|
| **Tier 1** (self-declared) | Standard Nostr event signing | None (already present) |
| **Tier 2** (web-of-trust) | Vouch events + score calculation | None |
| **Tier 3** (professional, adult) | Ring signature on credential | Ring signature library (secp256k1-based) |
| **Tier 4** (professional, adult+child) | Ring sig + age range proof | Ring sig + Bulletproofs library |
| **Blue checkmark / score** | Read existing events, compute score | None |
### The Credential Signing Decision
Verifiers sign credentials with their **Nostr key** (secp256k1 Schnorr). No second keypair required.
| Approach | Pro | Con | Decision |
|----------|-----|-----|----------|
| **Nostr key only** | One identity, Nostr-native, no extra keys | Expensive to prove inside ZK circuits if needed later | **Use this.** |
| ZK-friendly curve (Baby Jubjub) | Cheap to prove in ZK circuits | Verifiers need a second keypair | Defer unless ZK circuit proofs become essential. |
Ring signatures handle issuer privacy without ZK circuits. Bulletproofs handle age range proofs without leaving secp256k1. The ZK-friendly signature question only arises if the protocol needs to prove "this Nostr key signed this credential" inside a zero-knowledge circuit — and the current design avoids that need.
### Reference Libraries
| Library | Purpose | Notes |
|---------|---------|-------|
| `@noble/secp256k1` | Core Schnorr sign/verify | Stable, audited, 4.94KB gzipped |
| `@noble/hashes` | SHA-256 for Merkle trees | Stable, audited |
| Ring signature lib (e.g. Nostringer) | SAG on Nostr pubkeys | Experimental — needs audit before production |
| MuSig2 lib | Multi-party signing | Functional, BIP-327 |
| Bulletproofs lib | Range proofs on secp256k1 | Needs audit before production |
### Quantum Readiness
Every Signet event carries an `["algo", "secp256k1"]` tag identifying the asymmetric cryptographic algorithm used for event signing and key agreement. This tag serves two purposes:
1. **Forward compatibility.** When post-quantum algorithms (e.g. ML-DSA, SLH-DSA, ML-KEM) are standardised for Nostr, new events will carry a different `algo` value. Parsers can distinguish pre- and post-quantum events without heuristics.
2. **Graceful migration.** During a transition period, clients can accept both `secp256k1` and post-quantum algorithm values, enabling a rolling upgrade across the network.
**Rules for the `algo` tag:**
| Rule | Detail |
|------|--------|
| **MUST be present** on all Signet events (kind 31000 and kind 30078) | Builders set it to `DEFAULT_CRYPTO_ALGORITHM` (`secp256k1`) |
| **Parsers MUST default** to `secp256k1` if absent | Ensures backward compatibility with legacy events created before this tag was introduced |
| **Value is a free-form string** | Allows future algorithms without a protocol revision — just publish events with the new value |
| **One algorithm per event** | An event is signed under a single algorithm; hybrid constructions would use two separate events |
**Current status:** All Signet events use secp256k1 (Schnorr signatures via BIP-340). No post-quantum migration is currently planned, but the tagging ensures the protocol is ready when one becomes necessary.
### Open Implementation Questions
1. **Ring signature audit.** Ring signatures are critical for Tier 3/4 issuer privacy. The SAG math is sound (used by Monero for years) but JS implementations need audit.
2. **Bulletproofs library choice.** Pure JS (slower, easier to audit) vs WASM (faster, harder to audit the C layer).
3. **Ring size.** How many professional verifiers form the anonymity set? Target: 20-50 verifiers per profession per jurisdiction.
4. **Credential expiry.** Verification credentials should expire (recommended: 1-2 years) and be renewable.
5. **Revocation propagation.** NIP-09 deletion requests are advisory only. The kind 31000 (type: challenge) / kind 31000 (type: revocation) challenge-revocation mechanism handles this at the protocol level.
---
## 10. Social Proof — The Blue Checkmark
The verification system is not limited to child safety. It is a general-purpose Nostr identity layer.
### For Users Who Won't Show Documents
They can still build trust through:
- Peer vouches from verified users
- In-person key signings at meetups and conferences
- Account age and consistent behaviour
- Online vouches from high-IQ accounts
This gives them a visible Signet IQ score and a checkmark — weaker than professional verification, but more than nothing. And nothing is what everyone on Nostr has today.
### For Public Figures
Already-doxed individuals (podcasters, conference speakers, known community members) can leverage their public identity. Their checkmark is backed by the fact that hundreds of people have met them and can vouch. They become trust anchors for their communities.
### For Creators
A verified creator can prove they're real without revealing their legal name. Content gated by verification tiers becomes more valuable when the creator has a verified identity backing it.
### Checkmark Display
| Display | Meaning |
|---------|---------|
| No mark | Unverified (Tier 1) |
| ✓ | Web-of-trust vouched (Tier 2) |
| ✓✓ | Professional verified, adult (Tier 3) |
| ✓✓✓ | Professional verified, adult + child (Tier 4) |
| Signet IQ | Continuous identity quality (0–200) visible on drill-down |
---
## 11. Alignment with Existing Standards
| Standard | Relevance |
|----------|-----------|
| **NIP-58** (Badges, kind 30009/8) | Existing attestation system on Nostr. Signet credentials extend this pattern with cryptographic proofs. |
| **NIP-101** (proposed) | Decentralised trust system integrating W3C VC format with Nostr. Signet is complementary — simpler, Nostr-native, focused on progressive tiers. |
| **Nostr DID method** (`did:nostr:<hex_pubkey>`) | Enables Nostr keys to participate in W3C DID/VC ecosystem. Signet credentials could be wrapped as W3C VCs for interop. |
| **SchnorrSecp256k1Signature2019** (DIF) | Proposed proof type for W3C VCs using Schnorr over secp256k1. Would let Signet events be treated as standards-compliant W3C VCs. |
| **ISO/IEC 27566-1:2025** | Age assurance standard. Signet's architecture is compatible with the outcomes-based framework (effectiveness, privacy, security, acceptability). |
| **UK DIATF** | Digital Identity and Attributes Trust Framework. Signet's Tier 3/4 architecture aligns. Not yet certified. Certification path exists. |
| **EU eIDAS 2.0** | European digital identity framework. Signet's selective disclosure via Merkle trees and ZKP proofs aligns with eIDAS requirements for minimal disclosure. |
---
## 12. Regulatory Compatibility
Signet is designed to satisfy identity verification requirements across multiple jurisdictions without centralised data collection.
| Regulation | How Signet Addresses It |
|------------|------------------------|
| **UK Online Safety Act** (ss.9, 11, 12) | Tier 4 provides "highly effective age assurance" via professional in-person verification. Exceeds Ofcom's accepted methods. No centralised ID scanning. |
| **COPPA / COPPA 2.0** (US) | Cryptographic proof of parental consent via Tier 3/4 credential. Exceeds current parental consent mechanisms. The FTC's March 2026 policy statement permits data collection solely for age verification with robust deletion — Signet goes further by collecting no personal data at all. The ZKP proof contains zero PII. |
| **EU eIDAS 2.0** | Credential format compatible with eIDAS selective disclosure direction. Could accept EU digital identity wallet credentials as Tier 3 input. |
| **France SREN law** | ZKP-based age verification is explicitly what the law requires. |
| **Australia under-16 ban** | Tier 4 proves child's age range without central verification. |
| **ISO/IEC 27566-1:2025** | Protocol design is compatible with the outcomes-based framework. |
### The FTC's New Position and Signet
In March 2026, the FTC issued a policy statement signalling flexibility on COPPA age checks: it will not take enforcement action where personal data is collected solely for age verification purposes, provided the data is robustly deleted and clear notice is given to parents and children.
This is significant because it removes a major blocker — platforms were previously reluctant to implement age verification for fear of COPPA liability for collecting the verification data itself. The FTC is now saying: verify ages, just delete the data.
Signet leapfrogs this entirely:
| FTC Requirement | Signet's Position |
|----------------|-------------------|
| Data collected solely for age verification | No data collected — ZKP proves age range without transmitting personal data |
| Robust data deletion | Nothing to delete — no PII ever enters any system |
| Clear notice to parents/children | Parent initiates the entire verification process and holds all keys |
| Don't use data for other purposes | Cryptographically impossible — the proof contains no personal data to repurpose |
The FTC lowered the bar. Signet doesn't need the bar — it flies over it.
### The Privacy Argument
Every other approach to age verification involves a trade-off: privacy vs safety, user experience vs verification rigour, centralised control vs accountability. Signet is designed to avoid that trade-off:
- Professional verifies in person → ZKP credential
- Credential proves age range without revealing personal data
- No personal data stored centrally — no database to breach
- Anti-corruption layers on verifier network
- Audit trail on Nostr relays
---
## 13. Limitations
| Limitation | Why It's Acceptable |
|------------|---------------------|
| **A verified parent can still be a bad parent** | True of all systems. The protocol proves identity, not character. But it creates accountability — the parent's verified identity is cryptographically linked. |
| **Professional verifiers could collude** | Possible but career-ending. Cross-verification and professional body oversight mitigate this. Same risk exists in the existing notary/legal system. |
| **Doesn't prevent all predators** | A determined predator with a real child could still misuse the system. But they can no longer be anonymous — their Tier 4 credential links back to a professional who verified them in person. |
| **ZKP crypto is complex** | Implementation risk. Mitigated by using proven libraries and by designing the protocol independently of the crypto stack. |
| **Adoption requires verifiers** | Chicken-and-egg: users need verifiers, verifiers need users. Mitigated by the web-of-trust tier (no professionals needed) and by starting with existing professional networks. |
---
## 14. Implementation
Signet is designed as a standalone NIP. Any Nostr client can implement it independently. The protocol does not depend on any specific client.
### Integration Points
Clients implementing Signet can integrate credentials with:
- Parent-controlled vault tiers (cryptographic access control)
- Child account protection (NIP-26 delegation)
- Community verification policies
- Age-based permission defaults
### Contributing
Signet is open source. Contributions, feedback, and NIP discussion are welcome.
- Protocol specification: this document
- TypeScript library: `signet-protocol` on npm
- NIP proposal: pending (kind numbers are placeholders)
---
## 15. Identity Management & Peer Verification
### 15.1 Profile Creation (BIP-39 / NIP-06)
Signet identities are derived from a 12-word BIP-39 mnemonic phrase. This is the industry standard used across Bitcoin and Nostr — the same 12 words can recover the identity on any compatible app.
**Creation flow:**
```
1. Generate 128 bits of cryptographic entropy
2. SHA-256 hash → take first 4 bits as checksum
3. 132 bits → 12 groups of 11 bits → 12 BIP-39 English words
4. PBKDF2-SHA512(mnemonic, "mnemonic" + passphrase, 2048 iterations) → 64-byte seed
5. BIP-32 HD derivation at path m/44'/1237'/0'/0/0 (NIP-06) → Nostr private key
6. Schnorr x-only public key derived from private key → Nostr identity
```
The 12 words **are** the identity. The user writes them down and stores them securely. An optional passphrase adds a second factor (the "25th word").
**Child accounts** can be derived at different account indices on the same HD path: `m/44'/1237'/{index}'/0/0`. A parent's mnemonic can deterministically generate keys for all their children's accounts, keeping the family's key management under one recovery phrase.
### 15.2 Shared Backup (Shamir's Secret Sharing)
Writing down 12 words creates a single point of failure. Shamir's Secret Sharing solves this by splitting the entropy into N shares where any M can reconstruct it.
**Scheme:** GF(256) polynomial interpolation (same field used by AES).