openttt 0.2.4 → 0.2.5

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,7 @@
1
+ export interface GolayDecodeResult {
2
+ data: Uint8Array;
3
+ corrected: number;
4
+ uncorrectable: boolean;
5
+ }
6
+ export declare function golayEncode(data: Uint8Array): Uint8Array;
7
+ export declare function golayDecode(encoded: Uint8Array): GolayDecodeResult;
package/dist/golay.js ADDED
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ // sdk/src/golay.ts
3
+ // Golay(24,12) Extended Binary Golay Code
4
+ // Corrects up to 3 bit errors, detects 4 bit errors.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.golayEncode = golayEncode;
7
+ exports.golayDecode = golayDecode;
8
+ // Standard Golay Parity Matrix P (12x12) - Systematic Form [I12 | P]
9
+ // Every row has weight 7.
10
+ // Verified: P*P^T = I (mod 2), all rows weight 7.
11
+ const P = [
12
+ 0xC75, 0x49F, 0xD4B, 0x6E3, 0x9B3, 0xB66,
13
+ 0xECC, 0x1ED, 0x3DA, 0x7B4, 0xB1D, 0xE3A
14
+ ];
15
+ // P^T (transpose of P) — required for second syndrome computation.
16
+ // P is NOT symmetric, so s2 = s*P^T must use this separate matrix.
17
+ const PT = [
18
+ 0xAE3, 0xF25, 0x16F, 0x2DE, 0x5BC, 0xB78,
19
+ 0x9D5, 0xC8F, 0x63B, 0xC76, 0x7C9, 0xF92
20
+ ];
21
+ const UNIT_VECTORS = [
22
+ 0x800, 0x400, 0x200, 0x100, 0x080, 0x040,
23
+ 0x020, 0x010, 0x008, 0x004, 0x002, 0x001
24
+ ];
25
+ function weight(n) {
26
+ let count = 0;
27
+ let temp = n & 0xFFF;
28
+ while (temp > 0) {
29
+ temp &= (temp - 1);
30
+ count++;
31
+ }
32
+ return count;
33
+ }
34
+ function multiplyP(v) {
35
+ let res = 0;
36
+ for (let i = 0; i < 12; i++) {
37
+ if ((v >> (11 - i)) & 1) {
38
+ res ^= P[i];
39
+ }
40
+ }
41
+ return res & 0xFFF;
42
+ }
43
+ function multiplyPT(v) {
44
+ let res = 0;
45
+ for (let i = 0; i < 12; i++) {
46
+ if ((v >> (11 - i)) & 1) {
47
+ res ^= PT[i];
48
+ }
49
+ }
50
+ return res & 0xFFF;
51
+ }
52
+ function encodeWord(msg) {
53
+ const parity = multiplyP(msg & 0xFFF);
54
+ return ((msg & 0xFFF) << 12) | parity;
55
+ }
56
+ function decodeWord(received) {
57
+ let r_m = (received >> 12) & 0xFFF;
58
+ const r_p = received & 0xFFF;
59
+ const s = multiplyP(r_m) ^ r_p;
60
+ if (s === 0)
61
+ return { msg: r_m, corrected: 0, uncorrectable: false };
62
+ if (weight(s) <= 3) {
63
+ return { msg: r_m, corrected: weight(s), uncorrectable: false };
64
+ }
65
+ for (let i = 0; i < 12; i++) {
66
+ if (weight(s ^ P[i]) <= 2) {
67
+ return { msg: r_m ^ UNIT_VECTORS[i], corrected: weight(s ^ P[i]) + 1, uncorrectable: false };
68
+ }
69
+ }
70
+ const s2 = multiplyPT(s);
71
+ if (weight(s2) <= 3) {
72
+ return { msg: r_m ^ s2, corrected: weight(s2), uncorrectable: false };
73
+ }
74
+ for (let i = 0; i < 12; i++) {
75
+ if (weight(s2 ^ PT[i]) <= 2) {
76
+ const error_m = s2 ^ PT[i];
77
+ return { msg: r_m ^ error_m, corrected: weight(s2 ^ PT[i]) + 1, uncorrectable: false };
78
+ }
79
+ }
80
+ return { msg: r_m, corrected: 0, uncorrectable: true };
81
+ }
82
+ function golayEncode(data) {
83
+ const out = new Uint8Array(Math.ceil(data.length / 3) * 6);
84
+ let outIdx = 0;
85
+ for (let i = 0; i < data.length; i += 3) {
86
+ const b1 = data[i];
87
+ const b2 = i + 1 < data.length ? data[i + 1] : 0;
88
+ const b3 = i + 2 < data.length ? data[i + 2] : 0;
89
+ const w1 = (b1 << 4) | (b2 >> 4);
90
+ const c1 = encodeWord(w1);
91
+ out[outIdx++] = (c1 >> 16) & 0xFF;
92
+ out[outIdx++] = (c1 >> 8) & 0xFF;
93
+ out[outIdx++] = c1 & 0xFF;
94
+ if (i + 1 < data.length) {
95
+ const w2 = ((b2 & 0x0F) << 8) | b3;
96
+ const c2 = encodeWord(w2);
97
+ out[outIdx++] = (c2 >> 16) & 0xFF;
98
+ out[outIdx++] = (c2 >> 8) & 0xFF;
99
+ out[outIdx++] = c2 & 0xFF;
100
+ }
101
+ }
102
+ return out;
103
+ }
104
+ function golayDecode(encoded) {
105
+ if (encoded.length % 6 !== 0) {
106
+ throw new Error("Invalid Golay encoded data: length must be multiple of 6");
107
+ }
108
+ const outLen = Math.floor(encoded.length / 2);
109
+ const out = new Uint8Array(outLen);
110
+ let outIdx = 0;
111
+ let totalCorrected = 0;
112
+ let anyUncorrectable = false;
113
+ for (let i = 0; i < encoded.length; i += 6) {
114
+ const c1 = (encoded[i] << 16) | (encoded[i + 1] << 8) | encoded[i + 2];
115
+ const res1 = decodeWord(c1);
116
+ totalCorrected += res1.corrected;
117
+ if (res1.uncorrectable)
118
+ anyUncorrectable = true;
119
+ if (outIdx < outLen)
120
+ out[outIdx++] = (res1.msg >> 4) & 0xFF;
121
+ const b2_high = (res1.msg & 0x0F) << 4;
122
+ if (i + 3 < encoded.length) {
123
+ const c2 = (encoded[i + 3] << 16) | (encoded[i + 4] << 8) | encoded[i + 5];
124
+ const res2 = decodeWord(c2);
125
+ totalCorrected += res2.corrected;
126
+ if (res2.uncorrectable)
127
+ anyUncorrectable = true;
128
+ if (outIdx < outLen)
129
+ out[outIdx++] = b2_high | (res2.msg >> 8);
130
+ if (outIdx < outLen)
131
+ out[outIdx++] = res2.msg & 0xFF;
132
+ }
133
+ else {
134
+ if (outIdx < outLen)
135
+ out[outIdx++] = b2_high;
136
+ }
137
+ }
138
+ return { data: out, corrected: totalCorrected, uncorrectable: anyUncorrectable };
139
+ }
@@ -0,0 +1,7 @@
1
+ export declare class GrgForward {
2
+ static golombEncode(data: Uint8Array, m?: number): Uint8Array;
3
+ static redstuffEncode(data: Uint8Array, shards?: number, parity?: number): Uint8Array[];
4
+ static deriveHmacKey(chainId: number, poolAddress: string): Buffer;
5
+ static golayEncodeWrapper(data: Uint8Array, hmacKey: Buffer): Uint8Array;
6
+ static encode(data: Uint8Array, chainId: number, poolAddress: string): Uint8Array[];
7
+ }
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GrgForward = void 0;
4
+ // sdk/src/grg_forward.ts
5
+ const crypto_1 = require("crypto");
6
+ const ethers_1 = require("ethers");
7
+ const golay_1 = require("./golay");
8
+ const reed_solomon_1 = require("./reed_solomon");
9
+ class GrgForward {
10
+ static golombEncode(data, m = 16) {
11
+ if (m < 2)
12
+ throw new Error("[GRG] Golomb parameter m must be >= 2");
13
+ const k = Math.log2(m);
14
+ if (!Number.isInteger(k))
15
+ throw new Error("M must be power of 2");
16
+ const bits = [];
17
+ for (const byte of data) {
18
+ const q = Math.floor(byte / m);
19
+ const r = byte % m;
20
+ for (let i = 0; i < q; i++)
21
+ bits.push(1);
22
+ bits.push(0);
23
+ for (let i = k - 1; i >= 0; i--)
24
+ bits.push((r >> i) & 1);
25
+ }
26
+ const out = new Uint8Array(Math.ceil(bits.length / 8));
27
+ for (let i = 0; i < bits.length; i++) {
28
+ if (bits[i])
29
+ out[i >> 3] |= (0x80 >> (i & 7));
30
+ }
31
+ return out;
32
+ }
33
+ static redstuffEncode(data, shards = 4, parity = 2) {
34
+ return reed_solomon_1.ReedSolomon.encode(data, shards, parity);
35
+ }
36
+ static deriveHmacKey(chainId, poolAddress) {
37
+ if (chainId === undefined || chainId === null || !poolAddress) {
38
+ throw new Error("[GRG] chainId and poolAddress are required for HMAC key derivation. No default key is allowed.");
39
+ }
40
+ const packed = (0, ethers_1.keccak256)(ethers_1.AbiCoder.defaultAbiCoder().encode(["uint256", "address"], [chainId, poolAddress]));
41
+ return Buffer.from(packed.slice(2), "hex");
42
+ }
43
+ static golayEncodeWrapper(data, hmacKey) {
44
+ const encoded = (0, golay_1.golayEncode)(data);
45
+ const mac = (0, crypto_1.createHmac)("sha256", hmacKey).update(Buffer.from(encoded)).digest();
46
+ const checksum = mac.subarray(0, 8);
47
+ const final = new Uint8Array(encoded.length + 8);
48
+ final.set(encoded);
49
+ final.set(checksum, encoded.length);
50
+ return final;
51
+ }
52
+ static encode(data, chainId, poolAddress) {
53
+ if (data.length === 0) {
54
+ throw new Error("[GRG] Cannot encode empty input — roundtrip identity violation");
55
+ }
56
+ const compressed = this.golombEncode(data);
57
+ const withLen = new Uint8Array(4 + compressed.length);
58
+ withLen[0] = (data.length >> 24) & 0xFF;
59
+ withLen[1] = (data.length >> 16) & 0xFF;
60
+ withLen[2] = (data.length >> 8) & 0xFF;
61
+ withLen[3] = data.length & 0xFF;
62
+ withLen.set(compressed, 4);
63
+ const shards = this.redstuffEncode(withLen);
64
+ const hmacKey = this.deriveHmacKey(chainId, poolAddress);
65
+ return shards.map(s => this.golayEncodeWrapper(s, hmacKey));
66
+ }
67
+ }
68
+ exports.GrgForward = GrgForward;
@@ -0,0 +1,7 @@
1
+ export declare class GrgInverse {
2
+ private static readonly MAX_GOLOMB_Q;
3
+ static golayDecodeWrapper(data: Uint8Array, hmacKey: Buffer): Uint8Array;
4
+ static redstuffDecode(shards: (Uint8Array | null)[], dataShardCount?: number, parityShardCount?: number): Uint8Array;
5
+ static golombDecode(data: Uint8Array, m?: number, originalLength?: number): Uint8Array;
6
+ static verify(data: Uint8Array, originalShards: Uint8Array[], chainId: number, poolAddress: string): boolean;
7
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GrgInverse = void 0;
4
+ // sdk/src/grg_inverse.ts
5
+ const crypto_1 = require("crypto");
6
+ const golay_1 = require("./golay");
7
+ const grg_forward_1 = require("./grg_forward");
8
+ const logger_1 = require("./logger");
9
+ const reed_solomon_1 = require("./reed_solomon");
10
+ class GrgInverse {
11
+ static MAX_GOLOMB_Q = 1000000;
12
+ static golayDecodeWrapper(data, hmacKey) {
13
+ if (data.length < 8)
14
+ throw new Error("GRG shard too short for checksum");
15
+ const encoded = data.subarray(0, data.length - 8);
16
+ const checksum = data.subarray(data.length - 8);
17
+ const mac = (0, crypto_1.createHmac)("sha256", hmacKey).update(Buffer.from(encoded)).digest();
18
+ const expected = mac.subarray(0, 8);
19
+ if (!Buffer.from(checksum).equals(Buffer.from(expected))) {
20
+ throw new Error("GRG tamper detected: HMAC-SHA256 checksum mismatch");
21
+ }
22
+ const res = (0, golay_1.golayDecode)(encoded);
23
+ if (res.uncorrectable) {
24
+ throw new Error("GRG tamper detected: uncorrectable bit errors in Golay codeword");
25
+ }
26
+ return res.data;
27
+ }
28
+ static redstuffDecode(shards, dataShardCount = 4, parityShardCount = 2) {
29
+ return reed_solomon_1.ReedSolomon.decode(shards, dataShardCount, parityShardCount);
30
+ }
31
+ static golombDecode(data, m = 16, originalLength) {
32
+ if (m < 2)
33
+ throw new Error("[GRG] Golomb parameter m must be >= 2");
34
+ const k = Math.log2(m);
35
+ const totalBits = data.length * 8;
36
+ const readBit = (pos) => (data[pos >> 3] >> (7 - (pos & 7))) & 1;
37
+ const result = [];
38
+ let i = 0;
39
+ while (i < totalBits) {
40
+ if (originalLength !== undefined && result.length >= originalLength)
41
+ break;
42
+ let q = 0;
43
+ while (i < totalBits && readBit(i) === 1) {
44
+ q++;
45
+ i++;
46
+ if (q > this.MAX_GOLOMB_Q)
47
+ throw new Error(`[GRG] Golomb decode: unary run exceeds ${this.MAX_GOLOMB_Q} — malformed or malicious input`);
48
+ }
49
+ if (i < totalBits && readBit(i) === 0)
50
+ i++;
51
+ if (i + k > totalBits)
52
+ break;
53
+ let r = 0;
54
+ for (let j = 0; j < k; j++)
55
+ r = (r << 1) | readBit(i + j);
56
+ result.push(q * m + r);
57
+ i += k;
58
+ }
59
+ return new Uint8Array(result);
60
+ }
61
+ static verify(data, originalShards, chainId, poolAddress) {
62
+ try {
63
+ const hmacKey = grg_forward_1.GrgForward.deriveHmacKey(chainId, poolAddress);
64
+ const decodedShards = originalShards.map(s => {
65
+ try {
66
+ return this.golayDecodeWrapper(s, hmacKey);
67
+ }
68
+ catch {
69
+ return null;
70
+ }
71
+ });
72
+ const withLen = this.redstuffDecode(decodedShards);
73
+ if (withLen.length < 4)
74
+ return false;
75
+ const origLen = (withLen[0] << 24) | (withLen[1] << 16) | (withLen[2] << 8) | withLen[3];
76
+ const compressed = withLen.subarray(4);
77
+ const decoded = this.golombDecode(compressed);
78
+ const final = decoded.subarray(0, origLen);
79
+ if (final.length !== data.length)
80
+ return false;
81
+ for (let i = 0; i < data.length; i++) {
82
+ if (final[i] !== data[i])
83
+ return false;
84
+ }
85
+ return true;
86
+ }
87
+ catch (e) {
88
+ logger_1.logger.warn(`[GRG Inverse] Verification failed: ${e}`);
89
+ return false;
90
+ }
91
+ }
92
+ }
93
+ exports.GrgInverse = GrgInverse;
@@ -0,0 +1,5 @@
1
+ export declare class GrgPipeline {
2
+ private static readonly MAX_INPUT_SIZE;
3
+ static processForward(data: Uint8Array, chainId: number, poolAddress: string): Uint8Array[];
4
+ static processInverse(shards: (Uint8Array | null)[], originalLength: number, chainId: number, poolAddress: string): Uint8Array;
5
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GrgPipeline = void 0;
4
+ // sdk/src/grg_pipeline.ts
5
+ const grg_forward_1 = require("./grg_forward");
6
+ const grg_inverse_1 = require("./grg_inverse");
7
+ const logger_1 = require("./logger");
8
+ class GrgPipeline {
9
+ static MAX_INPUT_SIZE = 100 * 1024 * 1024; // 100 MB
10
+ static processForward(data, chainId, poolAddress) {
11
+ if (data.length > this.MAX_INPUT_SIZE) {
12
+ throw new Error(`[GRG] Input size ${data.length} exceeds MAX_INPUT_SIZE ${this.MAX_INPUT_SIZE}`);
13
+ }
14
+ logger_1.logger.info("Starting GRG forward pipeline...");
15
+ try {
16
+ const shards = grg_forward_1.GrgForward.encode(data, chainId, poolAddress);
17
+ logger_1.logger.info(`GRG forward pipeline complete. Generated ${shards.length} shards.`);
18
+ return shards;
19
+ }
20
+ catch (error) {
21
+ logger_1.logger.error(`GRG forward pipeline failed: ${error}`);
22
+ throw error;
23
+ }
24
+ }
25
+ static processInverse(shards, originalLength, chainId, poolAddress) {
26
+ logger_1.logger.info("Starting GRG inverse pipeline...");
27
+ try {
28
+ const hmacKey = grg_forward_1.GrgForward.deriveHmacKey(chainId, poolAddress);
29
+ const decodedShards = shards.map(s => {
30
+ try {
31
+ return s ? grg_inverse_1.GrgInverse.golayDecodeWrapper(s, hmacKey) : null;
32
+ }
33
+ catch (e) {
34
+ logger_1.logger.warn(`Golay decode failed for a shard: ${e}`);
35
+ return null;
36
+ }
37
+ });
38
+ const withLen = grg_inverse_1.GrgInverse.redstuffDecode(decodedShards);
39
+ const decodedLength = (withLen[0] << 24) | (withLen[1] << 16) | (withLen[2] << 8) | withLen[3];
40
+ const compressed = withLen.subarray(4);
41
+ const decompressed = grg_inverse_1.GrgInverse.golombDecode(compressed);
42
+ const final = decompressed.subarray(0, decodedLength);
43
+ if (final.length !== originalLength) {
44
+ throw new Error(`[GRG] Length mismatch in inverse: expected ${originalLength}, got ${final.length}`);
45
+ }
46
+ logger_1.logger.info("GRG inverse pipeline complete.");
47
+ return final;
48
+ }
49
+ catch (error) {
50
+ logger_1.logger.error(`GRG inverse pipeline failed: ${error}`);
51
+ throw error;
52
+ }
53
+ }
54
+ }
55
+ exports.GrgPipeline = GrgPipeline;
@@ -0,0 +1,13 @@
1
+ export declare class ReedSolomon {
2
+ private static expTable;
3
+ private static logTable;
4
+ private static initialized;
5
+ private static vandermondeCache;
6
+ static init(): void;
7
+ static mul(a: number, b: number): number;
8
+ static div(a: number, b: number): number;
9
+ static invertMatrix(matrix: number[][]): number[][];
10
+ static buildVandermonde(rows: number, cols: number): number[][];
11
+ static encode(data: Uint8Array, dataShards?: number, parityShards?: number): Uint8Array[];
12
+ static decode(shards: (Uint8Array | null)[], dataShards?: number, parityShards?: number): Uint8Array;
13
+ }
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ // sdk/src/reed_solomon.ts
3
+ // Reed-Solomon GF(2^8) erasure coding
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.ReedSolomon = void 0;
6
+ class ReedSolomon {
7
+ static expTable = new Uint8Array(256);
8
+ static logTable = new Uint8Array(256);
9
+ static initialized = false;
10
+ static vandermondeCache = new Map();
11
+ static init() {
12
+ if (this.initialized)
13
+ return;
14
+ let x = 1;
15
+ for (let i = 0; i < 255; i++) {
16
+ this.expTable[i] = x;
17
+ this.logTable[x] = i;
18
+ x <<= 1;
19
+ if (x & 0x100) {
20
+ x ^= 0x11D; // x^8 + x^4 + x^3 + x^2 + 1
21
+ }
22
+ }
23
+ this.expTable[255] = this.expTable[0];
24
+ this.logTable[0] = 0;
25
+ this.initialized = true;
26
+ }
27
+ static mul(a, b) {
28
+ if (a === 0 || b === 0)
29
+ return 0;
30
+ return this.expTable[(this.logTable[a] + this.logTable[b]) % 255];
31
+ }
32
+ static div(a, b) {
33
+ if (b === 0)
34
+ throw new Error("Division by zero");
35
+ if (a === 0)
36
+ return 0;
37
+ return this.expTable[(this.logTable[a] - this.logTable[b] + 255) % 255];
38
+ }
39
+ static invertMatrix(matrix) {
40
+ const n = matrix.length;
41
+ const aug = [];
42
+ for (let i = 0; i < n; i++) {
43
+ aug[i] = [];
44
+ for (let j = 0; j < n; j++)
45
+ aug[i][j] = matrix[i][j];
46
+ for (let j = 0; j < n; j++)
47
+ aug[i][j + n] = (i === j) ? 1 : 0;
48
+ }
49
+ for (let i = 0; i < n; i++) {
50
+ let pivot = i;
51
+ while (pivot < n && aug[pivot][i] === 0)
52
+ pivot++;
53
+ if (pivot === n)
54
+ throw new Error("Singular matrix");
55
+ if (pivot !== i) {
56
+ const temp = aug[i];
57
+ aug[i] = aug[pivot];
58
+ aug[pivot] = temp;
59
+ }
60
+ const pivotVal = aug[i][i];
61
+ if (pivotVal !== 1) {
62
+ for (let j = i; j < 2 * n; j++)
63
+ aug[i][j] = this.div(aug[i][j], pivotVal);
64
+ }
65
+ for (let j = 0; j < n; j++) {
66
+ if (i !== j && aug[j][i] !== 0) {
67
+ const factor = aug[j][i];
68
+ for (let k = i; k < 2 * n; k++)
69
+ aug[j][k] ^= this.mul(factor, aug[i][k]);
70
+ }
71
+ }
72
+ }
73
+ const inv = [];
74
+ for (let i = 0; i < n; i++) {
75
+ inv[i] = [];
76
+ for (let j = 0; j < n; j++)
77
+ inv[i][j] = aug[i][j + n];
78
+ }
79
+ return inv;
80
+ }
81
+ static buildVandermonde(rows, cols) {
82
+ const cacheKey = `${rows}-${cols}`;
83
+ const cached = this.vandermondeCache.get(cacheKey);
84
+ if (cached)
85
+ return cached;
86
+ const V = [];
87
+ for (let r = 0; r < rows; r++) {
88
+ V[r] = [];
89
+ const x = r + 1;
90
+ for (let c = 0; c < cols; c++) {
91
+ V[r][c] = c === 0 ? 1 : this.mul(V[r][c - 1], x);
92
+ }
93
+ }
94
+ const V_top = [];
95
+ for (let i = 0; i < cols; i++)
96
+ V_top.push([...V[i]]);
97
+ const V_top_inv = this.invertMatrix(V_top);
98
+ const G = [];
99
+ for (let r = 0; r < rows; r++) {
100
+ G[r] = [];
101
+ for (let c = 0; c < cols; c++) {
102
+ let val = 0;
103
+ for (let k = 0; k < cols; k++)
104
+ val ^= this.mul(V[r][k], V_top_inv[k][c]);
105
+ G[r][c] = val;
106
+ }
107
+ }
108
+ this.vandermondeCache.set(cacheKey, G);
109
+ return G;
110
+ }
111
+ static encode(data, dataShards = 4, parityShards = 2) {
112
+ this.init();
113
+ const totalShards = dataShards + parityShards;
114
+ const rawShardSize = Math.ceil(data.length / dataShards);
115
+ const shardSize = Math.ceil(rawShardSize / 3) * 3;
116
+ const matrix = this.buildVandermonde(totalShards, dataShards);
117
+ const shards = [];
118
+ for (let i = 0; i < totalShards; i++)
119
+ shards.push(new Uint8Array(shardSize));
120
+ for (let i = 0; i < dataShards; i++) {
121
+ shards[i].set(data.subarray(i * shardSize, Math.min((i + 1) * shardSize, data.length)));
122
+ }
123
+ for (let c = 0; c < shardSize; c++) {
124
+ for (let r = dataShards; r < totalShards; r++) {
125
+ let val = 0;
126
+ for (let j = 0; j < dataShards; j++)
127
+ val ^= this.mul(matrix[r][j], shards[j][c]);
128
+ shards[r][c] = val;
129
+ }
130
+ }
131
+ return shards;
132
+ }
133
+ static decode(shards, dataShards = 4, parityShards = 2) {
134
+ this.init();
135
+ const totalShards = dataShards + parityShards;
136
+ if (shards.length !== totalShards) {
137
+ throw new Error(`[RS] Expected ${totalShards} shards, got ${shards.length}`);
138
+ }
139
+ const presentIndices = [];
140
+ const presentShards = [];
141
+ for (let i = 0; i < totalShards; i++) {
142
+ if (shards[i] !== null && shards[i] !== undefined) {
143
+ presentIndices.push(i);
144
+ presentShards.push(shards[i]);
145
+ if (presentIndices.length === dataShards)
146
+ break;
147
+ }
148
+ }
149
+ if (presentIndices.length < dataShards) {
150
+ throw new Error(`[RS] Not enough shards for recovery: need ${dataShards}, got ${presentIndices.length}`);
151
+ }
152
+ const shardSize = presentShards[0].length;
153
+ const origMatrix = this.buildVandermonde(totalShards, dataShards);
154
+ const subMatrix = [];
155
+ for (let i = 0; i < dataShards; i++)
156
+ subMatrix.push([...origMatrix[presentIndices[i]]]);
157
+ const invMatrix = this.invertMatrix(subMatrix);
158
+ const result = new Uint8Array(shardSize * dataShards);
159
+ for (let c = 0; c < shardSize; c++) {
160
+ for (let r = 0; r < dataShards; r++) {
161
+ let val = 0;
162
+ for (let j = 0; j < dataShards; j++)
163
+ val ^= this.mul(invMatrix[r][j], presentShards[j][c]);
164
+ result[r * shardSize + c] = val;
165
+ }
166
+ }
167
+ return result;
168
+ }
169
+ }
170
+ exports.ReedSolomon = ReedSolomon;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openttt",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "description": "OpenTTT — TLS-grade transaction ordering for DeFi. Time + Logic + Sync.",
5
5
  "license": "BSL-1.1",
6
6
  "repository": {
@@ -31,11 +31,6 @@
31
31
  },
32
32
  "files": [
33
33
  "dist",
34
- "!dist/golay.*",
35
- "!dist/grg_forward.*",
36
- "!dist/grg_inverse.*",
37
- "!dist/grg_pipeline.*",
38
- "!dist/reed_solomon.*",
39
34
  "README.md"
40
35
  ],
41
36
  "scripts": {