@acpantenna/relay-protocol 0.0.0-stage → 0.2.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 (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -2
  3. package/dist/bip39-english.d.ts +28 -0
  4. package/dist/bip39-english.d.ts.map +1 -0
  5. package/dist/bip39-english.js +28 -0
  6. package/dist/bip39-english.js.map +1 -0
  7. package/dist/bytes.d.ts +21 -0
  8. package/dist/bytes.d.ts.map +1 -0
  9. package/dist/bytes.js +114 -0
  10. package/dist/bytes.js.map +1 -0
  11. package/dist/frames.d.ts +90 -0
  12. package/dist/frames.d.ts.map +1 -0
  13. package/dist/frames.js +234 -0
  14. package/dist/frames.js.map +1 -0
  15. package/dist/index.d.ts +14 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +14 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/link.d.ts +44 -0
  20. package/dist/link.d.ts.map +1 -0
  21. package/dist/link.js +120 -0
  22. package/dist/link.js.map +1 -0
  23. package/dist/noise.d.ts +181 -0
  24. package/dist/noise.d.ts.map +1 -0
  25. package/dist/noise.js +490 -0
  26. package/dist/noise.js.map +1 -0
  27. package/dist/relay.d.ts +37 -0
  28. package/dist/relay.d.ts.map +1 -0
  29. package/dist/relay.js +70 -0
  30. package/dist/relay.js.map +1 -0
  31. package/dist/sas.d.ts +11 -0
  32. package/dist/sas.d.ts.map +1 -0
  33. package/dist/sas.js +26 -0
  34. package/dist/sas.js.map +1 -0
  35. package/dist/session.d.ts +298 -0
  36. package/dist/session.d.ts.map +1 -0
  37. package/dist/session.js +608 -0
  38. package/dist/session.js.map +1 -0
  39. package/package.json +56 -5
  40. package/src/bip39-english.ts +30 -0
  41. package/src/bytes.ts +125 -0
  42. package/src/frames.ts +278 -0
  43. package/src/index.ts +14 -0
  44. package/src/link.ts +160 -0
  45. package/src/noise.ts +655 -0
  46. package/src/relay.ts +106 -0
  47. package/src/sas.ts +28 -0
  48. package/src/session.ts +848 -0
  49. package/test-vectors/frames.json +353 -0
  50. package/test-vectors/noise-kk.json +43 -0
  51. package/test-vectors/noise-nkpsk0.json +47 -0
  52. package/test-vectors/sas.json +21 -0
  53. package/test-vectors/session.json +58 -0
package/dist/noise.js ADDED
@@ -0,0 +1,490 @@
1
+ /**
2
+ * `Noise_NKpsk0_25519_ChaChaPoly_BLAKE2s` for pairing and
3
+ * `Noise_KK_25519_ChaChaPoly_BLAKE2s` for reconnecting, following the Noise
4
+ * Protocol Framework, revision 34 (https://noiseprotocol.org/noise.html): the
5
+ * CipherState, SymmetricState and HandshakeState objects of §5, with the
6
+ * `psk` modifier of §9 and `Rekey()` of §11.3.
7
+ *
8
+ * NKpsk0:
9
+ *
10
+ * <- s
11
+ * ...
12
+ * -> psk, e, es
13
+ * <- e, ee
14
+ *
15
+ * KK:
16
+ *
17
+ * -> s
18
+ * <- s
19
+ * ...
20
+ * -> e, es, ss
21
+ * <- e, ee, se
22
+ */
23
+ import { chacha20poly1305 } from "@noble/ciphers/chacha.js";
24
+ import { x25519 } from "@noble/curves/ed25519.js";
25
+ import { blake2s } from "@noble/hashes/blake2.js";
26
+ import { hmac } from "@noble/hashes/hmac.js";
27
+ import { concatBytes, randomBytes, utf8Encode } from "./bytes.js";
28
+ export const PROTOCOL_NAME = "Noise_NKpsk0_25519_ChaChaPoly_BLAKE2s";
29
+ export const KK_PROTOCOL_NAME = "Noise_KK_25519_ChaChaPoly_BLAKE2s";
30
+ export const DHLEN = 32;
31
+ export const HASHLEN = 32;
32
+ export const KEYLEN = 32;
33
+ export const TAGLEN = 16;
34
+ /** The largest Noise message, in bytes (§3). */
35
+ export const MAX_MESSAGE_LENGTH = 65535;
36
+ /** A decryption failed, or a message could not be processed. Always fatal. */
37
+ export class NoiseError extends Error {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = "NoiseError";
41
+ }
42
+ }
43
+ /** Makes an X25519 key pair, from `privateKey` if given. */
44
+ export function generateKeyPair(privateKey) {
45
+ const secret = privateKey ?? randomBytes(DHLEN);
46
+ if (secret.length !== DHLEN) {
47
+ throw new NoiseError("An X25519 private key is 32 bytes");
48
+ }
49
+ return { privateKey: secret, publicKey: x25519.getPublicKey(secret) };
50
+ }
51
+ /** A {@link StaticKey} over a key pair held in memory. */
52
+ export function staticKey(keyPair) {
53
+ return {
54
+ publicKey: keyPair.publicKey,
55
+ dh: async (publicKey) => dh(keyPair, publicKey),
56
+ };
57
+ }
58
+ async function staticDh(key, publicKey) {
59
+ let shared;
60
+ try {
61
+ shared = await key.dh(publicKey);
62
+ }
63
+ catch {
64
+ throw new NoiseError("Invalid X25519 public key");
65
+ }
66
+ if (shared.length !== DHLEN || shared.every((byte) => byte === 0)) {
67
+ throw new NoiseError("Invalid X25519 public key");
68
+ }
69
+ return shared;
70
+ }
71
+ function dh(keyPair, publicKey) {
72
+ try {
73
+ return x25519.getSharedSecret(keyPair.privateKey, publicKey);
74
+ }
75
+ catch {
76
+ // A low-order public key gives an all-zero result, which noble refuses.
77
+ throw new NoiseError("Invalid X25519 public key");
78
+ }
79
+ }
80
+ function hash(data) {
81
+ return blake2s(data);
82
+ }
83
+ /** HKDF from §4.3, with HMAC-BLAKE2s. */
84
+ function hkdf(chainingKey, inputKeyMaterial, outputs) {
85
+ const tempKey = hmac(blake2s, chainingKey, inputKeyMaterial);
86
+ const output1 = hmac(blake2s, tempKey, Uint8Array.of(1));
87
+ const output2 = hmac(blake2s, tempKey, concatBytes(output1, Uint8Array.of(2)));
88
+ if (outputs === 2) {
89
+ return [output1, output2];
90
+ }
91
+ const output3 = hmac(blake2s, tempKey, concatBytes(output2, Uint8Array.of(3)));
92
+ return [output1, output2, output3];
93
+ }
94
+ /** ChaChaPoly's nonce: 32 bits of zeros, then the 64-bit counter, little-endian. */
95
+ function chachaNonce(n) {
96
+ const nonce = new Uint8Array(12);
97
+ const view = new DataView(nonce.buffer);
98
+ view.setUint32(4, n >>> 0, true);
99
+ view.setUint32(8, Math.floor(n / 2 ** 32), true);
100
+ return nonce;
101
+ }
102
+ /** 2^64 − 1, the nonce `Rekey()` uses and no message may. */
103
+ const REKEY_NONCE = Uint8Array.of(0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255);
104
+ /**
105
+ * A key and a nonce counter (§5.1). The counter is a JavaScript number, so it
106
+ * stops at 2^53 rather than 2^64 − 1; a session never gets near either.
107
+ */
108
+ export class CipherState {
109
+ key;
110
+ nonce = 0;
111
+ constructor(key) {
112
+ if (key) {
113
+ this.initializeKey(key);
114
+ }
115
+ }
116
+ initializeKey(key) {
117
+ this.key = key;
118
+ this.nonce = 0;
119
+ }
120
+ hasKey() {
121
+ return this.key !== undefined;
122
+ }
123
+ /** How many messages this state has encrypted or decrypted. */
124
+ get messages() {
125
+ return this.nonce;
126
+ }
127
+ encryptWithAd(ad, plaintext) {
128
+ if (!this.key) {
129
+ return plaintext;
130
+ }
131
+ this.checkNonce();
132
+ const ciphertext = chacha20poly1305(this.key, chachaNonce(this.nonce), ad).encrypt(plaintext);
133
+ this.nonce++;
134
+ return ciphertext;
135
+ }
136
+ /** Throws a {@link NoiseError} if the tag does not verify; the nonce is then unchanged. */
137
+ decryptWithAd(ad, ciphertext) {
138
+ if (!this.key) {
139
+ return ciphertext;
140
+ }
141
+ this.checkNonce();
142
+ let plaintext;
143
+ try {
144
+ plaintext = chacha20poly1305(this.key, chachaNonce(this.nonce), ad).decrypt(ciphertext);
145
+ }
146
+ catch {
147
+ throw new NoiseError("Decryption failed");
148
+ }
149
+ this.nonce++;
150
+ return plaintext;
151
+ }
152
+ /** §11.3: replaces the key with the first 32 bytes of ENCRYPT(k, 2^64 − 1, ε, zeros). */
153
+ rekey() {
154
+ if (!this.key) {
155
+ throw new NoiseError("Cannot rekey a CipherState without a key");
156
+ }
157
+ this.key = chacha20poly1305(this.key, REKEY_NONCE, new Uint8Array(0))
158
+ .encrypt(new Uint8Array(KEYLEN))
159
+ .subarray(0, KEYLEN);
160
+ }
161
+ checkNonce() {
162
+ if (this.nonce >= Number.MAX_SAFE_INTEGER) {
163
+ throw new NoiseError("Nonce exhausted");
164
+ }
165
+ }
166
+ }
167
+ /** The chaining key, the handshake hash and a CipherState (§5.2). */
168
+ export class SymmetricState {
169
+ cipher = new CipherState();
170
+ chainingKey;
171
+ h;
172
+ constructor(protocolName) {
173
+ const name = utf8Encode(protocolName);
174
+ if (name.length <= HASHLEN) {
175
+ this.h = new Uint8Array(HASHLEN);
176
+ this.h.set(name);
177
+ }
178
+ else {
179
+ this.h = hash(name);
180
+ }
181
+ this.chainingKey = this.h;
182
+ }
183
+ get handshakeHash() {
184
+ return this.h;
185
+ }
186
+ mixKey(inputKeyMaterial) {
187
+ const [chainingKey, tempKey] = hkdf(this.chainingKey, inputKeyMaterial, 2);
188
+ this.chainingKey = chainingKey;
189
+ this.cipher.initializeKey(tempKey);
190
+ }
191
+ mixHash(data) {
192
+ this.h = hash(concatBytes(this.h, data));
193
+ }
194
+ mixKeyAndHash(inputKeyMaterial) {
195
+ const [chainingKey, tempHash, tempKey] = hkdf(this.chainingKey, inputKeyMaterial, 3);
196
+ this.chainingKey = chainingKey;
197
+ this.mixHash(tempHash);
198
+ this.cipher.initializeKey(tempKey);
199
+ }
200
+ encryptAndHash(plaintext) {
201
+ const ciphertext = this.cipher.encryptWithAd(this.h, plaintext);
202
+ this.mixHash(ciphertext);
203
+ return ciphertext;
204
+ }
205
+ decryptAndHash(ciphertext) {
206
+ const plaintext = this.cipher.decryptWithAd(this.h, ciphertext);
207
+ this.mixHash(ciphertext);
208
+ return plaintext;
209
+ }
210
+ /** Returns the initiator's sending and receiving CipherStates, in that order. */
211
+ split() {
212
+ const [key1, key2] = hkdf(this.chainingKey, new Uint8Array(0), 2);
213
+ return [
214
+ new CipherState(key1),
215
+ new CipherState(key2),
216
+ ];
217
+ }
218
+ }
219
+ /**
220
+ * The NKpsk0 HandshakeState (§5.3), for one side. Call `writeMessage` and
221
+ * `readMessage` in turn: the initiator writes message 1 and reads message 2,
222
+ * the responder the other way round. After message 2 `result` is set.
223
+ */
224
+ export class HandshakeState {
225
+ initiator;
226
+ symmetric = new SymmetricState(PROTOCOL_NAME);
227
+ psk;
228
+ staticKeyPair;
229
+ remoteStatic;
230
+ fixedEphemeral;
231
+ ephemeral;
232
+ remoteEphemeral;
233
+ step = 0;
234
+ result;
235
+ constructor(initiator, options) {
236
+ if (options.psk.length !== 32) {
237
+ throw new NoiseError("The psk is 32 bytes");
238
+ }
239
+ if (options.remoteStaticPublicKey.length !== DHLEN) {
240
+ throw new NoiseError("The responder's static key is 32 bytes");
241
+ }
242
+ this.initiator = initiator;
243
+ this.psk = options.psk;
244
+ this.staticKeyPair = options.staticKeyPair;
245
+ this.remoteStatic = options.remoteStaticPublicKey;
246
+ this.fixedEphemeral = options.ephemeralPrivateKey;
247
+ this.symmetric.mixHash(options.prologue);
248
+ // The pre-message `<- s`: both sides hash the responder's static key.
249
+ this.symmetric.mixHash(this.remoteStatic);
250
+ }
251
+ static initiator(options) {
252
+ return new HandshakeState(true, options);
253
+ }
254
+ static responder(options) {
255
+ return new HandshakeState(false, {
256
+ ...options,
257
+ remoteStaticPublicKey: options.staticKeyPair.publicKey,
258
+ });
259
+ }
260
+ get handshakeHash() {
261
+ return this.symmetric.handshakeHash;
262
+ }
263
+ /** Writes the next handshake message, carrying `payload`. */
264
+ writeMessage(payload = new Uint8Array(0)) {
265
+ if (this.step === 0 && this.initiator) {
266
+ // -> psk, e, es
267
+ this.symmetric.mixKeyAndHash(this.psk);
268
+ const e = this.writeEphemeral();
269
+ this.symmetric.mixKey(dh(this.ephemeralKeyPair(), this.remoteStatic));
270
+ const message = concatBytes(e, this.symmetric.encryptAndHash(payload));
271
+ this.step = 1;
272
+ return this.checkLength(message);
273
+ }
274
+ if (this.step === 1 && !this.initiator) {
275
+ // <- e, ee
276
+ const e = this.writeEphemeral();
277
+ this.symmetric.mixKey(dh(this.ephemeralKeyPair(), this.remoteEphemeralKey()));
278
+ const message = concatBytes(e, this.symmetric.encryptAndHash(payload));
279
+ this.finish();
280
+ return this.checkLength(message);
281
+ }
282
+ throw new NoiseError("Not this side's turn to write");
283
+ }
284
+ /** Reads the next handshake message and returns its payload. */
285
+ readMessage(message) {
286
+ if (message.length > MAX_MESSAGE_LENGTH) {
287
+ throw new NoiseError("Handshake message too long");
288
+ }
289
+ if (message.length < DHLEN + TAGLEN) {
290
+ throw new NoiseError("Handshake message too short");
291
+ }
292
+ const e = message.subarray(0, DHLEN);
293
+ const rest = message.subarray(DHLEN);
294
+ if (this.step === 0 && !this.initiator) {
295
+ // -> psk, e, es
296
+ this.symmetric.mixKeyAndHash(this.psk);
297
+ this.readEphemeral(e);
298
+ this.symmetric.mixKey(dh(this.staticKeys(), this.remoteEphemeralKey()));
299
+ const payload = this.symmetric.decryptAndHash(rest);
300
+ this.step = 1;
301
+ return payload;
302
+ }
303
+ if (this.step === 1 && this.initiator) {
304
+ // <- e, ee
305
+ this.readEphemeral(e);
306
+ this.symmetric.mixKey(dh(this.ephemeralKeyPair(), this.remoteEphemeralKey()));
307
+ const payload = this.symmetric.decryptAndHash(rest);
308
+ this.finish();
309
+ return payload;
310
+ }
311
+ throw new NoiseError("Not this side's turn to read");
312
+ }
313
+ writeEphemeral() {
314
+ this.ephemeral = generateKeyPair(this.fixedEphemeral);
315
+ this.symmetric.mixHash(this.ephemeral.publicKey);
316
+ // The psk modifier (§9.2): `e` also calls MixKey.
317
+ this.symmetric.mixKey(this.ephemeral.publicKey);
318
+ return this.ephemeral.publicKey;
319
+ }
320
+ readEphemeral(e) {
321
+ this.remoteEphemeral = e.slice();
322
+ this.symmetric.mixHash(this.remoteEphemeral);
323
+ this.symmetric.mixKey(this.remoteEphemeral);
324
+ }
325
+ ephemeralKeyPair() {
326
+ if (!this.ephemeral) {
327
+ throw new NoiseError("No ephemeral key");
328
+ }
329
+ return this.ephemeral;
330
+ }
331
+ remoteEphemeralKey() {
332
+ if (!this.remoteEphemeral) {
333
+ throw new NoiseError("No remote ephemeral key");
334
+ }
335
+ return this.remoteEphemeral;
336
+ }
337
+ staticKeys() {
338
+ if (!this.staticKeyPair) {
339
+ throw new NoiseError("No static key");
340
+ }
341
+ return this.staticKeyPair;
342
+ }
343
+ finish() {
344
+ const [initiatorSend, responderSend] = this.symmetric.split();
345
+ this.result = {
346
+ send: this.initiator ? initiatorSend : responderSend,
347
+ receive: this.initiator ? responderSend : initiatorSend,
348
+ handshakeHash: this.symmetric.handshakeHash,
349
+ remoteEphemeralPublicKey: this.remoteEphemeralKey(),
350
+ };
351
+ this.step = 2;
352
+ }
353
+ checkLength(message) {
354
+ if (message.length > MAX_MESSAGE_LENGTH) {
355
+ throw new NoiseError("Handshake message too long");
356
+ }
357
+ return message;
358
+ }
359
+ }
360
+ /**
361
+ * The KK HandshakeState (§5.3), for one side: both static keys are known in
362
+ * advance, so it needs no psk. As with {@link HandshakeState}, the initiator
363
+ * writes message 1 and reads message 2. Its steps are asynchronous because a
364
+ * {@link StaticKey}'s DH is.
365
+ */
366
+ export class KKHandshakeState {
367
+ initiator;
368
+ symmetric = new SymmetricState(KK_PROTOCOL_NAME);
369
+ staticKey;
370
+ remoteStatic;
371
+ fixedEphemeral;
372
+ ephemeral;
373
+ remoteEphemeral;
374
+ step = 0;
375
+ result;
376
+ constructor(initiator, options) {
377
+ if (options.remoteStaticPublicKey.length !== DHLEN ||
378
+ options.staticKey.publicKey.length !== DHLEN) {
379
+ throw new NoiseError("A static key is 32 bytes");
380
+ }
381
+ this.initiator = initiator;
382
+ this.staticKey = options.staticKey;
383
+ this.remoteStatic = options.remoteStaticPublicKey;
384
+ this.fixedEphemeral = options.ephemeralPrivateKey;
385
+ this.symmetric.mixHash(options.prologue);
386
+ // The pre-messages `-> s` and `<- s`: the initiator's key is hashed first.
387
+ const [initiatorStatic, responderStatic] = initiator
388
+ ? [this.staticKey.publicKey, this.remoteStatic]
389
+ : [this.remoteStatic, this.staticKey.publicKey];
390
+ this.symmetric.mixHash(initiatorStatic);
391
+ this.symmetric.mixHash(responderStatic);
392
+ }
393
+ static initiator(options) {
394
+ return new KKHandshakeState(true, options);
395
+ }
396
+ static responder(options) {
397
+ return new KKHandshakeState(false, options);
398
+ }
399
+ get handshakeHash() {
400
+ return this.symmetric.handshakeHash;
401
+ }
402
+ /** Writes the next handshake message, carrying `payload`. */
403
+ async writeMessage(payload = new Uint8Array(0)) {
404
+ if (this.step === 0 && this.initiator) {
405
+ // -> e, es, ss
406
+ this.step = -1;
407
+ const e = this.writeEphemeral();
408
+ this.symmetric.mixKey(dh(this.ephemeralKeyPair(), this.remoteStatic));
409
+ this.symmetric.mixKey(await staticDh(this.staticKey, this.remoteStatic));
410
+ const message = concatBytes(e, this.symmetric.encryptAndHash(payload));
411
+ this.step = 1;
412
+ return message;
413
+ }
414
+ if (this.step === 1 && !this.initiator) {
415
+ // <- e, ee, se
416
+ const e = this.writeEphemeral();
417
+ this.symmetric.mixKey(dh(this.ephemeralKeyPair(), this.remoteEphemeralKey()));
418
+ this.symmetric.mixKey(dh(this.ephemeralKeyPair(), this.remoteStatic));
419
+ const message = concatBytes(e, this.symmetric.encryptAndHash(payload));
420
+ this.finish();
421
+ return message;
422
+ }
423
+ throw new NoiseError("Not this side's turn to write");
424
+ }
425
+ /** Reads the next handshake message and returns its payload. */
426
+ async readMessage(message) {
427
+ if (message.length > MAX_MESSAGE_LENGTH) {
428
+ throw new NoiseError("Handshake message too long");
429
+ }
430
+ if (message.length < DHLEN + TAGLEN) {
431
+ throw new NoiseError("Handshake message too short");
432
+ }
433
+ const e = message.subarray(0, DHLEN);
434
+ const rest = message.subarray(DHLEN);
435
+ if (this.step === 0 && !this.initiator) {
436
+ // -> e, es, ss
437
+ this.step = -1;
438
+ this.readEphemeral(e);
439
+ this.symmetric.mixKey(await staticDh(this.staticKey, this.remoteEphemeralKey()));
440
+ this.symmetric.mixKey(await staticDh(this.staticKey, this.remoteStatic));
441
+ const payload = this.symmetric.decryptAndHash(rest);
442
+ this.step = 1;
443
+ return payload;
444
+ }
445
+ if (this.step === 1 && this.initiator) {
446
+ // <- e, ee, se
447
+ this.step = -1;
448
+ this.readEphemeral(e);
449
+ this.symmetric.mixKey(dh(this.ephemeralKeyPair(), this.remoteEphemeralKey()));
450
+ this.symmetric.mixKey(await staticDh(this.staticKey, this.remoteEphemeralKey()));
451
+ const payload = this.symmetric.decryptAndHash(rest);
452
+ this.finish();
453
+ return payload;
454
+ }
455
+ throw new NoiseError("Not this side's turn to read");
456
+ }
457
+ writeEphemeral() {
458
+ this.ephemeral = generateKeyPair(this.fixedEphemeral);
459
+ // No psk, so `e` is only hashed.
460
+ this.symmetric.mixHash(this.ephemeral.publicKey);
461
+ return this.ephemeral.publicKey;
462
+ }
463
+ readEphemeral(e) {
464
+ this.remoteEphemeral = e.slice();
465
+ this.symmetric.mixHash(this.remoteEphemeral);
466
+ }
467
+ ephemeralKeyPair() {
468
+ if (!this.ephemeral) {
469
+ throw new NoiseError("No ephemeral key");
470
+ }
471
+ return this.ephemeral;
472
+ }
473
+ remoteEphemeralKey() {
474
+ if (!this.remoteEphemeral) {
475
+ throw new NoiseError("No remote ephemeral key");
476
+ }
477
+ return this.remoteEphemeral;
478
+ }
479
+ finish() {
480
+ const [initiatorSend, responderSend] = this.symmetric.split();
481
+ this.result = {
482
+ send: this.initiator ? initiatorSend : responderSend,
483
+ receive: this.initiator ? responderSend : initiatorSend,
484
+ handshakeHash: this.symmetric.handshakeHash,
485
+ remoteEphemeralPublicKey: this.remoteEphemeralKey(),
486
+ };
487
+ this.step = 2;
488
+ }
489
+ }
490
+ //# sourceMappingURL=noise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noise.js","sourceRoot":"","sources":["../src/noise.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The relay's own messages: the text JSON around the opaque binary frames
3
+ * (spec §1). A peer's first message is its hello; the relay answers with
4
+ * status messages.
5
+ */
6
+ export declare const RELAY_PROTOCOL_VERSION = 1;
7
+ export type RelayRole = "agent" | "browser";
8
+ export interface RelayHello {
9
+ v: 1;
10
+ role: RelayRole;
11
+ /** Agent only: an optional plan credential. */
12
+ token?: string;
13
+ /** Browser only: a remembered browser coming back to reconnect. */
14
+ resume?: true;
15
+ }
16
+ export type RelayCloseReason = "time-limit" | "ttl" | "replaced" | "limit" | "protocol";
17
+ export type RelayStatus = {
18
+ t: "waiting";
19
+ } | {
20
+ t: "ready";
21
+ } | {
22
+ t: "peer-left";
23
+ } | {
24
+ t: "closed";
25
+ reason: RelayCloseReason;
26
+ };
27
+ /** WebSocket close code for a second browser in a room. */
28
+ export declare const CLOSE_CODE_ROOM_FULL = 4009;
29
+ /** The largest binary message a relay forwards: one Noise message. */
30
+ export declare const MAX_RELAY_BINARY_LENGTH: number;
31
+ /** The path of a room on a relay: `/v1/rooms/<room>`. */
32
+ export declare function roomPath(room: string): string;
33
+ /** Parses a status message from the relay, or returns undefined if it is not one. */
34
+ export declare function parseRelayStatus(text: string): RelayStatus | undefined;
35
+ /** Parses a peer's hello, or returns undefined if it is not one. */
36
+ export declare function parseRelayHello(text: string): RelayHello | undefined;
37
+ //# sourceMappingURL=relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE5C,MAAM,WAAW,UAAU;IAC1B,CAAC,EAAE,CAAC,CAAC;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,MAAM,CAAC,EAAE,IAAI,CAAC;CACd;AAED,MAAM,MAAM,gBAAgB,GACzB,YAAY,GACZ,KAAK,GACL,UAAU,GACV,OAAO,GACP,UAAU,CAAC;AAEd,MAAM,MAAM,WAAW,GACpB;IAAE,CAAC,EAAE,SAAS,CAAA;CAAE,GAChB;IAAE,CAAC,EAAE,OAAO,CAAA;CAAE,GACd;IAAE,CAAC,EAAE,WAAW,CAAA;CAAE,GAClB;IAAE,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAE7C,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,QAAa,CAAC;AAElD,yDAAyD;AACzD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAyBtE;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAiCpE"}
package/dist/relay.js ADDED
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The relay's own messages: the text JSON around the opaque binary frames
3
+ * (spec §1). A peer's first message is its hello; the relay answers with
4
+ * status messages.
5
+ */
6
+ export const RELAY_PROTOCOL_VERSION = 1;
7
+ /** WebSocket close code for a second browser in a room. */
8
+ export const CLOSE_CODE_ROOM_FULL = 4009;
9
+ /** The largest binary message a relay forwards: one Noise message. */
10
+ export const MAX_RELAY_BINARY_LENGTH = 65535 + 16;
11
+ /** The path of a room on a relay: `/v1/rooms/<room>`. */
12
+ export function roomPath(room) {
13
+ return `/v1/rooms/${room}`;
14
+ }
15
+ /** Parses a status message from the relay, or returns undefined if it is not one. */
16
+ export function parseRelayStatus(text) {
17
+ let value;
18
+ try {
19
+ value = JSON.parse(text);
20
+ }
21
+ catch {
22
+ return undefined;
23
+ }
24
+ if (!value || typeof value !== "object") {
25
+ return undefined;
26
+ }
27
+ const { t, reason } = value;
28
+ if (t === "waiting" || t === "ready" || t === "peer-left") {
29
+ return { t };
30
+ }
31
+ if (t === "closed" &&
32
+ (reason === "time-limit" ||
33
+ reason === "ttl" ||
34
+ reason === "replaced" ||
35
+ reason === "limit" ||
36
+ reason === "protocol")) {
37
+ return { t, reason };
38
+ }
39
+ return undefined;
40
+ }
41
+ /** Parses a peer's hello, or returns undefined if it is not one. */
42
+ export function parseRelayHello(text) {
43
+ let value;
44
+ try {
45
+ value = JSON.parse(text);
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ if (!value || typeof value !== "object") {
51
+ return undefined;
52
+ }
53
+ const { v, role, token, resume } = value;
54
+ if (v !== RELAY_PROTOCOL_VERSION) {
55
+ return undefined;
56
+ }
57
+ if (role === "browser" && token === undefined) {
58
+ if (resume === true) {
59
+ return { v, role, resume };
60
+ }
61
+ return resume === undefined ? { v, role } : undefined;
62
+ }
63
+ if (role === "agent" &&
64
+ resume === undefined &&
65
+ (token === undefined || typeof token === "string")) {
66
+ return token === undefined ? { v, role } : { v, role, token };
67
+ }
68
+ return undefined;
69
+ }
70
+ //# sourceMappingURL=relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AA0BxC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC,sEAAsE;AACtE,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,GAAG,EAAE,CAAC;AAElD,yDAAyD;AACzD,MAAM,UAAU,QAAQ,CAAC,IAAY;IACpC,OAAO,aAAa,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC5C,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACJ,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,KAA0C,CAAC;IACjE,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,WAAW,EAAE,CAAC;QAC3D,OAAO,EAAE,CAAC,EAAE,CAAC;IACd,CAAC;IACD,IACC,CAAC,KAAK,QAAQ;QACd,CAAC,MAAM,KAAK,YAAY;YACvB,MAAM,KAAK,KAAK;YAChB,MAAM,KAAK,UAAU;YACrB,MAAM,KAAK,OAAO;YAClB,MAAM,KAAK,UAAU,CAAC,EACtB,CAAC;QACF,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,eAAe,CAAC,IAAY;IAC3C,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QACJ,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAKlC,CAAC;IACF,IAAI,CAAC,KAAK,sBAAsB,EAAE,CAAC;QAClC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACrB,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC5B,CAAC;QACD,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACvD,CAAC;IACD,IACC,IAAI,KAAK,OAAO;QAChB,MAAM,KAAK,SAAS;QACpB,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ,CAAC,EACjD,CAAC;QACF,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IAC/D,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC"}
package/dist/sas.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The short authentication string: four words both sides show, so the user
3
+ * can see they are talking to the same peer. They come from
4
+ * `BLAKE2s("acpantenna-sas" ‖ h)`, `h` being the final handshake hash: its
5
+ * first 44 bits, most significant first, as four 11-bit indexes into the
6
+ * BIP-39 English wordlist.
7
+ */
8
+ export declare const SAS_LABEL = "acpantenna-sas";
9
+ export declare const SAS_WORDS = 4;
10
+ export declare function sasWords(handshakeHash: Uint8Array): string[];
11
+ //# sourceMappingURL=sas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sas.d.ts","sourceRoot":"","sources":["../src/sas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,eAAO,MAAM,SAAS,mBAAmB,CAAC;AAC1C,eAAO,MAAM,SAAS,IAAI,CAAC;AAE3B,wBAAgB,QAAQ,CAAC,aAAa,EAAE,UAAU,GAAG,MAAM,EAAE,CAY5D"}