signet-protocol 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +112 -0
  3. package/dist/anomaly.d.ts +42 -0
  4. package/dist/anomaly.d.ts.map +1 -0
  5. package/dist/anomaly.js +209 -0
  6. package/dist/anomaly.js.map +1 -0
  7. package/dist/badge.d.ts +56 -0
  8. package/dist/badge.d.ts.map +1 -0
  9. package/dist/badge.js +171 -0
  10. package/dist/badge.js.map +1 -0
  11. package/dist/bonds.d.ts +39 -0
  12. package/dist/bonds.d.ts.map +1 -0
  13. package/dist/bonds.js +149 -0
  14. package/dist/bonds.js.map +1 -0
  15. package/dist/challenges.d.ts +18 -0
  16. package/dist/challenges.d.ts.map +1 -0
  17. package/dist/challenges.js +145 -0
  18. package/dist/challenges.js.map +1 -0
  19. package/dist/cold-call.d.ts +74 -0
  20. package/dist/cold-call.d.ts.map +1 -0
  21. package/dist/cold-call.js +176 -0
  22. package/dist/cold-call.js.map +1 -0
  23. package/dist/compliance.d.ts +82 -0
  24. package/dist/compliance.d.ts.map +1 -0
  25. package/dist/compliance.js +478 -0
  26. package/dist/compliance.js.map +1 -0
  27. package/dist/connections.d.ts +63 -0
  28. package/dist/connections.d.ts.map +1 -0
  29. package/dist/connections.js +170 -0
  30. package/dist/connections.js.map +1 -0
  31. package/dist/constants.d.ts +86 -0
  32. package/dist/constants.d.ts.map +1 -0
  33. package/dist/constants.js +124 -0
  34. package/dist/constants.js.map +1 -0
  35. package/dist/credentials.d.ts +190 -0
  36. package/dist/credentials.d.ts.map +1 -0
  37. package/dist/credentials.js +686 -0
  38. package/dist/credentials.js.map +1 -0
  39. package/dist/crypto.d.ts +27 -0
  40. package/dist/crypto.d.ts.map +1 -0
  41. package/dist/crypto.js +75 -0
  42. package/dist/crypto.js.map +1 -0
  43. package/dist/errors.d.ts +17 -0
  44. package/dist/errors.d.ts.map +1 -0
  45. package/dist/errors.js +29 -0
  46. package/dist/errors.js.map +1 -0
  47. package/dist/i18n.d.ts +98 -0
  48. package/dist/i18n.d.ts.map +1 -0
  49. package/dist/i18n.js +1118 -0
  50. package/dist/i18n.js.map +1 -0
  51. package/dist/identity-bridge.d.ts +52 -0
  52. package/dist/identity-bridge.d.ts.map +1 -0
  53. package/dist/identity-bridge.js +228 -0
  54. package/dist/identity-bridge.js.map +1 -0
  55. package/dist/identity-tree.d.ts +47 -0
  56. package/dist/identity-tree.d.ts.map +1 -0
  57. package/dist/identity-tree.js +69 -0
  58. package/dist/identity-tree.js.map +1 -0
  59. package/dist/index.d.ts +55 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +86 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/key-derivation.d.ts +43 -0
  64. package/dist/key-derivation.d.ts.map +1 -0
  65. package/dist/key-derivation.js +212 -0
  66. package/dist/key-derivation.js.map +1 -0
  67. package/dist/lsag.d.ts +23 -0
  68. package/dist/lsag.d.ts.map +1 -0
  69. package/dist/lsag.js +35 -0
  70. package/dist/lsag.js.map +1 -0
  71. package/dist/merkle.d.ts +19 -0
  72. package/dist/merkle.d.ts.map +1 -0
  73. package/dist/merkle.js +155 -0
  74. package/dist/merkle.js.map +1 -0
  75. package/dist/policies.d.ts +22 -0
  76. package/dist/policies.d.ts.map +1 -0
  77. package/dist/policies.js +123 -0
  78. package/dist/policies.js.map +1 -0
  79. package/dist/range-proof.d.ts +6 -0
  80. package/dist/range-proof.d.ts.map +1 -0
  81. package/dist/range-proof.js +45 -0
  82. package/dist/range-proof.js.map +1 -0
  83. package/dist/relay.d.ts +106 -0
  84. package/dist/relay.d.ts.map +1 -0
  85. package/dist/relay.js +336 -0
  86. package/dist/relay.js.map +1 -0
  87. package/dist/ring-signature.d.ts +35 -0
  88. package/dist/ring-signature.d.ts.map +1 -0
  89. package/dist/ring-signature.js +56 -0
  90. package/dist/ring-signature.js.map +1 -0
  91. package/dist/shamir.d.ts +55 -0
  92. package/dist/shamir.d.ts.map +1 -0
  93. package/dist/shamir.js +253 -0
  94. package/dist/shamir.js.map +1 -0
  95. package/dist/signet-words.d.ts +42 -0
  96. package/dist/signet-words.d.ts.map +1 -0
  97. package/dist/signet-words.js +82 -0
  98. package/dist/signet-words.js.map +1 -0
  99. package/dist/store.d.ts +65 -0
  100. package/dist/store.d.ts.map +1 -0
  101. package/dist/store.js +290 -0
  102. package/dist/store.js.map +1 -0
  103. package/dist/trust-score.d.ts +9 -0
  104. package/dist/trust-score.d.ts.map +1 -0
  105. package/dist/trust-score.js +186 -0
  106. package/dist/trust-score.js.map +1 -0
  107. package/dist/types.d.ts +358 -0
  108. package/dist/types.d.ts.map +1 -0
  109. package/dist/types.js +15 -0
  110. package/dist/types.js.map +1 -0
  111. package/dist/utils.d.ts +11 -0
  112. package/dist/utils.d.ts.map +1 -0
  113. package/dist/utils.js +21 -0
  114. package/dist/utils.js.map +1 -0
  115. package/dist/validation.d.ts +33 -0
  116. package/dist/validation.d.ts.map +1 -0
  117. package/dist/validation.js +312 -0
  118. package/dist/validation.js.map +1 -0
  119. package/dist/verifiers.d.ts +18 -0
  120. package/dist/verifiers.d.ts.map +1 -0
  121. package/dist/verifiers.js +118 -0
  122. package/dist/verifiers.js.map +1 -0
  123. package/dist/vouches.d.ts +14 -0
  124. package/dist/vouches.d.ts.map +1 -0
  125. package/dist/vouches.js +103 -0
  126. package/dist/vouches.js.map +1 -0
  127. package/package.json +76 -0
  128. package/src/anomaly.ts +307 -0
  129. package/src/badge.ts +208 -0
  130. package/src/bonds.ts +203 -0
  131. package/src/challenges.ts +187 -0
  132. package/src/cold-call.ts +238 -0
  133. package/src/compliance.ts +612 -0
  134. package/src/connections.ts +216 -0
  135. package/src/constants.ts +146 -0
  136. package/src/credentials.ts +908 -0
  137. package/src/crypto.ts +85 -0
  138. package/src/errors.ts +31 -0
  139. package/src/i18n.ts +1347 -0
  140. package/src/identity-bridge.ts +262 -0
  141. package/src/identity-tree.ts +90 -0
  142. package/src/index.ts +452 -0
  143. package/src/lsag.ts +53 -0
  144. package/src/merkle.ts +176 -0
  145. package/src/policies.ts +154 -0
  146. package/src/range-proof.ts +66 -0
  147. package/src/relay.ts +433 -0
  148. package/src/ring-signature.ts +76 -0
  149. package/src/signet-words.ts +122 -0
  150. package/src/store.ts +336 -0
  151. package/src/trust-score.ts +208 -0
  152. package/src/types.ts +482 -0
  153. package/src/utils.ts +20 -0
  154. package/src/validation.ts +391 -0
  155. package/src/verifiers.ts +156 -0
  156. package/src/vouches.ts +141 -0
package/dist/relay.js ADDED
@@ -0,0 +1,336 @@
1
+ // Nostr Relay Client
2
+ // WebSocket-based publish/subscribe with NIP-42 AUTH support
3
+ import { signEvent, getPublicKey, verifyEvent } from './crypto.js';
4
+ import { SignetValidationError } from './errors.js';
5
+ import { validateFieldSizeBounds } from './validation.js';
6
+ /** NIP-42 client authentication event kind */
7
+ const NIP42_AUTH_KIND = 22242;
8
+ /** Maximum WebSocket message size (1 MB) — prevents DoS via oversized relay messages */
9
+ const MAX_MESSAGE_SIZE = 1_048_576;
10
+ /**
11
+ * Nostr relay client with NIP-42 AUTH support.
12
+ * Handles publishing events, subscribing to filters, and authentication.
13
+ */
14
+ export class RelayClient {
15
+ url;
16
+ options;
17
+ ws = null;
18
+ state = 'disconnected';
19
+ subscriptions = new Map();
20
+ pendingPublishes = new Map();
21
+ subCounter = 0;
22
+ reconnectAttempts = 0;
23
+ reconnectTimer = null;
24
+ disconnectRequested = false;
25
+ onStateChange;
26
+ constructor(url, options = {}) {
27
+ this.url = url;
28
+ this.options = options;
29
+ if (!/^wss?:\/\//i.test(this.url)) {
30
+ throw new SignetValidationError('Relay URL must use ws:// or wss:// scheme');
31
+ }
32
+ // Enforce TLS for non-localhost connections — identity data must not travel in cleartext
33
+ if (/^ws:\/\//i.test(this.url) && !/^ws:\/\/(localhost|127\.0\.0\.1)([:\/]|$)/i.test(this.url)) {
34
+ throw new SignetValidationError('Relay URL must use wss:// for non-localhost connections');
35
+ }
36
+ this.options = {
37
+ connectTimeout: 5000,
38
+ autoReconnect: true,
39
+ reconnectDelay: 3000,
40
+ maxReconnectAttempts: 5,
41
+ verifyEvents: true,
42
+ ...options,
43
+ };
44
+ }
45
+ /** Get current connection state */
46
+ getState() {
47
+ return this.state;
48
+ }
49
+ /** Set a state change listener */
50
+ onStateChanged(callback) {
51
+ this.onStateChange = callback;
52
+ }
53
+ setState(state) {
54
+ this.state = state;
55
+ this.onStateChange?.(state);
56
+ }
57
+ /** Connect to the relay */
58
+ connect() {
59
+ return new Promise((resolve, reject) => {
60
+ if (this.state === 'connected') {
61
+ resolve();
62
+ return;
63
+ }
64
+ this.setState('connecting');
65
+ const timeout = setTimeout(() => {
66
+ this.ws?.close();
67
+ reject(new SignetValidationError(`Connection timeout after ${this.options.connectTimeout}ms`));
68
+ }, this.options.connectTimeout);
69
+ this.ws = new WebSocket(this.url);
70
+ this.ws.onopen = () => {
71
+ clearTimeout(timeout);
72
+ this.setState('connected');
73
+ this.reconnectAttempts = 0;
74
+ // Re-subscribe existing subscriptions
75
+ for (const [id, sub] of this.subscriptions) {
76
+ this.sendSubscription(id, sub.filters);
77
+ }
78
+ resolve();
79
+ };
80
+ this.ws.onclose = () => {
81
+ clearTimeout(timeout);
82
+ this.setState('disconnected');
83
+ this.handleReconnect();
84
+ };
85
+ this.ws.onerror = () => {
86
+ clearTimeout(timeout);
87
+ this.setState('error');
88
+ reject(new SignetValidationError('WebSocket connection failed'));
89
+ };
90
+ this.ws.onmessage = (msg) => {
91
+ if (typeof msg.data !== 'string')
92
+ return; // ignore binary frames
93
+ this.handleMessage(msg.data);
94
+ };
95
+ });
96
+ }
97
+ /** Disconnect from the relay */
98
+ disconnect() {
99
+ if (this.reconnectTimer) {
100
+ clearTimeout(this.reconnectTimer);
101
+ this.reconnectTimer = null;
102
+ }
103
+ this.disconnectRequested = true;
104
+ this.ws?.close();
105
+ this.ws = null;
106
+ this.setState('disconnected');
107
+ // Clean up pending publishes
108
+ for (const [, pending] of this.pendingPublishes) {
109
+ clearTimeout(pending.timeout);
110
+ pending.resolve({ ok: false, message: 'Disconnected' });
111
+ }
112
+ this.pendingPublishes.clear();
113
+ }
114
+ /** Publish an event to the relay */
115
+ async publish(event) {
116
+ if (this.state !== 'connected' || !this.ws) {
117
+ throw new SignetValidationError('Not connected to relay');
118
+ }
119
+ if (!/^[0-9a-f]{64}$/.test(event.id)) {
120
+ throw new SignetValidationError('Invalid event ID: must be a 64-character lowercase hex string');
121
+ }
122
+ return new Promise((resolve) => {
123
+ const timeout = setTimeout(() => {
124
+ this.pendingPublishes.delete(event.id);
125
+ resolve({ ok: false, message: 'Publish timeout' });
126
+ }, 10000);
127
+ this.pendingPublishes.set(event.id, { resolve, timeout });
128
+ this.ws.send(JSON.stringify(['EVENT', event]));
129
+ });
130
+ }
131
+ /**
132
+ * Subscribe to events matching the given filters.
133
+ * @returns Subscription ID (use to close the subscription)
134
+ */
135
+ subscribe(filters, onEvent, onEose) {
136
+ const subId = `signet-sub-${++this.subCounter}`;
137
+ this.subscriptions.set(subId, {
138
+ filters,
139
+ callback: onEvent,
140
+ eoseCallback: onEose,
141
+ });
142
+ if (this.state === 'connected') {
143
+ this.sendSubscription(subId, filters);
144
+ }
145
+ return subId;
146
+ }
147
+ /** Close a subscription */
148
+ closeSubscription(subId) {
149
+ this.subscriptions.delete(subId);
150
+ if (this.state === 'connected' && this.ws) {
151
+ this.ws.send(JSON.stringify(['CLOSE', subId]));
152
+ }
153
+ }
154
+ /**
155
+ * Fetch events matching filters (returns after EOSE).
156
+ * Convenience method that subscribes, collects events, and closes.
157
+ */
158
+ fetch(filters, timeoutMs = 30000) {
159
+ return new Promise((resolve) => {
160
+ const events = [];
161
+ let resolved = false;
162
+ const done = () => {
163
+ if (resolved)
164
+ return;
165
+ resolved = true;
166
+ clearTimeout(timer);
167
+ this.closeSubscription(subId);
168
+ resolve(events);
169
+ };
170
+ const maxEvents = 10_000;
171
+ const subId = this.subscribe(filters, (event) => { events.push(event); if (events.length >= maxEvents)
172
+ done(); }, () => done());
173
+ // Timeout guard: resolve with events collected so far if EOSE never arrives
174
+ const timer = setTimeout(() => done(), timeoutMs);
175
+ });
176
+ }
177
+ sendSubscription(subId, filters) {
178
+ if (this.ws) {
179
+ this.ws.send(JSON.stringify(['REQ', subId, ...filters]));
180
+ }
181
+ }
182
+ handleMessage(data) {
183
+ if (data.length > MAX_MESSAGE_SIZE)
184
+ return;
185
+ try {
186
+ const msg = JSON.parse(data);
187
+ if (!Array.isArray(msg) || msg.length < 2 || typeof msg[0] !== 'string')
188
+ return;
189
+ switch (msg[0]) {
190
+ case 'EVENT': {
191
+ if (msg.length < 3 || typeof msg[1] !== 'string' || typeof msg[2] !== 'object' || msg[2] === null)
192
+ break;
193
+ const raw = msg[2];
194
+ // Validate required NostrEvent fields before casting
195
+ if (typeof raw.id !== 'string' || typeof raw.pubkey !== 'string' ||
196
+ typeof raw.kind !== 'number' || typeof raw.created_at !== 'number' ||
197
+ !Array.isArray(raw.tags) || typeof raw.content !== 'string' ||
198
+ typeof raw.sig !== 'string')
199
+ break;
200
+ const subId = msg[1];
201
+ const event = raw;
202
+ const boundsErrors = [];
203
+ validateFieldSizeBounds(event, boundsErrors);
204
+ if (boundsErrors.length > 0) {
205
+ break; // reject oversized events
206
+ }
207
+ const sub = this.subscriptions.get(subId);
208
+ if (sub) {
209
+ if (this.options.verifyEvents !== false) {
210
+ verifyEvent(event).then((valid) => {
211
+ if (valid) {
212
+ sub.callback(event);
213
+ }
214
+ else {
215
+ this.options.onEventRejected?.(event, 'invalid signature or event ID');
216
+ }
217
+ });
218
+ }
219
+ else {
220
+ sub.callback(event);
221
+ }
222
+ }
223
+ break;
224
+ }
225
+ case 'OK': {
226
+ if (msg.length < 4 || typeof msg[1] !== 'string' || typeof msg[2] !== 'boolean' || typeof msg[3] !== 'string')
227
+ break;
228
+ const eventId = msg[1];
229
+ const pending = this.pendingPublishes.get(eventId);
230
+ if (pending) {
231
+ clearTimeout(pending.timeout);
232
+ this.pendingPublishes.delete(eventId);
233
+ pending.resolve({ ok: msg[2], message: msg[3] });
234
+ }
235
+ break;
236
+ }
237
+ case 'EOSE': {
238
+ if (typeof msg[1] !== 'string')
239
+ break;
240
+ const sub = this.subscriptions.get(msg[1]);
241
+ sub?.eoseCallback?.();
242
+ break;
243
+ }
244
+ case 'AUTH': {
245
+ if (typeof msg[1] !== 'string')
246
+ break;
247
+ // Cap challenge length to prevent oversized AUTH events from malicious relays
248
+ if (msg[1].length > 256)
249
+ break;
250
+ this.handleAuth(msg[1]);
251
+ break;
252
+ }
253
+ case 'NOTICE': {
254
+ // Relay notices are informational — log but don't act
255
+ break;
256
+ }
257
+ }
258
+ }
259
+ catch {
260
+ // Malformed message — ignore
261
+ }
262
+ }
263
+ /** Handle NIP-42 AUTH challenge */
264
+ async handleAuth(challenge) {
265
+ if (!this.options.authPrivateKey)
266
+ return;
267
+ const pubkey = getPublicKey(this.options.authPrivateKey);
268
+ const authEvent = {
269
+ kind: NIP42_AUTH_KIND,
270
+ pubkey,
271
+ created_at: Math.floor(Date.now() / 1000),
272
+ tags: [
273
+ ['relay', this.url],
274
+ ['challenge', challenge],
275
+ ],
276
+ content: '',
277
+ };
278
+ const signed = await signEvent(authEvent, this.options.authPrivateKey);
279
+ this.ws?.send(JSON.stringify(['AUTH', signed]));
280
+ }
281
+ handleReconnect() {
282
+ if (this.disconnectRequested || !this.options.autoReconnect)
283
+ return;
284
+ if (this.reconnectAttempts >= (this.options.maxReconnectAttempts ?? 5))
285
+ return;
286
+ this.reconnectAttempts++;
287
+ this.reconnectTimer = setTimeout(() => {
288
+ this.connect().catch(() => {
289
+ // Will retry via onclose handler
290
+ });
291
+ }, this.options.reconnectDelay);
292
+ }
293
+ }
294
+ /**
295
+ * Publish a Signet event to multiple relays.
296
+ *
297
+ * WARNING: Relay URLs are accepted as-is. Callers are responsible for
298
+ * validating that URLs come from trusted sources and do not encode credentials.
299
+ * The RelayClient constructor enforces wss:// for non-localhost connections.
300
+ */
301
+ export async function publishToRelays(event, relayUrls) {
302
+ const results = new Map();
303
+ const promises = relayUrls.map(async (url) => {
304
+ const relay = new RelayClient(url);
305
+ try {
306
+ await relay.connect();
307
+ const result = await relay.publish(event);
308
+ results.set(url, result);
309
+ }
310
+ catch (err) {
311
+ results.set(url, { ok: false, message: err instanceof Error ? err.message : 'Connection failed' });
312
+ }
313
+ finally {
314
+ relay.disconnect();
315
+ }
316
+ });
317
+ await Promise.allSettled(promises);
318
+ return results;
319
+ }
320
+ /**
321
+ * Fetch Signet events from a relay by kind and optional filters.
322
+ *
323
+ * WARNING: Relay URL is accepted as-is. Callers are responsible for
324
+ * validating that URLs come from trusted sources and do not encode credentials.
325
+ */
326
+ export async function fetchFromRelay(relayUrl, filters) {
327
+ const relay = new RelayClient(relayUrl);
328
+ try {
329
+ await relay.connect();
330
+ return await relay.fetch(filters);
331
+ }
332
+ finally {
333
+ relay.disconnect();
334
+ }
335
+ }
336
+ //# sourceMappingURL=relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { type RingSignature, MAX_RING_SIZE } from '@forgesworn/ring-sig';
2
+ export { MAX_RING_SIZE, type RingSignature };
3
+ /**
4
+ * Sign a message with a ring signature using Signet's domain separator.
5
+ *
6
+ * @param message - The message to sign (will be hashed)
7
+ * @param ring - Array of x-only public keys (hex) forming the anonymity set
8
+ * @param signerIndex - Index of the actual signer in the ring
9
+ * @param privateKey - Signer's private key (hex)
10
+ * @returns A ring signature
11
+ */
12
+ export declare function ringSign(message: string, ring: string[], signerIndex: number, privateKey: string): RingSignature;
13
+ /**
14
+ * Verify a ring signature.
15
+ *
16
+ * @param sig - The ring signature to verify
17
+ * @returns true if the signature is valid
18
+ */
19
+ export declare function ringVerify(sig: RingSignature): boolean;
20
+ /**
21
+ * Create a ring signature for a Signet credential.
22
+ * Wraps ringSign with credential-specific message construction.
23
+ *
24
+ * @param credentialEventId - The event ID of the credential being signed
25
+ * @param subjectPubkey - The pubkey of the person being verified
26
+ * @param ring - Array of verifier pubkeys forming the anonymity set
27
+ * @param signerIndex - Index of the actual signing verifier
28
+ * @param privateKey - Signing verifier's private key
29
+ */
30
+ export declare function signCredentialRing(credentialEventId: string, subjectPubkey: string, ring: string[], signerIndex: number, privateKey: string): RingSignature;
31
+ /**
32
+ * Verify a ring signature on a Signet credential.
33
+ */
34
+ export declare function verifyCredentialRing(sig: RingSignature, credentialEventId: string, subjectPubkey: string): boolean;
35
+ //# sourceMappingURL=ring-signature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-signature.d.ts","sourceRoot":"","sources":["../src/ring-signature.ts"],"names":[],"mappings":"AAIA,OAAO,EAAoD,KAAK,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAI3H,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,CAAC;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,aAAa,CAKf;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAEtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,EAAE,EACd,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,aAAa,CAKf;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,aAAa,EAClB,iBAAiB,EAAE,MAAM,EACzB,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT"}
@@ -0,0 +1,56 @@
1
+ // SAG Ring Signatures — thin re-export from @forgesworn/ring-sig with Signet domain separator
2
+ // Proves "one of N public keys signed this message" without revealing which one.
3
+ // Used for Tier 3/4 issuer privacy: "a professional verified this" without revealing which professional.
4
+ import { ringSign as _ringSign, ringVerify as _ringVerify, MAX_RING_SIZE } from '@forgesworn/ring-sig';
5
+ const SIGNET_SAG_DOMAIN = 'signet-sag-v1';
6
+ export { MAX_RING_SIZE };
7
+ /**
8
+ * Sign a message with a ring signature using Signet's domain separator.
9
+ *
10
+ * @param message - The message to sign (will be hashed)
11
+ * @param ring - Array of x-only public keys (hex) forming the anonymity set
12
+ * @param signerIndex - Index of the actual signer in the ring
13
+ * @param privateKey - Signer's private key (hex)
14
+ * @returns A ring signature
15
+ */
16
+ export function ringSign(message, ring, signerIndex, privateKey) {
17
+ const sig = _ringSign(message, ring, signerIndex, privateKey, SIGNET_SAG_DOMAIN);
18
+ // Ensure the domain is carried in the signature so ringVerify uses the correct domain
19
+ sig.domain = SIGNET_SAG_DOMAIN;
20
+ return sig;
21
+ }
22
+ /**
23
+ * Verify a ring signature.
24
+ *
25
+ * @param sig - The ring signature to verify
26
+ * @returns true if the signature is valid
27
+ */
28
+ export function ringVerify(sig) {
29
+ return _ringVerify(sig);
30
+ }
31
+ /**
32
+ * Create a ring signature for a Signet credential.
33
+ * Wraps ringSign with credential-specific message construction.
34
+ *
35
+ * @param credentialEventId - The event ID of the credential being signed
36
+ * @param subjectPubkey - The pubkey of the person being verified
37
+ * @param ring - Array of verifier pubkeys forming the anonymity set
38
+ * @param signerIndex - Index of the actual signing verifier
39
+ * @param privateKey - Signing verifier's private key
40
+ */
41
+ export function signCredentialRing(credentialEventId, subjectPubkey, ring, signerIndex, privateKey) {
42
+ const message = `signet:credential:${credentialEventId}:${subjectPubkey}`;
43
+ const sig = _ringSign(message, ring, signerIndex, privateKey, SIGNET_SAG_DOMAIN);
44
+ sig.domain = SIGNET_SAG_DOMAIN;
45
+ return sig;
46
+ }
47
+ /**
48
+ * Verify a ring signature on a Signet credential.
49
+ */
50
+ export function verifyCredentialRing(sig, credentialEventId, subjectPubkey) {
51
+ const expectedMessage = `signet:credential:${credentialEventId}:${subjectPubkey}`;
52
+ if (sig.message !== expectedMessage)
53
+ return false;
54
+ return _ringVerify(sig);
55
+ }
56
+ //# sourceMappingURL=ring-signature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-signature.js","sourceRoot":"","sources":["../src/ring-signature.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,iFAAiF;AACjF,yGAAyG;AAEzG,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,UAAU,IAAI,WAAW,EAAsB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3H,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAsB,CAAC;AAE7C;;;;;;;;GAQG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAe,EACf,IAAc,EACd,WAAmB,EACnB,UAAkB;IAElB,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACjF,sFAAsF;IACtF,GAAG,CAAC,MAAM,GAAG,iBAAiB,CAAC;IAC/B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,GAAkB;IAC3C,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,iBAAyB,EACzB,aAAqB,EACrB,IAAc,EACd,WAAmB,EACnB,UAAkB;IAElB,MAAM,OAAO,GAAG,qBAAqB,iBAAiB,IAAI,aAAa,EAAE,CAAC;IAC1E,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACjF,GAAG,CAAC,MAAM,GAAG,iBAAiB,CAAC;IAC/B,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAkB,EAClB,iBAAyB,EACzB,aAAqB;IAErB,MAAM,eAAe,GAAG,qBAAqB,iBAAiB,IAAI,aAAa,EAAE,CAAC;IAClF,IAAI,GAAG,CAAC,OAAO,KAAK,eAAe;QAAE,OAAO,KAAK,CAAC;IAClD,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Shamir's Secret Sharing over GF(256).
3
+ *
4
+ * INTENTIONAL DUPLICATION: Dominion Protocol has its own GF(256) Shamir
5
+ * implementation. The low-level maths is identical but the protocols serve
6
+ * different purposes:
7
+ *
8
+ * - Signet: splits identity keys across PEOPLE (guardian recovery).
9
+ * Shares are encoded as BIP-39 words for human exchange.
10
+ * - Dominion: splits content keys across MACHINES (warden relays).
11
+ * Shares are raw bytes for relay distribution.
12
+ *
13
+ * Coupling the protocols via a shared dependency is worse than ~100 lines
14
+ * of duplicated arithmetic. GF(256) is stable and will never change.
15
+ *
16
+ * See: trott-business/docs/plans/2026-03-12-fathom-alpha-live-design.md
17
+ */
18
+ export interface ShamirShare {
19
+ id: number;
20
+ data: Uint8Array;
21
+ }
22
+ /** Addition in GF(256) is XOR */
23
+ export declare function gf256Add(a: number, b: number): number;
24
+ /** Multiplication in GF(256) using log/exp tables */
25
+ export declare function gf256Mul(a: number, b: number): number;
26
+ /** Multiplicative inverse in GF(256) */
27
+ export declare function gf256Inv(a: number): number;
28
+ /**
29
+ * Split a secret into shares using Shamir's Secret Sharing over GF(256).
30
+ *
31
+ * @param secret The secret bytes to split
32
+ * @param threshold Minimum shares needed to reconstruct (>= 2)
33
+ * @param shares Total number of shares to create (>= threshold, <= 255)
34
+ * @returns Array of ShamirShare objects
35
+ */
36
+ export declare function splitSecret(secret: Uint8Array, threshold: number, shares: number): ShamirShare[];
37
+ /**
38
+ * Reconstruct a secret from shares using Lagrange interpolation over GF(256).
39
+ *
40
+ * @param shares Array of shares (at least `threshold` shares)
41
+ * @param threshold The threshold used during splitting
42
+ * @returns The reconstructed secret bytes
43
+ */
44
+ export declare function reconstructSecret(shares: ShamirShare[], threshold: number): Uint8Array;
45
+ /**
46
+ * Encode a share as BIP-39 words.
47
+ * Prepends the share ID byte to the data, then converts to 11-bit groups.
48
+ */
49
+ export declare function shareToWords(share: ShamirShare): string[];
50
+ /**
51
+ * Decode BIP-39 words back to a share.
52
+ * Reverses the encoding from shareToWords.
53
+ */
54
+ export declare function wordsToShare(words: string[]): ShamirShare;
55
+ //# sourceMappingURL=shamir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shamir.d.ts","sourceRoot":"","sources":["../src/shamir.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;CAClB;AAwCD,iCAAiC;AACjC,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,qDAAqD;AACrD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wCAAwC;AACxC,wBAAgB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAG1C;AAkBD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,WAAW,EAAE,CAwCf;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,EAAE,EACrB,SAAS,EAAE,MAAM,GAChB,UAAU,CAuDZ;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,EAAE,CA+BzD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,WAAW,CAkDzD"}