From 30ab88572da4e4fe165415cb38da52c3f1ab3f15 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Sat, 27 Jan 2024 16:38:51 -0600 Subject: [PATCH] add tests for circom backend --- tests/codex/slots/prover/helpers.nim | 115 +++++++++++++++++ tests/codex/slots/prover/testcircomcompat.nim | 117 +++++------------- 2 files changed, 148 insertions(+), 84 deletions(-) create mode 100644 tests/codex/slots/prover/helpers.nim diff --git a/tests/codex/slots/prover/helpers.nim b/tests/codex/slots/prover/helpers.nim new file mode 100644 index 00000000..128e21e5 --- /dev/null +++ b/tests/codex/slots/prover/helpers.nim @@ -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] + )) + ) diff --git a/tests/codex/slots/prover/testcircomcompat.nim b/tests/codex/slots/prover/testcircomcompat.nim index e0e5cd2d..9d470456 100644 --- a/tests/codex/slots/prover/testcircomcompat.nim +++ b/tests/codex/slots/prover/testcircomcompat.nim @@ -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()