Skip to content

Commit

Permalink
feat: add hashtree hasher
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewkeil committed Jun 7, 2024
1 parent 6e43d5e commit 750d1c7
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
6 changes: 6 additions & 0 deletions packages/persistent-merkle-tree/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@
"homepage": "https://github.com/ChainSafe/persistent-merkle-tree#readme",
"dependencies": {
"@chainsafe/as-sha256": "0.4.2",
"@chainsafe/hashtree": "1.0.0",
"@noble/hashes": "^1.3.0"
},
"peerDependencies": {
"@chainsafe/hashtree-linux-x64-gnu": "1.0.0",
"@chainsafe/hashtree-linux-arm64-gnu": "1.0.0",
"@chainsafe/hashtree-darwin-arm64": "1.0.0"
}
}
44 changes: 43 additions & 1 deletion packages/persistent-merkle-tree/src/hasher/hashtree.ts
Original file line number Diff line number Diff line change
@@ -1 +1,43 @@
// TODO - batch: use @chainsafe/hashtree
import {hash} from "@chainsafe/hashtree";
import {byteArrayToHashObject, hashObjectToByteArray} from "@chainsafe/as-sha256";
import {Hasher, HashObject} from "./types";
import {HashComputation, Node} from "../node";

export const hasher: Hasher = {
digest64(obj1: Uint8Array, obj2: Uint8Array): Uint8Array {
return hash(Uint8Array.of(obj1, obj2));
},
digest64HashObjects(obj1: HashObject, obj2: HashObject): HashObject {
return byteArrayToHashObject(hasher.digest64(hashObjectToByteArray(obj1), hashObjectToByteArray(obj2)));
},
// eslint-disable-next-line @typescript-eslint/no-unused-vars
batchHashObjects(inputs: HashObject[]): HashObject[] {
throw new Error("batchHashObjects not implemented for hashtree hasher");
},
executeHashComputations(hashComputations: Array<HashComputation[]>): void {
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}`);
}

// size input array to 2 HashObject per computation * 32 bytes per object
const input: Uint8Array = Uint8Array.of(new Array(hcArr.length * 2 * 32));
const output: Node[] = [];
for (const [i, hc] of hcArr.entries()) {
const offset = (i - 1) * 64; // zero index * 2 leafs * 32 bytes
hashObjectToByteArray(hc.src0, input, offset);
hashObjectToByteArray(hc.src1, input, offset + 32);
output.push(hc.dest);
}

const result: Uint8Array = hash(input);

for (const [i, out] of output.entries()) {
const offset = (i - 1) * 32;
out.applyHash(result.slice(offset, offset + 32));
}
}
},
};

0 comments on commit 750d1c7

Please sign in to comment.