@forestrie/merklelog 0.0.1

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 (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -0
  3. package/dist/index.d.ts +21 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +20 -0
  6. package/dist/massifs/indexformat.d.ts +146 -0
  7. package/dist/massifs/indexformat.d.ts.map +1 -0
  8. package/dist/massifs/indexformat.js +191 -0
  9. package/dist/massifs/logformat.d.ts +49 -0
  10. package/dist/massifs/logformat.d.ts.map +1 -0
  11. package/dist/massifs/logformat.js +49 -0
  12. package/dist/massifs/massif.d.ts +86 -0
  13. package/dist/massifs/massif.d.ts.map +1 -0
  14. package/dist/massifs/massif.js +143 -0
  15. package/dist/massifs/massiffull.d.ts +14 -0
  16. package/dist/massifs/massiffull.d.ts.map +1 -0
  17. package/dist/massifs/massiffull.js +21 -0
  18. package/dist/massifs/massiflogentries.d.ts +23 -0
  19. package/dist/massifs/massiflogentries.d.ts.map +1 -0
  20. package/dist/massifs/massiflogentries.js +31 -0
  21. package/dist/massifs/massifstart.d.ts +63 -0
  22. package/dist/massifs/massifstart.d.ts.map +1 -0
  23. package/dist/massifs/massifstart.js +39 -0
  24. package/dist/massifs/mmrindex.d.ts +15 -0
  25. package/dist/massifs/mmrindex.d.ts.map +1 -0
  26. package/dist/massifs/mmrindex.js +24 -0
  27. package/dist/massifs/peakstackend.d.ts +21 -0
  28. package/dist/massifs/peakstackend.d.ts.map +1 -0
  29. package/dist/massifs/peakstackend.js +29 -0
  30. package/dist/massifs/types.d.ts +20 -0
  31. package/dist/massifs/types.d.ts.map +1 -0
  32. package/dist/massifs/types.js +23 -0
  33. package/dist/massifs/urkleindex.d.ts +116 -0
  34. package/dist/massifs/urkleindex.d.ts.map +1 -0
  35. package/dist/massifs/urkleindex.js +169 -0
  36. package/dist/massifs/v2storagepaths.d.ts +17 -0
  37. package/dist/massifs/v2storagepaths.d.ts.map +1 -0
  38. package/dist/massifs/v2storagepaths.js +46 -0
  39. package/dist/mmr/algorithms-sync.d.ts +17 -0
  40. package/dist/mmr/algorithms-sync.d.ts.map +1 -0
  41. package/dist/mmr/algorithms-sync.js +42 -0
  42. package/dist/mmr/algorithms.d.ts +79 -0
  43. package/dist/mmr/algorithms.d.ts.map +1 -0
  44. package/dist/mmr/algorithms.js +155 -0
  45. package/dist/mmr/index.d.ts +37 -0
  46. package/dist/mmr/index.d.ts.map +1 -0
  47. package/dist/mmr/index.js +64 -0
  48. package/dist/mmr/math.d.ts +67 -0
  49. package/dist/mmr/math.d.ts.map +1 -0
  50. package/dist/mmr/math.js +172 -0
  51. package/dist/mmr/types.d.ts +37 -0
  52. package/dist/mmr/types.d.ts.map +1 -0
  53. package/dist/mmr/types.js +4 -0
  54. package/dist/uint64/index.d.ts +90 -0
  55. package/dist/uint64/index.d.ts.map +1 -0
  56. package/dist/uint64/index.js +149 -0
  57. package/dist/utils/arrays.d.ts +15 -0
  58. package/dist/utils/arrays.d.ts.map +1 -0
  59. package/dist/utils/arrays.js +24 -0
  60. package/package.json +41 -0
  61. package/src/index.ts +68 -0
  62. package/src/massifs/indexformat.ts +217 -0
  63. package/src/massifs/logformat.ts +54 -0
  64. package/src/massifs/massif.ts +182 -0
  65. package/src/massifs/massiffull.ts +28 -0
  66. package/src/massifs/massiflogentries.ts +40 -0
  67. package/src/massifs/massifstart.ts +67 -0
  68. package/src/massifs/mmrindex.ts +32 -0
  69. package/src/massifs/peakstackend.ts +34 -0
  70. package/src/massifs/types.ts +55 -0
  71. package/src/massifs/urkleindex.ts +273 -0
  72. package/src/massifs/v2storagepaths.ts +61 -0
  73. package/src/mmr/algorithms-sync.ts +46 -0
  74. package/src/mmr/algorithms.ts +194 -0
  75. package/src/mmr/index.ts +75 -0
  76. package/src/mmr/math.ts +190 -0
  77. package/src/mmr/types.ts +39 -0
  78. package/src/uint64/index.ts +164 -0
  79. package/src/utils/arrays.ts +25 -0
@@ -0,0 +1,37 @@
1
+ /**
2
+ * MMR index calculation functions
3
+ *
4
+ * These functions are needed by the massifs module for computing
5
+ * firstIndex and peakStackLen.
6
+ *
7
+ * Also exports the core mmrIndex function for converting leaf indices to MMR indices.
8
+ */
9
+ /**
10
+ * Returns the number of peaks preceding iLeaf that the future tree requires.
11
+ *
12
+ * This corresponds to the number of preceding nodes that will be required to
13
+ * derive future interior nodes. If those preceding nodes are maintained in a
14
+ * stack, this is the current length of the stack.
15
+ *
16
+ * Translated from go-merklelog/mmr/spurs.go LeafMinusSpurSum
17
+ */
18
+ export declare function leafMinusSpurSum(leafIndex: bigint): bigint;
19
+ /**
20
+ * Returns the MMR index of the first leaf in the massif blob identified by massifIndex
21
+ *
22
+ * Translated from go-merklelog/massifs/massifstart.go MassifFirstLeaf
23
+ */
24
+ export declare function massifFirstLeaf(massifHeight: number, massifIndex: number): bigint;
25
+ /**
26
+ * Returns the node index for the leaf e
27
+ *
28
+ * Args:
29
+ * - leafIndex: the leaf index, where the leaves are numbered consecutively, ignoring interior nodes.
30
+ *
31
+ * Returns:
32
+ * The mmr index for the element leafIndex
33
+ *
34
+ * Translated from go-merklelog/mmr/mmrindex.go MMRIndex
35
+ */
36
+ export declare function mmrIndex(leafIndex: bigint): bigint;
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mmr/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAQ1D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,MAAM,CAYR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAalD"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * MMR index calculation functions
3
+ *
4
+ * These functions are needed by the massifs module for computing
5
+ * firstIndex and peakStackLen.
6
+ *
7
+ * Also exports the core mmrIndex function for converting leaf indices to MMR indices.
8
+ */
9
+ /**
10
+ * Returns the number of peaks preceding iLeaf that the future tree requires.
11
+ *
12
+ * This corresponds to the number of preceding nodes that will be required to
13
+ * derive future interior nodes. If those preceding nodes are maintained in a
14
+ * stack, this is the current length of the stack.
15
+ *
16
+ * Translated from go-merklelog/mmr/spurs.go LeafMinusSpurSum
17
+ */
18
+ export function leafMinusSpurSum(leafIndex) {
19
+ let sum = leafIndex;
20
+ let current = leafIndex >> 1n;
21
+ while (current > 0n) {
22
+ sum -= current;
23
+ current >>= 1n;
24
+ }
25
+ return sum;
26
+ }
27
+ /**
28
+ * Returns the MMR index of the first leaf in the massif blob identified by massifIndex
29
+ *
30
+ * Translated from go-merklelog/massifs/massifstart.go MassifFirstLeaf
31
+ */
32
+ export function massifFirstLeaf(massifHeight, massifIndex) {
33
+ // The number of nodes 'm' in a massif is: m = (1 << h) - 1
34
+ const m = BigInt((1 << massifHeight) - 1);
35
+ // The number of leaves 'f' in every massif: f = (m + 1) / 2
36
+ const f = (m + 1n) >> 1n;
37
+ // The first leaf index is then: leafIndex = f * massifIndex
38
+ const leafIndex = f * BigInt(massifIndex);
39
+ // Apply MMRIndex to the leaf index to get the MMR index
40
+ return mmrIndex(leafIndex);
41
+ }
42
+ /**
43
+ * Returns the node index for the leaf e
44
+ *
45
+ * Args:
46
+ * - leafIndex: the leaf index, where the leaves are numbered consecutively, ignoring interior nodes.
47
+ *
48
+ * Returns:
49
+ * The mmr index for the element leafIndex
50
+ *
51
+ * Translated from go-merklelog/mmr/mmrindex.go MMRIndex
52
+ */
53
+ export function mmrIndex(leafIndex) {
54
+ let sum = 0n;
55
+ let current = leafIndex;
56
+ while (current > 0n) {
57
+ // Find the position of the most significant bit (height)
58
+ const h = BigInt(current.toString(2).length);
59
+ sum += (1n << h) - 1n;
60
+ const half = 1n << (h - 1n);
61
+ current -= half;
62
+ }
63
+ return sum;
64
+ }
@@ -0,0 +1,67 @@
1
+ import { Uint64 } from "../uint64/index.js";
2
+ /**
3
+ * MMR Math Functions
4
+ *
5
+ * Core mathematical functions for Merkle Mountain Range operations.
6
+ * Uses Uint64 wrapper for all arithmetic to ensure correctness.
7
+ */
8
+ /**
9
+ * Returns the zero-based height index (g) of an MMR index
10
+ *
11
+ * The height index of a leaf is 0.
12
+ * Translated from go-merklelog/mmr/indexheight.go IndexHeight
13
+ */
14
+ export declare function heightIndex(mmrIndex: Uint64): number;
15
+ /**
16
+ * Returns the one-based height (h) of an MMR index
17
+ *
18
+ * h = g + 1 where g is the height index
19
+ */
20
+ export declare function height(mmrIndex: Uint64): number;
21
+ /**
22
+ * Converts leaf index to MMR index
23
+ *
24
+ * @param leafIndex - Zero-based leaf index
25
+ * @returns MMR index
26
+ */
27
+ export declare function mmrIndexFromLeafIndex(leafIndex: Uint64): Uint64;
28
+ /**
29
+ * Converts MMR index to leaf index
30
+ *
31
+ * @param mmrIndex - MMR index
32
+ * @returns Leaf index
33
+ */
34
+ export declare function leafIndex(mmrIndex: Uint64): Uint64;
35
+ /**
36
+ * Converts MMR index to MMR position (index + 1)
37
+ *
38
+ * @param mmrIndex - Zero-based MMR index
39
+ * @returns One-based MMR position
40
+ */
41
+ export declare function mmrPosition(mmrIndex: Uint64): Uint64;
42
+ /**
43
+ * Returns the number of nodes given a height index (g)
44
+ *
45
+ * n = 2^(g+1) - 1 = (2 << g) - 1
46
+ * Translated from go-merklelog/mmr/size.go HeightIndexSize
47
+ */
48
+ export declare function mmrSizeFromHeightIndex(heightIndex: number): Uint64;
49
+ /**
50
+ * Returns the number of leaves in the largest valid MMR whose size is
51
+ * <= `mmrSize`.
52
+ *
53
+ * Mirrors go-merklelog `LeafCount`, which is defined as `PeaksBitmap(mmrSize)`:
54
+ * the leaf count's binary representation maps directly onto the peak structure
55
+ * (each set bit is a perfect subtree). The naive `(n + 1) / 2` is only correct
56
+ * for single-peak (perfect) sizes — e.g. size 4 (3 leaves) gives 2 with the
57
+ * naive form but 3 here — so it must not be used. When `mmrSize` is not a valid
58
+ * MMR size this returns the leaf count of the highest valid size <= `mmrSize`.
59
+ */
60
+ export declare function leafCount(mmrSize: Uint64): Uint64;
61
+ /**
62
+ * Returns the number of leaves given a height index
63
+ *
64
+ * f = 2^g = 1 << g
65
+ */
66
+ export declare function leafCountFromHeightIndex(heightIndex: number): Uint64;
67
+ //# sourceMappingURL=math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../../src/mmr/math.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C;;;;;GAKG;AAEH;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/C;AAgDD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI/D;AAiBD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAclD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAElE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEjD;AAwBD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpE"}
@@ -0,0 +1,172 @@
1
+ import { Uint64 } from "../uint64/index.js";
2
+ /**
3
+ * MMR Math Functions
4
+ *
5
+ * Core mathematical functions for Merkle Mountain Range operations.
6
+ * Uses Uint64 wrapper for all arithmetic to ensure correctness.
7
+ */
8
+ /**
9
+ * Returns the zero-based height index (g) of an MMR index
10
+ *
11
+ * The height index of a leaf is 0.
12
+ * Translated from go-merklelog/mmr/indexheight.go IndexHeight
13
+ */
14
+ export function heightIndex(mmrIndex) {
15
+ // Convert from zero-based index to 1-based position
16
+ const pos = mmrIndex.add(new Uint64(1));
17
+ return posHeight(pos);
18
+ }
19
+ /**
20
+ * Returns the one-based height (h) of an MMR index
21
+ *
22
+ * h = g + 1 where g is the height index
23
+ */
24
+ export function height(mmrIndex) {
25
+ return heightIndex(mmrIndex) + 1;
26
+ }
27
+ /**
28
+ * PosHeight - obtains height from a 1-based position
29
+ *
30
+ * Translated from go-merklelog/mmr/indexheight.go PosHeight
31
+ */
32
+ function posHeight(pos) {
33
+ let current = pos;
34
+ while (!allOnes(current)) {
35
+ current = jumpLeftPerfect(current);
36
+ }
37
+ return bitLength(current) - 1;
38
+ }
39
+ /**
40
+ * JumpLeftPerfect - jumps left to the leftmost node at the same height
41
+ *
42
+ * Translated from go-merklelog/mmr/indexheight.go JumpLeftPerfect
43
+ */
44
+ function jumpLeftPerfect(pos) {
45
+ const bitLen = bitLength(pos);
46
+ const mostSignificantBit = new Uint64(1).shl(bitLen - 1);
47
+ return pos.sub(mostSignificantBit.sub(new Uint64(1)));
48
+ }
49
+ /**
50
+ * Checks if a value has all bits set (all ones in binary)
51
+ */
52
+ function allOnes(value) {
53
+ // A value has all ones if value + 1 is a power of 2
54
+ const next = value.add(new Uint64(1));
55
+ const bitLen = bitLength(next);
56
+ const powerOf2 = new Uint64(1).shl(bitLen - 1);
57
+ return next.equals(powerOf2);
58
+ }
59
+ /**
60
+ * Returns the number of bits needed to represent the value
61
+ */
62
+ function bitLength(value) {
63
+ const bigInt = value.toBigInt();
64
+ if (bigInt === 0n) {
65
+ return 0;
66
+ }
67
+ return bigInt.toString(2).length;
68
+ }
69
+ /**
70
+ * Converts leaf index to MMR index
71
+ *
72
+ * @param leafIndex - Zero-based leaf index
73
+ * @returns MMR index
74
+ */
75
+ export function mmrIndexFromLeafIndex(leafIndex) {
76
+ // Use the mmrIndex function from index.ts
77
+ // Import it dynamically to avoid circular dependency
78
+ return new Uint64(mmrIndexFromLeafIndexInternal(leafIndex.toBigInt()));
79
+ }
80
+ // Internal helper that matches the implementation in index.ts
81
+ function mmrIndexFromLeafIndexInternal(leafIndex) {
82
+ let sum = 0n;
83
+ let current = leafIndex;
84
+ while (current > 0n) {
85
+ const h = BigInt(current.toString(2).length);
86
+ sum += (1n << h) - 1n;
87
+ const half = 1n << (h - 1n);
88
+ current -= half;
89
+ }
90
+ return sum;
91
+ }
92
+ /**
93
+ * Converts MMR index to leaf index
94
+ *
95
+ * @param mmrIndex - MMR index
96
+ * @returns Leaf index
97
+ */
98
+ export function leafIndex(mmrIndex) {
99
+ // This needs to be implemented based on the MMR structure
100
+ // For now, we'll use an iterative approach
101
+ let current = mmrIndex;
102
+ let leafCount = new Uint64(0);
103
+ while (current.toBigInt() > 0n) {
104
+ const h = heightIndex(current);
105
+ const peakSize = new Uint64(1).shl(h + 1).sub(new Uint64(1)); // (1 << (h+1)) - 1
106
+ leafCount = leafCount.add(new Uint64(1).shl(h)); // Add 2^h leaves
107
+ current = current.sub(peakSize);
108
+ }
109
+ return leafCount.sub(new Uint64(1)); // Convert to zero-based
110
+ }
111
+ /**
112
+ * Converts MMR index to MMR position (index + 1)
113
+ *
114
+ * @param mmrIndex - Zero-based MMR index
115
+ * @returns One-based MMR position
116
+ */
117
+ export function mmrPosition(mmrIndex) {
118
+ return mmrIndex.add(new Uint64(1));
119
+ }
120
+ /**
121
+ * Returns the number of nodes given a height index (g)
122
+ *
123
+ * n = 2^(g+1) - 1 = (2 << g) - 1
124
+ * Translated from go-merklelog/mmr/size.go HeightIndexSize
125
+ */
126
+ export function mmrSizeFromHeightIndex(heightIndex) {
127
+ return new Uint64(1).shl(heightIndex + 1).sub(new Uint64(1));
128
+ }
129
+ /**
130
+ * Returns the number of leaves in the largest valid MMR whose size is
131
+ * <= `mmrSize`.
132
+ *
133
+ * Mirrors go-merklelog `LeafCount`, which is defined as `PeaksBitmap(mmrSize)`:
134
+ * the leaf count's binary representation maps directly onto the peak structure
135
+ * (each set bit is a perfect subtree). The naive `(n + 1) / 2` is only correct
136
+ * for single-peak (perfect) sizes — e.g. size 4 (3 leaves) gives 2 with the
137
+ * naive form but 3 here — so it must not be used. When `mmrSize` is not a valid
138
+ * MMR size this returns the leaf count of the highest valid size <= `mmrSize`.
139
+ */
140
+ export function leafCount(mmrSize) {
141
+ return new Uint64(peaksBitmap(mmrSize.toBigInt()));
142
+ }
143
+ /**
144
+ * Returns the peaks bitmap for an MMR size (go-merklelog `PeaksBitmap`).
145
+ *
146
+ * The numeric value equals the leaf count of the largest valid MMR with size
147
+ * <= `mmrSize`; each set bit marks a perfect subtree (peak) at that height.
148
+ */
149
+ function peaksBitmap(mmrSize) {
150
+ if (mmrSize === 0n)
151
+ return 0n;
152
+ let pos = mmrSize;
153
+ let peakSize = (1n << BigInt(bitLength(new Uint64(mmrSize)))) - 1n;
154
+ let peakMap = 0n;
155
+ while (peakSize > 0n) {
156
+ peakMap <<= 1n;
157
+ if (pos >= peakSize) {
158
+ pos -= peakSize;
159
+ peakMap |= 1n;
160
+ }
161
+ peakSize >>= 1n;
162
+ }
163
+ return peakMap;
164
+ }
165
+ /**
166
+ * Returns the number of leaves given a height index
167
+ *
168
+ * f = 2^g = 1 << g
169
+ */
170
+ export function leafCountFromHeightIndex(heightIndex) {
171
+ return new Uint64(1).shl(heightIndex);
172
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Proof types for MMR inclusion and consistency proofs
3
+ */
4
+ /**
5
+ * Proof - Inclusion or consistency proof structure
6
+ */
7
+ export interface Proof {
8
+ /** The proof path (sibling hashes) */
9
+ path: Uint8Array[];
10
+ /** The leaf index being proven */
11
+ leafIndex?: bigint;
12
+ /** The MMR index being proven */
13
+ mmrIndex?: bigint;
14
+ }
15
+ /**
16
+ * Peak - A peak node in the MMR
17
+ */
18
+ export interface Peak {
19
+ /** The MMR index of the peak */
20
+ index: bigint;
21
+ /** The hash value of the peak */
22
+ hash: Uint8Array;
23
+ }
24
+ /**
25
+ * Hasher interface for cryptographic hashing operations.
26
+ * digest() is async so callers can use crypto.subtle (Workers, browser) or
27
+ * wrap Node's crypto.createHash (e.g. digest(): Promise.resolve(syncDigest())).
28
+ */
29
+ export interface Hasher {
30
+ /** Reset the hasher state */
31
+ reset(): void;
32
+ /** Update the hasher with data */
33
+ update(data: Uint8Array): void;
34
+ /** Finalize and return the hash */
35
+ digest(): Promise<Uint8Array>;
36
+ }
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mmr/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,sCAAsC;IACtC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,kCAAkC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB,6BAA6B;IAC7B,KAAK,IAAI,IAAI,CAAC;IACd,kCAAkC;IAClC,MAAM,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,mCAAmC;IACnC,MAAM,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC;CAC/B"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Proof types for MMR inclusion and consistency proofs
3
+ */
4
+ export {};
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Uint64 - A BigInt-based wrapper for 64-bit unsigned integer operations
3
+ *
4
+ * Provides arithmetic and bitwise operations for 64-bit unsigned integers,
5
+ * ensuring all operations stay within the 64-bit range using BigInt.asUintN(64, value).
6
+ */
7
+ export declare class Uint64 {
8
+ private readonly value;
9
+ /**
10
+ * Creates a new Uint64 instance
11
+ * @param value - The initial value as number, bigint, or string
12
+ */
13
+ constructor(value: number | bigint | string | Uint64);
14
+ /**
15
+ * Addition with overflow handling (wraps around at 2^64)
16
+ * @param other - The value to add
17
+ * @returns New Uint64 instance with the result
18
+ */
19
+ add(other: Uint64): Uint64;
20
+ /**
21
+ * Subtraction with underflow handling (wraps around at 0)
22
+ * @param other - The value to subtract
23
+ * @returns New Uint64 instance with the result
24
+ */
25
+ sub(other: Uint64): Uint64;
26
+ /**
27
+ * Left shift
28
+ * @param bits - Number of bits to shift left
29
+ * @returns New Uint64 instance with the result
30
+ */
31
+ shl(bits: number): Uint64;
32
+ /**
33
+ * Right shift (logical, zero-fill)
34
+ * @param bits - Number of bits to shift right
35
+ * @returns New Uint64 instance with the result
36
+ */
37
+ shr(bits: number): Uint64;
38
+ /**
39
+ * Bitwise AND
40
+ * @param other - The value to AND with
41
+ * @returns New Uint64 instance with the result
42
+ */
43
+ and(other: Uint64): Uint64;
44
+ /**
45
+ * Bitwise OR
46
+ * @param other - The value to OR with
47
+ * @returns New Uint64 instance with the result
48
+ */
49
+ or(other: Uint64): Uint64;
50
+ /**
51
+ * Bitwise XOR
52
+ * @param other - The value to XOR with
53
+ * @returns New Uint64 instance with the result
54
+ */
55
+ xor(other: Uint64): Uint64;
56
+ /**
57
+ * Bitwise complement (one's complement)
58
+ * @returns New Uint64 instance with the result
59
+ */
60
+ not(): Uint64;
61
+ /**
62
+ * Mask lower bits (equivalent to value & ((1 << bits) - 1))
63
+ * @param bits - Number of lower bits to keep
64
+ * @returns New Uint64 instance with the result
65
+ */
66
+ mask(bits: number): Uint64;
67
+ /**
68
+ * Returns the value as a BigInt
69
+ * @returns The 64-bit unsigned value as BigInt
70
+ */
71
+ toBigInt(): bigint;
72
+ /**
73
+ * Returns the value as a number (with range check)
74
+ * @returns The value as number if it fits in Number.MAX_SAFE_INTEGER
75
+ * @throws Error if value exceeds Number.MAX_SAFE_INTEGER
76
+ */
77
+ toNumber(): number;
78
+ /**
79
+ * Returns the value as a string
80
+ * @returns String representation of the value
81
+ */
82
+ toString(): string;
83
+ /**
84
+ * Equality comparison
85
+ * @param other - The value to compare with
86
+ * @returns True if values are equal
87
+ */
88
+ equals(other: Uint64): boolean;
89
+ }
90
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/uint64/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAE/B;;;OAGG;gBACS,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM;IASpD;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAK1B;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAK1B;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQzB;;;;OAIG;IACH,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQzB;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAK1B;;;;OAIG;IACH,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAKzB;;;;OAIG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAK1B;;;OAGG;IACH,GAAG,IAAI,MAAM;IAMb;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAY1B;;;OAGG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;OAIG;IACH,QAAQ,IAAI,MAAM;IASlB;;;OAGG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;OAIG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;CAG/B"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Uint64 - A BigInt-based wrapper for 64-bit unsigned integer operations
3
+ *
4
+ * Provides arithmetic and bitwise operations for 64-bit unsigned integers,
5
+ * ensuring all operations stay within the 64-bit range using BigInt.asUintN(64, value).
6
+ */
7
+ export class Uint64 {
8
+ value;
9
+ /**
10
+ * Creates a new Uint64 instance
11
+ * @param value - The initial value as number, bigint, or string
12
+ */
13
+ constructor(value) {
14
+ if (value instanceof Uint64) {
15
+ this.value = value.value;
16
+ }
17
+ else {
18
+ const bigIntValue = typeof value === "bigint" ? value : BigInt(value);
19
+ this.value = BigInt.asUintN(64, bigIntValue);
20
+ }
21
+ }
22
+ /**
23
+ * Addition with overflow handling (wraps around at 2^64)
24
+ * @param other - The value to add
25
+ * @returns New Uint64 instance with the result
26
+ */
27
+ add(other) {
28
+ const result = this.value + other.value;
29
+ return new Uint64(BigInt.asUintN(64, result));
30
+ }
31
+ /**
32
+ * Subtraction with underflow handling (wraps around at 0)
33
+ * @param other - The value to subtract
34
+ * @returns New Uint64 instance with the result
35
+ */
36
+ sub(other) {
37
+ const result = this.value - other.value;
38
+ return new Uint64(BigInt.asUintN(64, result));
39
+ }
40
+ /**
41
+ * Left shift
42
+ * @param bits - Number of bits to shift left
43
+ * @returns New Uint64 instance with the result
44
+ */
45
+ shl(bits) {
46
+ if (bits < 0 || bits > 63) {
47
+ throw new Error("Shift amount must be between 0 and 63");
48
+ }
49
+ const result = this.value << BigInt(bits);
50
+ return new Uint64(BigInt.asUintN(64, result));
51
+ }
52
+ /**
53
+ * Right shift (logical, zero-fill)
54
+ * @param bits - Number of bits to shift right
55
+ * @returns New Uint64 instance with the result
56
+ */
57
+ shr(bits) {
58
+ if (bits < 0 || bits > 63) {
59
+ throw new Error("Shift amount must be between 0 and 63");
60
+ }
61
+ const result = this.value >> BigInt(bits);
62
+ return new Uint64(BigInt.asUintN(64, result));
63
+ }
64
+ /**
65
+ * Bitwise AND
66
+ * @param other - The value to AND with
67
+ * @returns New Uint64 instance with the result
68
+ */
69
+ and(other) {
70
+ const result = this.value & other.value;
71
+ return new Uint64(BigInt.asUintN(64, result));
72
+ }
73
+ /**
74
+ * Bitwise OR
75
+ * @param other - The value to OR with
76
+ * @returns New Uint64 instance with the result
77
+ */
78
+ or(other) {
79
+ const result = this.value | other.value;
80
+ return new Uint64(BigInt.asUintN(64, result));
81
+ }
82
+ /**
83
+ * Bitwise XOR
84
+ * @param other - The value to XOR with
85
+ * @returns New Uint64 instance with the result
86
+ */
87
+ xor(other) {
88
+ const result = this.value ^ other.value;
89
+ return new Uint64(BigInt.asUintN(64, result));
90
+ }
91
+ /**
92
+ * Bitwise complement (one's complement)
93
+ * @returns New Uint64 instance with the result
94
+ */
95
+ not() {
96
+ // For unsigned 64-bit, complement is ~value masked to 64 bits
97
+ const result = ~this.value;
98
+ return new Uint64(BigInt.asUintN(64, result));
99
+ }
100
+ /**
101
+ * Mask lower bits (equivalent to value & ((1 << bits) - 1))
102
+ * @param bits - Number of lower bits to keep
103
+ * @returns New Uint64 instance with the result
104
+ */
105
+ mask(bits) {
106
+ if (bits < 0 || bits > 64) {
107
+ throw new Error("Mask bits must be between 0 and 64");
108
+ }
109
+ if (bits === 64) {
110
+ return new Uint64(this.value);
111
+ }
112
+ const maskValue = (BigInt(1) << BigInt(bits)) - BigInt(1);
113
+ const result = this.value & maskValue;
114
+ return new Uint64(BigInt.asUintN(64, result));
115
+ }
116
+ /**
117
+ * Returns the value as a BigInt
118
+ * @returns The 64-bit unsigned value as BigInt
119
+ */
120
+ toBigInt() {
121
+ return this.value;
122
+ }
123
+ /**
124
+ * Returns the value as a number (with range check)
125
+ * @returns The value as number if it fits in Number.MAX_SAFE_INTEGER
126
+ * @throws Error if value exceeds Number.MAX_SAFE_INTEGER
127
+ */
128
+ toNumber() {
129
+ if (this.value > BigInt(Number.MAX_SAFE_INTEGER)) {
130
+ throw new Error(`Value ${this.value} exceeds Number.MAX_SAFE_INTEGER (${Number.MAX_SAFE_INTEGER})`);
131
+ }
132
+ return Number(this.value);
133
+ }
134
+ /**
135
+ * Returns the value as a string
136
+ * @returns String representation of the value
137
+ */
138
+ toString() {
139
+ return this.value.toString();
140
+ }
141
+ /**
142
+ * Equality comparison
143
+ * @param other - The value to compare with
144
+ * @returns True if values are equal
145
+ */
146
+ equals(other) {
147
+ return this.value === other.value;
148
+ }
149
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Utility functions for Uint8Array operations
3
+ */
4
+ /**
5
+ * Compares two Uint8Arrays for equality
6
+ *
7
+ * Simple and efficient byte-by-byte comparison. Optimized for small
8
+ * fixed-size arrays like trie keys (32 bytes) and extraBytes (24 bytes).
9
+ *
10
+ * @param a - First array to compare
11
+ * @param b - Second array to compare
12
+ * @returns true if arrays are equal, false otherwise
13
+ */
14
+ export declare function arraysEqual(a: Uint8Array, b: Uint8Array): boolean;
15
+ //# sourceMappingURL=arrays.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arrays.d.ts","sourceRoot":"","sources":["../../src/utils/arrays.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAUjE"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Utility functions for Uint8Array operations
3
+ */
4
+ /**
5
+ * Compares two Uint8Arrays for equality
6
+ *
7
+ * Simple and efficient byte-by-byte comparison. Optimized for small
8
+ * fixed-size arrays like trie keys (32 bytes) and extraBytes (24 bytes).
9
+ *
10
+ * @param a - First array to compare
11
+ * @param b - Second array to compare
12
+ * @returns true if arrays are equal, false otherwise
13
+ */
14
+ export function arraysEqual(a, b) {
15
+ if (a.length !== b.length) {
16
+ return false;
17
+ }
18
+ for (let i = 0; i < a.length; i++) {
19
+ if (a[i] !== b[i]) {
20
+ return false;
21
+ }
22
+ }
23
+ return true;
24
+ }