# # Groth16 prover # # WARNING! # the points H in `.zkey` are *NOT* what normal people would think they are # See # #[ import sugar import constantine/math/config/curves import constantine/math/io/io_fields import constantine/math/io/io_bigints import ./zkey ]# import constantine/math/arithmetic except Fp, Fr import constantine/math/io/io_extfields except Fp12 import constantine/math/extension_fields/towers except Fp2, Fp12 import ./bn128 import ./domain import ./poly import ./zkey_types import ./witness #------------------------------------------------------------------------------- type Proof* = object publicIO* : seq[Fr] pi_a* : G1 pi_b* : G2 pi_c* : G1 curve : string #------------------------------------------------------------------------------- # the verifier # proc verifyProof* (vkey: VKey, prf: Proof): bool = assert( prf.curve == "bn128" ) assert( isOnCurveG1(prf.pi_a) , "pi_a is not in G1" ) assert( isOnCurveG2(prf.pi_b) , "pi_b is not in G2" ) assert( isOnCurveG1(prf.pi_c) , "pi_c is not in G1" ) var pubG1 : G1 = msmG1( prf.publicIO , vkey.vpoints.pointsIC ) let lhs : Fp12 = pairing( negG1(prf.pi_a) , prf.pi_b ) # < -pi_a , pi_b > let rhs1 : Fp12 = vkey.spec.alphaBeta # < alpha , beta > let rhs2 : Fp12 = pairing( prf.pi_c , vkey.spec.delta2 ) # < pi_c , delta > let rhs3 : Fp12 = pairing( pubG1 , vkey.spec.gamma2 ) # < sum... , gamma > var eq : Fp12 eq = lhs eq *= rhs1 eq *= rhs2 eq *= rhs3 return bool(isOne(eq)) #------------------------------------------------------------------------------- # A, B, C column vectors # type ABC = object valuesA : seq[Fr] valuesB : seq[Fr] valuesC : seq[Fr] func buildABC( zkey: ZKey, witness: seq[Fr] ): ABC = let hdr: GrothHeader = zkey.header let domSize = hdr.domainSize var valuesA : seq[Fr] = newSeq[Fr](domSize) var valuesB : seq[Fr] = newSeq[Fr](domSize) for entry in zkey.coeffs: case entry.matrix of MatrixA: valuesA[entry.row] += entry.coeff * witness[entry.col] of MatrixB: valuesB[entry.row] += entry.coeff * witness[entry.col] else: raise newException(AssertionDefect, "fatal error") var valuesC : seq[Fr] = newSeq[Fr](domSize) for i in 0..= 1) var ys : seq[Fr] = newSeq[Fr](n) ys[0] = xs[0] if n >= 1: ys[1] = eta * xs[1] var spow : Fr = eta for i in 2.. # func computeSnarkjsScalarCoeffs( abc: ABC ): seq[Fr] = let n = abc.valuesA.len let D = createDomain(n) let eta = createDomain(2*n).domainGen let A1 = shiftEvalDomain( abc.valuesA, D, eta ) let B1 = shiftEvalDomain( abc.valuesB, D, eta ) let C1 = shiftEvalDomain( abc.valuesC, D, eta ) var ys : seq[Fr] = newSeq[Fr]( n ) for j in 0..