add tests for circom backend

This commit is contained in:
Dmitriy Ryajov 2024-01-27 16:38:51 -06:00
parent b50e46211c
commit 30ab88572d
No known key found for this signature in database
GPG Key ID: DA8C680CE7C657A4
2 changed files with 148 additions and 84 deletions

View File

@ -0,0 +1,115 @@
import std/json
import std/sequtils
import pkg/poseidon2
import pkg/constantine/math/arithmetic
import pkg/constantine/math/io/io_bigints
import pkg/codex/merkletree
import pkg/codex/slots/types
type
Input* = object
cellData*: seq[seq[byte]]
merklePaths*: seq[seq[Poseidon2Hash]]
slotProof*: seq[Poseidon2Hash]
datasetRoot*: Poseidon2Hash
slotRoot*: Poseidon2Hash
entropy*: Poseidon2Hash
nCellsPerSlot*: int
nSlotsPerDataSet*: int
slotIndex*: int
proc toInput*(inputJson: JsonNode): Input =
let
cellData =
inputJson["cellData"].mapIt(
it.mapIt(
block:
var
big: BigInt[256]
data = newSeq[byte](BigInt[256].bits div 8)
assert bool(big.fromDecimal( it.str ))
data.marshal(big, littleEndian)
data
).concat # flatten out elements
)
merklePaths =
inputJson["merklePaths"].mapIt(
it.mapIt(
block:
var
big: BigInt[254]
hash: Poseidon2Hash
assert bool(big.fromDecimal( it.str ))
hash.fromBig( big )
hash
)
)
slotProof = inputJson["slotProof"].mapIt(
block:
var
big: BigInt[254]
hash: Poseidon2Hash
assert bool(big.fromDecimal( it.str ))
hash.fromBig( big )
hash
)
datasetRoot = block:
var
big: BigInt[254]
hash: Poseidon2Hash
assert bool(big.fromDecimal( inputJson["dataSetRoot"].str ))
hash.fromBig( big )
hash
slotRoot = block:
var
big: BigInt[254]
hash: Poseidon2Hash
assert bool(big.fromDecimal( inputJson["slotRoot"].str ))
hash.fromBig( big )
hash
entropy = block:
var
big: BigInt[254]
hash: Poseidon2Hash
assert bool(big.fromDecimal( inputJson["entropy"].str ))
hash.fromBig( big )
hash
nCellsPerSlot = inputJson["nCellsPerSlot"].getInt
nSlotsPerDataSet = inputJson["nSlotsPerDataSet"].getInt
slotIndex = inputJson["slotIndex"].getInt
Input(
cellData: cellData,
merklePaths: merklePaths,
slotProof: slotProof,
datasetRoot: datasetRoot,
slotRoot: slotRoot,
entropy: entropy,
nCellsPerSlot: nCellsPerSlot,
nSlotsPerDataSet: nSlotsPerDataSet,
slotIndex: slotIndex)
proc toProofInput*[H](input: Input): ProofInput[H] =
ProofInput[H](
entropy: input.entropy,
slotIndex: input.slotIndex,
verifyRoot: input.datasetRoot,
verifyProof: input.slotProof,
slotRoot: input.slotRoot,
numCells: input.nCellsPerSlot,
numSlots: input.nSlotsPerDataSet,
samples: zip(input.cellData, input.merklePaths)
.mapIt(Sample[H](
data: it[0],
merkleProof: it[1]
))
)

View File

@ -2,9 +2,11 @@
import std/json
import std/sequtils
import std/sugar
import std/options
import pkg/chronos
import pkg/asynctest
import pkg/unittest2
import pkg/poseidon2
import pkg/codex/slots
import pkg/codex/slots/types
@ -14,95 +16,42 @@ import pkg/constantine/math/arithmetic
import pkg/constantine/math/io/io_fields
import pkg/constantine/math/io/io_bigints
import ./helpers
suite "Test Backend":
test "Should verify with known input":
let
r1cs = "tests/codex/slots/prover/fixtures/proof_main.r1cs"
wasm = "tests/codex/slots/prover/fixtures/proof_main.wasm"
var
circom: CircomCompat
proofInput: ProofInput[Poseidon2Hash]
setup:
let
r1cs = "tests/codex/slots/prover/fixtures/proof_main.r1cs"
wasm = "tests/codex/slots/prover/fixtures/proof_main.wasm"
zkey = "tests/codex/slots/prover/fixtures/proof_main.zkey"
inputData = readFile("tests/codex/slots/prover/fixtures/input.json")
inputJson = parseJson(inputData)
samples = collect(newSeq):
for i in 0..<5:
let
cellData = inputJson["cellData"][i].mapIt(
block:
var
big: BigInt[254]
data = newSeq[byte](big.bits div 8)
check bool(big.fromDecimal( it.str ))
data.marshal(big, littleEndian)
data
).concat
merklePaths = inputJson["merklePaths"][0].mapIt(
block:
var
big: BigInt[254]
hash: Poseidon2Hash
check bool(big.fromDecimal( it.str ))
hash.fromBig( big )
hash
)
proofInput = toProofInput[Poseidon2Hash](inputJson.toInput())
Sample[Poseidon2Hash](
data: cellData,
merkleProof: merklePaths)
# circom = CircomCompat.init(r1cs, wasm, zkey)
circom = CircomCompat.init(r1cs, wasm)
teardown:
circom.release()
test "Should verify with known input":
let
proof = circom.prove(proofInput).tryGet
check circom.verify(proof).tryGet
proof.release()
test "Should not verify with wrong input":
proofInput.slotIndex = 1 # change slot index
let
slotProof = inputJson["slotProof"].mapIt(
block:
var
big: BigInt[254]
hash: Poseidon2Hash
check bool(big.fromDecimal( it.str ))
hash.fromBig( big )
hash
)
proof = circom.prove(proofInput).tryGet
check circom.verify(proof).tryGet == false
datasetRoot = block:
var
big: BigInt[254]
hash: Poseidon2Hash
check bool(big.fromDecimal( inputJson["dataSetRoot"].str ))
hash.fromBig( big )
hash
slotRoot = block:
var
big: BigInt[254]
hash: Poseidon2Hash
check bool(big.fromDecimal( inputJson["slotRoot"].str ))
hash.fromBig( big )
hash
entropy = block:
var
big: BigInt[254]
hash: Poseidon2Hash
check bool(big.fromDecimal( inputJson["entropy"].str ))
hash.fromBig( big )
hash
nCellsPerSlot = inputJson["nCellsPerSlot"].getInt
nSlotsPerDataSet = inputJson["nSlotsPerDataSet"].getInt
slotIndex = inputJson["slotIndex"].getInt
proofInput = ProofInput[Poseidon2Hash](
entropy: entropy,
slotIndex: slotIndex,
verifyRoot: datasetRoot,
verifyProof: slotProof,
numCells: nCellsPerSlot,
numSlots: nSlotsPerDataSet,
samples: samples)
var
backend = CircomCompat[Poseidon2Hash, Proof].new(r1cs, wasm)
let
proof: Proof = (await backend.prove(proofInput)).tryGet
check (await backend.verify(proof)).tryGet
backend.release()
proof.release()