From 44f00726d83dfcbab618c0049e9b3e47d7569007 Mon Sep 17 00:00:00 2001 From: munna0908 Date: Tue, 5 May 2026 20:53:35 +0530 Subject: [PATCH] fix tests --- cli/nim.cfg | 2 +- groth16.nimble | 11 +-- groth16/example/nim.cfg | 3 + tests/groth16/testMultithreading.nim | 113 +++++++++++++++++++++++++++ tests/nim.cfg | 2 + tests/test.nim | 1 + 6 files changed, 123 insertions(+), 9 deletions(-) create mode 100644 groth16/example/nim.cfg create mode 100644 tests/groth16/testMultithreading.nim diff --git a/cli/nim.cfg b/cli/nim.cfg index abe4065..40003bd 100644 --- a/cli/nim.cfg +++ b/cli/nim.cfg @@ -1,3 +1,3 @@ --path:".." --threads:on ---mm:arc \ No newline at end of file +--mm:refc \ No newline at end of file diff --git a/groth16.nimble b/groth16.nimble index d1f8ecf..cc6dccc 100644 --- a/groth16.nimble +++ b/groth16.nimble @@ -1,3 +1,4 @@ + version = "0.1.1" author = "Balazs Komuves" description = "Groth16 proof system" @@ -13,12 +14,6 @@ requires "https://github.com/status-im/nim-taskpools >= 0.0.5" requires "https://github.com/mratsim/constantine" # requires "https://github.com/mratsim/constantine#bc3845aa492b52f7fef047503b1592e830d1a774" -task test_arc, "run the test suite under --mm:arc": - exec "nim c -r --threads:on --mm:arc tests/test.nim" -task test_refc, "run the test suite under --mm:refc": - exec "nim c -r --threads:on --mm:refc tests/test.nim" - -task test, "run the test suite under both --mm:arc and --mm:refc": - exec "nim c -r --threads:on --mm:arc tests/test.nim" - exec "nim c -r --threads:on --mm:refc tests/test.nim" +task test, "Run All Tests": + exec "nim c -r -d:release --opt=speed tests/test.nim " \ No newline at end of file diff --git a/groth16/example/nim.cfg b/groth16/example/nim.cfg new file mode 100644 index 0000000..23eed4d --- /dev/null +++ b/groth16/example/nim.cfg @@ -0,0 +1,3 @@ +--path:"../.." +--threads:on +--mm:arc diff --git a/tests/groth16/testMultithreading.nim b/tests/groth16/testMultithreading.nim new file mode 100644 index 0000000..f801c02 --- /dev/null +++ b/tests/groth16/testMultithreading.nim @@ -0,0 +1,113 @@ + +{.used.} + +# Multi-threading determinism tests. +# +# `generateProofWithTrivialMask` zeros the masking coefficients (r=s=0), so +# the proof is a pure deterministic function of (zkey, witness). Sweeping the +# taskpool thread count must produce byte-identical proof points. Any +# divergence ⇒ data race in the multi-threaded MSM/NTT path. +# +# These tests run under both --mm:arc and --mm:refc via the `test` nimble + +import std/unittest +import std/sequtils + +import taskpools + +# Without this, unittest's echo of the trailing `[OK]` line for the last test +# can stay in stdio buffers when the process exits right after pool.shutdown() +# joins its worker threads — making the suite look like it stopped early. +#setStdIoUnbuffered() + +import groth16/prover +import groth16/prover/groth16 as proverImpl +import groth16/verifier +import groth16/fake_setup +import groth16/zkey_types +import groth16/files/witness +import groth16/files/r1cs +import groth16/bn128/fields + +#------------------------------------------------------------------------------- +# Same simple multiplication circuit testProver.nim uses: 7*11*13 + 1022 = 2023. +# Small but exercises the full prover path (4 MSMs + quotient computation). + +const myWitnessCfg = + WitnessConfig( nWires: 8 + , nPubOut: 1 + , nPubIn: 1 + , nPrivIn: 3 + , nLabels: 0 + ) + +const myEq1 : Constraint = ( @[] , @[] , @[ (1,minusOneFr) , (2,oneFr) , (7,oneFr) ] ) +const myEq2 : Constraint = ( @[ (3,oneFr) ] , @[ (4,oneFr) ] , @[ (6,oneFr) ] ) +const myEq3 : Constraint = ( @[ (5,oneFr) ] , @[ (6,oneFr) ] , @[ (7,oneFr) ] ) + +const myConstraints : seq[Constraint] = @[ myEq1, myEq2, myEq3 ] + +const myR1CS = + R1CS( r: primeR + , cfg: myWitnessCfg + , nConstr: myConstraints.len + , constraints: myConstraints + , wireToLabel: @[] + ) + +let myWitnessValues = map( @[ 1, 2023, 1022, 7, 11, 13, 7*11, 7*11*13 ] , intToFr ) + +let myWitness = + Witness( curve: "bn128" + , r: primeR + , nvars: 8 + , values: myWitnessValues + ) + +const ThreadCounts = [1, 2, 4, 8] + +#------------------------------------------------------------------------------- + +proc proveWithThreads(zkey: ZKey, witness: Witness, nThreads: int): Proof = + var pool = Taskpool.new(numThreads = nThreads) + result = generateProofWithTrivialMask( zkey, witness, pool, printTimings = false ) + pool.shutdown() + +proc verifyWith(zkey: ZKey, proof: Proof): bool = + let vkey = extractVKey(zkey) + return verifyProof(vkey, proof) + +#------------------------------------------------------------------------------- + +suite "multithreading": + + test "repeated proofs on the same pool match (no per-call state leak)": + # Reusing one pool across many proofs must not change the output: rules + # out residual state in worker-local buffers between invocations. + let zkey = createFakeCircuitSetup( myR1cs, flavour=Snarkjs ) + var pool = Taskpool.new(numThreads = 4) + defer: pool.shutdown() + let first = generateProofWithTrivialMask(zkey, myWitness, pool, false) + for _ in 0 ..< 4: + let again = generateProofWithTrivialMask(zkey, myWitness, pool, false) + check isEqualProof(first, again) + + test "trivial-mask proof is deterministic across thread counts (JensGroth)": + let zkey = createFakeCircuitSetup( myR1cs, flavour=JensGroth ) + let reference = proveWithThreads(zkey, myWitness, ThreadCounts[0]) + check verifyWith(zkey, reference) + for j in ThreadCounts[1..^1]: + let proof = proveWithThreads(zkey, myWitness, j) + check isEqualProof(reference, proof) + check verifyWith(zkey, proof) + + test "trivial-mask proof is deterministic across thread counts (Snarkjs)": + let zkey = createFakeCircuitSetup( myR1cs, flavour=Snarkjs ) + let reference = proveWithThreads(zkey, myWitness, ThreadCounts[0]) + check verifyWith(zkey, reference) + for j in ThreadCounts[1..^1]: + let proof = proveWithThreads(zkey, myWitness, j) + check isEqualProof(reference, proof) + check verifyWith(zkey, proof) + + diff --git a/tests/nim.cfg b/tests/nim.cfg index 0f840a1..40003bd 100644 --- a/tests/nim.cfg +++ b/tests/nim.cfg @@ -1 +1,3 @@ --path:".." +--threads:on +--mm:refc \ No newline at end of file diff --git a/tests/test.nim b/tests/test.nim index 36aea78..194247e 100644 --- a/tests/test.nim +++ b/tests/test.nim @@ -2,4 +2,5 @@ import ./groth16/testPtCompression import ./groth16/testCurve import ./groth16/testProver +import ./groth16/testMultithreading