From 159f8b78c401ff21275432c68ea931a8275634cc Mon Sep 17 00:00:00 2001 From: Balazs Komuves Date: Mon, 15 Jun 2026 14:13:56 +0200 Subject: [PATCH] some sparse matrix stuff --- cli/cli_main.nim | 1 + groth16/dynamic/preprocess.nim | 4 +- groth16/dynamic/types.nim | 8 ++- groth16/fake_setup.nim | 47 ++++---------- groth16/math/matrix.nim | 115 +++++++++++++++++++++++++++++++++ groth16/misc.nim | 11 ---- groth16/zkey_types.nim | 55 +++++++++++++--- tests/groth16/testMisc.nim | 35 ++++++++++ tests/test.nim | 1 + 9 files changed, 216 insertions(+), 61 deletions(-) create mode 100644 groth16/math/matrix.nim create mode 100644 tests/groth16/testMisc.nim diff --git a/cli/cli_main.nim b/cli/cli_main.nim index e1dc300..273f3a8 100644 --- a/cli/cli_main.nim +++ b/cli/cli_main.nim @@ -175,6 +175,7 @@ proc cliMain(cfg: Config) = if cfg.debug: printGrothHeader(zkey.header) + printR1csStats(zkey) # debugPrintCoeffs(zkey.coeffs) if cfg.partial_sanity: diff --git a/groth16/dynamic/preprocess.nim b/groth16/dynamic/preprocess.nim index ce51ea6..1776f9f 100644 --- a/groth16/dynamic/preprocess.nim +++ b/groth16/dynamic/preprocess.nim @@ -115,7 +115,7 @@ proc testProjectionElementsV1*(N: int, tau: F, delta: F ): bool = #--------------------------------------- -func dynaPreprocessV1*(zkey: ZKey, setup: DynaSetupV1, partialWitness: PartialWitness): DynaPreprocess = +func dynaPreprocessV1*(zkey: ZKey, setup: DynaSetupV1, partialWitness: PartialWitness): DynaPreprocessV1 = let N = zkey.header.domainSize let D = createDomain(N) @@ -126,7 +126,7 @@ func dynaPreprocessV1*(zkey: ZKey, setup: DynaSetupV1, partialWitness: PartialWi let projA = projectionElementsV1( setup , D , partialAB.valuesAz , partialAB.complImageA ) let projB = projectionElementsV1( setup , D , partialAB.valuesBz , partialAB.complImageB ) - return DynaPreprocess( projA0: projA, projB0: projB ) + return DynaPreprocessV1( projA0: projA, projB0: projB ) #------------------------------------------------------------------------------- diff --git a/groth16/dynamic/types.nim b/groth16/dynamic/types.nim index 07d5226..67e1b06 100644 --- a/groth16/dynamic/types.nim +++ b/groth16/dynamic/types.nim @@ -36,18 +36,20 @@ type wConvDeltaLZ* : seq[G1] # the convolution of `W` and `pointsDeltaLZ` # things we can compute from the partial witness - DynaPreprocess* = object + DynaPreprocessV1* = object projA0* : seq[G1] # the points `delta^-1 * A0(tau) * L_i(tau) * g1` (well, "modulo Z(tau)") projB0* : seq[G1] # the same for B0 - DynaPreProof* = object + DynaPreProofV1* = object partialProof* : PartialProof - dyanPreprocess* : DynaPreprocess + dyanPreprocess* : DynaPreprocessV1 + # this is used in the "cross-term" OnlyAB* = object valuesAz* : seq[F] valuesBz* : seq[F] + # this one is used in the "projection-term" PartialAB* = object valuesAz* : seq[F] valuesBz* : seq[F] diff --git a/groth16/fake_setup.nim b/groth16/fake_setup.nim index 95b6c2b..92e65fb 100644 --- a/groth16/fake_setup.nim +++ b/groth16/fake_setup.nim @@ -15,6 +15,7 @@ import constantine/named/properties_fields import groth16/bn128 #import groth16/bn128/arrays import groth16/math/domain +import groth16/math/matrix import groth16/math/poly import groth16/zkey_types import groth16/files/r1cs @@ -69,16 +70,6 @@ func r1csToCoeffs*(r1cs: R1CS): seq[Coeff] = #------------------------------------------------------------------------------- # Note: dense matrices can be very big, this is only feasible for small circuits -type DenseColumn*[T] = seq[T] - -type DenseMatrix*[T] = seq[DenseColumn[T]] - -type - DenseMatrices* = object - A* : DenseMatrix[Fr[BN254_Snarks]] - B* : DenseMatrix[Fr[BN254_Snarks]] - C* : DenseMatrix[Fr[BN254_Snarks]] - #[ func r1csToDenseMatrices*(r1cs: R1CS): DenseMatrices = @@ -137,36 +128,17 @@ func denseMatricesToCoeffs*(matrices: DenseMatrices): seq[Coeff] = #------------------------------------------------------------------------------- -type SparseColumn*[T] = Table[int,T] - -proc columnInsertWithAddFr( col: var SparseColumn[Fr[BN254_Snarks]] , i: int, y: Fr[BN254_Snarks] ) = - var x = getOrDefault( col, i, zeroFr ) - x += y - col[i] = x - -proc sparseDenseDotProdFr( U: SparseColumn[Fr[BN254_Snarks]], V: DenseColumn[Fr[BN254_Snarks]] ): Fr[BN254_Snarks] = - var acc : Fr[BN254_Snarks] = zeroFr - for i,x in U.pairs: - acc += x * V[i] - return acc - -type SparseMatrix*[T] = seq[SparseColumn[T]] - -type - SparseMatrices* = object - A* : SparseMatrix[Fr[BN254_Snarks]] - B* : SparseMatrix[Fr[BN254_Snarks]] - C* : SparseMatrix[Fr[BN254_Snarks]] - func r1csToSparseMatrices*(r1cs: R1CS): SparseMatrices = let n = r1cs.constraints.len let m = r1cs.cfg.nWires let p = r1cs.cfg.nPubIn + r1cs.cfg.nPubOut + let dims = MatrixDims( nrows: n , ncols: m ) + let logDomSize = ceilingLog2(n+p+1) let domSize = 1 shl logDomSize - var matA, matB, matC: SparseMatrix[Fr[BN254_Snarks]] + var matA, matB, matC: SparseMatrixColumns[Fr[BN254_Snarks]] for i in 0..