From 8e12083c9d3a1ef6ae964ff117545e859cdf5f51 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Mon, 12 Feb 2024 13:17:15 -0600 Subject: [PATCH] hookup groth16 verifier types --- codex/slots/proofs/backends/circomcompat.nim | 27 +++----- codex/slots/proofs/backends/converters.nim | 70 ++++++++++++++++++++ codex/slots/proofs/prover.nim | 20 +++--- 3 files changed, 90 insertions(+), 27 deletions(-) create mode 100644 codex/slots/proofs/backends/converters.nim diff --git a/codex/slots/proofs/backends/circomcompat.nim b/codex/slots/proofs/backends/circomcompat.nim index 780921ca..43e4213a 100644 --- a/codex/slots/proofs/backends/circomcompat.nim +++ b/codex/slots/proofs/backends/circomcompat.nim @@ -20,8 +20,11 @@ import ../../types import ../../../stores import ../../../merkletree import ../../../codextypes +import ../../../contracts -export circomcompat +import ./converters + +export circomcompat, converters type CircomCompat* = object @@ -35,13 +38,6 @@ type zKeyPath : string # path to the zkey file backendCfg : ptr CircomBn254Cfg - CircomG1* = G1 - CircomG2* = G2 - - CircomProof* = Proof - CircomKey* = VerifyingKey - CircomInputs* = Inputs - proc release*(self: CircomCompat) = ## Release the backend ## @@ -64,7 +60,7 @@ proc getVerifyingKey*( proc prove*[H]( self: CircomCompat, - input: ProofInput[H]): ?!CircomProof = + input: ProofInputs[H]): ?!CircomProof = ## Encode buffers using a backend ## @@ -175,20 +171,19 @@ proc prove*[H]( success proof -proc verify*( +proc verify*[H]( self: CircomCompat, proof: CircomProof, - inputs: CircomInputs, - vkp: CircomKey): ?!bool = + inputs: ProofInputs[H]): ?!bool = ## Verify a proof using a backend ## var - proofPtr : ptr Proof = unsafeAddr proof - inputsPtr: ptr Inputs = unsafeAddr inputs - vpkPtr: ptr CircomKey = unsafeAddr vkp + proofPtr = unsafeAddr proof + inputs = inputs.toCircomInputs() + vkpPtr = ? self.getVerifyingKey() - let res = verifyCircuit(proofPtr, inputsPtr, vpkPtr) + let res = verifyCircuit(proofPtr, inputs.addr, vkpPtr) if res == ERR_OK: success true elif res == ERR_FAILED_TO_VERIFY_PROOF: diff --git a/codex/slots/proofs/backends/converters.nim b/codex/slots/proofs/backends/converters.nim new file mode 100644 index 00000000..be5695c3 --- /dev/null +++ b/codex/slots/proofs/backends/converters.nim @@ -0,0 +1,70 @@ +## Nim-Codex +## Copyright (c) 2024 Status Research & Development GmbH +## Licensed under either of +## * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE)) +## * MIT license ([LICENSE-MIT](LICENSE-MIT)) +## at your option. +## This file may not be copied, modified, or distributed except according to +## those terms. + +{.push raises: [].} + +import pkg/circomcompat + +import ../../../contracts + +import ../../types + +type + CircomG1* = G1 + CircomG2* = G2 + + CircomProof* = Proof + CircomKey* = VerifyingKey + CircomInputs* = Inputs + +proc toCircomInputs*[H](inputs: ProofInputs[H]): CircomInputs = + 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 releaseCircomInputs*(inputs: var CircomInputs) = + if not inputs.elms.isNil: + deallocShared(inputs.elms) + inputs.elms = nil + +func toG1*(g: CircomG1): G1Point = + G1Point( + x: UInt256.fromBytesLE(g.x), + y: UInt256.fromBytesLE(g.y)) + +func toG2*(g: CircomG2): G2Point = + G2Point( + x: [ + UInt256.fromBytesLE(g.x[0]), + UInt256.fromBytesLE(g.x[1]) + ], + y: [ + UInt256.fromBytesLE(g.y[0]), + UInt256.fromBytesLE(g.y[1]) + ]) + +func toGroth16Proof*(proof: CircomProof): Groth16Proof = + Groth16Proof( + a: proof.a.toG1, + b: proof.b.toG2, + c: proof.c.toG1) diff --git a/codex/slots/proofs/prover.nim b/codex/slots/proofs/prover.nim index 764dcf8e..6288baec 100644 --- a/codex/slots/proofs/prover.nim +++ b/codex/slots/proofs/prover.nim @@ -31,14 +31,13 @@ import ../types export backends type - AnyProof* = CircomProof - AnyInputs* = CircomInputs - AnyKeys* = CircomKey - AnyHash* = Poseidon2Hash AnyBackend* = CircomCompat - AnyBuilder* = Poseidon2Builder - AnySampler* = Poseidon2Sampler + AnyProof* = CircomProof + AnySampler* = Poseidon2Sampler + AnyBuilder* = Poseidon2Builder + + AnyProofInputs* = ProofInputs[Poseidon2Hash] Prover* = ref object of RootObj backend: AnyBackend store: BlockStore @@ -48,7 +47,7 @@ proc prove*( self: Prover, slotIdx: int, manifest: Manifest, - challenge: ProofChallenge): Future[?!AnyProof] {.async.} = + challenge: ProofChallenge): Future[?!(AnyProofInputs, AnyProof)] {.async.} = ## Prove a statement using backend. ## Returns a future that resolves to a proof. @@ -76,17 +75,16 @@ proc prove*( error "Unable to prove slot", err = err.msg return failure(err) - success proof + success (proofInput, proof) proc verify*( self: Prover, proof: AnyProof, - inputs: AnyInputs, - vpk: AnyKeys): Future[?!bool] {.async.} = + inputs: AnyProofInputs): Future[?!bool] {.async.} = ## Prove a statement using backend. ## Returns a future that resolves to a proof. - self.backend.verify(proof, inputs, vpk) + self.backend.verify(proof, inputs) proc new*( _: type Prover,