mirror of
https://github.com/logos-storage/nim-groth16.git
synced 2026-01-06 23:53:12 +00:00
refactor: replace Fp etc shortcuts by full generic type
reason: compile error deep in constantine, because it will try to determine the field, which it can't when we abbreviate it Co-Authored-By: Dmitriy Ryajov <dryajov@gmail.com>
This commit is contained in:
parent
e6e865a62e
commit
0f2a84ec33
@ -13,12 +13,12 @@
|
||||
#import constantine/platforms/abstractions
|
||||
#import constantine/math/isogenies/frobenius
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
import constantine/math/io/io_fields except Fp, Fr
|
||||
import constantine/math/io/io_bigints
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_fields
|
||||
|
||||
import constantine/named/properties_fields as tff except Fp, Fr
|
||||
import constantine/math/extension_fields/towers as ext except Fp, Fp2, Fp12, Fr
|
||||
import constantine/named/properties_fields as tff
|
||||
import constantine/math/extension_fields/towers as ext
|
||||
|
||||
import constantine/math/elliptic/ec_shortweierstrass_affine as aff
|
||||
import constantine/math/elliptic/ec_shortweierstrass_projective as prj
|
||||
@ -29,19 +29,19 @@ import groth16/bn128/fields
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
type G1* = aff.EC_ShortW_Aff[Fp , aff.G1]
|
||||
type G2* = aff.EC_ShortW_Aff[Fp2, aff.G2]
|
||||
type G1* = aff.EC_ShortW_Aff[Fp[BN254_Snarks] , aff.G1]
|
||||
type G2* = aff.EC_ShortW_Aff[Fp2[BN254_Snarks], aff.G2]
|
||||
|
||||
type ProjG1* = prj.EC_ShortW_Prj[Fp , prj.G1]
|
||||
type ProjG2* = prj.EC_ShortW_Prj[Fp2, prj.G2]
|
||||
type ProjG1* = prj.EC_ShortW_Prj[Fp[BN254_Snarks] , prj.G1]
|
||||
type ProjG2* = prj.EC_ShortW_Prj[Fp2[BN254_Snarks], prj.G2]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func unsafeMkG1* ( X, Y: Fp ) : G1 =
|
||||
return aff.EC_ShortW_Aff[Fp, aff.G1](x: X, y: Y)
|
||||
func unsafeMkG1* ( X, Y: Fp[BN254_Snarks] ) : G1 =
|
||||
return aff.EC_ShortW_Aff[Fp[BN254_Snarks], aff.G1](x: X, y: Y)
|
||||
|
||||
func unsafeMkG2* ( X, Y: Fp2 ) : G2 =
|
||||
return aff.EC_ShortW_Aff[Fp2, aff.G2](x: X, y: Y)
|
||||
func unsafeMkG2* ( X, Y: Fp2[BN254_Snarks] ) : G2 =
|
||||
return aff.EC_ShortW_Aff[Fp2[BN254_Snarks], aff.G2](x: X, y: Y)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -50,15 +50,15 @@ const infG2* : G2 = unsafeMkG2( zeroFp2 , zeroFp2 )
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func checkCurveEqG1*( x, y: Fp ) : bool =
|
||||
func checkCurveEqG1*( x, y: Fp[BN254_Snarks] ) : bool =
|
||||
if bool(isZero(x)) and bool(isZero(y)):
|
||||
# the point at infinity is on the curve by definition
|
||||
return true
|
||||
else:
|
||||
var x2 : Fp = squareFp(x)
|
||||
var y2 : Fp = squareFp(y)
|
||||
var x3 : Fp = x2 * x
|
||||
var eq : Fp
|
||||
var x2 = squareFp(x)
|
||||
var y2 = squareFp(y)
|
||||
var x3 = x2 * x
|
||||
var eq : Fp[BN254_Snarks]
|
||||
eq = x3
|
||||
eq += intToFp(3)
|
||||
eq -= y2
|
||||
@ -71,19 +71,19 @@ func checkCurveEqG1*( x, y: Fp ) : bool =
|
||||
# B = b1 + bu*u
|
||||
# b1 = 19485874751759354771024239261021720505790618469301721065564631296452457478373
|
||||
# b2 = 266929791119991161246907387137283842545076965332900288569378510910307636690
|
||||
const twistCoeffB_1 : Fp = fromHex(Fp, "0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5")
|
||||
const twistCoeffB_u : Fp = fromHex(Fp, "0x009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2")
|
||||
const twistCoeffB : Fp2 = mkFp2( twistCoeffB_1 , twistCoeffB_u )
|
||||
const twistCoeffB_1 = fromHex(Fp[BN254_Snarks], "0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5")
|
||||
const twistCoeffB_u = fromHex(Fp[BN254_Snarks], "0x009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2")
|
||||
const twistCoeffB = mkFp2( twistCoeffB_1 , twistCoeffB_u )
|
||||
|
||||
func checkCurveEqG2*( x, y: Fp2 ) : bool =
|
||||
func checkCurveEqG2*( x, y: Fp2[BN254_Snarks] ) : bool =
|
||||
if isZeroFp2(x) and isZeroFp2(y):
|
||||
# the point at infinity is on the curve by definition
|
||||
return true
|
||||
else:
|
||||
var x2 : Fp2 = squareFp2(x)
|
||||
var y2 : Fp2 = squareFp2(y)
|
||||
var x3 : Fp2 = x2 * x;
|
||||
var eq : Fp2
|
||||
var x2 = squareFp2(x)
|
||||
var y2 = squareFp2(y)
|
||||
var x3 = x2 * x
|
||||
var eq : Fp2[BN254_Snarks]
|
||||
eq = x3
|
||||
eq += twistCoeffB
|
||||
eq -= y2
|
||||
@ -91,14 +91,14 @@ func checkCurveEqG2*( x, y: Fp2 ) : bool =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func mkG1*( x, y: Fp ) : G1 =
|
||||
func mkG1*( x, y: Fp[BN254_Snarks] ) : G1 =
|
||||
if isZeroFp(x) and isZeroFp(y):
|
||||
return infG1
|
||||
else:
|
||||
assert( checkCurveEqG1(x,y) , "mkG1: not a G1 curve point" )
|
||||
return unsafeMkG1(x,y)
|
||||
|
||||
func mkG2*( x, y: Fp2 ) : G2 =
|
||||
func mkG2*( x, y: Fp2[BN254_Snarks] ) : G2 =
|
||||
if isZeroFp2(x) and isZeroFp2(y):
|
||||
return infG2
|
||||
else:
|
||||
@ -108,16 +108,16 @@ func mkG2*( x, y: Fp2 ) : G2 =
|
||||
#-------------------------------------------------------------------------------
|
||||
# group generators
|
||||
|
||||
const gen1_x : Fp = fromHex(Fp, "0x01")
|
||||
const gen1_y : Fp = fromHex(Fp, "0x02")
|
||||
const gen1_x = fromHex(Fp[BN254_Snarks], "0x01")
|
||||
const gen1_y = fromHex(Fp[BN254_Snarks], "0x02")
|
||||
|
||||
const gen2_xi : Fp = fromHex(Fp, "0x1adcd0ed10df9cb87040f46655e3808f98aa68a570acf5b0bde23fab1f149701")
|
||||
const gen2_xu : Fp = fromHex(Fp, "0x09e847e9f05a6082c3cd2a1d0a3a82e6fbfbe620f7f31269fa15d21c1c13b23b")
|
||||
const gen2_yi : Fp = fromHex(Fp, "0x056c01168a5319461f7ca7aa19d4fcfd1c7cdf52dbfc4cbee6f915250b7f6fc8")
|
||||
const gen2_yu : Fp = fromHex(Fp, "0x0efe500a2d02dd77f5f401329f30895df553b878fc3c0dadaaa86456a623235c")
|
||||
const gen2_xi = fromHex(Fp[BN254_Snarks], "0x1adcd0ed10df9cb87040f46655e3808f98aa68a570acf5b0bde23fab1f149701")
|
||||
const gen2_xu = fromHex(Fp[BN254_Snarks], "0x09e847e9f05a6082c3cd2a1d0a3a82e6fbfbe620f7f31269fa15d21c1c13b23b")
|
||||
const gen2_yi = fromHex(Fp[BN254_Snarks], "0x056c01168a5319461f7ca7aa19d4fcfd1c7cdf52dbfc4cbee6f915250b7f6fc8")
|
||||
const gen2_yu = fromHex(Fp[BN254_Snarks], "0x0efe500a2d02dd77f5f401329f30895df553b878fc3c0dadaaa86456a623235c")
|
||||
|
||||
const gen2_x : Fp2 = mkFp2( gen2_xi, gen2_xu )
|
||||
const gen2_y : Fp2 = mkFp2( gen2_yi, gen2_yu )
|
||||
const gen2_x = mkFp2( gen2_xi, gen2_xu )
|
||||
const gen2_y = mkFp2( gen2_yi, gen2_yu )
|
||||
|
||||
const gen1* : G1 = unsafeMkG1( gen1_x, gen1_y )
|
||||
const gen2* : G2 = unsafeMkG2( gen2_x, gen2_y )
|
||||
@ -214,8 +214,8 @@ func `**`*( coeff: BigInt , point: G2 ) : G2 =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func pairing* (p: G1, q: G2) : Fp12 =
|
||||
var t : Fp12
|
||||
func pairing* (p: G1, q: G2) : Fp12[BN254_Snarks] =
|
||||
var t : Fp12[BN254_Snarks]
|
||||
ate.pairing_bn( t, p, q )
|
||||
return t
|
||||
|
||||
|
||||
@ -18,17 +18,17 @@ import groth16/bn128/io
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
proc debugPrintFp*(prefix: string, x: Fp) =
|
||||
proc debugPrintFp*(prefix: string, x: Fp[BN254_Snarks]) =
|
||||
echo(prefix & toDecimalFp(x))
|
||||
|
||||
proc debugPrintFp2*(prefix: string, z: Fp2) =
|
||||
proc debugPrintFp2*(prefix: string, z: Fp2[BN254_Snarks]) =
|
||||
echo(prefix & " 1 ~> " & toDecimalFp(z.coords[0]))
|
||||
echo(prefix & " u ~> " & toDecimalFp(z.coords[1]))
|
||||
|
||||
proc debugPrintFr*(prefix: string, x: Fr) =
|
||||
proc debugPrintFr*(prefix: string, x: Fr[BN254_Snarks]) =
|
||||
echo(prefix & toDecimalFr(x))
|
||||
|
||||
proc debugPrintFrSeq*(msg: string, xs: seq[Fr]) =
|
||||
proc debugPrintFrSeq*(msg: string, xs: seq[Fr[BN254_Snarks]]) =
|
||||
echo "---------------------"
|
||||
echo msg
|
||||
for x in xs:
|
||||
|
||||
@ -20,15 +20,10 @@ import constantine/math/extension_fields/towers as ext
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
type B* = BigInt[256]
|
||||
type Fr* = tff.Fr[BN254Snarks]
|
||||
type Fp* = tff.Fp[BN254Snarks]
|
||||
|
||||
type Fp2* = ext.QuadraticExt[Fp]
|
||||
type Fp12* = ext.Fp12[BN254Snarks]
|
||||
|
||||
func mkFp2* (i: Fp, u: Fp) : Fp2 =
|
||||
let c : array[2, Fp] = [i,u]
|
||||
return ext.QuadraticExt[Fp]( coords: c )
|
||||
func mkFp2* (i: Fp[BN254_Snarks], u: Fp[BN254_Snarks]) : Fp2[BN254_Snarks] =
|
||||
let c : array[2, Fp[BN254_Snarks]] = [i,u]
|
||||
return ext.QuadraticExt[Fp[BN254_Snarks]]( coords: c )
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -37,16 +32,16 @@ const primeR* : B = fromHex( B, "0x30644e72e131a029b85045b68181585d2833e84879b97
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
const zeroFp* : Fp = fromHex( Fp, "0x00" )
|
||||
const zeroFr* : Fr = fromHex( Fr, "0x00" )
|
||||
const oneFp* : Fp = fromHex( Fp, "0x01" )
|
||||
const oneFr* : Fr = fromHex( Fr, "0x01" )
|
||||
const zeroFp* = fromHex( Fp[BN254_Snarks], "0x00" )
|
||||
const zeroFr* = fromHex( Fr[BN254_Snarks], "0x00" )
|
||||
const oneFp* = fromHex( Fp[BN254_Snarks], "0x01" )
|
||||
const oneFr* = fromHex( Fr[BN254_Snarks], "0x01" )
|
||||
|
||||
const zeroFp2* : Fp2 = mkFp2( zeroFp, zeroFp )
|
||||
const oneFp2* : Fp2 = mkFp2( oneFp , zeroFp )
|
||||
const zeroFp2* = mkFp2( zeroFp, zeroFp )
|
||||
const oneFp2* = mkFp2( oneFp , zeroFp )
|
||||
|
||||
const minusOneFp* : Fp = fromHex( Fp, "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46" )
|
||||
const minusOneFr* : Fr = fromHex( Fr, "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" )
|
||||
const minusOneFp* = fromHex( Fp[BN254_Snarks], "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46" )
|
||||
const minusOneFr* = fromHex( Fr[BN254_Snarks], "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000" )
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -55,13 +50,13 @@ func intToB*(a: uint): B =
|
||||
y.setUint(a)
|
||||
return y
|
||||
|
||||
func intToFp*(a: int): Fp =
|
||||
var y : Fp
|
||||
func intToFp*(a: int): Fp[BN254_Snarks] =
|
||||
var y : Fp[BN254_Snarks]
|
||||
y.fromInt(a)
|
||||
return y
|
||||
|
||||
func intToFr*(a: int): Fr =
|
||||
var y : Fr
|
||||
func intToFr*(a: int): Fr[BN254_Snarks] =
|
||||
var y : Fr[BN254_Snarks]
|
||||
y.fromInt(a)
|
||||
return y
|
||||
|
||||
@ -153,27 +148,27 @@ func smallPowFr*(base: Fr, expo: int): Fr =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func deltaFr*(i, j: int) : Fr =
|
||||
func deltaFr*[T](i, j: int) : Fr[T] =
|
||||
return (if (i == j): oneFr else: zeroFr)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# Montgomery batch inversion
|
||||
func batchInverseFr*( xs: seq[Fr] ) : seq[Fr] =
|
||||
func batchInverseFr*( xs: seq[Fr[BN254_Snarks]] ) : seq[Fr[BN254_Snarks]] =
|
||||
let n = xs.len
|
||||
assert(n>0)
|
||||
var us : seq[Fr] = newSeq[Fr](n+1)
|
||||
var us : seq[Fr[BN254_Snarks]] = newSeq[Fr[BN254_Snarks]](n+1)
|
||||
var a = xs[0]
|
||||
us[0] = oneFr
|
||||
us[1] = a
|
||||
for i in 1..<n: ( a *= xs[i] ; us[i+1] = a )
|
||||
var vs : seq[Fr] = newSeq[Fr](n)
|
||||
var vs : seq[Fr[BN254_Snarks]] = newSeq[Fr[BN254_Snarks]](n)
|
||||
vs[n-1] = invFr( us[n] )
|
||||
for i in countdown(n-2,0): vs[i] = vs[i+1] * xs[i+1]
|
||||
return collect( newSeq, (for i in 0..<n: us[i]*vs[i] ) )
|
||||
|
||||
proc sanityCheckBatchInverseFr*() =
|
||||
let xs : seq[Fr] = map( toSeq(101..137) , intToFr )
|
||||
let xs = map( toSeq(101..137) , intToFr )
|
||||
let ys = batchInverseFr( xs )
|
||||
let zs = collect( newSeq, (for x in xs: invFr(x)) )
|
||||
let n = xs.len
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
import std/strutils
|
||||
import std/streams
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fp2, Fr
|
||||
import constantine/math/io/io_fields except Fp, Fp2, Fp
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_fields
|
||||
import constantine/math/io/io_bigints
|
||||
import constantine/named/properties_fields as tff except Fp, Fp2, Fr
|
||||
import constantine/named/properties_fields
|
||||
import constantine/math/extension_fields/towers
|
||||
|
||||
import groth16/bn128/fields
|
||||
@ -25,13 +25,13 @@ func toDecimalBig*[n](a : BigInt[n]): string =
|
||||
if s.len == 0: s="0"
|
||||
return s
|
||||
|
||||
func toDecimalFp*(a : Fp): string =
|
||||
func toDecimalFp*(a : Fp[BN254_Snarks]): string =
|
||||
var s : string = toDecimal(a)
|
||||
s = s.strip( leading=true, trailing=false, chars={'0'} )
|
||||
if s.len == 0: s="0"
|
||||
return s
|
||||
|
||||
func toDecimalFr*(a : Fr): string =
|
||||
func toDecimalFr*(a : Fr[BN254_Snarks]): string =
|
||||
var s : string = toDecimal(a)
|
||||
s = s.strip( leading=true, trailing=false, chars={'0'} )
|
||||
if s.len == 0: s="0"
|
||||
@ -41,13 +41,13 @@ func toDecimalFr*(a : Fr): string =
|
||||
|
||||
const k65536 : BigInt[254] = fromHex( BigInt[254], "0x10000", bigEndian )
|
||||
|
||||
func signedToDecimalFp*(a : Fp): string =
|
||||
func signedToDecimalFp*(a : Fp[BN254_Snarks]): string =
|
||||
if bool( a.toBig() > primeP_254 - k65536 ):
|
||||
return "-" & toDecimalFp(negFp(a))
|
||||
else:
|
||||
return toDecimalFp(a)
|
||||
|
||||
func signedToDecimalFr*(a : Fr): string =
|
||||
func signedToDecimalFr*(a : Fr[BN254_Snarks]): string =
|
||||
if bool( a.toBig() > primeR_254 - k65536 ):
|
||||
return "-" & toDecimalFr(negFr(a))
|
||||
else:
|
||||
@ -58,38 +58,38 @@ func signedToDecimalFr*(a : Fr): string =
|
||||
#
|
||||
|
||||
# R=2^256; this computes 2^256 mod Fp
|
||||
func calcFpMontR*() : Fp =
|
||||
var x : Fp = intToFp(2)
|
||||
func calcFpMontR*() : Fp[BN254_Snarks] =
|
||||
var x : Fp[BN254_Snarks] = intToFp(2)
|
||||
for i in 1..8:
|
||||
square(x)
|
||||
return x
|
||||
|
||||
# R=2^256; this computes the inverse of (2^256 mod Fp)
|
||||
func calcFpInvMontR*() : Fp =
|
||||
var x : Fp = calcFpMontR()
|
||||
func calcFpInvMontR*() : Fp[BN254_Snarks] =
|
||||
var x : Fp[BN254_Snarks] = calcFpMontR()
|
||||
inv(x)
|
||||
return x
|
||||
|
||||
# R=2^256; this computes 2^256 mod Fr
|
||||
func calcFrMontR*() : Fr =
|
||||
var x : Fr = intToFr(2)
|
||||
func calcFrMontR*() : Fr[BN254_Snarks] =
|
||||
var x : Fr[BN254_Snarks] = intToFr(2)
|
||||
for i in 1..8:
|
||||
square(x)
|
||||
return x
|
||||
|
||||
# R=2^256; this computes the inverse of (2^256 mod Fp)
|
||||
func calcFrInvMontR*() : Fr =
|
||||
var x : Fr = calcFrMontR()
|
||||
func calcFrInvMontR*() : Fr[BN254_Snarks] =
|
||||
var x : Fr[BN254_Snarks] = calcFrMontR()
|
||||
inv(x)
|
||||
return x
|
||||
|
||||
# apparently we cannot compute these in compile time for some reason or other... (maybe because `intToFp()`?)
|
||||
const fpMontR* : Fp = fromHex( Fp, "0x0e0a77c19a07df2f666ea36f7879462c0a78eb28f5c70b3dd35d438dc58f0d9d" )
|
||||
const fpInvMontR* : Fp = fromHex( Fp, "0x2e67157159e5c639cf63e9cfb74492d9eb2022850278edf8ed84884a014afa37" )
|
||||
const fpMontR* = fromHex( Fp[BN254_Snarks], "0x0e0a77c19a07df2f666ea36f7879462c0a78eb28f5c70b3dd35d438dc58f0d9d" )
|
||||
const fpInvMontR* = fromHex( Fp[BN254_Snarks], "0x2e67157159e5c639cf63e9cfb74492d9eb2022850278edf8ed84884a014afa37" )
|
||||
|
||||
# apparently we cannot compute these in compile time for some reason or other... (maybe because `intToFp()`?)
|
||||
const frMontR* : Fr = fromHex( Fr, "0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb" )
|
||||
const frInvMontR* : Fr = fromHex( Fr, "0x15ebf95182c5551cc8260de4aeb85d5d090ef5a9e111ec87dc5ba0056db1194e" )
|
||||
const frMontR* = fromHex( Fr[BN254_Snarks], "0x0e0a77c19a07df2f666ea36f7879462e36fc76959f60cd29ac96341c4ffffffb" )
|
||||
const frInvMontR* = fromHex( Fr[BN254_Snarks], "0x15ebf95182c5551cc8260de4aeb85d5d090ef5a9e111ec87dc5ba0056db1194e" )
|
||||
|
||||
proc checkMontgomeryConstants*() =
|
||||
assert( bool( fpMontR == calcFpMontR() ) )
|
||||
@ -103,18 +103,18 @@ proc checkMontgomeryConstants*() =
|
||||
# the binary file `.zkey` used by the `circom` ecosystem uses little-endian
|
||||
# Montgomery representation. So when we unmarshal with Constantine, it will
|
||||
# give the wrong result. Calling this function on the result fixes that.
|
||||
func fromMontgomeryFp*(x : Fp) : Fp =
|
||||
var y : Fp = x;
|
||||
func fromMontgomeryFp*(x : Fp[BN254_Snarks]) : Fp[BN254_Snarks] =
|
||||
var y : Fp[BN254_Snarks] = x;
|
||||
y *= fpInvMontR
|
||||
return y
|
||||
|
||||
func fromMontgomeryFr*(x : Fr) : Fr =
|
||||
var y : Fr = x;
|
||||
func fromMontgomeryFr*(x : Fr[BN254_Snarks]) : Fr[BN254_Snarks] =
|
||||
var y = x;
|
||||
y *= frInvMontR
|
||||
return y
|
||||
|
||||
func toMontgomeryFr*(x : Fr) : Fr =
|
||||
var y : Fr = x;
|
||||
func toMontgomeryFr*(x : Fr[BN254_Snarks]) : Fr[BN254_Snarks] =
|
||||
var y = x;
|
||||
y *= frMontR
|
||||
return y
|
||||
|
||||
@ -123,47 +123,47 @@ func toMontgomeryFr*(x : Fr) : Fr =
|
||||
# Note: in the `.zkey` coefficients, e apparently DOUBLE Montgomery encoding is used ?!?
|
||||
#
|
||||
|
||||
func unmarshalFpMont* ( bs: array[32,byte] ) : Fp =
|
||||
func unmarshalFpMont* ( bs: array[32,byte] ) : Fp[BN254_Snarks] =
|
||||
var big : BigInt[254]
|
||||
unmarshal( big, bs, littleEndian );
|
||||
var x : Fp
|
||||
var x : Fp[BN254_Snarks]
|
||||
x.fromBig( big )
|
||||
return fromMontgomeryFp(x)
|
||||
|
||||
# WTF Jordi, go home you are drunk
|
||||
func unmarshalFrWTF* ( bs: array[32,byte] ) : Fr =
|
||||
func unmarshalFrWTF* ( bs: array[32,byte] ) : Fr[BN254_Snarks] =
|
||||
var big : BigInt[254]
|
||||
unmarshal( big, bs, littleEndian );
|
||||
var x : Fr
|
||||
var x : Fr[BN254_Snarks]
|
||||
x.fromBig( big )
|
||||
return fromMontgomeryFr(fromMontgomeryFr(x))
|
||||
|
||||
func unmarshalFrStd* ( bs: array[32,byte] ) : Fr =
|
||||
func unmarshalFrStd* ( bs: array[32,byte] ) : Fr[BN254_Snarks] =
|
||||
var big : BigInt[254]
|
||||
unmarshal( big, bs, littleEndian );
|
||||
var x : Fr
|
||||
var x : Fr[BN254_Snarks]
|
||||
x.fromBig( big )
|
||||
return x
|
||||
|
||||
func unmarshalFrMont* ( bs: array[32,byte] ) : Fr =
|
||||
func unmarshalFrMont* ( bs: array[32,byte] ) : Fr[BN254_Snarks] =
|
||||
var big : BigInt[254]
|
||||
unmarshal( big, bs, littleEndian );
|
||||
var x : Fr
|
||||
var x : Fr[BN254_Snarks]
|
||||
x.fromBig( big )
|
||||
return fromMontgomeryFr(x)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func unmarshalFpMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fp] =
|
||||
var vals : seq[Fp] = newSeq[Fp]( len )
|
||||
func unmarshalFpMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fp[BN254_Snarks]] =
|
||||
var vals : seq[Fp[BN254_Snarks]] = newSeq[Fp[BN254_Snarks]]( len )
|
||||
var bytes : array[32,byte]
|
||||
for i in 0..<len:
|
||||
copyMem( addr(bytes) , unsafeAddr(bs[32*i]) , 32 )
|
||||
vals[i] = unmarshalFpMont( bytes )
|
||||
return vals
|
||||
|
||||
func unmarshalFrMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fr] =
|
||||
var vals : seq[Fr] = newSeq[Fr]( len )
|
||||
func unmarshalFrMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fr[BN254_Snarks]] =
|
||||
var vals : seq[Fr[BN254_Snarks]] = newSeq[Fr[BN254_Snarks]]( len )
|
||||
var bytes : array[32,byte]
|
||||
for i in 0..<len:
|
||||
copyMem( addr(bytes) , unsafeAddr(bs[32*i]) , 32 )
|
||||
@ -172,7 +172,7 @@ func unmarshalFrMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fr] =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
proc loadValueFrWTF*( stream: Stream ) : Fr =
|
||||
proc loadValueFrWTF*( stream: Stream ) : Fr[BN254_Snarks] =
|
||||
var bytes : array[32,byte]
|
||||
let n = stream.readData( addr(bytes), 32 )
|
||||
# for i in 0..<32: stdout.write(" " & toHex(bytes[i]))
|
||||
@ -180,45 +180,45 @@ proc loadValueFrWTF*( stream: Stream ) : Fr =
|
||||
assert( n == 32 )
|
||||
return unmarshalFrWTF(bytes)
|
||||
|
||||
proc loadValueFrStd*( stream: Stream ) : Fr =
|
||||
proc loadValueFrStd*( stream: Stream ) : Fr[BN254_Snarks] =
|
||||
var bytes : array[32,byte]
|
||||
let n = stream.readData( addr(bytes), 32 )
|
||||
assert( n == 32 )
|
||||
return unmarshalFrStd(bytes)
|
||||
|
||||
proc loadValueFrMont*( stream: Stream ) : Fr =
|
||||
proc loadValueFrMont*( stream: Stream ) : Fr[BN254_Snarks] =
|
||||
var bytes : array[32,byte]
|
||||
let n = stream.readData( addr(bytes), 32 )
|
||||
assert( n == 32 )
|
||||
return unmarshalFrMont(bytes)
|
||||
|
||||
proc loadValueFpMont*( stream: Stream ) : Fp =
|
||||
proc loadValueFpMont*( stream: Stream ) : Fp[BN254_Snarks] =
|
||||
var bytes : array[32,byte]
|
||||
let n = stream.readData( addr(bytes), 32 )
|
||||
assert( n == 32 )
|
||||
return unmarshalFpMont(bytes)
|
||||
|
||||
proc loadValueFp2Mont*( stream: Stream ) : Fp2 =
|
||||
proc loadValueFp2Mont*( stream: Stream ) : Fp2[BN254_Snarks] =
|
||||
let i = loadValueFpMont( stream )
|
||||
let u = loadValueFpMont( stream )
|
||||
return mkFp2(i,u)
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
proc loadValuesFrStd*( len: int, stream: Stream ) : seq[Fr] =
|
||||
var values : seq[Fr]
|
||||
proc loadValuesFrStd*( len: int, stream: Stream ) : seq[Fr[BN254_Snarks]] =
|
||||
var values: seq[Fr[BN254_Snarks]]
|
||||
for i in 1..len:
|
||||
values.add( loadValueFrStd(stream) )
|
||||
return values
|
||||
|
||||
proc loadValuesFpMont*( len: int, stream: Stream ) : seq[Fp] =
|
||||
var values : seq[Fp]
|
||||
proc loadValuesFpMont*( len: int, stream: Stream ) : seq[Fp[BN254_Snarks]] =
|
||||
var values : seq[Fp[BN254_Snarks]]
|
||||
for i in 1..len:
|
||||
values.add( loadValueFpMont(stream) )
|
||||
return values
|
||||
|
||||
proc loadValuesFrMont*( len: int, stream: Stream ) : seq[Fr] =
|
||||
var values : seq[Fr]
|
||||
proc loadValuesFrMont*( len: int, stream: Stream ) : seq[Fr[BN254_Snarks]] =
|
||||
var values: seq[Fr[BN254_Snarks]]
|
||||
for i in 1..len:
|
||||
values.add( loadValueFrMont(stream) )
|
||||
return values
|
||||
|
||||
@ -12,12 +12,12 @@ import taskpools
|
||||
import constantine/platforms/abstractions except Subgroup
|
||||
import constantine/math/endomorphisms/frobenius except Subgroup
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fp2, Fr
|
||||
import constantine/math/io/io_fields except Fp, Fp2, Fr
|
||||
import constantine/math/io/io_bigints
|
||||
import constantine/named/properties_fields except Fp, Fr, Subgroup
|
||||
import constantine/named/properties_fields except Subgroup
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_fields
|
||||
|
||||
import constantine/math/extension_fields/towers as ext except Fp, Fp2, Fp12, Fr
|
||||
import constantine/math/extension_fields/towers as ext
|
||||
import constantine/math/elliptic/ec_shortweierstrass_affine as aff except Subgroup
|
||||
import constantine/math/elliptic/ec_shortweierstrass_projective as prj except Subgroup
|
||||
import constantine/math/elliptic/ec_scalar_mul_vartime as scl except Subgroup
|
||||
@ -31,7 +31,7 @@ import std/times
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
proc msmConstantineG1*( coeffs: openArray[Fr] , points: openArray[G1] ): G1 =
|
||||
proc msmConstantineG1*( coeffs: openArray[Fr[BN254_Snarks]] , points: openArray[G1] ): G1 =
|
||||
|
||||
# let start = cpuTime()
|
||||
|
||||
@ -59,7 +59,7 @@ proc msmConstantineG1*( coeffs: openArray[Fr] , points: openArray[G1] ): G1 =
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
func msmConstantineG2*( coeffs: openArray[Fr] , points: openArray[G2] ): G2 =
|
||||
func msmConstantineG2*( coeffs: openArray[Fr[BN254_Snarks]] , points: openArray[G2] ): G2 =
|
||||
|
||||
let N = coeffs.len
|
||||
assert( N == points.len, "incompatible sequence lengths" )
|
||||
@ -85,7 +85,7 @@ func msmConstantineG2*( coeffs: openArray[Fr] , points: openArray[G2] ): G2 =
|
||||
|
||||
const task_multiplier : int = 1
|
||||
|
||||
proc msmMultiThreadedG1*( nthreads_hint: int, coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
||||
proc msmMultiThreadedG1*( nthreads_hint: int, coeffs: seq[Fr[BN254_Snarks]] , points: seq[G1] ): G1 =
|
||||
|
||||
# for N <= 255 , we use 1 thread
|
||||
# for N == 256 , we use 2 threads
|
||||
@ -124,7 +124,7 @@ proc msmMultiThreadedG1*( nthreads_hint: int, coeffs: seq[Fr] , points: seq[G1]
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
proc msmMultiThreadedG2*( nthreads_hint: int, coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
||||
proc msmMultiThreadedG2*( nthreads_hint: int, coeffs: seq[Fr[BN254_Snarks]] , points: seq[G2] ): G2 =
|
||||
|
||||
let N = coeffs.len
|
||||
assert( N == points.len, "incompatible sequence lengths" )
|
||||
@ -158,7 +158,7 @@ proc msmMultiThreadedG2*( nthreads_hint: int, coeffs: seq[Fr] , points: seq[G2]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func msmNaiveG1*( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
||||
func msmNaiveG1*( coeffs: seq[Fr[BN254_Snarks]] , points: seq[G1] ): G1 =
|
||||
let N = coeffs.len
|
||||
assert( N == points.len, "incompatible sequence lengths" )
|
||||
|
||||
@ -178,7 +178,7 @@ func msmNaiveG1*( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
func msmNaiveG2*( coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
||||
func msmNaiveG2*( coeffs: seq[Fr[BN254_Snarks]] , points: seq[G2] ): G2 =
|
||||
let N = coeffs.len
|
||||
assert( N == points.len, "incompatible sequence lengths" )
|
||||
|
||||
@ -198,8 +198,8 @@ func msmNaiveG2*( coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
proc msmG1*( coeffs: seq[Fr] , points: seq[G1] ): G1 = msmConstantineG1(coeffs, points)
|
||||
proc msmG2*( coeffs: seq[Fr] , points: seq[G2] ): G2 = msmConstantineG2(coeffs, points)
|
||||
proc msmG1*( coeffs: seq[Fr[BN254_Snarks]] , points: seq[G1] ): G1 = msmConstantineG1(coeffs, points)
|
||||
proc msmG2*( coeffs: seq[Fr[BN254_Snarks]] , points: seq[G2] ): G2 = msmConstantineG2(coeffs, points)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@ import std/random
|
||||
|
||||
# import constantine/platforms/abstractions
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fp2, Fr
|
||||
import constantine/math/io/io_fields except Fp, Fp2, Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_fields
|
||||
import constantine/math/io/io_bigints
|
||||
import constantine/named/properties_fields
|
||||
|
||||
@ -60,9 +60,9 @@ proc randBig*[bits: static int](): BigInt[bits] =
|
||||
|
||||
return d
|
||||
|
||||
proc randFr*(): Fr =
|
||||
proc randFr*(): Fr[BN254_Snarks] =
|
||||
let b : BigInt[254] = randBig[254]()
|
||||
var y : Fr
|
||||
var y : Fr[BN254_Snarks]
|
||||
y.fromBig( b )
|
||||
return y
|
||||
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
import sugar
|
||||
import std/tables
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/named/properties_fields
|
||||
|
||||
import groth16/bn128
|
||||
import groth16/math/domain
|
||||
@ -22,11 +23,11 @@ import groth16/misc
|
||||
|
||||
type
|
||||
ToxicWaste* = object
|
||||
alpha*: Fr
|
||||
beta*: Fr
|
||||
gamma*: Fr
|
||||
delta*: Fr
|
||||
tau*: Fr
|
||||
alpha*: Fr[BN254_Snarks]
|
||||
beta*: Fr[BN254_Snarks]
|
||||
gamma*: Fr[BN254_Snarks]
|
||||
delta*: Fr[BN254_Snarks]
|
||||
tau*: Fr[BN254_Snarks]
|
||||
|
||||
proc randomToxicWaste*(): ToxicWaste =
|
||||
let a = randFr()
|
||||
@ -73,9 +74,9 @@ type DenseMatrix*[T] = seq[DenseColumn[T]]
|
||||
|
||||
type
|
||||
DenseMatrices* = object
|
||||
A* : DenseMatrix[Fr]
|
||||
B* : DenseMatrix[Fr]
|
||||
C* : DenseMatrix[Fr]
|
||||
A* : DenseMatrix[Fr[BN254_Snarks]]
|
||||
B* : DenseMatrix[Fr[BN254_Snarks]]
|
||||
C* : DenseMatrix[Fr[BN254_Snarks]]
|
||||
|
||||
#[
|
||||
|
||||
@ -137,13 +138,13 @@ func denseMatricesToCoeffs*(matrices: DenseMatrices): seq[Coeff] =
|
||||
|
||||
type SparseColumn*[T] = Table[int,T]
|
||||
|
||||
proc columnInsertWithAddFr( col: var SparseColumn[Fr] , i: int, y: Fr ) =
|
||||
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], V: DenseColumn[Fr] ): Fr =
|
||||
var acc : Fr = zeroFr
|
||||
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
|
||||
@ -152,9 +153,9 @@ type SparseMatrix*[T] = seq[SparseColumn[T]]
|
||||
|
||||
type
|
||||
SparseMatrices* = object
|
||||
A* : SparseMatrix[Fr]
|
||||
B* : SparseMatrix[Fr]
|
||||
C* : SparseMatrix[Fr]
|
||||
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
|
||||
@ -164,11 +165,11 @@ func r1csToSparseMatrices*(r1cs: R1CS): SparseMatrices =
|
||||
let logDomSize = ceilingLog2(n+p+1)
|
||||
let domSize = 1 shl logDomSize
|
||||
|
||||
var matA, matB, matC: SparseMatrix[Fr]
|
||||
var matA, matB, matC: SparseMatrix[Fr[BN254_Snarks]]
|
||||
for i in 0..<m:
|
||||
var colA : SparseColumn[Fr] = initTable[int,Fr]()
|
||||
var colB : SparseColumn[Fr] = initTable[int,Fr]()
|
||||
var colC : SparseColumn[Fr] = initTable[int,Fr]()
|
||||
var colA : SparseColumn[Fr[BN254_Snarks]] = initTable[int,Fr[BN254_Snarks]]()
|
||||
var colB : SparseColumn[Fr[BN254_Snarks]] = initTable[int,Fr[BN254_Snarks]]()
|
||||
var colC : SparseColumn[Fr[BN254_Snarks]] = initTable[int,Fr[BN254_Snarks]]()
|
||||
matA.add( colA )
|
||||
matB.add( colB )
|
||||
matC.add( colC )
|
||||
@ -188,10 +189,10 @@ func r1csToSparseMatrices*(r1cs: R1CS): SparseMatrices =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func dotProdFr(xs, ys: seq[Fr]): Fr =
|
||||
func dotProdFr(xs, ys: seq[Fr[BN254_Snarks]]): Fr[BN254_Snarks] =
|
||||
let n = xs.len
|
||||
assert( n == ys.len, "dotProdFr: incompatible vector lengths" )
|
||||
var s : Fr = zeroFr
|
||||
var s : Fr[BN254_Snarks] = zeroFr
|
||||
for i in 0..<n:
|
||||
s += xs[i] * ys[i]
|
||||
return s
|
||||
@ -252,7 +253,7 @@ func fakeCircuitSetup*(r1cs: R1CS, toxic: ToxicWaste, flavour=Snarkjs): ZKey =
|
||||
|
||||
# the Lagrange polynomials L_k(x) evaluated at x=tau
|
||||
# we can then simply take the dot product of these with the column vectors to compute the points A,B1,B2,C
|
||||
let lagrangeTaus : seq[Fr] = collect( newSeq, (for k in 0..<domSize: evalLagrangePolyAt(D, k, toxic.tau) ))
|
||||
let lagrangeTaus : seq[Fr[BN254_Snarks]] = collect( newSeq, (for k in 0..<domSize: evalLagrangePolyAt(D, k, toxic.tau) ))
|
||||
|
||||
#[
|
||||
# dense matrices use way too much memory
|
||||
@ -261,17 +262,17 @@ func fakeCircuitSetup*(r1cs: R1CS, toxic: ToxicWaste, flavour=Snarkjs): ZKey =
|
||||
let columnTausC : seq[Fr] = collect( newSeq, (for col in matrices.C: dotProdFr(col,lagrangeTaus) ))
|
||||
]#
|
||||
|
||||
let columnTausA : seq[Fr] = collect( newSeq, (for col in matrices.A: sparseDenseDotProdFr(col,lagrangeTaus) ))
|
||||
let columnTausB : seq[Fr] = collect( newSeq, (for col in matrices.B: sparseDenseDotProdFr(col,lagrangeTaus) ))
|
||||
let columnTausC : seq[Fr] = collect( newSeq, (for col in matrices.C: sparseDenseDotProdFr(col,lagrangeTaus) ))
|
||||
let columnTausA : seq[Fr[BN254_Snarks]] = collect( newSeq, (for col in matrices.A: sparseDenseDotProdFr(col,lagrangeTaus) ))
|
||||
let columnTausB : seq[Fr[BN254_Snarks]] = collect( newSeq, (for col in matrices.B: sparseDenseDotProdFr(col,lagrangeTaus) ))
|
||||
let columnTausC : seq[Fr[BN254_Snarks]] = collect( newSeq, (for col in matrices.C: sparseDenseDotProdFr(col,lagrangeTaus) ))
|
||||
|
||||
let pointsA : seq[G1] = collect( newSeq , (for y in columnTausA: (y ** gen1) ))
|
||||
let pointsB1 : seq[G1] = collect( newSeq , (for y in columnTausB: (y ** gen1) ))
|
||||
let pointsB2 : seq[G2] = collect( newSeq , (for y in columnTausB: (y ** gen2) ))
|
||||
let pointsC : seq[G1] = collect( newSeq , (for y in columnTausC: (y ** gen1) ))
|
||||
|
||||
let gammaInv : Fr = invFr(toxic.gamma)
|
||||
let deltaInv : Fr = invFr(toxic.delta)
|
||||
let gammaInv : Fr[BN254_Snarks] = invFr(toxic.gamma)
|
||||
let deltaInv : Fr[BN254_Snarks] = invFr(toxic.delta)
|
||||
|
||||
let pointsL : seq[G1] = collect( newSeq , (for j in 0..npub:
|
||||
gammaInv ** ( toxic.beta ** pointsA[j] + toxic.alpha ** pointsB1[j] + pointsC[j] ) ))
|
||||
|
||||
@ -25,7 +25,7 @@ import std/streams
|
||||
|
||||
import sugar
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_bigints
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -3,19 +3,20 @@
|
||||
# export proof and public input in `circom`-compatible JSON files
|
||||
#
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
#import constantine/math/io/io_fields except Fp, Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/named/properties_fields
|
||||
import constantine/math/extension_fields/towers
|
||||
|
||||
import groth16/bn128
|
||||
from groth16/prover import Proof
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func toQuotedDecimalFp(x: Fp): string =
|
||||
func toQuotedDecimalFp(x: Fp[BN254_Snarks]): string =
|
||||
let s : string = toDecimalFp(x)
|
||||
return ("\"" & s & "\"")
|
||||
|
||||
func toQuotedDecimalFr(x: Fr): string =
|
||||
func toQuotedDecimalFr(x: Fr[BN254_Snarks]): string =
|
||||
let s : string = toDecimalFr(x)
|
||||
return ("\"" & s & "\"")
|
||||
|
||||
|
||||
@ -51,8 +51,9 @@
|
||||
|
||||
import std/streams
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_bigints
|
||||
import constantine/named/properties_fields
|
||||
|
||||
import groth16/bn128
|
||||
import groth16/files/container
|
||||
@ -68,7 +69,7 @@ type
|
||||
nPrivIn* : int # number of private inputs
|
||||
nLabels* : int # number of labels
|
||||
|
||||
Term* = tuple[ wireIdx: int, value: Fr ]
|
||||
Term* = tuple[ wireIdx: int, value: Fr[BN254_Snarks] ]
|
||||
LinComb* = seq[Term]
|
||||
Constraint* = tuple[ A: LinComb, B: LinComb, C: LinComb ]
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
import std/streams
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_bigints
|
||||
import constantine/named/properties_fields
|
||||
|
||||
@ -30,7 +30,7 @@ type
|
||||
curve* : string
|
||||
r* : BigInt[256]
|
||||
nvars* : int
|
||||
values* : seq[Fr]
|
||||
values* : seq[Fr[BN254_Snarks]]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@
|
||||
|
||||
import std/streams
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
import constantine/math/arithmetic
|
||||
#import constantine/math/io/io_bigints
|
||||
|
||||
import groth16/bn128
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
# power-of-two sized multiplicative FFT domains in the scalar field
|
||||
#
|
||||
|
||||
import constantine/math/arithmetic except Fp,Fr
|
||||
import constantine/math/io/io_fields except Fp,Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_fields
|
||||
#import constantine/math/io/io_bigints
|
||||
import constantine/named/properties_fields
|
||||
|
||||
@ -17,25 +17,25 @@ type
|
||||
Domain* = object
|
||||
domainSize* : int # `N = 2^n`
|
||||
logDomainSize* : int # `n = log2(N)`
|
||||
domainGen* : Fr # `g`
|
||||
invDomainGen* : Fr # `g^-1`
|
||||
invDomainSize* : Fr # `1/n`
|
||||
domainGen* : Fr[BN254_Snarks] # `g`
|
||||
invDomainGen* : Fr[BN254_Snarks] # `g^-1`
|
||||
invDomainSize* : Fr[BN254_Snarks] # `1/n`
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# the generator of the multiplicative subgroup with size `2^28`
|
||||
const gen28 : Fr = fromHex( Fr, "0x2a3c09f0a58a7e8500e0a7eb8ef62abc402d111e41112ed49bd61b6e725b19f0" )
|
||||
const gen28 = fromHex( Fr[BN254_Snarks], "0x2a3c09f0a58a7e8500e0a7eb8ef62abc402d111e41112ed49bd61b6e725b19f0" )
|
||||
|
||||
func createDomain*(size: int): Domain =
|
||||
let log2 = ceilingLog2(size)
|
||||
assert( (1 shl log2) == size , "domain must have a power-of-two size" )
|
||||
|
||||
let expo : uint = 1'u shl (28 - log2)
|
||||
let gen : Fr = smallPowFr(gen28, expo)
|
||||
let gen = smallPowFr(gen28, expo)
|
||||
|
||||
let halfSize = size div 2
|
||||
let a : Fr = smallPowFr(gen, size )
|
||||
let b : Fr = smallPowFr(gen, halfSize)
|
||||
let a = smallPowFr(gen, size )
|
||||
let b = smallPowFr(gen, halfSize)
|
||||
assert( bool(a == oneFr) , "domain generator sanity check /A" )
|
||||
assert( not bool(b == oneFr) , "domain generator sanity check /B" )
|
||||
|
||||
@ -48,9 +48,9 @@ func createDomain*(size: int): Domain =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func enumerateDomain*(D: Domain): seq[Fr] =
|
||||
var xs : seq[Fr] = newSeq[Fr](D.domainSize)
|
||||
var g : Fr = oneFr
|
||||
func enumerateDomain*(D: Domain): seq[Fr[BN254_Snarks]] =
|
||||
var xs = newSeq[Fr[BN254_Snarks]](D.domainSize)
|
||||
var g = oneFr
|
||||
for i in 0..<D.domainSize:
|
||||
xs[i] = g
|
||||
g *= D.domainGen
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
import constantine/math/arithmetic except Fp,Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/math/io/io_fields
|
||||
import constantine/named/properties_fields
|
||||
|
||||
@ -17,10 +17,10 @@ import groth16/math/domain
|
||||
|
||||
func forwardNTT_worker( m: int
|
||||
, srcStride: int
|
||||
, gpows: seq[Fr]
|
||||
, src: seq[Fr] , srcOfs: int
|
||||
, buf: var seq[Fr] , bufOfs: int
|
||||
, tgt: var seq[Fr] , tgtOfs: int ) =
|
||||
, gpows: seq[Fr[BN254_Snarks]]
|
||||
, src: seq[Fr[BN254_Snarks]] , srcOfs: int
|
||||
, buf: var seq[Fr[BN254_Snarks]] , bufOfs: int
|
||||
, tgt: var seq[Fr[BN254_Snarks]] , tgtOfs: int ) =
|
||||
case m
|
||||
|
||||
of 0:
|
||||
@ -46,25 +46,25 @@ func forwardNTT_worker( m: int
|
||||
, buf , bufOfs + N
|
||||
, buf , bufOfs + halfN )
|
||||
for j in 0..<halfN:
|
||||
let y : Fr = gpows[j*srcStride] * buf[bufOfs+j+halfN]
|
||||
let y = gpows[j*srcStride] * buf[bufOfs+j+halFN]
|
||||
tgt[tgtOfs+j ] = buf[bufOfs+j] + y
|
||||
tgt[tgtOfs+j+halfN] = buf[bufOfs+j] - y
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
# forward number-theoretical transform (corresponds to polynomial evaluation)
|
||||
func forwardNTT*(src: seq[Fr], D: Domain): seq[Fr] =
|
||||
func forwardNTT*(src: seq[Fr[BN254_Snarks]], D: Domain): seq[Fr[BN254_Snarks]] =
|
||||
assert( D.domainSize == (1 shl D.logDomainSize) , "domain must have a power-of-two size" )
|
||||
assert( D.domainSize == src.len , "input must have the same size as the domain" )
|
||||
var buf : seq[Fr] = newSeq[Fr]( 2 * D.domainSize )
|
||||
var tgt : seq[Fr] = newSeq[Fr]( D.domainSize )
|
||||
var buf = newSeq[Fr[BN254_Snarks] ]( 2 * D.domainSize )
|
||||
var tgt = newSeq[Fr[BN254_Snarks]]( D.domainSize )
|
||||
|
||||
# precalc powers of gen
|
||||
let N = D.domainSize
|
||||
let halFN = N div 2
|
||||
var gpows : seq[Fr] = newSeq[Fr]( halfN )
|
||||
var x : Fr = oneFr
|
||||
let gen : Fr = D.domainGen
|
||||
var gpows = newSeq[Fr[BN254_Snarks]]( halFN )
|
||||
var x = oneFr
|
||||
let gen = D.domainGen
|
||||
for i in 0..<halfN:
|
||||
gpows[i] = x
|
||||
x *= gen
|
||||
@ -79,28 +79,28 @@ func forwardNTT*(src: seq[Fr], D: Domain): seq[Fr] =
|
||||
|
||||
# pads the input with zeros to get a pwoer of two size
|
||||
# TODO: optimize the FFT so that it doesn't do the multiplications with zeros
|
||||
func extendAndForwardNTT*(src: seq[Fr], D: Domain): seq[Fr] =
|
||||
func extendAndForwardNTT*(src: seq[Fr[BN254_Snarks]], D: Domain): seq[Fr[BN254_Snarks]] =
|
||||
let n = src.len
|
||||
let N = D.domainSize
|
||||
assert( n <= N )
|
||||
if n == N:
|
||||
return forwardNTT(src, D)
|
||||
else:
|
||||
var padded : seq[Fr] = newSeq[Fr]( N )
|
||||
var padded = newSeq[Fr[BN254_Snarks]]( N )
|
||||
for i in 0..<n: padded[i] = src[i]
|
||||
# for i in n..<N: padded[i] = zeroFr
|
||||
return forwardNTT(padded, D)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
const oneHalfFr* : Fr = fromHex(Fr, "0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000001")
|
||||
const oneHalfFr* = fromHex(Fr[BN254_Snarks], "0x183227397098d014dc2822db40c0ac2e9419f4243cdcb848a1f0fac9f8000001")
|
||||
|
||||
func inverseNTT_worker( m: int
|
||||
, tgtStride: int
|
||||
, gpows: seq[Fr]
|
||||
, src: seq[Fr] , srcOfs: int
|
||||
, buf: var seq[Fr] , bufOfs: int
|
||||
, tgt: var seq[Fr] , tgtOfs: int ) =
|
||||
, gpows: seq[Fr[BN254_Snarks]]
|
||||
, src: seq[Fr[BN254_Snarks]] , srcOfs: int
|
||||
, buf: var seq[Fr[BN254_Snarks]] , bufOfs: int
|
||||
, tgt: var seq[Fr[BN254_Snarks]] , tgtOfs: int ) =
|
||||
case m
|
||||
|
||||
of 0:
|
||||
@ -137,18 +137,18 @@ func inverseNTT_worker( m: int
|
||||
#---------------------------------------
|
||||
|
||||
# inverse number-theoretical transform (corresponds to polynomial interpolation)
|
||||
func inverseNTT*(src: seq[Fr], D: Domain): seq[Fr] =
|
||||
func inverseNTT*(src: seq[Fr[BN254_Snarks]], D: Domain): seq[Fr[BN254_Snarks]] =
|
||||
assert( D.domainSize == (1 shl D.logDomainSize) , "domain must have a power-of-two size" )
|
||||
assert( D.domainSize == src.len , "input must have the same size as the domain" )
|
||||
var buf : seq[Fr] = newSeq[Fr]( 2 * D.domainSize )
|
||||
var tgt : seq[Fr] = newSeq[Fr]( D.domainSize )
|
||||
var buf = newSeq[Fr[BN254_Snarks]]( 2 * D.domainSize )
|
||||
var tgt = newSeq[Fr[BN254_Snarks]]( D.domainSize )
|
||||
|
||||
# precalc 1/2 times powers of gen^-1
|
||||
let N = D.domainSize
|
||||
let halFN = N div 2
|
||||
var gpows : seq[Fr] = newSeq[Fr]( halfN )
|
||||
var x : Fr = oneHalfFr
|
||||
let ginv : Fr = invFr( D.domainGen )
|
||||
var gpows = newSeq[Fr[BN254_Snarks]]( halFN )
|
||||
var x = oneHalfFr
|
||||
let ginv = invFr( D.domainGen )
|
||||
for i in 0..<halfN:
|
||||
gpows[i] = x
|
||||
x *= ginv
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import std/sequtils
|
||||
import std/sugar
|
||||
|
||||
import constantine/math/arithmetic except Fp,Fr
|
||||
import constantine/math/arithmetic
|
||||
#import constantine/math/io/io_fields
|
||||
import constantine/named/properties_fields
|
||||
|
||||
@ -22,7 +22,7 @@ import groth16/misc
|
||||
|
||||
type
|
||||
Poly* = object
|
||||
coeffs* : seq[Fr]
|
||||
coeffs* : seq[Fr[BN254_Snarks]]
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
@ -42,8 +42,8 @@ func polyIsZero*(P: Poly) : bool =
|
||||
return b
|
||||
|
||||
func polyIsEqual*(P, Q: Poly) : bool =
|
||||
let xs : seq[Fr] = P.coeffs ; let n = xs.len
|
||||
let ys : seq[Fr] = Q.coeffs ; let m = ys.len
|
||||
let xs = P.coeffs ; let n = xs.len
|
||||
let ys = Q.coeffs ; let m = ys.len
|
||||
var b = true
|
||||
if n >= m:
|
||||
for i in 0..<m: ( if not isEqualFr(xs[i], ys[i]): ( b = false ; break ) )
|
||||
@ -55,10 +55,10 @@ func polyIsEqual*(P, Q: Poly) : bool =
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func polyEvalAt*(P: Poly, x0: Fr): Fr =
|
||||
func polyEvalAt*(P: Poly, x0: Fr[BN254_Snarks]): Fr[BN254_Snarks] =
|
||||
let cs = P.coeffs ; let n = cs.len
|
||||
var y : Fr = zeroFr
|
||||
var r : Fr = oneFr
|
||||
var y : Fr[BN254_Snarks] = zeroFr
|
||||
var r : Fr[BN254_Snarks] = oneFr
|
||||
if n > 0: y = cs[0]
|
||||
for i in 1..<n:
|
||||
r *= x0
|
||||
@ -68,13 +68,13 @@ func polyEvalAt*(P: Poly, x0: Fr): Fr =
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func polyNeg*(P: Poly) : Poly =
|
||||
let zs : seq[Fr] = map( P.coeffs , negFr )
|
||||
let zs = map( P.coeffs , negFr )
|
||||
return Poly(coeffs: zs)
|
||||
|
||||
func polyAdd*(P, Q: Poly) : Poly =
|
||||
let xs = P.coeffs ; let n = xs.len
|
||||
let ys = Q.coeffs ; let m = ys.len
|
||||
var zs : seq[Fr] = newSeq[Fr](max(n,m))
|
||||
var zs = newSeq[Fr[BN254_Snarks]](max(n,m))
|
||||
if n >= m:
|
||||
for i in 0..<m: zs[i] = ( xs[i] + ys[i] )
|
||||
for i in m..<n: zs[i] = ( xs[i] )
|
||||
@ -86,7 +86,7 @@ func polyAdd*(P, Q: Poly) : Poly =
|
||||
func polySub*(P, Q: Poly) : Poly =
|
||||
let xs = P.coeffs ; let n = xs.len
|
||||
let ys = Q.coeffs ; let m = ys.len
|
||||
var zs : seq[Fr] = newSeq[Fr](max(n,m))
|
||||
var zs = newSeq[Fr[BN254_Snarks]](max(n,m))
|
||||
if n >= m:
|
||||
for i in 0..<m: zs[i] = ( xs[i] - ys[i] )
|
||||
for i in m..<n: zs[i] = ( xs[i] )
|
||||
@ -98,7 +98,7 @@ func polySub*(P, Q: Poly) : Poly =
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
func polyScale*(s: Fr, P: Poly): Poly =
|
||||
let zs : seq[Fr] = map( P.coeffs , proc (x: Fr): Fr = s*x )
|
||||
let zs = map( P.coeffs , proc (x: Fr[BN254_Snarks]): Fr[BN254_Snarks] = s*x )
|
||||
return Poly(coeffs: zs)
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -107,7 +107,7 @@ func polyMulNaive*(P, Q : Poly): Poly =
|
||||
let xs = P.coeffs ; let n1 = xs.len
|
||||
let ys = Q.coeffs ; let n2 = ys.len
|
||||
let N = n1 + n2 - 1
|
||||
var zs : seq[Fr] = newSeq[Fr](N)
|
||||
var zs = newSeq[Fr[BN254_Snarks]](N)
|
||||
for k in 0..<N:
|
||||
# 0 <= i <= min(k , n1-1)
|
||||
# 0 <= j <= min(k , n2-1)
|
||||
@ -133,10 +133,10 @@ func polyMulFFT*(P, Q: Poly): Poly =
|
||||
let N : int = (1 shl log2)
|
||||
let D : Domain = createDomain( N )
|
||||
|
||||
let us : seq[Fr] = extendAndForwardNTT( P.coeffs, D )
|
||||
let vs : seq[Fr] = extendAndForwardNTT( Q.coeffs, D )
|
||||
let zs : seq[Fr] = collect( newSeq, (for i in 0..<N: us[i]*vs[i] ))
|
||||
let ws : seq[Fr] = inverseNTT( zs, D )
|
||||
let us = extendAndForwardNTT( P.coeffs, D )
|
||||
let vs = extendAndForwardNTT( Q.coeffs, D )
|
||||
let zs = collect( newSeq, (for i in 0..<N: us[i]*vs[i] ))
|
||||
let ws = inverseNTT( zs, D )
|
||||
|
||||
return Poly(coeffs: ws)
|
||||
|
||||
@ -161,9 +161,9 @@ func `*`*(P: Poly, s: Fr ): Poly = return polyScale(s, P)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# the generalized vanishing polynomial `(a*x^N - b)`
|
||||
func generalizedVanishingPoly*(N: int, a: Fr, b: Fr): Poly =
|
||||
func generalizedVanishingPoly*(N: int, a: Fr[BN254_Snarks], b: Fr[BN254_Snarks]): Poly =
|
||||
assert( N>=1 )
|
||||
var cs : seq[Fr] = newSeq[Fr]( N+1 )
|
||||
var cs = newSeq[Fr[BN254_Snarks]]( N+1 )
|
||||
cs[0] = negFr(b)
|
||||
cs[N] = a
|
||||
return Poly(coeffs: cs)
|
||||
@ -187,9 +187,9 @@ type
|
||||
func polyQuotRemByVanishing*(P: Poly, N: int): QuotRem[Poly] =
|
||||
assert( N>=1 )
|
||||
let deg : int = polyDegree(P)
|
||||
let src : seq[Fr] = P.coeffs
|
||||
var quot : seq[Fr] = newSeq[Fr]( max(1, deg - N + 1) )
|
||||
var rem : seq[Fr] = newSeq[Fr]( N )
|
||||
let src = P.coeffs
|
||||
var quot = newSeq[Fr[BN254_Snarks]]( max(1, deg - N + 1) )
|
||||
var rem = newSeq[Fr[BN254_Snarks]]( N )
|
||||
|
||||
if deg < N:
|
||||
rem = src
|
||||
@ -223,14 +223,14 @@ func polyDivideByVanishing*(P: Poly, N: int): Poly =
|
||||
# Lagrange basis polynomials
|
||||
func lagrangePoly*(D: Domain, k: int): Poly =
|
||||
let N = D.domainSize
|
||||
let omMinusK : Fr = smallPowFr( D.invDomainGen , k )
|
||||
let invN : Fr = invFr(intToFr(N))
|
||||
let omMinusK = smallPowFr( D.invDomainGen , k )
|
||||
let invN = invFr(intToFr(N))
|
||||
|
||||
var cs : seq[Fr] = newSeq[Fr]( N )
|
||||
var cs = newSeq[Fr[BN254_Snarks]]( N )
|
||||
if k == 0:
|
||||
for i in 0..<N: cs[i] = invN
|
||||
else:
|
||||
var s : Fr = invN
|
||||
var s = invN
|
||||
for i in 0..<N:
|
||||
cs[i] = s
|
||||
s *= omMinusK
|
||||
@ -240,7 +240,7 @@ func lagrangePoly*(D: Domain, k: int): Poly =
|
||||
#---------------------------------------
|
||||
|
||||
# evaluate a Lagrange basis polynomial at a given point `zeta` (outside the domain)
|
||||
func evalLagrangePolyAt*(D: Domain, k: int, zeta: Fr): Fr =
|
||||
func evalLagrangePolyAt*(D: Domain, k: int, zeta: Fr[BN254_Snarks]): Fr[BN254_Snarks] =
|
||||
let omegaK = smallPowFr(D.domainGen, k)
|
||||
let denom = (zeta - omegaK)
|
||||
if bool(isZero(denom)):
|
||||
@ -253,16 +253,16 @@ func evalLagrangePolyAt*(D: Domain, k: int, zeta: Fr): Fr =
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
# evaluates a polynomial on an FFT domain
|
||||
func polyForwardNTT*(P: Poly, D: Domain): seq[Fr] =
|
||||
func polyForwardNTT*(P: Poly, D: Domain): seq[Fr[BN254_Snarks]] =
|
||||
let n = P.coeffs.len
|
||||
assert( n <= D.domainSize , "the domain must be as least as big as the polynomial" )
|
||||
let src : seq[Fr] = P.coeffs
|
||||
let src = P.coeffs
|
||||
return forwardNTT(src, D)
|
||||
|
||||
#---------------------------------------
|
||||
|
||||
# interpolates a polynomial on an FFT domain
|
||||
func polyInverseNTT*(ys: seq[Fr], D: Domain): Poly =
|
||||
func polyInverseNTT*(ys: seq[Fr[BN254_Snarks]], D: Domain): Poly =
|
||||
let n = ys.len
|
||||
assert( n == D.domainSize , "the domain must be same size as the input" )
|
||||
let tgt = inverseNTT(ys, D)
|
||||
|
||||
@ -20,11 +20,11 @@ import std/times
|
||||
import std/cpuinfo
|
||||
import system
|
||||
import taskpools
|
||||
import constantine/math/arithmetic
|
||||
import constantine/named/properties_fields
|
||||
import constantine/math/extension_fields/towers
|
||||
|
||||
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 groth16/bn128
|
||||
import groth16/math/domain
|
||||
@ -37,7 +37,7 @@ import groth16/misc
|
||||
|
||||
type
|
||||
Proof* = object
|
||||
publicIO* : seq[Fr]
|
||||
publicIO* : seq[Fr[BN254_Snarks]]
|
||||
pi_a* : G1
|
||||
pi_b* : G2
|
||||
pi_c* : G1
|
||||
@ -49,17 +49,17 @@ type
|
||||
|
||||
type
|
||||
ABC = object
|
||||
valuesAz : seq[Fr]
|
||||
valuesBz : seq[Fr]
|
||||
valuesCz : seq[Fr]
|
||||
valuesAz : seq[Fr[BN254_Snarks]]
|
||||
valuesBz : seq[Fr[BN254_Snarks]]
|
||||
valuesCz : seq[Fr[BN254_Snarks]]
|
||||
|
||||
# computes the vectors A*z, B*z, C*z where z is the witness
|
||||
func buildABC( zkey: ZKey, witness: seq[Fr] ): ABC =
|
||||
func buildABC( zkey: ZKey, witness: seq[Fr[BN254_Snarks]] ): ABC =
|
||||
let hdr: GrothHeader = zkey.header
|
||||
let domSize = hdr.domainSize
|
||||
|
||||
var valuesAz : seq[Fr] = newSeq[Fr](domSize)
|
||||
var valuesBz : seq[Fr] = newSeq[Fr](domSize)
|
||||
var valuesAz = newSeq[Fr[BN254_Snarks]](domSize)
|
||||
var valuesBz = newSeq[Fr[BN254_Snarks]](domSize)
|
||||
|
||||
for entry in zkey.coeffs:
|
||||
case entry.matrix
|
||||
@ -67,7 +67,7 @@ func buildABC( zkey: ZKey, witness: seq[Fr] ): ABC =
|
||||
of MatrixB: valuesBz[entry.row] += entry.coeff * witness[entry.col]
|
||||
else: raise newException(AssertionDefect, "fatal error")
|
||||
|
||||
var valuesCz : seq[Fr] = newSeq[Fr](domSize)
|
||||
var valuesCz = newSeq[Fr[BN254_Snarks]](domSize)
|
||||
for i in 0..<domSize:
|
||||
valuesCz[i] = valuesAz[i] * valuesBz[i]
|
||||
|
||||
@ -94,23 +94,26 @@ func computeQuotientNaive( abc: ABC ): Poly=
|
||||
#---------------------------------------
|
||||
|
||||
# returns [ eta^i * xs[i] | i<-[0..n-1] ]
|
||||
func multiplyByPowers( xs: seq[Fr], eta: Fr ): seq[Fr] =
|
||||
func multiplyByPowers( xs: seq[Fr[BN254_Snarks]], eta: Fr[BN254_Snarks] ): seq[Fr[BN254_Snarks]] =
|
||||
let n = xs.len
|
||||
assert(n >= 1)
|
||||
var ys : seq[Fr] = newSeq[Fr](n)
|
||||
var ys = newSeq[Fr[BN254_Snarks]](n)
|
||||
ys[0] = xs[0]
|
||||
if n >= 1: ys[1] = eta * xs[1]
|
||||
var spow : Fr = eta
|
||||
var spow = eta
|
||||
for i in 2..<n:
|
||||
spow *= eta
|
||||
ys[i] = spow * xs[i]
|
||||
return ys
|
||||
|
||||
# interpolates a polynomial, shift the variable by `eta`, and compute the shifted values
|
||||
func shiftEvalDomain( values: seq[Fr], D: Domain, eta: Fr ): seq[Fr] =
|
||||
func shiftEvalDomain(
|
||||
values: seq[Fr[BN254_Snarks]],
|
||||
D: Domain,
|
||||
eta: Fr[BN254_Snarks] ): seq[Fr[BN254_Snarks]] =
|
||||
let poly : Poly = polyInverseNTT( values , D )
|
||||
let cs : seq[Fr] = poly.coeffs
|
||||
var ds : seq[Fr] = multiplyByPowers( cs, eta )
|
||||
let cs : seq[Fr[BN254_Snarks]] = poly.coeffs
|
||||
var ds : seq[Fr[BN254_Snarks]] = multiplyByPowers( cs, eta )
|
||||
return polyForwardNTT( Poly(coeffs:ds), D )
|
||||
|
||||
# computes the quotient polynomial Q = (A*B - C) / Z
|
||||
@ -130,15 +133,15 @@ proc computeQuotientPointwise( nthreads: int, abc: ABC ): Poly =
|
||||
|
||||
var pool = Taskpool.new(num_threads = nthreads)
|
||||
|
||||
var A1fv : FlowVar[seq[Fr]] = pool.spawn shiftEvalDomain( abc.valuesAz, D, eta )
|
||||
var B1fv : FlowVar[seq[Fr]] = pool.spawn shiftEvalDomain( abc.valuesBz, D, eta )
|
||||
var C1fv : FlowVar[seq[Fr]] = pool.spawn shiftEvalDomain( abc.valuesCz, D, eta )
|
||||
var A1fv : FlowVar[seq[Fr[BN254_Snarks]]] = pool.spawn shiftEvalDomain( abc.valuesAz, D, eta )
|
||||
var B1fv : FlowVar[seq[Fr[BN254_Snarks]]] = pool.spawn shiftEvalDomain( abc.valuesBz, D, eta )
|
||||
var C1fv : FlowVar[seq[Fr[BN254_Snarks]]] = pool.spawn shiftEvalDomain( abc.valuesCz, D, eta )
|
||||
|
||||
let A1 = sync A1fv
|
||||
let B1 = sync B1fv
|
||||
let C1 = sync C1fv
|
||||
|
||||
var ys : seq[Fr] = newSeq[Fr]( n )
|
||||
var ys : seq[Fr[BN254_Snarks]] = newSeq[Fr[BN254_Snarks]]( n )
|
||||
for j in 0..<n: ys[j] = ( A1[j]*B1[j] - C1[j] ) * invZ1
|
||||
let Q1 = polyInverseNTT( ys, D )
|
||||
let cs = multiplyByPowers( Q1.coeffs, invFr(eta) )
|
||||
@ -156,7 +159,7 @@ proc computeQuotientPointwise( nthreads: int, abc: ABC ): Poly =
|
||||
# (shifted) Lagrange bases.
|
||||
# see <https://geometry.xyz/notebook/the-hidden-little-secret-in-snarkjs>
|
||||
#
|
||||
proc computeSnarkjsScalarCoeffs( nthreads: int, abc: ABC): seq[Fr] =
|
||||
proc computeSnarkjsScalarCoeffs( nthreads: int, abc: ABC): seq[Fr[BN254_Snarks]] =
|
||||
let n = abc.valuesAz.len
|
||||
assert( abc.valuesBz.len == n )
|
||||
assert( abc.valuesCz.len == n )
|
||||
@ -165,15 +168,15 @@ proc computeSnarkjsScalarCoeffs( nthreads: int, abc: ABC): seq[Fr] =
|
||||
|
||||
var pool = Taskpool.new(num_threads = nthreads)
|
||||
|
||||
var A1fv : FlowVar[seq[Fr]] = pool.spawn shiftEvalDomain( abc.valuesAz, D, eta )
|
||||
var B1fv : FlowVar[seq[Fr]] = pool.spawn shiftEvalDomain( abc.valuesBz, D, eta )
|
||||
var C1fv : FlowVar[seq[Fr]] = pool.spawn shiftEvalDomain( abc.valuesCz, D, eta )
|
||||
var A1fv : FlowVar[seq[Fr[BN254_Snarks]]] = pool.spawn shiftEvalDomain( abc.valuesAz, D, eta )
|
||||
var B1fv : FlowVar[seq[Fr[BN254_Snarks]]] = pool.spawn shiftEvalDomain( abc.valuesBz, D, eta )
|
||||
var C1fv : FlowVar[seq[Fr[BN254_Snarks]]] = pool.spawn shiftEvalDomain( abc.valuesCz, D, eta )
|
||||
|
||||
let A1 = sync A1fv
|
||||
let B1 = sync B1fv
|
||||
let C1 = sync C1fv
|
||||
|
||||
var ys : seq[Fr] = newSeq[Fr]( n )
|
||||
var ys : seq[Fr[BN254_Snarks]] = newSeq[Fr[BN254_Snarks]]( n )
|
||||
for j in 0..<n: ys[j] = ( A1[j] * B1[j] - C1[j] )
|
||||
|
||||
pool.syncAll()
|
||||
@ -210,8 +213,8 @@ proc computeSnarkjsScalarCoeffs( nthreads: int, abc: ABC ): seq[Fr] =
|
||||
|
||||
type
|
||||
Mask* = object
|
||||
r*: Fr # masking coefficients
|
||||
s*: Fr # for zero knowledge
|
||||
r*: Fr[BN254_Snarks] # masking coefficients
|
||||
s*: Fr[BN254_Snarks] # for zero knowledge
|
||||
|
||||
proc generateProofWithMask*( nthreads: int, printTimings: bool, zkey: ZKey, wtns: Witness, mask: Mask ): Proof =
|
||||
|
||||
@ -237,7 +240,7 @@ proc generateProofWithMask*( nthreads: int, printTimings: bool, zkey: ZKey, wtns
|
||||
assert( nvars == witness.len , "wrong witness length" )
|
||||
|
||||
# remark: with the special variable "1" we actuall have (npub+1) public IO variables
|
||||
var pubIO : seq[Fr] = newSeq[Fr]( npubs + 1)
|
||||
var pubIO = newSeq[Fr[BN254_Snarks]]( npubs + 1)
|
||||
for i in 0..npubs: pubIO[i] = witness[i]
|
||||
|
||||
start = cpuTime()
|
||||
@ -246,7 +249,7 @@ proc generateProofWithMask*( nthreads: int, printTimings: bool, zkey: ZKey, wtns
|
||||
abc = buildABC( zkey, witness )
|
||||
|
||||
start = cpuTime()
|
||||
var qs : seq[Fr]
|
||||
var qs : seq[Fr[BN254_Snarks]]
|
||||
withMeasureTime(printTimings,"computing the quotient (FFTs)"):
|
||||
case zkey.header.flavour
|
||||
|
||||
@ -260,7 +263,7 @@ proc generateProofWithMask*( nthreads: int, printTimings: bool, zkey: ZKey, wtns
|
||||
of Snarkjs:
|
||||
qs = computeSnarkjsScalarCoeffs( nthreads, abc )
|
||||
|
||||
var zs : seq[Fr] = newSeq[Fr]( nvars - npubs - 1 )
|
||||
var zs = newSeq[Fr[BN254_Snarks]]( nvars - npubs - 1 )
|
||||
for j in npubs+1..<nvars:
|
||||
zs[j-npubs-1] = witness[j]
|
||||
|
||||
@ -313,8 +316,8 @@ proc generateProofWithTrivialMask*( nthreads: int, printTimings: bool, zkey: ZKe
|
||||
proc generateProof*( nthreads: int, printTimings: bool, zkey: ZKey, wtns: Witness ): Proof =
|
||||
|
||||
# masking coeffs
|
||||
let r : Fr = randFr()
|
||||
let s : Fr = randFr()
|
||||
let r = randFr()
|
||||
let s = randFr()
|
||||
let mask = Mask(r: r, s: s)
|
||||
|
||||
return generateProofWithMask( nthreads, printTimings, zkey, wtns, mask )
|
||||
|
||||
@ -16,8 +16,9 @@ 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 constantine/math/io/io_extfields
|
||||
import constantine/named/properties_fields
|
||||
import constantine/math/extension_fields/towers
|
||||
|
||||
import groth16/bn128
|
||||
import groth16/zkey_types
|
||||
@ -38,12 +39,12 @@ proc verifyProof* (vkey: VKey, prf: Proof): bool =
|
||||
|
||||
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 >
|
||||
let lhs = pairing( negG1(prf.pi_a) , prf.pi_b ) # < -pi_a , pi_b >
|
||||
let rhs1 = vkey.spec.alphaBeta # < alpha , beta >
|
||||
let rhs2 = pairing( prf.pi_c , vkey.spec.delta2 ) # < pi_c , delta >
|
||||
let rhs3 = pairing( pubG1 , vkey.spec.gamma2 ) # < sum... , gamma >
|
||||
|
||||
var eq : Fp12
|
||||
var eq : Fp12[BN254_Snarks]
|
||||
eq = lhs
|
||||
eq *= rhs1
|
||||
eq *= rhs2
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
import constantine/math/arithmetic except Fp, Fr
|
||||
import constantine/math/arithmetic
|
||||
import constantine/named/properties_fields
|
||||
import constantine/math/extension_fields/towers
|
||||
|
||||
@ -30,7 +30,7 @@ type
|
||||
gamma2* : G2 # = gamma * g2
|
||||
delta1* : G1 # = delta * g1
|
||||
delta2* : G2 # = delta * g2
|
||||
alphaBeta* : Fp12 # = <alpha1 , beta2>
|
||||
alphaBeta* : Fp12[BN254_Snarks] # = <alpha1 , beta2>
|
||||
|
||||
VerifierPoints* = object
|
||||
pointsIC* : seq[G1] # the points `delta^-1 * ( beta*A_j(tau) + alpha*B_j(tau) + C_j(tau) ) * g1` (for j <= npub)
|
||||
@ -51,7 +51,7 @@ type
|
||||
matrix* : MatrixSel
|
||||
row* : int
|
||||
col* : int
|
||||
coeff* : Fr
|
||||
coeff* : Fr[BN254_Snarks]
|
||||
|
||||
ZKey* = object
|
||||
# sectionMask* : uint32
|
||||
|
||||
@ -44,7 +44,7 @@ const myR1CS =
|
||||
)
|
||||
|
||||
# the equation we want prove is `7*11*13 + 1022 == 2023`
|
||||
let myWitnessValues : seq[Fr] = map( @[ 1, 2023, 1022, 7, 11, 13, 7*11, 7*11*13 ] , intToFr )
|
||||
let myWitnessValues = map( @[ 1, 2023, 1022, 7, 11, 13, 7*11, 7*11*13 ] , intToFr )
|
||||
# wire indices: ^^^^^^^ 0 1 2 3 4 5 6 7
|
||||
|
||||
let myWitness =
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user