From 67d0126cf4a7fb4faa8309a8f6312eb2a0624990 Mon Sep 17 00:00:00 2001 From: Balazs Komuves Date: Mon, 15 Jun 2026 19:25:45 +0200 Subject: [PATCH] row permutations (so that the final witness delta's image can be in a subgroup) --- groth16/bn128/arrays.nim | 60 ++++++++++++ groth16/dynamic/permute.nim | 176 ++++++++++++++++++++++++++++++++++++ groth16/dynamic/setup.nim | 6 ++ groth16/files/r1cs.nim | 15 +++ groth16/math/domain.nim | 26 +++++- groth16/misc.nim | 4 + groth16/partial/finish.nim | 1 + groth16/partial/precalc.nim | 41 +++++++++ groth16/partial/types.nim | 2 + 9 files changed, 326 insertions(+), 5 deletions(-) create mode 100644 groth16/dynamic/permute.nim diff --git a/groth16/bn128/arrays.nim b/groth16/bn128/arrays.nim index eeb96d2..4856d77 100644 --- a/groth16/bn128/arrays.nim +++ b/groth16/bn128/arrays.nim @@ -29,6 +29,66 @@ func constSeq*[T]( N: int , y: T ): seq[T] = xs[i] = y return xs +#------------------------------------------------------------------------------- +# bool arrays + +func countTrues*( bs: seq[bool] ): int = + var cnt = 0 + for b in bs: + if b: + cnt += 1 + return cnt + +func countFalses*( bs: seq[bool] ): int = + var cnt = 0 + for b in bs: + if not b: + cnt += 1 + return cnt + +func trueIndices*( bs: seq[bool] ): seq[int] = + let k = countTrues(bs) + var idxs: seq[int] = newSeq[int]( k ) + var j = 0 + for (i,b) in bs.pairs: + if b: + idxs[j] = i + j += 1 + return idxs + +func falseIndices*( bs: seq[bool] ): seq[int] = + let k = countFalses(bs) + var idxs: seq[int] = newSeq[int]( k ) + var j = 0 + for (i,b) in bs.pairs: + if not b: + idxs[j] = i + j += 1 + return idxs + +func notBoolSeq*( us: seq[bool]): seq[bool] = + let n = us.len + var ws: seq[bool] = newSeq[bool]( n ) + for i in 0..= 1 ) + assert( K <= N ) + assert( (N mod K) == 0 ) + return Subgroup( bigDomain: D, smallDomain: createDomain(K) ) + +#------------------------------------------------------------------------------- diff --git a/groth16/misc.nim b/groth16/misc.nim index 2426925..247d0e2 100644 --- a/groth16/misc.nim +++ b/groth16/misc.nim @@ -46,6 +46,10 @@ func ceilingLog2* (x : int) : int = else: return (floorLog2(x-1) + 1) +func isPowerOfTwo*( N: int): bool = + let reN = (1 shl ceilingLog2(N)) + return ( N == reN ) + #------------------------------------------------------------------------------- #[ diff --git a/groth16/partial/finish.nim b/groth16/partial/finish.nim index 33857b4..e8676dd 100644 --- a/groth16/partial/finish.nim +++ b/groth16/partial/finish.nim @@ -14,6 +14,7 @@ import constantine/named/properties_fields import groth16/bn128 import groth16/math/domain import groth16/math/poly +import groth16/math/matrix import groth16/zkey_types import groth16/files/witness import groth16/misc diff --git a/groth16/partial/precalc.nim b/groth16/partial/precalc.nim index c1b1d83..9a179f1 100644 --- a/groth16/partial/precalc.nim +++ b/groth16/partial/precalc.nim @@ -18,15 +18,56 @@ import system import taskpools import groth16/bn128 +import groth16/bn128/arrays import groth16/zkey_types import groth16/misc +import groth16/math/matrix import groth16/partial/types #import groth16/math/domain #import groth16/math/poly #import groth16/prover/shared +#------------------------------------------------------------------------------- + +proc printPartialWitnessStats*(zkey: ZKey, pw: PartialWitness) = + let n = zkey.header.domainSize + let m = zkey.header.nvars + + echo "" + echo "N (domain) = " & $n + echo "M (witness) = " & $m + + let matrices = zkeyToSparseMatrices(zkey) + var partial_mask: seq[bool] = newSeq[bool] ( m ) + var delta_mask: seq[bool] = newSeq[bool] ( m ) + for j in 0..