@chainsafe/persistent-merkle-tree
Version:
Merkle tree implemented as a persistent datastructure
51 lines • 2.19 kB
JavaScript
import { sha256 } from "@noble/hashes/sha256";
import { digest64HashObjects, byteArrayIntoHashObject } from "@chainsafe/as-sha256";
import { BLOCK_SIZE, doDigestNLevel, doMerkleizeBlockArray, doMerkleizeBlocksBytes, hashObjectToUint8Array, } from "./util.js";
const digest64 = (a, b) => sha256.create().update(a).update(b).digest();
const hashInto = (input, output) => {
if (input.length % 64 !== 0) {
throw new Error(`Invalid input length ${input.length}`);
}
if (input.length !== output.length * 2) {
throw new Error(`Invalid output length ${output.length}`);
}
const count = Math.floor(input.length / 64);
for (let i = 0; i < count; i++) {
const offset = i * 64;
const in1 = input.subarray(offset, offset + 32);
const in2 = input.subarray(offset + 32, offset + 64);
const out = digest64(in1, in2);
output.set(out, i * 32);
}
};
/** should be multiple of 64, make it the same to as-sha256 */
const buffer = new Uint8Array(4 * BLOCK_SIZE);
export const hasher = {
name: "noble",
digest64,
digest64HashObjects: (left, right, parent) => {
byteArrayIntoHashObject(digest64(hashObjectToUint8Array(left), hashObjectToUint8Array(right)), 0, parent);
},
merkleizeBlocksBytes(blocksBytes, padFor, output, offset) {
return doMerkleizeBlocksBytes(blocksBytes, padFor, output, offset, hashInto);
},
merkleizeBlockArray(blocks, blockLimit, padFor, output, offset) {
return doMerkleizeBlockArray(blocks, blockLimit, padFor, output, offset, hashInto, buffer);
},
digestNLevel(data, nLevel) {
return doDigestNLevel(data, nLevel, hashInto);
},
executeHashComputations: (hashComputations) => {
for (let level = hashComputations.length - 1; level >= 0; level--) {
const hcArr = hashComputations[level];
if (!hcArr) {
// should not happen
throw Error(`no hash computations for level ${level}`);
}
for (const hc of hcArr) {
hc.dest.applyHash(digest64HashObjects(hc.src0, hc.src1));
}
}
},
};
//# sourceMappingURL=noble.js.map