@nori-zk/ethprocessor
Version:
zkApp for verifying SP1 Helios Nori proof and storing latest execution state root on Mina
81 lines (80 loc) • 3.66 kB
JavaScript
import { Field, Poseidon, Provable, Struct, UInt64, ZkProgram, } from 'o1js';
import { DynamicArray } from 'mina-attestations';
import { computeMerkleTreeDepthAndSize, getMerklePathFromLeaves as getMerklePathFromLeavesInner, getMerkleZeros, } from './merkleTree.js';
export function merkleLeafAttestorGenerator(// extends Struct<any>
treeDepth, name, provableLeafType, leafContentsHasher) {
const MerklePath = DynamicArray(Field, { maxLength: treeDepth });
class MerkleTreeLeafAttestorInput extends Struct({
rootHash: Field,
path: MerklePath,
index: UInt64,
value: provableLeafType,
}) {
}
const MerkleTreeLeafAttestor = ZkProgram({
name: name,
publicInput: MerkleTreeLeafAttestorInput,
publicOutput: Field,
methods: {
compute: {
privateInputs: [],
async method(input) {
let { index, path, rootHash } = input; // value
let currentHash = leafContentsHasher(input.value);
/*Provable.asProver(() => {
Provable.log(`Finding index i ${index}`);
});
Provable.asProver(() => {
Provable.log(`Generated hash of value ${currentHash}`);
});*/
const bitPath = index.value.toBits(path.maxLength);
path.forEach((sibling, isDummy, i) => {
const bit = bitPath[i];
/*Provable.asProver(() => {
Provable.log(
`Path index i ${i}, bit ${bit}, bit path ${bitPath.map(
(i) => (i.toBoolean() ? 1 : 0)
)} isDummy ${isDummy}`
);
});*/
const left = Provable.if(bit, Field, sibling, currentHash);
const right = Provable.if(bit, Field, currentHash, sibling);
const nextHash = Poseidon.hash([left, right]);
/*Provable.asProver(() => {
Provable.log(
`Path index i ${i}, left ${left}, right ${right}`
);
});*/
currentHash = Provable.if(isDummy, Field, currentHash, nextHash);
});
/*Provable.asProver(() => {
Provable.log(
`Got to assert root ${rootHash}, current ${currentHash}`
);
});*/
currentHash.assertEquals(rootHash);
return { publicOutput: currentHash };
},
},
},
});
function buildLeaves(leafContents) {
return leafContents.map((leaf) => leafContentsHasher(leaf));
}
function getMerklePathFromLeaves(merkleLeaves, index) {
const nLeaves = merkleLeaves.length;
const { depth, paddedSize } = computeMerkleTreeDepthAndSize(nLeaves);
const path = getMerklePathFromLeavesInner(merkleLeaves, paddedSize, depth, index, getMerkleZeros(depth));
const merklePath = MerklePath.from([]);
path.forEach((element) => merklePath.push(element));
return merklePath;
}
const inputs = MerkleTreeLeafAttestorInput;
return {
MerkleTreeLeafAttestorInput: inputs,
MerkleTreeLeafAttestor,
buildLeaves,
getMerklePathFromLeaves,
};
}
//# sourceMappingURL=merkleLeafAttestor.js.map