bitchat-node 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.
- package/README.md +223 -0
- package/dist/bin/bitchat.d.ts +7 -0
- package/dist/bin/bitchat.d.ts.map +1 -0
- package/dist/bin/bitchat.js +69 -0
- package/dist/bin/bitchat.js.map +1 -0
- package/dist/client.d.ts +77 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +411 -0
- package/dist/client.js.map +1 -0
- package/dist/crypto/index.d.ts +6 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +6 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/noise.d.ts +72 -0
- package/dist/crypto/noise.d.ts.map +1 -0
- package/dist/crypto/noise.js +470 -0
- package/dist/crypto/noise.js.map +1 -0
- package/dist/crypto/signing.d.ts +34 -0
- package/dist/crypto/signing.d.ts.map +1 -0
- package/dist/crypto/signing.js +56 -0
- package/dist/crypto/signing.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +48 -0
- package/dist/index.js.map +1 -0
- package/dist/mesh/deduplicator.d.ts +48 -0
- package/dist/mesh/deduplicator.d.ts.map +1 -0
- package/dist/mesh/deduplicator.js +107 -0
- package/dist/mesh/deduplicator.js.map +1 -0
- package/dist/mesh/index.d.ts +6 -0
- package/dist/mesh/index.d.ts.map +1 -0
- package/dist/mesh/index.js +6 -0
- package/dist/mesh/index.js.map +1 -0
- package/dist/mesh/router.d.ts +90 -0
- package/dist/mesh/router.d.ts.map +1 -0
- package/dist/mesh/router.js +204 -0
- package/dist/mesh/router.js.map +1 -0
- package/dist/protocol/binary.d.ts +37 -0
- package/dist/protocol/binary.d.ts.map +1 -0
- package/dist/protocol/binary.js +310 -0
- package/dist/protocol/binary.js.map +1 -0
- package/dist/protocol/constants.d.ts +30 -0
- package/dist/protocol/constants.d.ts.map +1 -0
- package/dist/protocol/constants.js +37 -0
- package/dist/protocol/constants.js.map +1 -0
- package/dist/protocol/index.d.ts +8 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +8 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/packets.d.ts +38 -0
- package/dist/protocol/packets.d.ts.map +1 -0
- package/dist/protocol/packets.js +177 -0
- package/dist/protocol/packets.js.map +1 -0
- package/dist/protocol/types.d.ts +134 -0
- package/dist/protocol/types.d.ts.map +1 -0
- package/dist/protocol/types.js +108 -0
- package/dist/protocol/types.js.map +1 -0
- package/dist/session/index.d.ts +5 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +5 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/manager.d.ts +113 -0
- package/dist/session/manager.d.ts.map +1 -0
- package/dist/session/manager.js +371 -0
- package/dist/session/manager.js.map +1 -0
- package/dist/transport/ble.d.ts +92 -0
- package/dist/transport/ble.d.ts.map +1 -0
- package/dist/transport/ble.js +434 -0
- package/dist/transport/ble.js.map +1 -0
- package/dist/transport/index.d.ts +5 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +5 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +2 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/server.d.ts +16 -0
- package/dist/ui/server.d.ts.map +1 -0
- package/dist/ui/server.js +510 -0
- package/dist/ui/server.js.map +1 -0
- package/package.json +79 -0
- package/src/bin/bitchat.ts +87 -0
- package/src/client.ts +519 -0
- package/src/crypto/index.ts +22 -0
- package/src/crypto/noise.ts +574 -0
- package/src/crypto/signing.ts +66 -0
- package/src/index.ts +95 -0
- package/src/mesh/deduplicator.ts +129 -0
- package/src/mesh/index.ts +6 -0
- package/src/mesh/router.ts +258 -0
- package/src/protocol/binary.ts +345 -0
- package/src/protocol/constants.ts +43 -0
- package/src/protocol/index.ts +15 -0
- package/src/protocol/packets.ts +223 -0
- package/src/protocol/types.ts +182 -0
- package/src/session/index.ts +9 -0
- package/src/session/manager.ts +476 -0
- package/src/transport/ble.ts +553 -0
- package/src/transport/index.ts +10 -0
- package/src/ui/index.ts +1 -0
- package/src/ui/server.ts +569 -0
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Noise Protocol Implementation
|
|
3
|
+
* Implements Noise_XX_25519_ChaChaPoly_SHA256 per the Noise spec
|
|
4
|
+
* From: bitchat/Noise/NoiseProtocol.swift
|
|
5
|
+
*
|
|
6
|
+
* @see http://www.noiseprotocol.org/noise.html
|
|
7
|
+
*/
|
|
8
|
+
import * as chacha from '@stablelib/chacha20poly1305';
|
|
9
|
+
import { hmac } from '@stablelib/hmac';
|
|
10
|
+
import { hash, SHA256 } from '@stablelib/sha256';
|
|
11
|
+
import * as x25519 from '@stablelib/x25519';
|
|
12
|
+
const PROTOCOL_NAME = 'Noise_XX_25519_ChaChaPoly_SHA256';
|
|
13
|
+
const KEY_SIZE = 32;
|
|
14
|
+
const NONCE_SIZE = 12;
|
|
15
|
+
const TAG_SIZE = 16;
|
|
16
|
+
const NONCE_BYTES_IN_PACKET = 4; // For extracted nonce mode
|
|
17
|
+
// -------------------------------------------------------------------
|
|
18
|
+
// HKDF Implementation
|
|
19
|
+
// -------------------------------------------------------------------
|
|
20
|
+
function hkdfExtract(chainingKey, inputKeyMaterial) {
|
|
21
|
+
return Uint8Array.from(hmac(SHA256, chainingKey, inputKeyMaterial));
|
|
22
|
+
}
|
|
23
|
+
function hkdfExpand(prk, numOutputs) {
|
|
24
|
+
const outputs = [];
|
|
25
|
+
let prev = new Uint8Array(0);
|
|
26
|
+
for (let i = 0; i < numOutputs; i++) {
|
|
27
|
+
const input = new Uint8Array(prev.length + 1);
|
|
28
|
+
input.set(prev);
|
|
29
|
+
input[prev.length] = i + 1;
|
|
30
|
+
prev = Uint8Array.from(hmac(SHA256, prk, input));
|
|
31
|
+
outputs.push(Uint8Array.from(prev));
|
|
32
|
+
}
|
|
33
|
+
return outputs;
|
|
34
|
+
}
|
|
35
|
+
function hkdf(chainingKey, inputKeyMaterial, numOutputs) {
|
|
36
|
+
const tempKey = hkdfExtract(chainingKey, inputKeyMaterial);
|
|
37
|
+
return hkdfExpand(tempKey, numOutputs);
|
|
38
|
+
}
|
|
39
|
+
// -------------------------------------------------------------------
|
|
40
|
+
// Cipher State
|
|
41
|
+
// -------------------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Manages symmetric encryption with nonce tracking and replay protection
|
|
44
|
+
*/
|
|
45
|
+
export class CipherState {
|
|
46
|
+
key = null;
|
|
47
|
+
nonce = 0n;
|
|
48
|
+
useExtractedNonce;
|
|
49
|
+
// Replay protection (sliding window)
|
|
50
|
+
highestReceivedNonce = 0n;
|
|
51
|
+
replayWindow = new Uint8Array(128); // 1024 bits
|
|
52
|
+
constructor(key, useExtractedNonce = false) {
|
|
53
|
+
if (key)
|
|
54
|
+
this.key = Uint8Array.from(key);
|
|
55
|
+
this.useExtractedNonce = useExtractedNonce;
|
|
56
|
+
}
|
|
57
|
+
initializeKey(key) {
|
|
58
|
+
this.key = Uint8Array.from(key);
|
|
59
|
+
this.nonce = 0n;
|
|
60
|
+
}
|
|
61
|
+
hasKey() {
|
|
62
|
+
return this.key !== null;
|
|
63
|
+
}
|
|
64
|
+
makeNonceBytes(n) {
|
|
65
|
+
const bytes = new Uint8Array(NONCE_SIZE);
|
|
66
|
+
const view = new DataView(bytes.buffer);
|
|
67
|
+
// Noise spec: 4 zero bytes + 8 bytes little-endian counter
|
|
68
|
+
view.setBigUint64(4, n, true);
|
|
69
|
+
return bytes;
|
|
70
|
+
}
|
|
71
|
+
isValidNonce(receivedNonce) {
|
|
72
|
+
const windowSize = 1024n;
|
|
73
|
+
if (this.highestReceivedNonce >= windowSize &&
|
|
74
|
+
receivedNonce <= this.highestReceivedNonce - windowSize) {
|
|
75
|
+
return false; // Too old
|
|
76
|
+
}
|
|
77
|
+
if (receivedNonce > this.highestReceivedNonce) {
|
|
78
|
+
return true; // New
|
|
79
|
+
}
|
|
80
|
+
// Check window
|
|
81
|
+
const offset = Number(this.highestReceivedNonce - receivedNonce);
|
|
82
|
+
const byteIndex = Math.floor(offset / 8);
|
|
83
|
+
const bitIndex = offset % 8;
|
|
84
|
+
return (this.replayWindow[byteIndex] & (1 << bitIndex)) === 0;
|
|
85
|
+
}
|
|
86
|
+
markNonceAsSeen(receivedNonce) {
|
|
87
|
+
if (receivedNonce > this.highestReceivedNonce) {
|
|
88
|
+
const shift = Number(receivedNonce - this.highestReceivedNonce);
|
|
89
|
+
if (shift >= 1024) {
|
|
90
|
+
this.replayWindow.fill(0);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Shift window
|
|
94
|
+
for (let i = this.replayWindow.length - 1; i >= 0; i--) {
|
|
95
|
+
const sourceByteIndex = i - Math.floor(shift / 8);
|
|
96
|
+
let newByte = 0;
|
|
97
|
+
if (sourceByteIndex >= 0) {
|
|
98
|
+
newByte = this.replayWindow[sourceByteIndex] >> (shift % 8);
|
|
99
|
+
if (sourceByteIndex > 0 && shift % 8 !== 0) {
|
|
100
|
+
newByte |= this.replayWindow[sourceByteIndex - 1] << (8 - (shift % 8));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this.replayWindow[i] = newByte;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
this.highestReceivedNonce = receivedNonce;
|
|
107
|
+
this.replayWindow[0] |= 1;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
const offset = Number(this.highestReceivedNonce - receivedNonce);
|
|
111
|
+
const byteIndex = Math.floor(offset / 8);
|
|
112
|
+
const bitIndex = offset % 8;
|
|
113
|
+
this.replayWindow[byteIndex] |= 1 << bitIndex;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
encrypt(plaintext, ad = new Uint8Array()) {
|
|
117
|
+
if (!this.key)
|
|
118
|
+
throw new Error('Cipher not initialized');
|
|
119
|
+
const currentNonce = this.nonce;
|
|
120
|
+
this.nonce += 1n;
|
|
121
|
+
const nonceBytes = this.makeNonceBytes(currentNonce);
|
|
122
|
+
const cipher = new chacha.ChaCha20Poly1305(this.key);
|
|
123
|
+
const ciphertext = cipher.seal(nonceBytes, plaintext, ad);
|
|
124
|
+
if (this.useExtractedNonce) {
|
|
125
|
+
// Prepend 4-byte nonce (big-endian)
|
|
126
|
+
const result = new Uint8Array(NONCE_BYTES_IN_PACKET + ciphertext.length);
|
|
127
|
+
const view = new DataView(result.buffer);
|
|
128
|
+
view.setUint32(0, Number(currentNonce), false);
|
|
129
|
+
result.set(ciphertext, NONCE_BYTES_IN_PACKET);
|
|
130
|
+
return result;
|
|
131
|
+
}
|
|
132
|
+
return ciphertext;
|
|
133
|
+
}
|
|
134
|
+
decrypt(ciphertext, ad = new Uint8Array()) {
|
|
135
|
+
if (!this.key)
|
|
136
|
+
throw new Error('Cipher not initialized');
|
|
137
|
+
let actualCiphertext;
|
|
138
|
+
let decryptionNonce;
|
|
139
|
+
if (this.useExtractedNonce) {
|
|
140
|
+
if (ciphertext.length < NONCE_BYTES_IN_PACKET + TAG_SIZE) {
|
|
141
|
+
throw new Error('Ciphertext too short');
|
|
142
|
+
}
|
|
143
|
+
const view = new DataView(ciphertext.buffer, ciphertext.byteOffset);
|
|
144
|
+
decryptionNonce = BigInt(view.getUint32(0, false));
|
|
145
|
+
actualCiphertext = ciphertext.subarray(NONCE_BYTES_IN_PACKET);
|
|
146
|
+
if (!this.isValidNonce(decryptionNonce)) {
|
|
147
|
+
throw new Error('Replay detected');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
decryptionNonce = this.nonce;
|
|
152
|
+
this.nonce += 1n;
|
|
153
|
+
actualCiphertext = ciphertext;
|
|
154
|
+
}
|
|
155
|
+
const nonceBytes = this.makeNonceBytes(decryptionNonce);
|
|
156
|
+
const cipher = new chacha.ChaCha20Poly1305(this.key);
|
|
157
|
+
const plaintext = cipher.open(nonceBytes, actualCiphertext, ad);
|
|
158
|
+
if (!plaintext) {
|
|
159
|
+
throw new Error('Decryption failed');
|
|
160
|
+
}
|
|
161
|
+
if (this.useExtractedNonce) {
|
|
162
|
+
this.markNonceAsSeen(decryptionNonce);
|
|
163
|
+
}
|
|
164
|
+
return plaintext;
|
|
165
|
+
}
|
|
166
|
+
clear() {
|
|
167
|
+
if (this.key) {
|
|
168
|
+
this.key.fill(0);
|
|
169
|
+
this.key = null;
|
|
170
|
+
}
|
|
171
|
+
this.nonce = 0n;
|
|
172
|
+
this.highestReceivedNonce = 0n;
|
|
173
|
+
this.replayWindow.fill(0);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// -------------------------------------------------------------------
|
|
177
|
+
// Symmetric State
|
|
178
|
+
// -------------------------------------------------------------------
|
|
179
|
+
class SymmetricState {
|
|
180
|
+
cipherState;
|
|
181
|
+
chainingKey;
|
|
182
|
+
h;
|
|
183
|
+
constructor(protocolName) {
|
|
184
|
+
this.cipherState = new CipherState();
|
|
185
|
+
const nameBytes = new TextEncoder().encode(protocolName);
|
|
186
|
+
if (nameBytes.length <= 32) {
|
|
187
|
+
this.h = new Uint8Array(32);
|
|
188
|
+
this.h.set(nameBytes);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
this.h = hash(nameBytes);
|
|
192
|
+
}
|
|
193
|
+
this.chainingKey = Uint8Array.from(this.h);
|
|
194
|
+
}
|
|
195
|
+
mixKey(inputKeyMaterial) {
|
|
196
|
+
const outputs = hkdf(this.chainingKey, inputKeyMaterial, 2);
|
|
197
|
+
this.chainingKey = outputs[0];
|
|
198
|
+
this.cipherState.initializeKey(outputs[1]);
|
|
199
|
+
}
|
|
200
|
+
mixHash(data) {
|
|
201
|
+
const combined = new Uint8Array(this.h.length + data.length);
|
|
202
|
+
combined.set(this.h);
|
|
203
|
+
combined.set(data, this.h.length);
|
|
204
|
+
this.h = hash(combined);
|
|
205
|
+
}
|
|
206
|
+
getHandshakeHash() {
|
|
207
|
+
return Uint8Array.from(this.h);
|
|
208
|
+
}
|
|
209
|
+
hasCipherKey() {
|
|
210
|
+
return this.cipherState.hasKey();
|
|
211
|
+
}
|
|
212
|
+
encryptAndHash(plaintext) {
|
|
213
|
+
if (this.cipherState.hasKey()) {
|
|
214
|
+
const ciphertext = this.cipherState.encrypt(plaintext, this.h);
|
|
215
|
+
this.mixHash(ciphertext);
|
|
216
|
+
return ciphertext;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
this.mixHash(plaintext);
|
|
220
|
+
return plaintext;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
decryptAndHash(ciphertext) {
|
|
224
|
+
if (this.cipherState.hasKey()) {
|
|
225
|
+
const plaintext = this.cipherState.decrypt(ciphertext, this.h);
|
|
226
|
+
this.mixHash(ciphertext);
|
|
227
|
+
return plaintext;
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
this.mixHash(ciphertext);
|
|
231
|
+
return ciphertext;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
split(useExtractedNonce) {
|
|
235
|
+
const outputs = hkdf(this.chainingKey, new Uint8Array(), 2);
|
|
236
|
+
const c1 = new CipherState(outputs[0], useExtractedNonce);
|
|
237
|
+
const c2 = new CipherState(outputs[1], useExtractedNonce);
|
|
238
|
+
// Clear sensitive state
|
|
239
|
+
this.chainingKey.fill(0);
|
|
240
|
+
this.h.fill(0);
|
|
241
|
+
return [c1, c2];
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const XX_PATTERNS = [['e'], ['e', 'ee', 's', 'es'], ['s', 'se']];
|
|
245
|
+
/**
|
|
246
|
+
* Orchestrates the XX handshake
|
|
247
|
+
*/
|
|
248
|
+
export class HandshakeState {
|
|
249
|
+
role;
|
|
250
|
+
symmetricState;
|
|
251
|
+
currentPattern = 0;
|
|
252
|
+
localStaticPrivate;
|
|
253
|
+
localStaticPublic;
|
|
254
|
+
localEphemeralPrivate;
|
|
255
|
+
localEphemeralPublic;
|
|
256
|
+
remoteStaticPublic;
|
|
257
|
+
remoteEphemeralPublic;
|
|
258
|
+
constructor(role, localStaticKeyPair, prologue = new Uint8Array()) {
|
|
259
|
+
this.role = role;
|
|
260
|
+
this.localStaticPrivate = localStaticKeyPair.secretKey;
|
|
261
|
+
this.localStaticPublic = localStaticKeyPair.publicKey;
|
|
262
|
+
this.symmetricState = new SymmetricState(PROTOCOL_NAME);
|
|
263
|
+
this.symmetricState.mixHash(prologue);
|
|
264
|
+
}
|
|
265
|
+
writeMessage(payload = new Uint8Array()) {
|
|
266
|
+
if (this.currentPattern >= XX_PATTERNS.length) {
|
|
267
|
+
throw new Error('Handshake already complete');
|
|
268
|
+
}
|
|
269
|
+
const parts = [];
|
|
270
|
+
const pattern = XX_PATTERNS[this.currentPattern];
|
|
271
|
+
for (const token of pattern) {
|
|
272
|
+
switch (token) {
|
|
273
|
+
case 'e': {
|
|
274
|
+
const kp = x25519.generateKeyPair();
|
|
275
|
+
this.localEphemeralPrivate = kp.secretKey;
|
|
276
|
+
this.localEphemeralPublic = kp.publicKey;
|
|
277
|
+
parts.push(Uint8Array.from(this.localEphemeralPublic));
|
|
278
|
+
this.symmetricState.mixHash(this.localEphemeralPublic);
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
case 's': {
|
|
282
|
+
const encrypted = this.symmetricState.encryptAndHash(this.localStaticPublic);
|
|
283
|
+
parts.push(encrypted);
|
|
284
|
+
break;
|
|
285
|
+
}
|
|
286
|
+
case 'ee': {
|
|
287
|
+
if (!this.localEphemeralPrivate || !this.remoteEphemeralPublic) {
|
|
288
|
+
throw new Error('Missing ephemeral keys for ee');
|
|
289
|
+
}
|
|
290
|
+
const shared = x25519.sharedKey(this.localEphemeralPrivate, this.remoteEphemeralPublic);
|
|
291
|
+
this.symmetricState.mixKey(shared);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
case 'es': {
|
|
295
|
+
const [localKey, remoteKey] = this.role === 'initiator'
|
|
296
|
+
? [this.localEphemeralPrivate, this.remoteStaticPublic]
|
|
297
|
+
: [this.localStaticPrivate, this.remoteEphemeralPublic];
|
|
298
|
+
if (!localKey || !remoteKey)
|
|
299
|
+
throw new Error('Missing keys for es');
|
|
300
|
+
const shared = x25519.sharedKey(localKey, remoteKey);
|
|
301
|
+
this.symmetricState.mixKey(shared);
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
case 'se': {
|
|
305
|
+
const [localKey, remoteKey] = this.role === 'initiator'
|
|
306
|
+
? [this.localStaticPrivate, this.remoteEphemeralPublic]
|
|
307
|
+
: [this.localEphemeralPrivate, this.remoteStaticPublic];
|
|
308
|
+
if (!localKey || !remoteKey)
|
|
309
|
+
throw new Error('Missing keys for se');
|
|
310
|
+
const shared = x25519.sharedKey(localKey, remoteKey);
|
|
311
|
+
this.symmetricState.mixKey(shared);
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
case 'ss': {
|
|
315
|
+
if (!this.remoteStaticPublic)
|
|
316
|
+
throw new Error('Missing remote static for ss');
|
|
317
|
+
const shared = x25519.sharedKey(this.localStaticPrivate, this.remoteStaticPublic);
|
|
318
|
+
this.symmetricState.mixKey(shared);
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const encryptedPayload = this.symmetricState.encryptAndHash(payload);
|
|
324
|
+
parts.push(encryptedPayload);
|
|
325
|
+
this.currentPattern++;
|
|
326
|
+
// Concatenate
|
|
327
|
+
const totalLength = parts.reduce((sum, p) => sum + p.length, 0);
|
|
328
|
+
const result = new Uint8Array(totalLength);
|
|
329
|
+
let offset = 0;
|
|
330
|
+
for (const part of parts) {
|
|
331
|
+
result.set(part, offset);
|
|
332
|
+
offset += part.length;
|
|
333
|
+
}
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
readMessage(message) {
|
|
337
|
+
if (this.currentPattern >= XX_PATTERNS.length) {
|
|
338
|
+
throw new Error('Handshake already complete');
|
|
339
|
+
}
|
|
340
|
+
let offset = 0;
|
|
341
|
+
const pattern = XX_PATTERNS[this.currentPattern];
|
|
342
|
+
for (const token of pattern) {
|
|
343
|
+
switch (token) {
|
|
344
|
+
case 'e': {
|
|
345
|
+
if (offset + KEY_SIZE > message.length) {
|
|
346
|
+
throw new Error('Message too short for ephemeral key');
|
|
347
|
+
}
|
|
348
|
+
this.remoteEphemeralPublic = Uint8Array.from(message.subarray(offset, offset + KEY_SIZE));
|
|
349
|
+
this.symmetricState.mixHash(this.remoteEphemeralPublic);
|
|
350
|
+
offset += KEY_SIZE;
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
case 's': {
|
|
354
|
+
const keyLen = this.symmetricState.hasCipherKey() ? KEY_SIZE + TAG_SIZE : KEY_SIZE;
|
|
355
|
+
if (offset + keyLen > message.length) {
|
|
356
|
+
throw new Error('Message too short for static key');
|
|
357
|
+
}
|
|
358
|
+
const staticData = message.subarray(offset, offset + keyLen);
|
|
359
|
+
const decrypted = this.symmetricState.decryptAndHash(staticData);
|
|
360
|
+
this.remoteStaticPublic = Uint8Array.from(decrypted);
|
|
361
|
+
offset += keyLen;
|
|
362
|
+
break;
|
|
363
|
+
}
|
|
364
|
+
case 'ee':
|
|
365
|
+
case 'es':
|
|
366
|
+
case 'se':
|
|
367
|
+
case 'ss': {
|
|
368
|
+
this.performDH(token);
|
|
369
|
+
break;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
const encryptedPayload = message.subarray(offset);
|
|
374
|
+
const payload = this.symmetricState.decryptAndHash(encryptedPayload);
|
|
375
|
+
this.currentPattern++;
|
|
376
|
+
return payload;
|
|
377
|
+
}
|
|
378
|
+
performDH(token) {
|
|
379
|
+
let localKey;
|
|
380
|
+
let remoteKey;
|
|
381
|
+
switch (token) {
|
|
382
|
+
case 'ee':
|
|
383
|
+
localKey = this.localEphemeralPrivate;
|
|
384
|
+
remoteKey = this.remoteEphemeralPublic;
|
|
385
|
+
break;
|
|
386
|
+
case 'es':
|
|
387
|
+
if (this.role === 'initiator') {
|
|
388
|
+
localKey = this.localEphemeralPrivate;
|
|
389
|
+
remoteKey = this.remoteStaticPublic;
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
localKey = this.localStaticPrivate;
|
|
393
|
+
remoteKey = this.remoteEphemeralPublic;
|
|
394
|
+
}
|
|
395
|
+
break;
|
|
396
|
+
case 'se':
|
|
397
|
+
if (this.role === 'initiator') {
|
|
398
|
+
localKey = this.localStaticPrivate;
|
|
399
|
+
remoteKey = this.remoteEphemeralPublic;
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
localKey = this.localEphemeralPrivate;
|
|
403
|
+
remoteKey = this.remoteStaticPublic;
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
case 'ss':
|
|
407
|
+
localKey = this.localStaticPrivate;
|
|
408
|
+
remoteKey = this.remoteStaticPublic;
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
if (!localKey || !remoteKey) {
|
|
412
|
+
throw new Error(`Missing keys for ${token}`);
|
|
413
|
+
}
|
|
414
|
+
const shared = x25519.sharedKey(localKey, remoteKey);
|
|
415
|
+
this.symmetricState.mixKey(shared);
|
|
416
|
+
}
|
|
417
|
+
isComplete() {
|
|
418
|
+
return this.currentPattern >= XX_PATTERNS.length;
|
|
419
|
+
}
|
|
420
|
+
getRemoteStaticPublicKey() {
|
|
421
|
+
return this.remoteStaticPublic;
|
|
422
|
+
}
|
|
423
|
+
getHandshakeHash() {
|
|
424
|
+
return this.symmetricState.getHandshakeHash();
|
|
425
|
+
}
|
|
426
|
+
split(useExtractedNonce = true) {
|
|
427
|
+
if (!this.isComplete()) {
|
|
428
|
+
throw new Error('Handshake not complete');
|
|
429
|
+
}
|
|
430
|
+
const handshakeHash = this.symmetricState.getHandshakeHash();
|
|
431
|
+
const [c1, c2] = this.symmetricState.split(useExtractedNonce);
|
|
432
|
+
const ciphers = this.role === 'initiator' ? { send: c1, receive: c2 } : { send: c2, receive: c1 };
|
|
433
|
+
return { ...ciphers, hash: handshakeHash };
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
// -------------------------------------------------------------------
|
|
437
|
+
// Session
|
|
438
|
+
// -------------------------------------------------------------------
|
|
439
|
+
/**
|
|
440
|
+
* An established Noise session for transport encryption
|
|
441
|
+
*/
|
|
442
|
+
export class NoiseSession {
|
|
443
|
+
sendCipher;
|
|
444
|
+
receiveCipher;
|
|
445
|
+
handshakeHash;
|
|
446
|
+
remotePublicKey;
|
|
447
|
+
constructor(sendCipher, receiveCipher, handshakeHash, remotePublicKey) {
|
|
448
|
+
this.sendCipher = sendCipher;
|
|
449
|
+
this.receiveCipher = receiveCipher;
|
|
450
|
+
this.handshakeHash = Uint8Array.from(handshakeHash);
|
|
451
|
+
this.remotePublicKey = Uint8Array.from(remotePublicKey);
|
|
452
|
+
}
|
|
453
|
+
encrypt(plaintext) {
|
|
454
|
+
return this.sendCipher.encrypt(plaintext);
|
|
455
|
+
}
|
|
456
|
+
decrypt(ciphertext) {
|
|
457
|
+
return this.receiveCipher.decrypt(ciphertext);
|
|
458
|
+
}
|
|
459
|
+
clear() {
|
|
460
|
+
this.sendCipher.clear();
|
|
461
|
+
this.receiveCipher.clear();
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
// -------------------------------------------------------------------
|
|
465
|
+
// Key Generation
|
|
466
|
+
// -------------------------------------------------------------------
|
|
467
|
+
export function generateKeyPair() {
|
|
468
|
+
return x25519.generateKeyPair();
|
|
469
|
+
}
|
|
470
|
+
//# sourceMappingURL=noise.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"noise.js","sourceRoot":"","sources":["../../src/crypto/noise.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519 Signing Utilities
|
|
3
|
+
* Used for packet authentication and identity binding
|
|
4
|
+
*/
|
|
5
|
+
export interface SigningKeyPair {
|
|
6
|
+
publicKey: Uint8Array;
|
|
7
|
+
secretKey: Uint8Array;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Generate a new Ed25519 signing key pair
|
|
11
|
+
*/
|
|
12
|
+
export declare function generateSigningKeyPair(): SigningKeyPair;
|
|
13
|
+
/**
|
|
14
|
+
* Sign a message with Ed25519
|
|
15
|
+
*/
|
|
16
|
+
export declare function sign(message: Uint8Array, secretKey: Uint8Array): Uint8Array;
|
|
17
|
+
/**
|
|
18
|
+
* Verify an Ed25519 signature
|
|
19
|
+
*/
|
|
20
|
+
export declare function verify(message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* SHA-256 hash
|
|
23
|
+
*/
|
|
24
|
+
export declare function sha256(data: Uint8Array): Uint8Array;
|
|
25
|
+
/**
|
|
26
|
+
* Derive a fingerprint from a public key
|
|
27
|
+
* Used for identity verification
|
|
28
|
+
*/
|
|
29
|
+
export declare function fingerprint(publicKey: Uint8Array): string;
|
|
30
|
+
/**
|
|
31
|
+
* Format fingerprint for display (colon-separated groups)
|
|
32
|
+
*/
|
|
33
|
+
export declare function formatFingerprint(fp: string): string;
|
|
34
|
+
//# sourceMappingURL=signing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.d.ts","sourceRoot":"","sources":["../../src/crypto/signing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,UAAU,CAAC;IACtB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,cAAc,CAEvD;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,CAE3E;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAMjG;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAEnD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,CAKzD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMpD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519 Signing Utilities
|
|
3
|
+
* Used for packet authentication and identity binding
|
|
4
|
+
*/
|
|
5
|
+
import * as ed25519 from '@stablelib/ed25519';
|
|
6
|
+
import { hash } from '@stablelib/sha256';
|
|
7
|
+
/**
|
|
8
|
+
* Generate a new Ed25519 signing key pair
|
|
9
|
+
*/
|
|
10
|
+
export function generateSigningKeyPair() {
|
|
11
|
+
return ed25519.generateKeyPair();
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Sign a message with Ed25519
|
|
15
|
+
*/
|
|
16
|
+
export function sign(message, secretKey) {
|
|
17
|
+
return ed25519.sign(secretKey, message);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Verify an Ed25519 signature
|
|
21
|
+
*/
|
|
22
|
+
export function verify(message, signature, publicKey) {
|
|
23
|
+
try {
|
|
24
|
+
return ed25519.verify(publicKey, message, signature);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* SHA-256 hash
|
|
32
|
+
*/
|
|
33
|
+
export function sha256(data) {
|
|
34
|
+
return hash(data);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Derive a fingerprint from a public key
|
|
38
|
+
* Used for identity verification
|
|
39
|
+
*/
|
|
40
|
+
export function fingerprint(publicKey) {
|
|
41
|
+
const h = sha256(publicKey);
|
|
42
|
+
return Array.from(h)
|
|
43
|
+
.map((b) => b.toString(16).padStart(2, '0'))
|
|
44
|
+
.join('');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Format fingerprint for display (colon-separated groups)
|
|
48
|
+
*/
|
|
49
|
+
export function formatFingerprint(fp) {
|
|
50
|
+
const groups = [];
|
|
51
|
+
for (let i = 0; i < fp.length; i += 4) {
|
|
52
|
+
groups.push(fp.slice(i, i + 4));
|
|
53
|
+
}
|
|
54
|
+
return groups.join(':').toUpperCase();
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=signing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signing.js","sourceRoot":"","sources":["../../src/crypto/signing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAOzC;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,OAAO,CAAC,eAAe,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,OAAmB,EAAE,SAAqB;IAC7D,OAAO,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,OAAmB,EAAE,SAAqB,EAAE,SAAqB;IACtF,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,IAAgB;IACrC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,SAAqB;IAC/C,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;SACjB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC1C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AACxC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* bitchat-node
|
|
3
|
+
* Node.js implementation of the Bitchat BLE mesh protocol
|
|
4
|
+
*
|
|
5
|
+
* Compatible with Jack Dorsey's Bitchat app.
|
|
6
|
+
* @see https://github.com/permissionlesstech/bitchat
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { BitchatClient } from 'bitchat-node';
|
|
11
|
+
*
|
|
12
|
+
* const client = new BitchatClient({ nickname: 'my-node' });
|
|
13
|
+
*
|
|
14
|
+
* client.on('message', (message) => {
|
|
15
|
+
* console.log(`${message.senderNickname}: ${message.content}`);
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* client.on('peer:connected', (peer) => {
|
|
19
|
+
* console.log(`Connected to ${peer.nickname}`);
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* await client.start();
|
|
23
|
+
* await client.sendPublicMessage('Hello mesh!');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export { BitchatClient, type BitchatClientConfig, type BitchatClientEvents } from './client.js';
|
|
27
|
+
export { CipherState, fingerprint, formatFingerprint, generateKeyPair, generateSigningKeyPair, HandshakeState as NoiseHandshakeState, type NoiseKeyPair, type NoiseRole, NoiseSession, type SigningKeyPair, sha256, sign, verify, } from './crypto/index.js';
|
|
28
|
+
export { type DeduplicatorConfig, type Link, MeshRouter, MessageDeduplicator, type RouterConfig, } from './mesh/index.js';
|
|
29
|
+
export { type BitchatPacket, CHARACTERISTIC_UUID, type ChatMessage, DEFAULT_TTL, type DeliveryStatus, decode, encode, encodeForSigning, HandshakeState, MAX_MESSAGE_LENGTH, MAX_TTL, MessageType, makeDeduplicationID, NoisePayloadType, PacketFlags, PeerID, type PeerInfo, type ReadReceipt, SERVICE_UUID, SERVICE_UUID_TESTNET, } from './protocol/index.js';
|
|
30
|
+
export { SessionManager, type SessionManagerConfig, type SessionManagerEvents, } from './session/index.js';
|
|
31
|
+
export { BLELink, BLETransport, type BLETransportConfig, type BLETransportEvents, } from './transport/index.js';
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEhG,OAAO,EAEL,WAAW,EACX,WAAW,EACX,iBAAiB,EACjB,eAAe,EAEf,sBAAsB,EACtB,cAAc,IAAI,mBAAmB,EACrC,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,YAAY,EACZ,KAAK,cAAc,EACnB,MAAM,EACN,IAAI,EACJ,MAAM,GACP,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,IAAI,EACT,UAAU,EACV,mBAAmB,EACnB,KAAK,YAAY,GAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,KAAK,aAAa,EAClB,mBAAmB,EACnB,KAAK,WAAW,EAChB,WAAW,EACX,KAAK,cAAc,EACnB,MAAM,EAEN,MAAM,EACN,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,OAAO,EAEP,WAAW,EACX,mBAAmB,EACnB,gBAAgB,EAChB,WAAW,EACX,MAAM,EACN,KAAK,QAAQ,EACb,KAAK,WAAW,EAEhB,YAAY,EACZ,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,OAAO,EACP,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC"}
|