UNPKG

@nori-zk/o1js-zk-utils

Version:

o1js-zk-utils supporting Nori Bridge

87 lines (86 loc) 3.98 kB
import { Field, Poseidon, Provable, Struct, UInt64, ZkProgram, } from 'o1js'; import { DynamicArray } from '@nori-zk/mina-attestations/dynamic/array'; 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({ path: MerklePath, index: UInt64, value: provableLeafType, }) { } const MerkleTreeLeafAttestor = ZkProgram({ name: name, publicInput: MerkleTreeLeafAttestorInput, publicOutput: Field, methods: { compute: { privateInputs: [], async method(input) { let { index, path } = input; 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}` ); });*/ /*Provable.asProver(() => { Provable.log( nextHash.toBigInt(), currentHash.toBigInt(), isDummy.toBoolean() ); });*/ currentHash = Provable.if(isDummy, Field, currentHash, nextHash); }); /*Provable.asProver(() => { Provable.log( `Computed root: ${currentHash}` ); });*/ 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; class MerkleTreeLeafAttestorProofTyped extends ZkProgram.Proof(MerkleTreeLeafAttestor) { } return { MerkleTreeLeafAttestorInput: inputs, MerkleTreeLeafAttestor, MerkleTreeLeafAttestorProof: MerkleTreeLeafAttestorProofTyped, buildLeaves, getMerklePathFromLeaves, }; } //# sourceMappingURL=merkleLeafAttestor.js.map