# # Groth16 prover # # WARNING! # the points H in `.zkey` are *NOT* what normal people would think they are # See # {.push raises:[].} import system import taskpools import constantine/math/arithmetic import constantine/named/properties_fields import groth16/bn128 import groth16/math/domain import groth16/math/poly import groth16/zkey_types import groth16/sharedbuf #import groth16/misc import groth16/prover/types # `FrBN` shadows `Fr[BN254_Snarks]` to dodge a taskpools `spawn` macro issue: # its `getImpl().replaceSymsByIdents()` doesn't roundtrip qualified generic # instantiations cleanly, so the bare ident `Fr[BN254_Snarks]` re-resolves # wrong at the wrapper-proc reconstruction step. Using a plain alias gives # the macro an unambiguous symbol to work with. Same workaround as # `AffG1`/`AffG2` in `groth16/bn128/msm.nim`. type FrBN = Fr[BN254_Snarks] #------------------------------------------------------------------------------- proc randomMask*(): Mask = # masking coeffs let r = randFr() let s = randFr() let mask = Mask(r: r, s: s) return mask #------------------------------------------------------------------------------- # computes the vectors A*z, B*z, C*z where z is the witness func buildABC*( zkey: ZKey, witness: seq[Fr[BN254_Snarks]] ): ABC = let hdr: GrothHeader = zkey.header let domSize = hdr.domainSize var valuesAz = newSeq[Fr[BN254_Snarks]](domSize) var valuesBz = newSeq[Fr[BN254_Snarks]](domSize) for entry in zkey.coeffs: case entry.matrix of MatrixA: valuesAz[entry.row] += entry.coeff * witness[entry.col] of MatrixB: valuesBz[entry.row] += entry.coeff * witness[entry.col] else: raise newException(AssertionDefect, "fatal error") var valuesCz = newSeq[Fr[BN254_Snarks]](domSize) for i in 0..= 1) var ys = newSeq[Fr[BN254_Snarks]](n) ys[0] = xs[0] if n >= 1: ys[1] = eta * xs[1] var spow = eta for i in 2.. # proc computeSnarkjsScalarCoeffs*( abc: ABC, pool: TaskPool ): seq[Fr[BN254_Snarks]] = let n = abc.valuesAz.len assert( abc.valuesBz.len == n ) assert( abc.valuesCz.len == n ) let D = createDomain(n) let eta = createDomain(2*n).domainGen var outA = newSeq[Fr[BN254_Snarks]](n) var outB = newSeq[Fr[BN254_Snarks]](n) var outC = newSeq[Fr[BN254_Snarks]](n) let taskA1 = pool.spawn shiftEvalDomainTask( SharedBuf.view(toOpenArray(abc.valuesAz, 0, n - 1)), D, eta, SharedBuf.view(toOpenArray(outA, 0, n - 1))) let taskB1 = pool.spawn shiftEvalDomainTask( SharedBuf.view(toOpenArray(abc.valuesBz, 0, n - 1)), D, eta, SharedBuf.view(toOpenArray(outB, 0, n - 1))) let taskC1 = pool.spawn shiftEvalDomainTask( SharedBuf.view(toOpenArray(abc.valuesCz, 0, n - 1)), D, eta, SharedBuf.view(toOpenArray(outC, 0, n - 1))) discard sync taskA1 discard sync taskB1 discard sync taskC1 var ys : seq[Fr[BN254_Snarks]] = newSeq[Fr[BN254_Snarks]]( n ) for j in 0..