Prover works with zkey (#711)

* rework backend to instantiate key at initialization

* add groth16 convertes for solidity

* prover taks num samples on construction

* add zkey file

* rework helpers

* rename types

* update tests

* reworked test helpers

* rename types

* rework test

* test all slots artifacts

* bump to latest version
This commit is contained in:
Dmitriy Ryajov 2024-02-19 12:58:39 -06:00 committed by GitHub
parent 6b86601597
commit 9e13d2251a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 233 additions and 186 deletions

View File

@ -20,8 +20,11 @@ import ../../types
import ../../../stores
import ../../../merkletree
import ../../../codextypes
import ../../../contracts
export circomcompat
import ./converters
export circomcompat, converters
type
CircomCompat* = object
@ -32,40 +35,24 @@ type
numSamples : int # number of samples per slot
r1csPath : string # path to the r1cs file
wasmPath : string # path to the wasm file
zKeyPath : string # path to the zkey file
zkeyPath : string # path to the zkey file
backendCfg : ptr CircomBn254Cfg
CircomG1* = G1
CircomG2* = G2
CircomProof* = Proof
CircomKey* = VerifyingKey
CircomInputs* = Inputs
vkp* : ptr CircomKey
proc release*(self: CircomCompat) =
## Release the backend
## Release the ctx
##
self.backendCfg.unsafeAddr.releaseCfg()
if not isNil(self.backendCfg):
self.backendCfg.unsafeAddr.releaseCfg()
proc getVerifyingKey*(
self: CircomCompat): ?!ptr CircomKey =
## Get the verifying key
##
var
cfg: ptr CircomBn254Cfg = self.backendCfg
vkpPtr: ptr VerifyingKey = nil
if cfg.getVerifyingKey(vkpPtr.addr) != ERR_OK or vkpPtr == nil:
return failure("Failed to get verifying key")
success vkpPtr
if not isNil(self.vkp):
self.vkp.unsafeAddr.release_key()
proc prove*[H](
self: CircomCompat,
input: ProofInput[H]): ?!CircomProof =
## Encode buffers using a backend
input: ProofInputs[H]): ?!CircomProof =
## Encode buffers using a ctx
##
# NOTE: All inputs are statically sized per circuit
@ -86,43 +73,43 @@ proc prove*[H](
# TODO: All parameters should match circom's static parametter
var
backend: ptr CircomCompatCtx
ctx: ptr CircomCompatCtx
defer:
if backend != nil:
backend.addr.releaseCircomCompat()
if ctx != nil:
ctx.addr.releaseCircomCompat()
if initCircomCompat(
self.backendCfg,
addr backend) != ERR_OK or backend == nil:
raiseAssert("failed to initialize CircomCompat backend")
addr ctx) != ERR_OK or ctx == nil:
raiseAssert("failed to initialize CircomCompat ctx")
var
entropy = input.entropy.toBytes
dataSetRoot = input.datasetRoot.toBytes
slotRoot = input.slotRoot.toBytes
if backend.pushInputU256Array(
if ctx.pushInputU256Array(
"entropy".cstring, entropy[0].addr, entropy.len.uint32) != ERR_OK:
return failure("Failed to push entropy")
if backend.pushInputU256Array(
if ctx.pushInputU256Array(
"dataSetRoot".cstring, dataSetRoot[0].addr, dataSetRoot.len.uint32) != ERR_OK:
return failure("Failed to push data set root")
if backend.pushInputU256Array(
if ctx.pushInputU256Array(
"slotRoot".cstring, slotRoot[0].addr, slotRoot.len.uint32) != ERR_OK:
return failure("Failed to push data set root")
if backend.pushInputU32(
if ctx.pushInputU32(
"nCellsPerSlot".cstring, input.nCellsPerSlot.uint32) != ERR_OK:
return failure("Failed to push nCellsPerSlot")
if backend.pushInputU32(
if ctx.pushInputU32(
"nSlotsPerDataSet".cstring, input.nSlotsPerDataSet.uint32) != ERR_OK:
return failure("Failed to push nSlotsPerDataSet")
if backend.pushInputU32(
if ctx.pushInputU32(
"slotIndex".cstring, input.slotIndex.uint32) != ERR_OK:
return failure("Failed to push slotIndex")
@ -132,7 +119,7 @@ proc prove*[H](
slotProof.setLen(self.datasetDepth) # zero pad inputs to correct size
# arrays are always flattened
if backend.pushInputU256Array(
if ctx.pushInputU256Array(
"slotProof".cstring,
slotProof[0].addr,
uint (slotProof[0].len * slotProof.len)) != ERR_OK:
@ -144,14 +131,14 @@ proc prove*[H](
data = s.cellData
merklePaths.setLen(self.slotDepth) # zero pad inputs to correct size
if backend.pushInputU256Array(
if ctx.pushInputU256Array(
"merklePaths".cstring,
merklePaths[0].addr,
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 backend.pushInputU256Array(
if ctx.pushInputU256Array(
"cellData".cstring,
data[0].addr,
data.len.uint) != ERR_OK:
@ -163,7 +150,7 @@ proc prove*[H](
let proof =
try:
if (
let res = self.backendCfg.proveCircuit(backend, proofPtr.addr);
let res = self.backendCfg.proveCircuit(ctx, proofPtr.addr);
res != ERR_OK) or
proofPtr == nil:
return failure("Failed to prove - err code: " & $res)
@ -175,55 +162,66 @@ proc prove*[H](
success proof
proc verify*(
proc verify*[H](
self: CircomCompat,
proof: CircomProof,
inputs: CircomInputs,
vkp: CircomKey): ?!bool =
## Verify a proof using a backend
inputs: ProofInputs[H]): ?!bool =
## Verify a proof using a ctx
##
var
proofPtr : ptr Proof = unsafeAddr proof
inputsPtr: ptr Inputs = unsafeAddr inputs
vpkPtr: ptr CircomKey = unsafeAddr vkp
proofPtr = unsafeAddr proof
inputs = inputs.toCircomInputs()
let res = verifyCircuit(proofPtr, inputsPtr, vpkPtr)
if res == ERR_OK:
success true
elif res == ERR_FAILED_TO_VERIFY_PROOF:
success false
else:
failure("Failed to verify proof - err code: " & $res)
try:
let res = verifyCircuit(proofPtr, inputs.addr, self.vkp)
if res == ERR_OK:
success true
elif res == ERR_FAILED_TO_VERIFY_PROOF:
success false
else:
failure("Failed to verify proof - err code: " & $res)
finally:
inputs.releaseCircomInputs()
proc init*(
_: type CircomCompat,
r1csPath : string,
wasmPath : string,
zKeyPath : string = "",
zkeyPath : string = "",
slotDepth = DefaultMaxSlotDepth,
datasetDepth = DefaultMaxDatasetDepth,
blkDepth = DefaultBlockDepth,
cellElms = DefaultCellElms,
numSamples = DefaultSamplesNum): CircomCompat =
## Create a new backend
## Create a new ctx
##
var cfg: ptr CircomBn254Cfg
var zkey = if zkeyPath.len > 0: zkeyPath.cstring else: nil
if initCircomConfig(
r1csPath.cstring,
wasmPath.cstring,
if zKeyPath.len > 0: zKeyPath.cstring else: nil,
addr cfg) != ERR_OK or cfg == nil:
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
if cfg.getVerifyingKey(vkpPtr.addr) != ERR_OK or vkpPtr == nil:
if vkpPtr != nil: vkpPtr.addr.releaseKey()
raiseAssert("Failed to get verifying key")
CircomCompat(
r1csPath : r1csPath,
wasmPath : wasmPath,
zKeyPath : zKeyPath,
backendCfg : cfg,
zkeyPath : zkeyPath,
slotDepth : slotDepth,
datasetDepth: datasetDepth,
blkDepth : blkDepth,
cellElms : cellElms,
numSamples : numSamples)
numSamples : numSamples,
backendCfg : cfg,
vkp : vkpPtr)

View File

@ -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
import ../../../merkletree
type
CircomG1* = G1
CircomG2* = G2
CircomProof* = Proof
CircomKey* = VerifyingKey
CircomInputs* = Inputs
proc toCircomInputs*(inputs: ProofInputs[Poseidon2Hash]): 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)

View File

@ -30,25 +30,27 @@ import ../types
export backends
type
AnyProof* = CircomProof
AnyInputs* = CircomInputs
AnyKeys* = CircomKey
AnyHash* = Poseidon2Hash
AnyBackend* = CircomCompat
AnyBuilder* = Poseidon2Builder
AnySampler* = Poseidon2Sampler
logScope:
topics = "codex prover"
type
AnyBackend* = CircomCompat
AnyProof* = CircomProof
AnySampler* = Poseidon2Sampler
AnyBuilder* = Poseidon2Builder
AnyProofInputs* = ProofInputs[Poseidon2Hash]
Prover* = ref object of RootObj
backend: AnyBackend
store: BlockStore
nSamples: int
proc prove*(
self: Prover,
slotIdx: int,
manifest: Manifest,
challenge: ProofChallenge,
nSamples = DefaultSamplesNum): Future[?!AnyProof] {.async.} =
challenge: ProofChallenge): Future[?!(AnyProofInputs, AnyProof)] {.async.} =
## Prove a statement using backend.
## Returns a future that resolves to a proof.
@ -67,7 +69,7 @@ proc prove*(
error "Unable to create data sampler", err = err.msg
return failure(err)
without proofInput =? await sampler.getProofInput(challenge, nSamples), err:
without proofInput =? await sampler.getProofInput(challenge, self.nSamples), err:
error "Unable to get proof input for slot", err = err.msg
return failure(err)
@ -76,23 +78,24 @@ 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,
store: BlockStore,
backend: AnyBackend): Prover =
backend: AnyBackend,
nSamples: int): Prover =
Prover(
backend: backend,
store: store)
store: store,
nSamples: nSamples)

View File

@ -91,7 +91,7 @@ proc getSample*[T, H](
proc getProofInput*[T, H](
self: DataSampler[T, H],
entropy: ProofChallenge,
nSamples: Natural): Future[?!ProofInput[H]] {.async.} =
nSamples: Natural): Future[?!ProofInputs[H]] {.async.} =
## Generate proofs as input to the proving circuit.
##
@ -124,7 +124,7 @@ proc getProofInput*[T, H](
(await self.getSample(cellIdx, slotTreeCid, slotRoot)).valueOr:
return failure("Failed to get sample")
success ProofInput[H](
success ProofInputs[H](
entropy: entropy,
datasetRoot: datasetRoot,
slotProof: slotProof.path,

View File

@ -17,7 +17,7 @@ type
datasetRoot*: H
entropy*: H
ProofInput*[H] = object
ProofInputs*[H] = object
entropy*: H
datasetRoot*: H
slotIndex*: Natural

Binary file not shown.

View File

@ -2,8 +2,10 @@
import std/sequtils
import std/sugar
import std/strutils
import std/options
import pkg/poseidon2
import pkg/poseidon2/io
import pkg/constantine/math/arithmetic
import pkg/constantine/math/io/io_bigints
import pkg/constantine/math/io/io_fields
@ -15,7 +17,7 @@ import pkg/codex/utils/json
export types
func fromCircomData*[H](cellData: seq[byte]): seq[H] =
func fromCircomData*(_: type Poseidon2Hash, cellData: seq[byte]): seq[Poseidon2Hash] =
var
pos = 0
cellElms: seq[Bn254Fr]
@ -30,43 +32,40 @@ func fromCircomData*[H](cellData: seq[byte]): seq[H] =
cellElms
func toPublicInputs*[H](input: ProofInput[H]): PublicInputs[H] =
PublicInputs[H](
slotIndex: input.slotIndex,
datasetRoot: input.datasetRoot,
entropy: input.entropy
)
proc toCircomInputs*[H](inputs: PublicInputs[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 releaseNimInputs*(inputs: var CircomInputs) =
if not inputs.elms.isNil:
deallocShared(inputs.elms)
inputs.elms = nil
func toJsonDecimal*(big: BigInt[254]): string =
let s = big.toDecimal.strip( leading = true, trailing = false, chars = {'0'} )
if s.len == 0: "0" else: s
func toJson*[H](input: ProofInput[H]): JsonNode =
func toJson*(g1: CircomG1): JsonNode =
%* {
"x": Bn254Fr.fromBytes(g1.x).get.toBig.toJsonDecimal,
"y": Bn254Fr.fromBytes(g1.y).get.toBig.toJsonDecimal
}
func toJson*(g2: CircomG2): JsonNode =
%* {
"x": [
Bn254Fr.fromBytes(g2.x[0]).get.toBig.toJsonDecimal,
Bn254Fr.fromBytes(g2.x[1]).get.toBig.toJsonDecimal],
"y": [
Bn254Fr.fromBytes(g2.y[0]).get.toBig.toJsonDecimal,
Bn254Fr.fromBytes(g2.y[1]).get.toBig.toJsonDecimal]
}
proc toJson*(vpk: VerifyingKey): JsonNode =
let
ic = toSeq(cast[ptr UncheckedArray[CircomG1]](vpk.ic).toOpenArray(0, vpk.icLen.int - 1))
echo ic.len
%* {
"alpha1": vpk.alpha1.toJson,
"beta2": vpk.beta2.toJson,
"gamma2": vpk.gamma2.toJson,
"delta2": vpk.delta2.toJson,
"ic": ic.mapIt( it.toJson )
}
func toJson*(input: ProofInputs[Poseidon2Hash]): JsonNode =
var
input = input
@ -79,14 +78,14 @@ func toJson*[H](input: ProofInput[H]): JsonNode =
"slotRoot": input.slotRoot.toDecimal,
"slotProof": input.slotProof.mapIt( it.toBig.toJsonDecimal ),
"cellData": input.samples.mapIt(
toSeq( it.cellData.elements(H) ).mapIt( it.toBig.toJsonDecimal )
toSeq( it.cellData.elements(Poseidon2Hash) ).mapIt( it.toBig.toJsonDecimal )
),
"merklePaths": input.samples.mapIt(
it.merklePaths.mapIt( it.toBig.toJsonDecimal )
)
}
func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
func jsonToProofInput*(_: type Poseidon2Hash, inputJson: JsonNode): ProofInputs[Poseidon2Hash] =
let
cellData =
inputJson["cellData"].mapIt(
@ -107,7 +106,7 @@ func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
block:
var
big: BigInt[254]
hash: H
hash: Poseidon2Hash
assert bool(big.fromDecimal( it.getStr ))
hash.fromBig( big )
hash
@ -118,7 +117,7 @@ func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
block:
var
big: BigInt[254]
hash: H
hash: Poseidon2Hash
assert bool(big.fromDecimal( it.str ))
hash.fromBig( big )
hash
@ -127,7 +126,7 @@ func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
datasetRoot = block:
var
big: BigInt[254]
hash: H
hash: Poseidon2Hash
assert bool(big.fromDecimal( inputJson["dataSetRoot"].str ))
hash.fromBig( big )
hash
@ -135,7 +134,7 @@ func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
slotRoot = block:
var
big: BigInt[254]
hash: H
hash: Poseidon2Hash
assert bool(big.fromDecimal( inputJson["slotRoot"].str ))
hash.fromBig( big )
hash
@ -143,7 +142,7 @@ func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
entropy = block:
var
big: BigInt[254]
hash: H
hash: Poseidon2Hash
assert bool(big.fromDecimal( inputJson["entropy"].str ))
hash.fromBig( big )
hash
@ -152,7 +151,7 @@ func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
nSlotsPerDataSet = inputJson["nSlotsPerDataSet"].getInt
slotIndex = inputJson["slotIndex"].getInt
ProofInput[H](
ProofInputs[Poseidon2Hash](
entropy: entropy,
slotIndex: slotIndex,
datasetRoot: datasetRoot,
@ -161,7 +160,7 @@ func jsonToProofInput*[H](inputJson: JsonNode): ProofInput[H] =
nCellsPerSlot: nCellsPerSlot,
nSlotsPerDataSet: nSlotsPerDataSet,
samples: zip(cellData, merklePaths)
.mapIt(Sample[H](
.mapIt(Sample[Poseidon2Hash](
cellData: it[0],
merklePaths: it[1]
))

View File

@ -3,8 +3,9 @@ import std/sequtils
import std/sugar
import std/options
import pkg/chronos
import ../../../asynctest
import pkg/chronos
import pkg/poseidon2
import pkg/datastore
@ -16,10 +17,6 @@ import pkg/codex/codextypes
import pkg/codex/manifest
import pkg/codex/stores
import pkg/constantine/math/arithmetic
import pkg/constantine/math/io/io_fields
import pkg/constantine/math/io/io_bigints
import ./helpers
import ../helpers
@ -27,56 +24,50 @@ suite "Test Circom Compat Backend - control inputs":
let
r1cs = "tests/circuits/fixtures/proof_main.r1cs"
wasm = "tests/circuits/fixtures/proof_main.wasm"
zkey = "tests/circuits/fixtures/proof_main.zkey"
var
circom: CircomCompat
verifyingKeyPtr: ptr CircomKey
proofInput: ProofInput[Poseidon2Hash]
publicInputs: CircomInputs
proofInputs: ProofInputs[Poseidon2Hash]
setup:
let
inputData = readFile("tests/circuits/fixtures/input.json")
inputJson = parseJson(inputData)
proofInput = jsonToProofInput[Poseidon2Hash](inputJson)
publicInputs = toPublicInputs[Poseidon2Hash](proofInput).toCircomInputs
# circom = CircomCompat.init(r1cs, wasm, zkey)
circom = CircomCompat.init(r1cs, wasm)
verifyingKeyPtr = circom.getVerifyingKey().tryGet
proofInputs = Poseidon2Hash.jsonToProofInput(inputJson)
circom = CircomCompat.init(r1cs, wasm, zkey)
teardown:
publicInputs.releaseNimInputs() # this is allocated by nim
verifyingKeyPtr.addr.releaseKey() # this comes from the rust FFI
circom.release() # this comes from the rust FFI
circom.release() # this comes from the rust FFI
test "Should verify with correct inputs":
let
proof = circom.prove(proofInput).tryGet
proof = circom.prove(proofInputs).tryGet
check circom.verify(proof, publicInputs, verifyingKeyPtr[]).tryGet
check circom.verify(proof, proofInputs).tryGet
test "Should not verify with incorrect inputs":
proofInput.slotIndex = 1 # change slot index
proofInputs.slotIndex = 1 # change slot index
let
proof = circom.prove(proofInput).tryGet
proof = circom.prove(proofInputs).tryGet
check circom.verify(proof, publicInputs, verifyingKeyPtr[]).tryGet == false
check circom.verify(proof, proofInputs).tryGet == false
suite "Test Circom Compat Backend":
let
slotId = 3
samples = 5
ecK = 2
ecM = 2
slotId = 3
samples = 5
numDatasetBlocks = 8
blockSize = DefaultBlockSize
cellSize = DefaultCellSize
r1cs = "tests/circuits/fixtures/proof_main.r1cs"
wasm = "tests/circuits/fixtures/proof_main.wasm"
zkey = "tests/circuits/fixtures/proof_main.zkey"
var
store: BlockStore
@ -84,9 +75,7 @@ suite "Test Circom Compat Backend":
protected: Manifest
verifiable: Manifest
circom: CircomCompat
verifyingKeyPtr: ptr CircomKey
proofInput: ProofInput[Poseidon2Hash]
publicInputs: CircomInputs
proofInputs: ProofInputs[Poseidon2Hash]
challenge: array[32, byte]
builder: Poseidon2Builder
sampler: Poseidon2Sampler
@ -109,29 +98,24 @@ suite "Test Circom Compat Backend":
builder = Poseidon2Builder.new(store, verifiable).tryGet
sampler = Poseidon2Sampler.new(slotId, store, builder).tryGet
# circom = CircomCompat.init(r1cs, wasm, zkey)
circom = CircomCompat.init(r1cs, wasm)
verifyingKeyPtr = circom.getVerifyingKey().tryGet
circom = CircomCompat.init(r1cs, wasm, zkey)
challenge = 1234567.toF.toBytes.toArray32
proofInput = (await sampler.getProofInput(challenge, samples)).tryGet
publicInputs = proofInput.toPublicInputs.toCircomInputs
proofInputs = (await sampler.getProofInput(challenge, samples)).tryGet
teardown:
publicInputs.releaseNimInputs() # this is allocated by nim
verifyingKeyPtr.addr.releaseKey() # this comes from the rust FFI
circom.release() # this comes from the rust FFI
circom.release() # this comes from the rust FFI
test "Should verify with correct input":
var
proof = circom.prove(proofInput).tryGet
proof = circom.prove(proofInputs).tryGet
check circom.verify(proof, publicInputs, verifyingKeyPtr[]).tryGet
check circom.verify(proof, proofInputs).tryGet
test "Should not verify with incorrect input":
proofInput.slotIndex = 1 # change slot index
proofInputs.slotIndex = 1 # change slot index
let
proof = circom.prove(proofInput).tryGet
proof = circom.prove(proofInputs).tryGet
check circom.verify(proof, publicInputs, verifyingKeyPtr[]).tryGet == false
check circom.verify(proof, proofInputs).tryGet == false

View File

@ -31,12 +31,12 @@ suite "Test Sampler - control samples":
var
inputData: string
inputJson: JsonNode
proofInput: ProofInput[Poseidon2Hash]
proofInput: ProofInputs[Poseidon2Hash]
setup:
inputData = readFile("tests/circuits/fixtures/input.json")
inputJson = parseJson(inputData)
proofInput = jsonToProofInput[Poseidon2Hash](inputJson)
proofInput = Poseidon2Hash.jsonToProofInput(inputJson)
test "Should verify control samples":
let
@ -58,7 +58,7 @@ suite "Test Sampler - control samples":
proofInput.nCellsPerSlot,
sample.merklePaths[5..<9]).tryGet
cellData = fromCircomData[Poseidon2Hash](sample.cellData)
cellData = Poseidon2Hash.fromCircomData(sample.cellData)
cellLeaf = Poseidon2Hash.spongeDigest(cellData, rate = 2).tryGet
slotLeaf = cellProof.reconstructRoot(cellLeaf).tryGet
@ -154,7 +154,7 @@ suite "Test Sampler":
nSlotCells,
sample.merklePaths[5..<sample.merklePaths.len]).tryGet
cellData = fromCircomData[Poseidon2Hash](sample.cellData)
cellData = Poseidon2Hash.fromCircomData(sample.cellData)
cellLeaf = Poseidon2Hash.spongeDigest(cellData, rate = 2).tryGet
slotLeaf = cellProof.reconstructRoot(cellLeaf).tryGet

View File

@ -34,12 +34,12 @@ asyncchecksuite "Test proof sampler utils":
var
inputData: string
inputJson: JsonNode
proofInput: ProofInput[Poseidon2Hash]
proofInput: ProofInputs[Poseidon2Hash]
setup:
inputData = readFile("tests/circuits/fixtures/input.json")
inputJson = parseJson(inputData)
proofInput = jsonToProofInput[Poseidon2Hash](inputJson)
proofInput = Poseidon2Hash.jsonToProofInput(inputJson)
test "Extract low bits":
proc extract(value: uint64, nBits: int): uint64 =

View File

@ -18,10 +18,6 @@ import pkg/codex/stores
import pkg/poseidon2/io
import pkg/codex/utils/poseidon2digest
import pkg/constantine/math/arithmetic
import pkg/constantine/math/io/io_bigints
import pkg/constantine/math/io/io_fields
import ./helpers
import ../helpers
import ./backends/helpers
@ -30,11 +26,11 @@ suite "Test Prover":
let
slotId = 1
samples = 5
blockSize = DefaultBlockSize
cellSize = DefaultCellSize
ecK = 3
ecM = 2
numDatasetBlocks = 8
blockSize = DefaultBlockSize
cellSize = DefaultCellSize
var
datasetBlocks: seq[bt.Block]
@ -65,14 +61,9 @@ suite "Test Prover":
wasm = "tests/circuits/fixtures/proof_main.wasm"
circomBackend = CircomCompat.init(r1cs, wasm)
prover = Prover.new(store, circomBackend)
prover = Prover.new(store, circomBackend, samples)
challenge = 1234567.toF.toBytes.toArray32
proof = (await prover.prove(1, verifiable, challenge, 5)).tryGet
key = circomBackend.getVerifyingKey().tryGet
builder = Poseidon2Builder.new(store, verifiable).tryGet
sampler = Poseidon2Sampler.new(1, store, builder).tryGet
proofInput = (await sampler.getProofInput(challenge, 5)).tryGet
inputs = proofInput.toPublicInputs.toCircomInputs
(inputs, proof) = (await prover.prove(1, verifiable, challenge)).tryGet
check:
(await prover.verify(proof, inputs, key[])).tryGet == true
(await prover.verify(proof, inputs)).tryGet == true

View File

@ -1,5 +1,7 @@
import ./slots/testslotbuilder
import ./slots/testsampler
import ./slots/testconverters
import ./slots/testbackends
import ./slots/testprover
{.warning[UnusedImport]: off.}

@ -1 +1 @@
Subproject commit fa513b123e081c76ec0bb3237ad886d4830b8071
Subproject commit e710e4c333f367353aaa1ee82a55a47326b63a65