wip rework backend

This commit is contained in:
Dmitriy Ryajov 2024-01-26 19:53:11 -06:00
parent 0d3b18cb5e
commit b0e5058d45
No known key found for this signature in database
GPG Key ID: DA8C680CE7C657A4
2 changed files with 102 additions and 79 deletions

View File

@ -17,49 +17,70 @@ import pkg/circomcompat
import ../../../stores
import ../../types
import ../../../merkletree
export circomcompat
type
CircomCompat*[H, P] = ref object of RootObj
r1csPath : string
wasmPath : string
zKeyPath : string
backend : ptr CircomCompatCtx
CircomCompat* = object
r1csPath : string
wasmPath : string
zKeyPath : string
backendCfg : ptr CircomBn254Cfg
proc release*[H, P](self: CircomCompat[H, P]) =
CircomProof* = object
proof*: Proof
backend: ptr CircomCompatCtx
cfg: ptr CircomBn254Cfg
proc release*(self: CircomCompat) =
## Release the backend
##
self.backend.addr.releaseCircomCompat()
self.backendCfg.unsafeAddr.releaseCfg()
proc prove*[H, P](
self: CircomCompat[H, P],
input: ProofInput[H]): Future[?!P] {.async.} =
proc release*(proof: CircomProof) =
## Release the backend context
##
proof.backend.unsafeAddr.release_circom_compat()
doAssert(proof.backend == nil)
proc prove*(
self: CircomCompat,
input: ProofInput[Poseidon2Hash]): ?!CircomProof =
## Encode buffers using a backend
##
var
backend: ptr CircomCompatCtx
if initCircomCompat(
self.backendCfg,
addr backend) != ERR_OK or backend == nil:
raiseAssert("failed to initialize CircomCompat backend")
var
entropy = input.entropy.toBytes
verifyRoot = input.verifyRoot.toBytes
if self.backend.pushInputU256Array(
if backend.pushInputU256Array(
"entropy".cstring, entropy.addr, entropy.len.uint32) != ERR_OK:
return failure("Failed to push entropy")
if self.backend.pushInputU256Array(
if backend.pushInputU256Array(
"dataSetRoot".cstring, verifyRoot.addr, verifyRoot.len.uint32) != ERR_OK:
return failure("Failed to push data set root")
if self.backend.pushInputU32(
if backend.pushInputU32(
"nCellsPerSlot".cstring, input.numCells.uint32) != ERR_OK:
return failure("Failed to push nCellsPerSlot")
if self.backend.pushInputU32(
if backend.pushInputU32(
"nSlotsPerDataSet".cstring, input.numSlots.uint32) != ERR_OK:
return failure("Failed to push nSlotsPerDataSet")
if self.backend.pushInputU32(
if backend.pushInputU32(
"slotIndex".cstring, input.slotIndex.uint32) != ERR_OK:
return failure("Failed to push slotIndex")
@ -67,7 +88,7 @@ proc prove*[H, P](
slotProof = input.verifyProof.mapIt( it.toBytes ).concat
# arrays are always flattened
if self.backend.pushInputU256Array(
if backend.pushInputU256Array(
"slotProof".cstring,
slotProof.addr,
uint input.verifyProof.len) != ERR_OK:
@ -78,13 +99,13 @@ proc prove*[H, P](
merklePaths = s.merkleProof.mapIt( it.toBytes ).concat
data = s.data
if self.backend.pushInputU256Array(
if backend.pushInputU256Array(
"merklePaths".cstring,
merklePaths[0].addr,
uint merklePaths.len) != ERR_OK:
return failure("Failed to push merkle paths")
if self.backend.pushInputU256Array(
if backend.pushInputU256Array(
"cellData".cstring,
data[0].addr,
uint data.len) != ERR_OK:
@ -93,21 +114,23 @@ proc prove*[H, P](
var
proofPtr: ptr Proof = nil
let
proof =
try:
if self.backend.proveCircuit(proofPtr.addr) != ERR_OK or
proofPtr == nil:
return failure("Failed to prove")
let proof =
try:
if self.backendCfg.proveCircuit(backend, proofPtr.addr) != ERR_OK or
proofPtr == nil:
return failure("Failed to prove")
proofPtr[]
finally:
if proofPtr != nil:
release_proof(proofPtr.addr)
proofPtr[]
finally:
if proofPtr != nil:
release_proof(proofPtr.addr)
success proof
success CircomProof(
proof: proof,
cfg: self.backendCfg,
backend: backend)
proc verify*[H, P](self: CircomCompat[H, P], proof: P): Future[?!bool] {.async.} =
proc verify*(proof: CircomProof): ?!bool =
## Verify a proof using a backend
##
@ -115,16 +138,16 @@ proc verify*[H, P](self: CircomCompat[H, P], proof: P): Future[?!bool] {.async.}
inputsPtr: ptr Inputs = nil
vkPtr: ptr VerifyingKey = nil
if (let res = self.backend.getVerifyingKey(vkPtr.addr); res != ERR_OK) or
if (let res = proof.cfg.getVerifyingKey(vkPtr.addr); res != ERR_OK) or
vkPtr == nil:
return failure("Failed to get verifying key - err code: " & $res)
if (let res = self.backend.getPubInputs(inputsPtr.addr); res != ERR_OK) or
if (let res = proof.backend.getPubInputs(inputsPtr.addr); res != ERR_OK) or
inputsPtr == nil:
return failure("Failed to get public inputs - err code: " & $res)
try:
let res = verifyCircuit(proof.unsafeAddr, inputsPtr, vkPtr)
let res = verifyCircuit(proof.proof.unsafeAddr, inputsPtr, vkPtr)
if res == ERR_OK:
success true
elif res == ERR_FAILED_TO_VERIFY_PROOF:
@ -139,24 +162,24 @@ proc verify*[H, P](self: CircomCompat[H, P], proof: P): Future[?!bool] {.async.}
if vkPtr != nil:
releaseKey(vkPtr.addr)
proc new*[H, P](
_: type CircomCompat[H, P],
proc init*(
_: type CircomCompat,
r1csPath: string,
wasmPath: string,
zKeyPath: string = ""): CircomCompat[H, P] =
zKeyPath: string = ""): CircomCompat =
## Create a new backend
##
var backend: ptr CircomCompatCtx
if initCircomCompat(
var cfg: ptr CircomBn254Cfg
if initCircomConfig(
r1csPath.cstring,
wasmPath.cstring,
if zKeyPath.len > 0: zKeyPath.cstring else: nil,
addr backend) != ERR_OK or backend == nil:
raiseAssert("failed to initialize CircomCompat backend")
addr cfg) != ERR_OK or cfg == nil:
raiseAssert("failed to initialize circom compat config")
CircomCompat[H, P](
CircomCompat(
r1csPath: r1csPath,
wasmPath: wasmPath,
zKeyPath: zKeyPath,
backend: backend)
backendCfg: cfg)

View File

@ -1,46 +1,46 @@
## 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.
##
# ## 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.
# ##
import pkg/chronos
import pkg/circomcompat
import pkg/poseidon2
import pkg/questionable/results
# import pkg/chronos
# import pkg/circomcompat
# import pkg/poseidon2
# import pkg/questionable/results
import ../../merkletree
# import ../../merkletree
import ./backends
import ../types
# import ./backends
# import ../types
type
Prover*[HashT, ProofT, BackendT] = ref object of RootObj
backend: BackendT
# type
# Prover*[HashT, ProofT, BackendT] = ref object of RootObj
# backend: BackendT
AnyProof* = Proof
AnyHash* = Poseidon2Hash
AnyProverBacked* = CircomCompat[AnyHash, AnyProof]
AnyProver* = Prover[AnyHash, AnyProof, AnyProverBacked]
# AnyProof* = Proof
# AnyHash* = Poseidon2Hash
# AnyProverBacked* = CircomCompat
# AnyProver* = Prover[AnyHash, AnyProof, AnyProverBacked]
proc prove*(
self: AnyProver,
input: ProofInput[AnyHash]): Future[?!AnyProof] {.async.} =
## Prove a statement using backend.
## Returns a future that resolves to a proof.
# proc prove*(
# self: AnyProver,
# input: ProofInput[AnyHash]): Future[?!AnyProof] {.async.} =
# ## Prove a statement using backend.
# ## Returns a future that resolves to a proof.
## TODO: implement
await self.backend.prove(input)
# ## TODO: implement
# # discard self.backend.prove(input)
proc verify*(
self: AnyProver,
proof: AnyProof): Future[?!bool] {.async.} =
## Prove a statement using backend.
## Returns a future that resolves to a proof.
# proc verify*(
# self: AnyProver,
# proof: AnyProof): Future[?!bool] {.async.} =
# ## Prove a statement using backend.
# ## Returns a future that resolves to a proof.
## TODO: implement
await self.backend.verify(proof)
# ## TODO: implement
# # discard self.backend.verify(proof)