Skip to content

Commit a52c20a

Browse files
committed
#134 Update smt utils calculations
1 parent ae451a9 commit a52c20a

2 files changed

Lines changed: 22 additions & 11 deletions

File tree

src/api/InclusionCertificate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export class InclusionCertificate {
5050
const sibling = isRight ? node.left : node.right;
5151

5252
if (sibling != null) {
53-
bitmap[Math.floor(node.depth / 8)] |= 0x80 >> (node.depth % 8);
53+
bitmap[node.depth >> 3] |= 0x80 >> (node.depth & 7);
5454
siblings.push(sibling.hash);
5555
}
5656

src/smt/SparseMerkleTreePathUtils.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,31 @@
55
* branch (its stored region is only meaningful up to that depth).
66
*/
77
export function commonPrefixLength(a: Uint8Array, b: Uint8Array, maxDepth: number): number {
8-
let length = 0;
9-
while (length < maxDepth && getBitAtDepth(a, length) === getBitAtDepth(b, length)) {
10-
length += 1;
8+
const fullBytes = maxDepth >> 3;
9+
for (let i = 0; i < fullBytes; i++) {
10+
if (a[i] !== b[i]) {
11+
return (i << 3) + Math.clz32(a[i] ^ b[i]) - 24;
12+
}
1113
}
12-
return length;
14+
15+
const remainderBits = maxDepth & 7;
16+
if (remainderBits > 0) {
17+
const diff = (a[fullBytes] ^ b[fullBytes]) & (0xff << (8 - remainderBits));
18+
if (diff !== 0) {
19+
return (fullBytes << 3) + Math.clz32(diff) - 24;
20+
}
21+
}
22+
23+
return maxDepth;
1324
}
1425

1526
/**
1627
* The key's first `depth` bits, with the remaining bits of the 32-byte array zeroed.
1728
*/
1829
export function regionFromKey(key: Uint8Array, depth: number): Uint8Array {
1930
const region = new Uint8Array(32);
20-
const fullBytes = Math.floor(depth / 8);
21-
const remainderBits = depth % 8;
31+
const fullBytes = depth >> 3;
32+
const remainderBits = depth & 7;
2233
region.set(key.subarray(0, fullBytes));
2334
if (remainderBits > 0) {
2435
region[fullBytes] = key[fullBytes] & ((0xff << (8 - remainderBits)) & 0xff);
@@ -35,8 +46,8 @@ export function getBitAtDepth(data: Uint8Array, depth: number): number {
3546
if (!Number.isInteger(depth) || depth < 0 || depth >= data.length * 8) {
3647
throw new Error(`Depth ${depth} is out of bounds for a ${data.length}-byte value.`);
3748
}
38-
const byteIndex = Math.floor(depth / 8);
39-
const bitInByte = depth % 8;
49+
const byteIndex = depth >> 3;
50+
const bitInByte = depth & 7;
4051
return (data[byteIndex] >> (7 - bitInByte)) & 1;
4152
}
4253

@@ -48,8 +59,8 @@ export function bitsToString(data: Uint8Array, length: number): string {
4859
if (!Number.isInteger(length) || length < 0 || length > data.length * 8) {
4960
throw new Error(`Length ${length} is out of bounds for a ${data.length}-byte value.`);
5061
}
51-
const fullBytes = Math.floor(length / 8);
52-
const remainderBits = length % 8;
62+
const fullBytes = length >> 3;
63+
const remainderBits = length & 7;
5364
let bits = '';
5465
for (let i = 0; i < fullBytes; i++) {
5566
bits += data[i].toString(2).padStart(8, '0');

0 commit comments

Comments
 (0)