From 018be61ebc9ede709101bc7d3ed6efc970099e6b Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Fri, 10 May 2024 22:47:39 +0300 Subject: [PATCH] import circom helpers --- benchmarks/circom_ark_prover_cli.nim | 160 +++++++++++++-------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/benchmarks/circom_ark_prover_cli.nim b/benchmarks/circom_ark_prover_cli.nim index 737056fd..5f065190 100644 --- a/benchmarks/circom_ark_prover_cli.nim +++ b/benchmarks/circom_ark_prover_cli.nim @@ -13,15 +13,15 @@ import pkg/constantine/math/[arithmetic, io/io_bigints, io/io_fields] import ./utils import ./create_circuits -type CircuitFiles* = object +type CircomCircuit* = object r1cs*: string wasm*: string zkey*: string inputs*: string dir*: string circName*: string - backendCfg : ptr CircomBn254Cfg - vkp* : ptr VerifyingKey + backendCfg: ptr CircomBn254Cfg + vkp*: ptr VerifyingKey proc release*(self: CircomCompat) = ## Release the ctx @@ -33,9 +33,7 @@ proc release*(self: CircomCompat) = if not isNil(self.vkp): self.vkp.unsafeAddr.release_key() -proc prove*[H]( - self: CircomCompat, - input: ProofInputs[H]): ?!CircomProof = +proc prove*[H](self: CircomCompat, input: ProofInputs[H]): ?!CircomProof = ## Encode buffers using a ctx ## @@ -44,28 +42,27 @@ proc prove*[H]( # to the circom ffi - `setLen` is used to adjust the # sequence length to the correct size which also 0 pads # to the correct length - doAssert input.samples.len == self.numSamples, - "Number of samples does not match" + doAssert input.samples.len == self.numSamples, "Number of samples does not match" doAssert input.slotProof.len <= self.datasetDepth, "Number of slot proofs does not match" doAssert input.samples.allIt( block: - (it.merklePaths.len <= self.slotDepth + self.blkDepth and - it.cellData.len <= self.cellElms * 32)), "Merkle paths length does not match" + ( + it.merklePaths.len <= self.slotDepth + self.blkDepth and + it.cellData.len <= self.cellElms * 32 + ) + ), "Merkle paths length does not match" # TODO: All parameters should match circom's static parametter - var - ctx: ptr CircomCompatCtx + var ctx: ptr CircomCompatCtx defer: if ctx != nil: ctx.addr.releaseCircomCompat() - if initCircomCompat( - self.backendCfg, - addr ctx) != ERR_OK or ctx == nil: + if initCircomCompat(self.backendCfg, addr ctx) != ERR_OK or ctx == nil: raiseAssert("failed to initialize CircomCompat ctx") var @@ -73,70 +70,62 @@ proc prove*[H]( dataSetRoot = input.datasetRoot.toBytes slotRoot = input.slotRoot.toBytes - if ctx.pushInputU256Array( - "entropy".cstring, entropy[0].addr, entropy.len.uint32) != ERR_OK: + if ctx.pushInputU256Array("entropy".cstring, entropy[0].addr, entropy.len.uint32) != + ERR_OK: return failure("Failed to push entropy") if ctx.pushInputU256Array( - "dataSetRoot".cstring, dataSetRoot[0].addr, dataSetRoot.len.uint32) != ERR_OK: + "dataSetRoot".cstring, dataSetRoot[0].addr, dataSetRoot.len.uint32 + ) != ERR_OK: return failure("Failed to push data set root") - if ctx.pushInputU256Array( - "slotRoot".cstring, slotRoot[0].addr, slotRoot.len.uint32) != ERR_OK: + if ctx.pushInputU256Array("slotRoot".cstring, slotRoot[0].addr, slotRoot.len.uint32) != + ERR_OK: return failure("Failed to push data set root") - if ctx.pushInputU32( - "nCellsPerSlot".cstring, input.nCellsPerSlot.uint32) != ERR_OK: + if ctx.pushInputU32("nCellsPerSlot".cstring, input.nCellsPerSlot.uint32) != ERR_OK: return failure("Failed to push nCellsPerSlot") - if ctx.pushInputU32( - "nSlotsPerDataSet".cstring, input.nSlotsPerDataSet.uint32) != ERR_OK: + if ctx.pushInputU32("nSlotsPerDataSet".cstring, input.nSlotsPerDataSet.uint32) != + ERR_OK: return failure("Failed to push nSlotsPerDataSet") - if ctx.pushInputU32( - "slotIndex".cstring, input.slotIndex.uint32) != ERR_OK: + if ctx.pushInputU32("slotIndex".cstring, input.slotIndex.uint32) != ERR_OK: return failure("Failed to push slotIndex") - var - slotProof = input.slotProof.mapIt( it.toBytes ).concat + var slotProof = input.slotProof.mapIt(it.toBytes).concat slotProof.setLen(self.datasetDepth) # zero pad inputs to correct size # arrays are always flattened if ctx.pushInputU256Array( - "slotProof".cstring, - slotProof[0].addr, - uint (slotProof[0].len * slotProof.len)) != ERR_OK: - return failure("Failed to push slot proof") + "slotProof".cstring, slotProof[0].addr, uint (slotProof[0].len * slotProof.len) + ) != ERR_OK: + return failure("Failed to push slot proof") for s in input.samples: var - merklePaths = s.merklePaths.mapIt( it.toBytes ) + merklePaths = s.merklePaths.mapIt(it.toBytes) data = s.cellData merklePaths.setLen(self.slotDepth) # zero pad inputs to correct size if ctx.pushInputU256Array( "merklePaths".cstring, merklePaths[0].addr, - uint (merklePaths[0].len * merklePaths.len)) != ERR_OK: - return failure("Failed to push merkle paths") + uint (merklePaths[0].len * merklePaths.len), + ) != ERR_OK: + return failure("Failed to push merkle paths") data.setLen(self.cellElms * 32) # zero pad inputs to correct size - if ctx.pushInputU256Array( - "cellData".cstring, - data[0].addr, - data.len.uint) != ERR_OK: - return failure("Failed to push cell data") + if ctx.pushInputU256Array("cellData".cstring, data[0].addr, data.len.uint) != ERR_OK: + return failure("Failed to push cell data") - var - proofPtr: ptr Proof = nil + var proofPtr: ptr Proof = nil let proof = try: - if ( - let res = self.backendCfg.proveCircuit(ctx, proofPtr.addr); - res != ERR_OK) or - proofPtr == nil: + if (let res = self.backendCfg.proveCircuit(ctx, proofPtr.addr); res != ERR_OK) or + proofPtr == nil: return failure("Failed to prove - err code: " & $res) proofPtr[] @@ -146,10 +135,20 @@ proc prove*[H]( success proof -proc verify*[H]( - self: CircomCompat, - proof: CircomProof, - inputs: ProofInputs[H]): ?!bool = +proc toCircomInputs*(inputs: ProofInputs[Poseidon2Hash]): Inputs = + var + slotIndex = inputs.slotIndex.toF.toBytes.toArray32 + datasetRoot = inputs.datasetRoot.toBytes.toArray32 + entropy = inputs.entropy.toBytes.toArray32 + + elms = [entropy, datasetRoot, slotIndex] + + let inputsPtr = allocShared0(32 * elms.len) + copyMem(inputsPtr, addr elms[0], elms.len * 32) + + CircomInputs(elms: cast[ptr array[32, byte]](inputsPtr), len: elms.len.uint) + +proc verify*(self: CircomCompat, proof: CircomProof, inputs: ProofInputs[H]): ?!bool = ## Verify a proof using a ctx ## @@ -169,49 +168,50 @@ proc verify*[H]( inputs.releaseCircomInputs() proc init*( - _: type CircomCompat, - r1csPath : string, - wasmPath : string, - zkeyPath : string = "", - slotDepth = DefaultMaxSlotDepth, - datasetDepth = DefaultMaxDatasetDepth, - blkDepth = DefaultBlockDepth, - cellElms = DefaultCellElms, - numSamples = DefaultSamplesNum): CircomCompat = + _: type CircomCompat, + r1csPath: string, + wasmPath: string, + zkeyPath: string = "", + slotDepth = DefaultMaxSlotDepth, + datasetDepth = DefaultMaxDatasetDepth, + blkDepth = DefaultBlockDepth, + cellElms = DefaultCellElms, + numSamples = DefaultSamplesNum, +): CircomCompat = ## Create a new ctx ## var cfg: ptr CircomBn254Cfg var zkey = if zkeyPath.len > 0: zkeyPath.cstring else: nil - if initCircomConfig( - r1csPath.cstring, - wasmPath.cstring, - zkey, cfg.addr) != ERR_OK or cfg == nil: - if cfg != nil: cfg.addr.releaseCfg() - raiseAssert("failed to initialize circom compat config") + if initCircomConfig(r1csPath.cstring, wasmPath.cstring, zkey, cfg.addr) != ERR_OK or + cfg == nil: + if cfg != nil: + cfg.addr.releaseCfg() + raiseAssert("failed to initialize circom compat config") - var - vkpPtr: ptr VerifyingKey = nil + var vkpPtr: ptr VerifyingKey = nil if cfg.getVerifyingKey(vkpPtr.addr) != ERR_OK or vkpPtr == nil: - if vkpPtr != nil: vkpPtr.addr.releaseKey() + if vkpPtr != nil: + vkpPtr.addr.releaseKey() raiseAssert("Failed to get verifying key") CircomCompat( - r1csPath : r1csPath, - wasmPath : wasmPath, - zkeyPath : zkeyPath, - slotDepth : slotDepth, + r1csPath: r1csPath, + wasmPath: wasmPath, + zkeyPath: zkeyPath, + slotDepth: slotDepth, datasetDepth: datasetDepth, - blkDepth : blkDepth, - cellElms : cellElms, - numSamples : numSamples, - backendCfg : cfg, - vkp : vkpPtr) + blkDepth: blkDepth, + cellElms: cellElms, + numSamples: numSamples, + backendCfg: cfg, + vkp: vkpPtr, + ) proc runArkCircom( - args: CircuitArgs, files: CircuitFiles, proofInputs: ProofInputs[Poseidon2Hash] + args: CircuitArgs, files: CircomCircuit, proofInputs: ProofInputs[Poseidon2Hash] ) = echo "Loading sample proof..." var circom = CircomCompat.init( @@ -250,7 +250,7 @@ proc printHelp() = quit(1) -proc parseCliOptions(args: var CircuitArgs, files: var CircuitFiles) = +proc parseCliOptions(args: var CircuitArgs, files: var CircomCircuit) = var argCtr: int = 0 template expectPath(val: string): string = if val == "": @@ -299,7 +299,7 @@ proc run*() = var args = CircuitArgs() - files = CircuitFiles() + files = CircomCircuit() parseCliOptions(args, files)