yakmesh 1.1.0 → 1.3.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.
@@ -0,0 +1,383 @@
1
+ /**
2
+ * YAKMESH™ Temporal Mesh Encoding (TME)
3
+ *
4
+ * A novel approach to packet resilience that exploits YAKMESH's unique capabilities:
5
+ * - Atomic time synchronization (PTP/PCIe-level nanosecond precision)
6
+ * - Post-quantum ML-DSA-65 signatures for cryptographic time binding
7
+ * - Mesh topology awareness for intelligent path diversity
8
+ *
9
+ * Instead of traditional erasure coding (encoding data across space),
10
+ * TME encodes data across TIME - using the mesh's synchronized clocks
11
+ * as the redundancy dimension.
12
+ *
13
+ * Key Innovation: "Time IS the redundancy dimension"
14
+ * - Temporal slicing with cryptographic chaining
15
+ * - Predictive reconstruction from timing proofs
16
+ * - Mesh heartbeat differential encoding
17
+ *
18
+ * @module mesh/temporal-encoder
19
+ * @license MIT
20
+ * @copyright 2026 YAKMESH Contributors
21
+ */
22
+
23
+ import { randomBytes, createHash } from 'crypto';
24
+
25
+ const TME_CONFIG = {
26
+ defaultSliceIntervalNs: 50_000_000,
27
+ maxSlicesPerStream: 256,
28
+ reconstructionWindowNs: 500_000_000,
29
+ timingToleranceNs: 5_000_000,
30
+ hashAlgorithm: 'sha256',
31
+ temporalHashLength: 32,
32
+ minSlicesForReconstruction: 0.6,
33
+ maxMissingConsecutive: 3,
34
+ minPathDiversity: 2,
35
+ maxPathReuse: 3,
36
+ };
37
+
38
+ class TemporalSlice {
39
+ constructor(options) {
40
+ this.data = Buffer.from(options.data);
41
+ this.timestamp = BigInt(options.timestamp);
42
+ this.sequenceNumber = options.sequenceNumber;
43
+ this.streamId = options.streamId;
44
+ this.prevTemporalHash = options.prevTemporalHash || Buffer.alloc(32);
45
+ this.meshPosition = options.meshPosition || [0, 0, 0];
46
+ this.createdAt = Date.now();
47
+ this.temporalHash = this._computeTemporalHash();
48
+ }
49
+
50
+ _computeTemporalHash() {
51
+ const hash = createHash(TME_CONFIG.hashAlgorithm);
52
+ hash.update(this.data);
53
+ const timeBuffer = Buffer.alloc(8);
54
+ timeBuffer.writeBigUInt64BE(this.timestamp);
55
+ hash.update(timeBuffer);
56
+ const seqBuffer = Buffer.alloc(4);
57
+ seqBuffer.writeUInt32BE(this.sequenceNumber);
58
+ hash.update(seqBuffer);
59
+ hash.update(this.streamId);
60
+ hash.update(this.prevTemporalHash);
61
+ const posBuffer = Buffer.alloc(12);
62
+ posBuffer.writeFloatBE(this.meshPosition[0], 0);
63
+ posBuffer.writeFloatBE(this.meshPosition[1], 4);
64
+ posBuffer.writeFloatBE(this.meshPosition[2], 8);
65
+ hash.update(posBuffer);
66
+ return hash.digest();
67
+ }
68
+
69
+ verify() {
70
+ const computed = this._computeTemporalHash();
71
+ return computed.equals(this.temporalHash);
72
+ }
73
+
74
+ serialize() {
75
+ return {
76
+ data: this.data.toString('base64'),
77
+ timestamp: this.timestamp.toString(),
78
+ sequenceNumber: this.sequenceNumber,
79
+ streamId: this.streamId,
80
+ prevTemporalHash: this.prevTemporalHash.toString('hex'),
81
+ temporalHash: this.temporalHash.toString('hex'),
82
+ meshPosition: this.meshPosition,
83
+ };
84
+ }
85
+
86
+ static deserialize(obj) {
87
+ const slice = new TemporalSlice({
88
+ data: Buffer.from(obj.data, 'base64'),
89
+ timestamp: BigInt(obj.timestamp),
90
+ sequenceNumber: obj.sequenceNumber,
91
+ streamId: obj.streamId,
92
+ prevTemporalHash: Buffer.from(obj.prevTemporalHash, 'hex'),
93
+ meshPosition: obj.meshPosition,
94
+ });
95
+ const expectedHash = Buffer.from(obj.temporalHash, 'hex');
96
+ if (!slice.temporalHash.equals(expectedHash)) {
97
+ throw new Error('Temporal hash mismatch - slice may be corrupted or tampered');
98
+ }
99
+ return slice;
100
+ }
101
+ }
102
+
103
+ class TemporalStream {
104
+ constructor(options = {}) {
105
+ this.streamId = options.streamId || this._generateStreamId();
106
+ this.sliceSize = options.sliceSize || 1024;
107
+ this.baseTimestamp = BigInt(options.baseTimestamp || Date.now() * 1_000_000);
108
+ this.sliceIntervalNs = options.sliceIntervalNs || TME_CONFIG.defaultSliceIntervalNs;
109
+ this.slices = new Map();
110
+ this.totalSlices = 0;
111
+ this.isComplete = false;
112
+ }
113
+
114
+ _generateStreamId() {
115
+ return randomBytes(16).toString('hex');
116
+ }
117
+
118
+ encode(message, meshPosition = [0, 0, 0]) {
119
+ const data = Buffer.from(message);
120
+ const slices = [];
121
+ let prevHash = Buffer.alloc(32);
122
+ this.totalSlices = Math.ceil(data.length / this.sliceSize);
123
+ if (this.totalSlices > TME_CONFIG.maxSlicesPerStream) {
124
+ throw new Error('Message too large: requires ' + this.totalSlices + ' slices, max is ' + TME_CONFIG.maxSlicesPerStream);
125
+ }
126
+ for (let i = 0; i < this.totalSlices; i++) {
127
+ const start = i * this.sliceSize;
128
+ const end = Math.min(start + this.sliceSize, data.length);
129
+ const sliceData = data.slice(start, end);
130
+ const timestamp = this.baseTimestamp + BigInt(i * this.sliceIntervalNs);
131
+ const slice = new TemporalSlice({
132
+ data: sliceData,
133
+ timestamp,
134
+ sequenceNumber: i,
135
+ streamId: this.streamId,
136
+ prevTemporalHash: prevHash,
137
+ meshPosition,
138
+ });
139
+ slices.push(slice);
140
+ this.slices.set(i, slice);
141
+ prevHash = slice.temporalHash;
142
+ }
143
+ this.isComplete = true;
144
+ return slices;
145
+ }
146
+
147
+ addSlice(slice) {
148
+ if (slice.streamId !== this.streamId) return false;
149
+ if (!slice.verify()) return false;
150
+ if (slice.sequenceNumber > 0 && this.slices.has(slice.sequenceNumber - 1)) {
151
+ const prevSlice = this.slices.get(slice.sequenceNumber - 1);
152
+ if (!slice.prevTemporalHash.equals(prevSlice.temporalHash)) return false;
153
+ }
154
+ this.slices.set(slice.sequenceNumber, slice);
155
+ return true;
156
+ }
157
+
158
+ canReconstruct() {
159
+ if (this.totalSlices === 0) return false;
160
+ return (this.slices.size / this.totalSlices) >= TME_CONFIG.minSlicesForReconstruction;
161
+ }
162
+
163
+ getMissingSlices() {
164
+ const missing = [];
165
+ for (let i = 0; i < this.totalSlices; i++) {
166
+ if (!this.slices.has(i)) missing.push(i);
167
+ }
168
+ return missing;
169
+ }
170
+
171
+ getCompletionPercent() {
172
+ if (this.totalSlices === 0) return 0;
173
+ return (this.slices.size / this.totalSlices) * 100;
174
+ }
175
+ }
176
+
177
+ class TemporalReconstructor {
178
+ constructor() {
179
+ this.streams = new Map();
180
+ this.timingProofs = new Map();
181
+ }
182
+
183
+ registerStream(stream) {
184
+ this.streams.set(stream.streamId, stream);
185
+ this.timingProofs.set(stream.streamId, new Map());
186
+ }
187
+
188
+ addTimingProof(streamId, sequenceNumber, proof) {
189
+ if (!this.timingProofs.has(streamId)) {
190
+ this.timingProofs.set(streamId, new Map());
191
+ }
192
+ const streamProofs = this.timingProofs.get(streamId);
193
+ if (!streamProofs.has(sequenceNumber)) {
194
+ streamProofs.set(sequenceNumber, []);
195
+ }
196
+ streamProofs.get(sequenceNumber).push({
197
+ nodeId: proof.nodeId,
198
+ timestamp: BigInt(proof.timestamp),
199
+ temporalHash: Buffer.from(proof.temporalHash, 'hex'),
200
+ signature: proof.signature,
201
+ receivedAt: Date.now(),
202
+ });
203
+ }
204
+
205
+ verifyMissingSlice(streamId, sequenceNumber) {
206
+ const streamProofs = this.timingProofs.get(streamId);
207
+ if (!streamProofs || !streamProofs.has(sequenceNumber)) return null;
208
+ const proofs = streamProofs.get(sequenceNumber);
209
+ if (proofs.length < 2) return null;
210
+ const hashCounts = new Map();
211
+ for (const proof of proofs) {
212
+ const hashHex = proof.temporalHash.toString('hex');
213
+ hashCounts.set(hashHex, (hashCounts.get(hashHex) || 0) + 1);
214
+ }
215
+ let consensusHash = null;
216
+ let maxCount = 0;
217
+ for (const [hash, count] of hashCounts) {
218
+ if (count > maxCount) {
219
+ maxCount = count;
220
+ consensusHash = hash;
221
+ }
222
+ }
223
+ if (maxCount >= 2) {
224
+ return { verified: true, consensusHash, proofCount: maxCount, totalProofs: proofs.length };
225
+ }
226
+ return null;
227
+ }
228
+
229
+ reconstruct(streamId) {
230
+ const stream = this.streams.get(streamId);
231
+ if (!stream) return { success: false, error: 'Stream not found' };
232
+ const missing = stream.getMissingSlices();
233
+ if (missing.length === 0) return this._assembleComplete(stream);
234
+ if (!stream.canReconstruct()) {
235
+ return {
236
+ success: false,
237
+ error: 'Insufficient slices for reconstruction',
238
+ received: stream.slices.size,
239
+ required: Math.ceil(stream.totalSlices * TME_CONFIG.minSlicesForReconstruction),
240
+ total: stream.totalSlices,
241
+ };
242
+ }
243
+ const reconstructed = [];
244
+ const unrecoverable = [];
245
+ for (const seq of missing) {
246
+ const result = this._interpolateSlice(stream, seq);
247
+ if (result.success) reconstructed.push(seq);
248
+ else unrecoverable.push(seq);
249
+ }
250
+ if (unrecoverable.length > 0) {
251
+ return {
252
+ success: false,
253
+ error: 'Some slices unrecoverable',
254
+ reconstructed,
255
+ unrecoverable,
256
+ completionPercent: stream.getCompletionPercent(),
257
+ };
258
+ }
259
+ return this._assembleComplete(stream);
260
+ }
261
+
262
+ _interpolateSlice(stream, sequenceNumber) {
263
+ const prev = stream.slices.get(sequenceNumber - 1);
264
+ const next = stream.slices.get(sequenceNumber + 1);
265
+ if (prev && next) {
266
+ const expectedHash = next.prevTemporalHash;
267
+ return { success: false, expectedHash: expectedHash.toString('hex'), reason: 'Need data from mesh neighbors' };
268
+ }
269
+ return { success: false, reason: 'Insufficient surrounding slices' };
270
+ }
271
+
272
+ _assembleComplete(stream) {
273
+ const sortedSlices = Array.from(stream.slices.entries())
274
+ .sort((a, b) => a[0] - b[0])
275
+ .map(([_, slice]) => slice);
276
+ for (let i = 1; i < sortedSlices.length; i++) {
277
+ const prev = sortedSlices[i - 1];
278
+ const curr = sortedSlices[i];
279
+ if (!curr.prevTemporalHash.equals(prev.temporalHash)) {
280
+ return { success: false, error: 'Temporal chain broken at slice ' + i };
281
+ }
282
+ }
283
+ const data = Buffer.concat(sortedSlices.map(s => s.data));
284
+ return { success: true, data, sliceCount: sortedSlices.length, streamId: stream.streamId };
285
+ }
286
+ }
287
+
288
+ class TemporalMeshEncoder {
289
+ constructor(options = {}) {
290
+ this.nodeId = options.nodeId || randomBytes(16).toString('hex');
291
+ this.meshPosition = options.meshPosition || [0, 0, 0];
292
+ this.reconstructor = new TemporalReconstructor();
293
+ this.outboundStreams = new Map();
294
+ this.inboundStreams = new Map();
295
+ this.stats = {
296
+ slicesSent: 0,
297
+ slicesReceived: 0,
298
+ streamsCompleted: 0,
299
+ reconstructionAttempts: 0,
300
+ successfulReconstructions: 0,
301
+ };
302
+ }
303
+
304
+ encode(message, options = {}) {
305
+ const stream = new TemporalStream({
306
+ sliceSize: options.sliceSize || 1024,
307
+ baseTimestamp: options.baseTimestamp,
308
+ sliceIntervalNs: options.sliceIntervalNs,
309
+ });
310
+ const slices = stream.encode(message, this.meshPosition);
311
+ this.outboundStreams.set(stream.streamId, stream);
312
+ this.stats.slicesSent += slices.length;
313
+ return {
314
+ streamId: stream.streamId,
315
+ slices: slices.map(s => s.serialize()),
316
+ metadata: {
317
+ totalSlices: stream.totalSlices,
318
+ sliceSize: stream.sliceSize,
319
+ sliceIntervalNs: stream.sliceIntervalNs,
320
+ baseTimestamp: stream.baseTimestamp.toString(),
321
+ },
322
+ };
323
+ }
324
+
325
+ initReceive(metadata) {
326
+ const stream = new TemporalStream({
327
+ streamId: metadata.streamId,
328
+ sliceSize: metadata.sliceSize,
329
+ baseTimestamp: BigInt(metadata.baseTimestamp),
330
+ sliceIntervalNs: metadata.sliceIntervalNs,
331
+ });
332
+ stream.totalSlices = metadata.totalSlices;
333
+ this.inboundStreams.set(metadata.streamId, stream);
334
+ this.reconstructor.registerStream(stream);
335
+ return stream.streamId;
336
+ }
337
+
338
+ receiveSlice(serializedSlice) {
339
+ try {
340
+ const slice = TemporalSlice.deserialize(serializedSlice);
341
+ const stream = this.inboundStreams.get(slice.streamId);
342
+ if (!stream) return { accepted: false, error: 'Unknown stream' };
343
+ const added = stream.addSlice(slice);
344
+ if (added) this.stats.slicesReceived++;
345
+ const completionPercent = stream.getCompletionPercent();
346
+ const streamComplete = completionPercent === 100;
347
+ if (streamComplete) this.stats.streamsCompleted++;
348
+ return { accepted: added, streamComplete, completionPercent, missing: stream.getMissingSlices() };
349
+ } catch (err) {
350
+ return { accepted: false, error: err.message };
351
+ }
352
+ }
353
+
354
+ addTimingProof(streamId, sequenceNumber, proof) {
355
+ this.reconstructor.addTimingProof(streamId, sequenceNumber, proof);
356
+ }
357
+
358
+ decode(streamId) {
359
+ this.stats.reconstructionAttempts++;
360
+ const result = this.reconstructor.reconstruct(streamId);
361
+ if (result.success) this.stats.successfulReconstructions++;
362
+ return result;
363
+ }
364
+
365
+ getStreamStatus(streamId) {
366
+ const stream = this.inboundStreams.get(streamId);
367
+ if (!stream) return null;
368
+ return {
369
+ streamId,
370
+ totalSlices: stream.totalSlices,
371
+ receivedSlices: stream.slices.size,
372
+ completionPercent: stream.getCompletionPercent(),
373
+ missing: stream.getMissingSlices(),
374
+ canReconstruct: stream.canReconstruct(),
375
+ };
376
+ }
377
+
378
+ getStats() {
379
+ return { ...this.stats };
380
+ }
381
+ }
382
+
383
+ export { TME_CONFIG, TemporalSlice, TemporalStream, TemporalReconstructor, TemporalMeshEncoder };
package/package.json CHANGED
@@ -1,52 +1,83 @@
1
- {
2
- "name": "yakmesh",
3
- "version": "1.1.0",
4
- "description": "YAKMESH: Yielding Atomic Kernel Modular Encryption Secured Hub - Post-quantum secure P2P mesh network for the 2026 threat landscape",
5
- "type": "module",
6
- "main": "server/index.js",
7
- "bin": {
8
- "yakmesh": "cli/index.js"
9
- },
10
- "scripts": {
11
- "start": "node server/index.js",
12
- "dev": "node --watch server/index.js",
13
- "test": "node --test oracle/tests/",
14
- "test:time": "node oracle/tests/time-source.test.js",
15
- "test:phase": "node oracle/tests/phase-epoch.test.js"
16
- },
17
- "dependencies": {
18
- "@noble/hashes": "^2.0.0",
19
- "@noble/post-quantum": "^0.5.4",
20
- "chalk": "^5.3.0",
21
- "commander": "^12.0.0",
22
- "express": "^4.18.2",
23
- "express-rate-limit": "^8.2.1",
24
- "sql.js": "^1.10.0",
25
- "ws": "^8.16.0"
26
- },
27
- "devDependencies": {
28
- "nodemon": "^3.0.0"
29
- },
30
- "engines": {
31
- "node": ">=18.0.0"
32
- },
33
- "keywords": [
34
- "p2p",
35
- "mesh",
36
- "decentralized",
37
- "yakmesh",
38
- "yak",
39
- "post-quantum",
40
- "distributed-oracle"
41
- ],
42
- "author": "Yakmesh",
43
- "license": "MIT",
44
- "homepage": "https://yakmesh.dev",
45
- "repository": {
46
- "url": "git+https://github.com/peerquanta/yakmesh.git",
47
- "type": "git"
48
- },
49
- "bugs": {
50
- "url": "https://github.com/peerquanta/yakmesh/issues"
51
- }
1
+ {
2
+ "name": "yakmesh",
3
+ "version": "1.3.0",
4
+ "description": "YAKMESH: Yielding Atomic Kernel Modular Encryption Secured Hub - Post-quantum secure P2P mesh network for the 2026 threat landscape",
5
+ "type": "module",
6
+ "main": "server/index.js",
7
+ "exports": {
8
+ ".": "./server/index.js",
9
+ "./cli": "./cli/index.js",
10
+ "./oracle": "./oracle/index.js",
11
+ "./oracle/time-source": "./oracle/time-source.js",
12
+ "./oracle/phase-epoch": "./oracle/phase-epoch.js",
13
+ "./oracle/consensus": "./oracle/consensus-engine.js",
14
+ "./oracle/validation": "./oracle/validation-oracle-hardened.js",
15
+ "./oracle/genesis": "./oracle/genesis-network-v2.js",
16
+ "./oracle/identity": "./oracle/network-identity.js",
17
+ "./oracle/code-proof": "./oracle/code-proof-protocol.js",
18
+ "./oracle/module-sealer": "./oracle/module-sealer.js",
19
+ "./mesh/network": "./mesh/network.js",
20
+ "./mesh/rate-limiter": "./mesh/rate-limiter.js",
21
+ "./mesh/message-validator": "./mesh/message-validator.js",
22
+ "./mesh/replay-defense": "./mesh/replay-defense.js",
23
+ "./mesh/sybil-defense": "./mesh/sybil-defense.js",
24
+ "./mesh/echo-ranging": "./mesh/echo-ranging.js",
25
+ "./mesh/pulse-sync": "./mesh/pulse-sync.js",
26
+ "./mesh/phantom-routing": "./mesh/phantom-routing.js",
27
+ "./mesh/beacon-broadcast": "./mesh/beacon-broadcast.js"
28
+ },
29
+ "bin": {
30
+ "yakmesh": "cli/index.js"
31
+ },
32
+ "scripts": {
33
+ "start": "node server/index.js",
34
+ "dev": "node --watch server/index.js",
35
+ "test": "node --test oracle/tests/",
36
+ "test:time": "node oracle/tests/time-source.test.js",
37
+ "test:phase": "node oracle/tests/phase-epoch.test.js",
38
+ "test:all": "node test-novel-systems.mjs"
39
+ },
40
+ "dependencies": {
41
+ "@noble/hashes": "^2.0.0",
42
+ "@noble/post-quantum": "^0.5.4",
43
+ "chalk": "^5.3.0",
44
+ "commander": "^12.0.0",
45
+ "express": "^4.18.2",
46
+ "express-rate-limit": "^8.2.1",
47
+ "sql.js": "^1.10.0",
48
+ "ws": "^8.16.0"
49
+ },
50
+ "devDependencies": {
51
+ "nodemon": "^3.0.0"
52
+ },
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ },
56
+ "keywords": [
57
+ "p2p",
58
+ "mesh",
59
+ "decentralized",
60
+ "yakmesh",
61
+ "yak",
62
+ "post-quantum",
63
+ "distributed-oracle",
64
+ "onion-routing",
65
+ "echo-ranging",
66
+ "phantom-routing",
67
+ "pulse-sync",
68
+ "beacon-broadcast",
69
+ "kyber",
70
+ "ml-kem",
71
+ "ml-dsa"
72
+ ],
73
+ "author": "Yakmesh",
74
+ "license": "MIT",
75
+ "homepage": "https://yakmesh.dev",
76
+ "repository": {
77
+ "url": "git+https://github.com/peerquanta/yakmesh.git",
78
+ "type": "git"
79
+ },
80
+ "bugs": {
81
+ "url": "https://github.com/peerquanta/yakmesh/issues"
82
+ }
52
83
  }