mirror of
https://github.com/logos-storage/nim-groth16.git
synced 2026-01-08 00:23:09 +00:00
nimbify package
This commit is contained in:
parent
5ce7926e92
commit
4b8487b0df
@ -1,6 +1,7 @@
|
|||||||
|
import pkg/groth16
|
||||||
|
|
||||||
import ../test_proof
|
import ../tests/test_proof
|
||||||
import ../export_json
|
import ../src/export_json
|
||||||
|
|
||||||
let zkey_fname : string = "./build/product.zkey"
|
let zkey_fname : string = "./build/product.zkey"
|
||||||
let wtns_fname : string = "./build/product.wtns"
|
let wtns_fname : string = "./build/product.wtns"
|
||||||
@ -8,4 +9,3 @@ let proof = testProveAndVerify( zkey_fname, wtns_fname)
|
|||||||
|
|
||||||
exportPublicIO( "./build/nim_public.json" , proof )
|
exportPublicIO( "./build/nim_public.json" , proof )
|
||||||
exportProof( "./build/nim_proof.json" , proof )
|
exportProof( "./build/nim_proof.json" , proof )
|
||||||
|
|
||||||
|
|||||||
13
groth16.nimble
Normal file
13
groth16.nimble
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Package
|
||||||
|
|
||||||
|
version = "0.1.0"
|
||||||
|
author = "Dmitriy Ryajov"
|
||||||
|
description = "A circom/snarkjs compatible groth16 implementation"
|
||||||
|
license = "MIT"
|
||||||
|
srcDir = "src"
|
||||||
|
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
requires "nim >= 1.6.14",
|
||||||
|
"https://github.com/mratsim/constantine#5f7ba18"
|
||||||
49
misc.nim
49
misc.nim
@ -1,49 +0,0 @@
|
|||||||
|
|
||||||
#
|
|
||||||
# miscellaneous routines
|
|
||||||
#
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func delta*(i, j: int) : int =
|
|
||||||
return (if (i == j): 1 else: 0)
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
func floorLog2* (x : int) : int =
|
|
||||||
var k = -1
|
|
||||||
var y = x
|
|
||||||
while (y > 0):
|
|
||||||
k += 1
|
|
||||||
y = y shr 1
|
|
||||||
return k
|
|
||||||
|
|
||||||
func ceilingLog2* (x : int) : int =
|
|
||||||
if (x==0):
|
|
||||||
return -1
|
|
||||||
else:
|
|
||||||
return (floorLog2(x-1) + 1)
|
|
||||||
|
|
||||||
#-------------------
|
|
||||||
|
|
||||||
#[
|
|
||||||
import std/math
|
|
||||||
|
|
||||||
proc sanityCheckLog2* () =
|
|
||||||
for i in 0..18:
|
|
||||||
let x = float64(i)
|
|
||||||
echo( i," | ",floorLog2(i),"=",floor(log2(x))," | ",ceilingLog2(i),"=",ceil(log2(x)) )
|
|
||||||
]#
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#[
|
|
||||||
func rotateSeq[T](xs: seq[T], ofs: int): seq[T] =
|
|
||||||
let n = xs.len
|
|
||||||
var ys : seq[T]
|
|
||||||
for i in (0..<n):
|
|
||||||
ys.add( xs[ (i+n+ofs) mod n ] )
|
|
||||||
return ys
|
|
||||||
]#
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
|
||||||
@ -20,7 +20,7 @@ import std/random
|
|||||||
import constantine/math/arithmetic
|
import constantine/math/arithmetic
|
||||||
import constantine/math/io/io_fields
|
import constantine/math/io/io_fields
|
||||||
import constantine/math/io/io_bigints
|
import constantine/math/io/io_bigints
|
||||||
import constantine/math/config/curves
|
import constantine/math/config/curves
|
||||||
import constantine/math/config/type_ff as tff
|
import constantine/math/config/type_ff as tff
|
||||||
|
|
||||||
import constantine/math/extension_fields/towers as ext
|
import constantine/math/extension_fields/towers as ext
|
||||||
@ -49,10 +49,10 @@ func mkFp2* (i: Fp, u: Fp) : Fp2 =
|
|||||||
let c : array[2, Fp] = [i,u]
|
let c : array[2, Fp] = [i,u]
|
||||||
return ext.QuadraticExt[Fp]( coords: c )
|
return ext.QuadraticExt[Fp]( coords: c )
|
||||||
|
|
||||||
func unsafeMkG1* ( X, Y: Fp ) : G1 =
|
func unsafeMkG1* ( X, Y: Fp ) : G1 =
|
||||||
return aff.ECP_ShortW_Aff[Fp, aff.G1](x: X, y: Y)
|
return aff.ECP_ShortW_Aff[Fp, aff.G1](x: X, y: Y)
|
||||||
|
|
||||||
func unsafeMkG2* ( X, Y: Fp2 ) : G2 =
|
func unsafeMkG2* ( X, Y: Fp2 ) : G2 =
|
||||||
return aff.ECP_ShortW_Aff[Fp2, aff.G2](x: X, y: Y)
|
return aff.ECP_ShortW_Aff[Fp2, aff.G2](x: X, y: Y)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@ -113,25 +113,25 @@ func `===`*(x, y: Fr): bool = isEqualFr(x,y)
|
|||||||
|
|
||||||
#-------------------
|
#-------------------
|
||||||
|
|
||||||
func isEqualFpSeq*(xs, ys: seq[Fp]): bool =
|
func isEqualFpSeq*(xs, ys: seq[Fp]): bool =
|
||||||
let n = xs.len
|
let n = xs.len
|
||||||
assert( n == ys.len )
|
assert( n == ys.len )
|
||||||
var b = true
|
var b = true
|
||||||
for i in 0..<n:
|
for i in 0..<n:
|
||||||
if not bool(xs[i] == ys[i]):
|
if not bool(xs[i] == ys[i]):
|
||||||
b = false
|
b = false
|
||||||
break
|
break
|
||||||
return b
|
return b
|
||||||
|
|
||||||
func isEqualFrSeq*(xs, ys: seq[Fr]): bool =
|
func isEqualFrSeq*(xs, ys: seq[Fr]): bool =
|
||||||
let n = xs.len
|
let n = xs.len
|
||||||
assert( n == ys.len )
|
assert( n == ys.len )
|
||||||
var b = true
|
var b = true
|
||||||
for i in 0..<n:
|
for i in 0..<n:
|
||||||
if not bool(xs[i] == ys[i]):
|
if not bool(xs[i] == ys[i]):
|
||||||
b = false
|
b = false
|
||||||
break
|
break
|
||||||
return b
|
return b
|
||||||
|
|
||||||
func `===`*(xs, ys: seq[Fp]): bool = isEqualFpSeq(xs,ys)
|
func `===`*(xs, ys: seq[Fp]): bool = isEqualFpSeq(xs,ys)
|
||||||
func `===`*(xs, ys: seq[Fr]): bool = isEqualFrSeq(xs,ys)
|
func `===`*(xs, ys: seq[Fr]): bool = isEqualFrSeq(xs,ys)
|
||||||
@ -142,7 +142,7 @@ func `===`*(xs, ys: seq[Fr]): bool = isEqualFrSeq(xs,ys)
|
|||||||
func `+`*[n](x, y: BigInt[n] ): BigInt[n] = ( var z : BigInt[n] = x ; z += y ; return z )
|
func `+`*[n](x, y: BigInt[n] ): BigInt[n] = ( var z : BigInt[n] = x ; z += y ; return z )
|
||||||
func `+`*(x, y: Fp): Fp = ( var z : Fp = x ; z += y ; return z )
|
func `+`*(x, y: Fp): Fp = ( var z : Fp = x ; z += y ; return z )
|
||||||
func `+`*(x, y: Fr): Fr = ( var z : Fr = x ; z += y ; return z )
|
func `+`*(x, y: Fr): Fr = ( var z : Fr = x ; z += y ; return z )
|
||||||
|
|
||||||
#func `-`*(x, y: B ): B = ( var z : B = x ; z -= y ; return z )
|
#func `-`*(x, y: B ): B = ( var z : B = x ; z -= y ; return z )
|
||||||
func `-`*[n](x, y: BigInt[n] ): BigInt[n] = ( var z : BigInt[n] = x ; z -= y ; return z )
|
func `-`*[n](x, y: BigInt[n] ): BigInt[n] = ( var z : BigInt[n] = x ; z -= y ; return z )
|
||||||
func `-`*(x, y: Fp): Fp = ( var z : Fp = x ; z -= y ; return z )
|
func `-`*(x, y: Fp): Fp = ( var z : Fp = x ; z -= y ; return z )
|
||||||
@ -161,17 +161,17 @@ func invFr*(y: Fr): Fr = ( var z : Fr = y ; inv(z) ; return z )
|
|||||||
# /Users/bkomuves/.nimble/pkgs/constantine-0.0.1/constantine/math/arithmetic/finite_fields.nim(389, 7) template/generic instantiation of `fieldMod` from here
|
# /Users/bkomuves/.nimble/pkgs/constantine-0.0.1/constantine/math/arithmetic/finite_fields.nim(389, 7) template/generic instantiation of `fieldMod` from here
|
||||||
# /Users/bkomuves/.nimble/pkgs/constantine-0.0.1/constantine/math/config/curves_prop_field_derived.nim(67, 5) Error: undeclared identifier: 'getCurveOrder'
|
# /Users/bkomuves/.nimble/pkgs/constantine-0.0.1/constantine/math/config/curves_prop_field_derived.nim(67, 5) Error: undeclared identifier: 'getCurveOrder'
|
||||||
# ...
|
# ...
|
||||||
func smallPowFr*(base: Fr, expo: uint): Fr =
|
func smallPowFr*(base: Fr, expo: uint): Fr =
|
||||||
var a : Fr = oneFr
|
var a : Fr = oneFr
|
||||||
var s : Fr = base
|
var s : Fr = base
|
||||||
var e : uint = expo
|
var e : uint = expo
|
||||||
while (e > 0):
|
while (e > 0):
|
||||||
if bitand(e,1) > 0: a *= s
|
if bitand(e,1) > 0: a *= s
|
||||||
e = (e shr 1)
|
e = (e shr 1)
|
||||||
square(s)
|
square(s)
|
||||||
return a
|
return a
|
||||||
|
|
||||||
func smallPowFr*(base: Fr, expo: int): Fr =
|
func smallPowFr*(base: Fr, expo: int): Fr =
|
||||||
if expo >= 0:
|
if expo >= 0:
|
||||||
return smallPowFr( base, uint(expo) )
|
return smallPowFr( base, uint(expo) )
|
||||||
else:
|
else:
|
||||||
@ -233,7 +233,7 @@ proc debugPrintFr*(prefix: string, x: Fr) =
|
|||||||
proc debugPrintFrSeq*(msg: string, xs: seq[Fr]) =
|
proc debugPrintFrSeq*(msg: string, xs: seq[Fr]) =
|
||||||
echo "---------------------"
|
echo "---------------------"
|
||||||
echo msg
|
echo msg
|
||||||
for x in xs:
|
for x in xs:
|
||||||
debugPrintFr( " " , x )
|
debugPrintFr( " " , x )
|
||||||
|
|
||||||
proc debugPrintG1*(msg: string, pt: G1) =
|
proc debugPrintG1*(msg: string, pt: G1) =
|
||||||
@ -249,7 +249,7 @@ proc debugPrintG2*(msg: string, pt: G2) =
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
# Montgomery batch inversion
|
# Montgomery batch inversion
|
||||||
func batchInverse*( xs: seq[Fr] ) : seq[Fr] =
|
func batchInverse*( xs: seq[Fr] ) : seq[Fr] =
|
||||||
let n = xs.len
|
let n = xs.len
|
||||||
assert(n>0)
|
assert(n>0)
|
||||||
var us : seq[Fr] = newSeq[Fr](n+1)
|
var us : seq[Fr] = newSeq[Fr](n+1)
|
||||||
@ -269,9 +269,9 @@ proc sanityCheckBatchInverse*() =
|
|||||||
let n = xs.len
|
let n = xs.len
|
||||||
# for i in 0..<n: echo(i," | batch = ",toDecimalFr(ys[i])," | ref = ",toDecimalFr(zs[i]) )
|
# for i in 0..<n: echo(i," | batch = ",toDecimalFr(ys[i])," | ref = ",toDecimalFr(zs[i]) )
|
||||||
for i in 0..<n:
|
for i in 0..<n:
|
||||||
if not bool(ys[i] == zs[i]):
|
if not bool(ys[i] == zs[i]):
|
||||||
echo "batch inverse test FAILED!"
|
echo "batch inverse test FAILED!"
|
||||||
return
|
return
|
||||||
echo "batch iverse test OK."
|
echo "batch iverse test OK."
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@ -280,7 +280,7 @@ proc sanityCheckBatchInverse*() =
|
|||||||
var randomInitialized : bool = false
|
var randomInitialized : bool = false
|
||||||
var randomState : Rand = initRand( 12345 )
|
var randomState : Rand = initRand( 12345 )
|
||||||
|
|
||||||
proc rndUint64() : uint64 =
|
proc rndUint64() : uint64 =
|
||||||
return randomState.next()
|
return randomState.next()
|
||||||
|
|
||||||
proc initializeRandomIfNecessary() =
|
proc initializeRandomIfNecessary() =
|
||||||
@ -293,15 +293,15 @@ const m64 : B = fromHex( B, "0x000000000000000000000000000000000000000000000001
|
|||||||
const m128 : B = fromHex( B, "0x0000000000000000000000000000000100000000000000000000000000000000", bigEndian )
|
const m128 : B = fromHex( B, "0x0000000000000000000000000000000100000000000000000000000000000000", bigEndian )
|
||||||
const m192 : B = fromHex( B, "0x0000000000000001000000000000000000000000000000000000000000000000", bigEndian )
|
const m192 : B = fromHex( B, "0x0000000000000001000000000000000000000000000000000000000000000000", bigEndian )
|
||||||
#----------------------------| 01234567890abcdf01234567890abcdf01234567890abcdf01234567890abcdf
|
#----------------------------| 01234567890abcdf01234567890abcdf01234567890abcdf01234567890abcdf
|
||||||
|
|
||||||
proc randBig*[bits: static int](): BigInt[bits] =
|
proc randBig*[bits: static int](): BigInt[bits] =
|
||||||
|
|
||||||
initializeRandomIfNecessary()
|
initializeRandomIfNecessary()
|
||||||
|
|
||||||
let a0 : uint64 = rndUint64()
|
let a0 : uint64 = rndUint64()
|
||||||
let a1 : uint64 = rndUint64()
|
let a1 : uint64 = rndUint64()
|
||||||
let a2 : uint64 = rndUint64()
|
let a2 : uint64 = rndUint64()
|
||||||
let a3 : uint64 = rndUint64()
|
let a3 : uint64 = rndUint64()
|
||||||
|
|
||||||
# echo((a0,a1,a2,a3))
|
# echo((a0,a1,a2,a3))
|
||||||
|
|
||||||
@ -311,16 +311,16 @@ proc randBig*[bits: static int](): BigInt[bits] =
|
|||||||
var b3 : BigInt[bits] ; b3.fromUint(a3)
|
var b3 : BigInt[bits] ; b3.fromUint(a3)
|
||||||
|
|
||||||
# constantine doesn't appear to have left shift....
|
# constantine doesn't appear to have left shift....
|
||||||
var c1,c2,c3 : BigInt[bits]
|
var c1,c2,c3 : BigInt[bits]
|
||||||
prod( c1 , b1 , m64 )
|
prod( c1 , b1 , m64 )
|
||||||
prod( c2 , b2 , m128 )
|
prod( c2 , b2 , m128 )
|
||||||
prod( c3 , b3 , m192 )
|
prod( c3 , b3 , m192 )
|
||||||
|
|
||||||
var d : BigInt[bits]
|
var d : BigInt[bits]
|
||||||
d = b0
|
d = b0
|
||||||
d += c1
|
d += c1
|
||||||
d += c2
|
d += c2
|
||||||
d += c3
|
d += c3
|
||||||
|
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ proc randFr*(): Fr =
|
|||||||
y.fromBig( b )
|
y.fromBig( b )
|
||||||
return y
|
return y
|
||||||
|
|
||||||
proc testRandom*() =
|
proc testRandom*() =
|
||||||
for i in 1..20:
|
for i in 1..20:
|
||||||
let x = randFr()
|
let x = randFr()
|
||||||
echo(x.toHex())
|
echo(x.toHex())
|
||||||
@ -358,7 +358,7 @@ func checkCurveEqG1*( x, y: Fp ) : bool =
|
|||||||
|
|
||||||
# y^2 = x^3 + B
|
# y^2 = x^3 + B
|
||||||
# B = b1 + bu*u
|
# B = b1 + bu*u
|
||||||
# b1 = 19485874751759354771024239261021720505790618469301721065564631296452457478373
|
# b1 = 19485874751759354771024239261021720505790618469301721065564631296452457478373
|
||||||
# b2 = 266929791119991161246907387137283842545076965332900288569378510910307636690
|
# b2 = 266929791119991161246907387137283842545076965332900288569378510910307636690
|
||||||
const twistCoeffB_1 : Fp = fromHex(Fp, "0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5")
|
const twistCoeffB_1 : Fp = fromHex(Fp, "0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5")
|
||||||
const twistCoeffB_u : Fp = fromHex(Fp, "0x009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2")
|
const twistCoeffB_u : Fp = fromHex(Fp, "0x009713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2")
|
||||||
@ -380,14 +380,14 @@ func checkCurveEqG2*( x, y: Fp2 ) : bool =
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
func mkG1( x, y: Fp ) : G1 =
|
func mkG1( x, y: Fp ) : G1 =
|
||||||
if bool(isZero(x)) and bool(isZero(y)):
|
if bool(isZero(x)) and bool(isZero(y)):
|
||||||
return infG1
|
return infG1
|
||||||
else:
|
else:
|
||||||
assert( checkCurveEqG1(x,y) , "mkG1: not a G1 curve point" )
|
assert( checkCurveEqG1(x,y) , "mkG1: not a G1 curve point" )
|
||||||
return unsafeMkG1(x,y)
|
return unsafeMkG1(x,y)
|
||||||
|
|
||||||
func mkG2( x, y: Fp2 ) : G2 =
|
func mkG2( x, y: Fp2 ) : G2 =
|
||||||
if bool(isZero(x)) and bool(isZero(y)):
|
if bool(isZero(x)) and bool(isZero(y)):
|
||||||
return infG2
|
return infG2
|
||||||
else:
|
else:
|
||||||
@ -413,10 +413,10 @@ const gen2* : G2 = unsafeMkG2( gen2_x, gen2_y )
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
func isOnCurveG1* ( p: G1 ) : bool =
|
func isOnCurveG1* ( p: G1 ) : bool =
|
||||||
return checkCurveEqG1( p.x, p.y )
|
return checkCurveEqG1( p.x, p.y )
|
||||||
|
|
||||||
func isOnCurveG2* ( p: G2 ) : bool =
|
func isOnCurveG2* ( p: G2 ) : bool =
|
||||||
return checkCurveEqG2( p.x, p.y )
|
return checkCurveEqG2( p.x, p.y )
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
@ -424,27 +424,27 @@ func isOnCurveG2* ( p: G2 ) : bool =
|
|||||||
#
|
#
|
||||||
|
|
||||||
# R=2^256; this computes 2^256 mod Fp
|
# R=2^256; this computes 2^256 mod Fp
|
||||||
func calcFpMontR*() : Fp =
|
func calcFpMontR*() : Fp =
|
||||||
var x : Fp = intToFp(2)
|
var x : Fp = intToFp(2)
|
||||||
for i in 1..8:
|
for i in 1..8:
|
||||||
square(x)
|
square(x)
|
||||||
return x
|
return x
|
||||||
|
|
||||||
# R=2^256; this computes the inverse of (2^256 mod Fp)
|
# R=2^256; this computes the inverse of (2^256 mod Fp)
|
||||||
func calcFpInvMontR*() : Fp =
|
func calcFpInvMontR*() : Fp =
|
||||||
var x : Fp = calcFpMontR()
|
var x : Fp = calcFpMontR()
|
||||||
inv(x)
|
inv(x)
|
||||||
return x
|
return x
|
||||||
|
|
||||||
# R=2^256; this computes 2^256 mod Fr
|
# R=2^256; this computes 2^256 mod Fr
|
||||||
func calcFrMontR*() : Fr =
|
func calcFrMontR*() : Fr =
|
||||||
var x : Fr = intToFr(2)
|
var x : Fr = intToFr(2)
|
||||||
for i in 1..8:
|
for i in 1..8:
|
||||||
square(x)
|
square(x)
|
||||||
return x
|
return x
|
||||||
|
|
||||||
# R=2^256; this computes the inverse of (2^256 mod Fp)
|
# R=2^256; this computes the inverse of (2^256 mod Fp)
|
||||||
func calcFrInvMontR*() : Fr =
|
func calcFrInvMontR*() : Fr =
|
||||||
var x : Fr = calcFrMontR()
|
var x : Fr = calcFrMontR()
|
||||||
inv(x)
|
inv(x)
|
||||||
return x
|
return x
|
||||||
@ -467,20 +467,20 @@ proc checkMontgomeryConstants*() =
|
|||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
|
|
||||||
# the binary files used by the `circom` ecosystem (EXCEPT the witness file!)
|
# the binary files used by the `circom` ecosystem (EXCEPT the witness file!)
|
||||||
# always use little-endian Montgomery representation. So when we unmarshal
|
# always use little-endian Montgomery representation. So when we unmarshal
|
||||||
# with Constantine, it will give the wrong result. Calling this function on
|
# with Constantine, it will give the wrong result. Calling this function on
|
||||||
# the result fixes that.
|
# the result fixes that.
|
||||||
func fromMontgomeryFp*(x : Fp) : Fp =
|
func fromMontgomeryFp*(x : Fp) : Fp =
|
||||||
var y : Fp = x;
|
var y : Fp = x;
|
||||||
y *= fpInvMontR
|
y *= fpInvMontR
|
||||||
return y
|
return y
|
||||||
|
|
||||||
func fromMontgomeryFr*(x : Fr) : Fr =
|
func fromMontgomeryFr*(x : Fr) : Fr =
|
||||||
var y : Fr = x;
|
var y : Fr = x;
|
||||||
y *= frInvMontR
|
y *= frInvMontR
|
||||||
return y
|
return y
|
||||||
|
|
||||||
func toMontgomeryFr*(x : Fr) : Fr =
|
func toMontgomeryFr*(x : Fr) : Fr =
|
||||||
var y : Fr = x;
|
var y : Fr = x;
|
||||||
y *= frMontR
|
y *= frMontR
|
||||||
return y
|
return y
|
||||||
@ -493,37 +493,37 @@ func toMontgomeryFr*(x : Fr) : Fr =
|
|||||||
#
|
#
|
||||||
|
|
||||||
# WTF Jordi, go home you are drunk
|
# WTF Jordi, go home you are drunk
|
||||||
func unmarshalFrWTF* ( bs: array[32,byte] ) : Fr =
|
func unmarshalFrWTF* ( bs: array[32,byte] ) : Fr =
|
||||||
var big : BigInt[254]
|
var big : BigInt[254]
|
||||||
unmarshal( big, bs, littleEndian );
|
unmarshal( big, bs, littleEndian );
|
||||||
var x : Fr
|
var x : Fr
|
||||||
x.fromBig( big )
|
x.fromBig( big )
|
||||||
return fromMontgomeryFr(fromMontgomeryFr(x))
|
return fromMontgomeryFr(fromMontgomeryFr(x))
|
||||||
|
|
||||||
func unmarshalFrStd* ( bs: array[32,byte] ) : Fr =
|
func unmarshalFrStd* ( bs: array[32,byte] ) : Fr =
|
||||||
var big : BigInt[254]
|
var big : BigInt[254]
|
||||||
unmarshal( big, bs, littleEndian );
|
unmarshal( big, bs, littleEndian );
|
||||||
var x : Fr
|
var x : Fr
|
||||||
x.fromBig( big )
|
x.fromBig( big )
|
||||||
return x
|
return x
|
||||||
|
|
||||||
func unmarshalFpMont* ( bs: array[32,byte] ) : Fp =
|
func unmarshalFpMont* ( bs: array[32,byte] ) : Fp =
|
||||||
var big : BigInt[254]
|
var big : BigInt[254]
|
||||||
unmarshal( big, bs, littleEndian );
|
unmarshal( big, bs, littleEndian );
|
||||||
var x : Fp
|
var x : Fp
|
||||||
x.fromBig( big )
|
x.fromBig( big )
|
||||||
return fromMontgomeryFp(x)
|
return fromMontgomeryFp(x)
|
||||||
|
|
||||||
func unmarshalFrMont* ( bs: array[32,byte] ) : Fr =
|
func unmarshalFrMont* ( bs: array[32,byte] ) : Fr =
|
||||||
var big : BigInt[254]
|
var big : BigInt[254]
|
||||||
unmarshal( big, bs, littleEndian );
|
unmarshal( big, bs, littleEndian );
|
||||||
var x : Fr
|
var x : Fr
|
||||||
x.fromBig( big )
|
x.fromBig( big )
|
||||||
return fromMontgomeryFr(x)
|
return fromMontgomeryFr(x)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
func unmarshalFpMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fp] =
|
func unmarshalFpMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fp] =
|
||||||
var vals : seq[Fp] = newSeq[Fp]( len )
|
var vals : seq[Fp] = newSeq[Fp]( len )
|
||||||
var bytes : array[32,byte]
|
var bytes : array[32,byte]
|
||||||
for i in 0..<len:
|
for i in 0..<len:
|
||||||
@ -531,7 +531,7 @@ func unmarshalFpMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fp] =
|
|||||||
vals[i] = unmarshalFpMont( bytes )
|
vals[i] = unmarshalFpMont( bytes )
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
func unmarshalFrMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fr] =
|
func unmarshalFrMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fr] =
|
||||||
var vals : seq[Fr] = newSeq[Fr]( len )
|
var vals : seq[Fr] = newSeq[Fr]( len )
|
||||||
var bytes : array[32,byte]
|
var bytes : array[32,byte]
|
||||||
for i in 0..<len:
|
for i in 0..<len:
|
||||||
@ -541,7 +541,7 @@ func unmarshalFrMontSeq* ( len: int, bs: openArray[byte] ) : seq[Fr] =
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc loadValueFrWTF*( stream: Stream ) : Fr =
|
proc loadValueFrWTF*( stream: Stream ) : Fr =
|
||||||
var bytes : array[32,byte]
|
var bytes : array[32,byte]
|
||||||
let n = stream.readData( addr(bytes), 32 )
|
let n = stream.readData( addr(bytes), 32 )
|
||||||
# for i in 0..<32: stdout.write(" " & toHex(bytes[i]))
|
# for i in 0..<32: stdout.write(" " & toHex(bytes[i]))
|
||||||
@ -549,44 +549,44 @@ proc loadValueFrWTF*( stream: Stream ) : Fr =
|
|||||||
assert( n == 32 )
|
assert( n == 32 )
|
||||||
return unmarshalFrWTF(bytes)
|
return unmarshalFrWTF(bytes)
|
||||||
|
|
||||||
proc loadValueFrStd*( stream: Stream ) : Fr =
|
proc loadValueFrStd*( stream: Stream ) : Fr =
|
||||||
var bytes : array[32,byte]
|
var bytes : array[32,byte]
|
||||||
let n = stream.readData( addr(bytes), 32 )
|
let n = stream.readData( addr(bytes), 32 )
|
||||||
assert( n == 32 )
|
assert( n == 32 )
|
||||||
return unmarshalFrStd(bytes)
|
return unmarshalFrStd(bytes)
|
||||||
|
|
||||||
proc loadValueFrMont*( stream: Stream ) : Fr =
|
proc loadValueFrMont*( stream: Stream ) : Fr =
|
||||||
var bytes : array[32,byte]
|
var bytes : array[32,byte]
|
||||||
let n = stream.readData( addr(bytes), 32 )
|
let n = stream.readData( addr(bytes), 32 )
|
||||||
assert( n == 32 )
|
assert( n == 32 )
|
||||||
return unmarshalFrMont(bytes)
|
return unmarshalFrMont(bytes)
|
||||||
|
|
||||||
proc loadValueFpMont*( stream: Stream ) : Fp =
|
proc loadValueFpMont*( stream: Stream ) : Fp =
|
||||||
var bytes : array[32,byte]
|
var bytes : array[32,byte]
|
||||||
let n = stream.readData( addr(bytes), 32 )
|
let n = stream.readData( addr(bytes), 32 )
|
||||||
assert( n == 32 )
|
assert( n == 32 )
|
||||||
return unmarshalFpMont(bytes)
|
return unmarshalFpMont(bytes)
|
||||||
|
|
||||||
proc loadValueFp2Mont*( stream: Stream ) : Fp2 =
|
proc loadValueFp2Mont*( stream: Stream ) : Fp2 =
|
||||||
let i = loadValueFpMont( stream )
|
let i = loadValueFpMont( stream )
|
||||||
let u = loadValueFpMont( stream )
|
let u = loadValueFpMont( stream )
|
||||||
return mkFp2(i,u)
|
return mkFp2(i,u)
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
|
|
||||||
proc loadValuesFrStd*( len: int, stream: Stream ) : seq[Fr] =
|
proc loadValuesFrStd*( len: int, stream: Stream ) : seq[Fr] =
|
||||||
var values : seq[Fr]
|
var values : seq[Fr]
|
||||||
for i in 1..len:
|
for i in 1..len:
|
||||||
values.add( loadValueFrStd(stream) )
|
values.add( loadValueFrStd(stream) )
|
||||||
return values
|
return values
|
||||||
|
|
||||||
proc loadValuesFpMont*( len: int, stream: Stream ) : seq[Fp] =
|
proc loadValuesFpMont*( len: int, stream: Stream ) : seq[Fp] =
|
||||||
var values : seq[Fp]
|
var values : seq[Fp]
|
||||||
for i in 1..len:
|
for i in 1..len:
|
||||||
values.add( loadValueFpMont(stream) )
|
values.add( loadValueFpMont(stream) )
|
||||||
return values
|
return values
|
||||||
|
|
||||||
proc loadValuesFrMont*( len: int, stream: Stream ) : seq[Fr] =
|
proc loadValuesFrMont*( len: int, stream: Stream ) : seq[Fr] =
|
||||||
var values : seq[Fr]
|
var values : seq[Fr]
|
||||||
for i in 1..len:
|
for i in 1..len:
|
||||||
values.add( loadValueFrMont(stream) )
|
values.add( loadValueFrMont(stream) )
|
||||||
@ -594,25 +594,25 @@ proc loadValuesFrMont*( len: int, stream: Stream ) : seq[Fr] =
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc loadPointG1*( stream: Stream ) : G1 =
|
proc loadPointG1*( stream: Stream ) : G1 =
|
||||||
let x = loadValueFpMont( stream )
|
let x = loadValueFpMont( stream )
|
||||||
let y = loadValueFpMont( stream )
|
let y = loadValueFpMont( stream )
|
||||||
return mkG1(x,y)
|
return mkG1(x,y)
|
||||||
|
|
||||||
proc loadPointG2*( stream: Stream ) : G2 =
|
proc loadPointG2*( stream: Stream ) : G2 =
|
||||||
let x = loadValueFp2Mont( stream )
|
let x = loadValueFp2Mont( stream )
|
||||||
let y = loadValueFp2Mont( stream )
|
let y = loadValueFp2Mont( stream )
|
||||||
return mkG2(x,y)
|
return mkG2(x,y)
|
||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
|
|
||||||
proc loadPointsG1*( len: int, stream: Stream ) : seq[G1] =
|
proc loadPointsG1*( len: int, stream: Stream ) : seq[G1] =
|
||||||
var points : seq[G1]
|
var points : seq[G1]
|
||||||
for i in 1..len:
|
for i in 1..len:
|
||||||
points.add( loadPointG1(stream) )
|
points.add( loadPointG1(stream) )
|
||||||
return points
|
return points
|
||||||
|
|
||||||
proc loadPointsG2*( len: int, stream: Stream ) : seq[G2] =
|
proc loadPointsG2*( len: int, stream: Stream ) : seq[G2] =
|
||||||
var points : seq[G2]
|
var points : seq[G2]
|
||||||
for i in 1..len:
|
for i in 1..len:
|
||||||
points.add( loadPointG2(stream) )
|
points.add( loadPointG2(stream) )
|
||||||
@ -620,30 +620,30 @@ proc loadPointsG2*( len: int, stream: Stream ) : seq[G2] =
|
|||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
|
|
||||||
func addG1*(p,q: G1): G1 =
|
func addG1*(p,q: G1): G1 =
|
||||||
var r, x, y : ProjG1
|
var r, x, y : ProjG1
|
||||||
prj.fromAffine(x, p)
|
prj.fromAffine(x, p)
|
||||||
prj.fromAffine(y, q)
|
prj.fromAffine(y, q)
|
||||||
prj.sum(r, x, y)
|
prj.sum(r, x, y)
|
||||||
var s : G1
|
var s : G1
|
||||||
prj.affine(s, r)
|
prj.affine(s, r)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
func addG2*(p,q: G2): G2 =
|
func addG2*(p,q: G2): G2 =
|
||||||
var r, x, y : ProjG2
|
var r, x, y : ProjG2
|
||||||
prj.fromAffine(x, p)
|
prj.fromAffine(x, p)
|
||||||
prj.fromAffine(y, q)
|
prj.fromAffine(y, q)
|
||||||
prj.sum(r, x, y)
|
prj.sum(r, x, y)
|
||||||
var s : G2
|
var s : G2
|
||||||
prj.affine(s, r)
|
prj.affine(s, r)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
func negG1*(p: G1): G1 =
|
func negG1*(p: G1): G1 =
|
||||||
var r : G1 = p
|
var r : G1 = p
|
||||||
neg(r)
|
neg(r)
|
||||||
return r
|
return r
|
||||||
|
|
||||||
func negG2*(p: G2): G2 =
|
func negG2*(p: G2): G2 =
|
||||||
var r : G2 = p
|
var r : G2 = p
|
||||||
neg(r)
|
neg(r)
|
||||||
return r
|
return r
|
||||||
@ -660,7 +660,7 @@ func `-=`*(p: var G2, q: G2) = p = addG2(p,negG2(q))
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
#[
|
#[
|
||||||
func msmG1( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
func msmG1( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
||||||
|
|
||||||
let N = coeffs.len
|
let N = coeffs.len
|
||||||
assert( N == points.len, "incompatible sequence lengths" )
|
assert( N == points.len, "incompatible sequence lengths" )
|
||||||
@ -675,7 +675,7 @@ func msmG1( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
|||||||
var r : G1
|
var r : G1
|
||||||
|
|
||||||
# [Fp,aff.G1]
|
# [Fp,aff.G1]
|
||||||
msm.multiScalarMul_vartime( r,
|
msm.multiScalarMul_vartime( r,
|
||||||
toOpenArray(bigcfs, 0, N-1),
|
toOpenArray(bigcfs, 0, N-1),
|
||||||
toOpenArray(points, 0, N-1) )
|
toOpenArray(points, 0, N-1) )
|
||||||
|
|
||||||
@ -687,15 +687,15 @@ func msmG1( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
|||||||
# (affine) scalar multiplication
|
# (affine) scalar multiplication
|
||||||
#
|
#
|
||||||
|
|
||||||
func `**`*( coeff: Fr , point: G1 ) : G1 =
|
func `**`*( coeff: Fr , point: G1 ) : G1 =
|
||||||
var q : ProjG1
|
var q : ProjG1
|
||||||
prj.fromAffine( q , point )
|
prj.fromAffine( q , point )
|
||||||
scl.scalarMul( q , coeff.toBig() )
|
scl.scalarMul( q , coeff.toBig() )
|
||||||
var r : G1
|
var r : G1
|
||||||
prj.affine( r, q )
|
prj.affine( r, q )
|
||||||
return r
|
return r
|
||||||
|
|
||||||
func `**`*( coeff: Fr , point: G2 ) : G2 =
|
func `**`*( coeff: Fr , point: G2 ) : G2 =
|
||||||
var q : ProjG2
|
var q : ProjG2
|
||||||
prj.fromAffine( q , point )
|
prj.fromAffine( q , point )
|
||||||
scl.scalarMul( q , coeff.toBig() )
|
scl.scalarMul( q , coeff.toBig() )
|
||||||
@ -705,15 +705,15 @@ func `**`*( coeff: Fr , point: G2 ) : G2 =
|
|||||||
|
|
||||||
#-------------------
|
#-------------------
|
||||||
|
|
||||||
func `**`*( coeff: BigInt , point: G1 ) : G1 =
|
func `**`*( coeff: BigInt , point: G1 ) : G1 =
|
||||||
var q : ProjG1
|
var q : ProjG1
|
||||||
prj.fromAffine( q , point )
|
prj.fromAffine( q , point )
|
||||||
scl.scalarMul( q , coeff )
|
scl.scalarMul( q , coeff )
|
||||||
var r : G1
|
var r : G1
|
||||||
prj.affine( r, q )
|
prj.affine( r, q )
|
||||||
return r
|
return r
|
||||||
|
|
||||||
func `**`*( coeff: BigInt , point: G2 ) : G2 =
|
func `**`*( coeff: BigInt , point: G2 ) : G2 =
|
||||||
var q : ProjG2
|
var q : ProjG2
|
||||||
prj.fromAffine( q , point )
|
prj.fromAffine( q , point )
|
||||||
scl.scalarMul( q , coeff )
|
scl.scalarMul( q , coeff )
|
||||||
@ -723,10 +723,10 @@ func `**`*( coeff: BigInt , point: G2 ) : G2 =
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
func msmNaiveG1( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
func msmNaiveG1( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
||||||
let N = coeffs.len
|
let N = coeffs.len
|
||||||
assert( N == points.len, "incompatible sequence lengths" )
|
assert( N == points.len, "incompatible sequence lengths" )
|
||||||
|
|
||||||
var s : ProjG1
|
var s : ProjG1
|
||||||
s.setInf()
|
s.setInf()
|
||||||
|
|
||||||
@ -743,10 +743,10 @@ func msmNaiveG1( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
|||||||
|
|
||||||
#---------------------------------------
|
#---------------------------------------
|
||||||
|
|
||||||
func msmNaiveG2( coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
func msmNaiveG2( coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
||||||
let N = coeffs.len
|
let N = coeffs.len
|
||||||
assert( N == points.len, "incompatible sequence lengths" )
|
assert( N == points.len, "incompatible sequence lengths" )
|
||||||
|
|
||||||
var s : ProjG2
|
var s : ProjG2
|
||||||
s.setInf()
|
s.setInf()
|
||||||
|
|
||||||
@ -764,15 +764,15 @@ func msmNaiveG2( coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
# TODO: proper MSM implementation (couldn't make constantine work at first...)
|
# TODO: proper MSM implementation (couldn't make constantine work at first...)
|
||||||
func msmG1*( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
func msmG1*( coeffs: seq[Fr] , points: seq[G1] ): G1 =
|
||||||
return msmNaiveG1( coeffs, points )
|
return msmNaiveG1( coeffs, points )
|
||||||
|
|
||||||
func msmG2*( coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
func msmG2*( coeffs: seq[Fr] , points: seq[G2] ): G2 =
|
||||||
return msmNaiveG2( coeffs, points )
|
return msmNaiveG2( coeffs, points )
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc sanityCheckGroupGen*() =
|
proc sanityCheckGroupGen*() =
|
||||||
echo( "gen1 on the curve = ", checkCurveEqG1(gen1.x,gen1.y) )
|
echo( "gen1 on the curve = ", checkCurveEqG1(gen1.x,gen1.y) )
|
||||||
echo( "gen2 on the curve = ", checkCurveEqG2(gen2.x,gen2.y) )
|
echo( "gen2 on the curve = ", checkCurveEqG2(gen2.x,gen2.y) )
|
||||||
echo( "order of gen1 is R = ", (not bool(isInf(gen1))) and bool(isInf(primeR ** gen1)) )
|
echo( "order of gen1 is R = ", (not bool(isInf(gen1))) and bool(isInf(primeR ** gen1)) )
|
||||||
@ -14,7 +14,7 @@
|
|||||||
#
|
#
|
||||||
# for each section:
|
# for each section:
|
||||||
# -----------------
|
# -----------------
|
||||||
# section id : word32
|
# section id : word32
|
||||||
# section size : word64
|
# section size : word64
|
||||||
# section data : <section_size> number of bytes
|
# section data : <section_size> number of bytes
|
||||||
#
|
#
|
||||||
@ -30,25 +30,25 @@ import constantine/math/io/io_bigints
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
SectionCallback*[T] = proc (stream: Stream, sectId: int, sectLen: int, user: var T) {.closure.}
|
SectionCallback*[T] = proc (stream: Stream, sectId: int, sectLen: int, user: var T) {.closure.}
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
func magicWord(magic: string): uint32 =
|
func magicWord(magic: string): uint32 =
|
||||||
assert( magic.len == 4, "magicWord: expecting a string of 4 characters" )
|
assert( magic.len == 4, "magicWord: expecting a string of 4 characters" )
|
||||||
var w : uint32 = 0
|
var w : uint32 = 0
|
||||||
for i in 0..3:
|
for i in 0..3:
|
||||||
let a = uint32(ord(magic[i]))
|
let a = uint32(ord(magic[i]))
|
||||||
w += a shl (8*i)
|
w += a shl (8*i)
|
||||||
return w
|
return w
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc parsePrimeField*( stream: Stream ) : (int, BigInt[256]) =
|
proc parsePrimeField*( stream: Stream ) : (int, BigInt[256]) =
|
||||||
let n8p = int( stream.readUint32() )
|
let n8p = int( stream.readUint32() )
|
||||||
assert( n8p <= 32 , "at most 256 bit primes are allowed" )
|
assert( n8p <= 32 , "at most 256 bit primes are allowed" )
|
||||||
var p_bytes : array[32, uint8]
|
var p_bytes : array[32, uint8]
|
||||||
discard stream.readData( addr(p_bytes), n8p )
|
discard stream.readData( addr(p_bytes), n8p )
|
||||||
var p : BigInt[256]
|
var p : BigInt[256]
|
||||||
unmarshal(p, p_bytes, littleEndian);
|
unmarshal(p, p_bytes, littleEndian);
|
||||||
@ -60,7 +60,7 @@ proc readSection[T] ( expectedMagic: string
|
|||||||
, expectedVersion: int
|
, expectedVersion: int
|
||||||
, stream: Stream
|
, stream: Stream
|
||||||
, user: var T
|
, user: var T
|
||||||
, callback: SectionCallback[T]
|
, callback: SectionCallback[T]
|
||||||
, filt: (int) -> bool ) =
|
, filt: (int) -> bool ) =
|
||||||
|
|
||||||
let sectId = int( stream.readUint32() )
|
let sectId = int( stream.readUint32() )
|
||||||
@ -76,7 +76,7 @@ proc parseContainer*[T] ( expectedMagic: string
|
|||||||
, expectedVersion: int
|
, expectedVersion: int
|
||||||
, fname: string
|
, fname: string
|
||||||
, user: var T
|
, user: var T
|
||||||
, callback: SectionCallback[T]
|
, callback: SectionCallback[T]
|
||||||
, filt: (int) -> bool ) =
|
, filt: (int) -> bool ) =
|
||||||
|
|
||||||
let stream = newFileStream(fname, mode = fmRead)
|
let stream = newFileStream(fname, mode = fmRead)
|
||||||
@ -11,22 +11,22 @@ from ./groth16 import Proof
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
func toQuotedDecimalFp(x: Fp): string =
|
func toQuotedDecimalFp(x: Fp): string =
|
||||||
let s : string = toDecimalFp(x)
|
let s : string = toDecimalFp(x)
|
||||||
return ("\"" & s & "\"")
|
return ("\"" & s & "\"")
|
||||||
|
|
||||||
func toQuotedDecimalFr(x: Fr): string =
|
func toQuotedDecimalFr(x: Fr): string =
|
||||||
let s : string = toDecimalFr(x)
|
let s : string = toDecimalFr(x)
|
||||||
return ("\"" & s & "\"")
|
return ("\"" & s & "\"")
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
# exports the public input/output into as a JSON file
|
# exports the public input/output into as a JSON file
|
||||||
proc exportPublicIO*( fpath: string, prf: Proof ) =
|
proc exportPublicIO*( fpath: string, prf: Proof ) =
|
||||||
|
|
||||||
# debugPrintFrSeq("public IO",prf.publicIO)
|
# debugPrintFrSeq("public IO",prf.publicIO)
|
||||||
|
|
||||||
let n : int = prf.publicIO.len
|
let n : int = prf.publicIO.len
|
||||||
assert( n > 0 )
|
assert( n > 0 )
|
||||||
assert( bool(prf.publicIO[0] == oneFr) )
|
assert( bool(prf.publicIO[0] == oneFr) )
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ proc writeG2( f: File, p: G2 ) =
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
# exports the proof into as a JSON file
|
# exports the proof into as a JSON file
|
||||||
proc exportProof*( fpath: string, prf: Proof ) =
|
proc exportProof*( fpath: string, prf: Proof ) =
|
||||||
|
|
||||||
let f = open(fpath, fmWrite)
|
let f = open(fpath, fmWrite)
|
||||||
defer: f.close()
|
defer: f.close()
|
||||||
@ -82,7 +82,7 @@ proc exportProof*( fpath: string, prf: Proof ) =
|
|||||||
#[
|
#[
|
||||||
#import std/sequtils
|
#import std/sequtils
|
||||||
|
|
||||||
func getFakeProof*() : Proof =
|
func getFakeProof*() : Proof =
|
||||||
let pub : seq[Fr] = map( [1,101,102,103,117,119] , intToFr )
|
let pub : seq[Fr] = map( [1,101,102,103,117,119] , intToFr )
|
||||||
let p = unsafeMkG1( intToFp(666) , intToFp(777) )
|
let p = unsafeMkG1( intToFp(666) , intToFp(777) )
|
||||||
let r = unsafeMkG1( intToFp(888) , intToFp(999) )
|
let r = unsafeMkG1( intToFp(888) , intToFp(999) )
|
||||||
@ -91,7 +91,7 @@ func getFakeProof*() : Proof =
|
|||||||
let q = unsafeMkG2( x , y )
|
let q = unsafeMkG2( x , y )
|
||||||
return Proof( publicIO:pub, pi_a:p, pi_b:q, pi_c:r )
|
return Proof( publicIO:pub, pi_a:p, pi_b:q, pi_c:r )
|
||||||
|
|
||||||
proc exportFakeProof*() =
|
proc exportFakeProof*() =
|
||||||
let prf = getFakeProof()
|
let prf = getFakeProof()
|
||||||
exportPublicIO( "fake_pub.json" , prf )
|
exportPublicIO( "fake_pub.json" , prf )
|
||||||
exportProof( "fake_prf.json" , prf )
|
exportProof( "fake_prf.json" , prf )
|
||||||
44
src/misc.nim
Normal file
44
src/misc.nim
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
#
|
||||||
|
# miscellaneous routines
|
||||||
|
#
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func floorLog2* (x : int) : int =
|
||||||
|
var k = -1
|
||||||
|
var y = x
|
||||||
|
while (y > 0):
|
||||||
|
k += 1
|
||||||
|
y = y shr 1
|
||||||
|
return k
|
||||||
|
|
||||||
|
func ceilingLog2* (x : int) : int =
|
||||||
|
if (x==0):
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return (floorLog2(x-1) + 1)
|
||||||
|
|
||||||
|
#-------------------
|
||||||
|
|
||||||
|
when isMainModule:
|
||||||
|
|
||||||
|
import std/math
|
||||||
|
|
||||||
|
proc sanityCheckLog2* () =
|
||||||
|
for i in 0..18:
|
||||||
|
let x = float64(i)
|
||||||
|
echo( i," | ",floorLog2(i),"=",floor(log2(x))," | ",ceilingLog2(i),"=",ceil(log2(x)) )
|
||||||
|
|
||||||
|
sanityCheckLog2()
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
func rotateSeq[T](xs: seq[T], ofs: int): seq[T] =
|
||||||
|
let n = xs.len
|
||||||
|
var ys : seq[T]
|
||||||
|
for i in (0..<n):
|
||||||
|
ys.add( xs[ (i+n+ofs) mod n ] )
|
||||||
|
return ys
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------------
|
||||||
@ -19,7 +19,7 @@ import misc
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
Poly* = object
|
Poly* = object
|
||||||
coeffs* : seq[Fr]
|
coeffs* : seq[Fr]
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ func polyDegree*(P: Poly) : int =
|
|||||||
while isZeroFr(xs[d]) and (d >= 0): d -= 1
|
while isZeroFr(xs[d]) and (d >= 0): d -= 1
|
||||||
return d
|
return d
|
||||||
|
|
||||||
func polyIsZero*(P: Poly) : bool =
|
func polyIsZero*(P: Poly) : bool =
|
||||||
let xs = P.coeffs ; let n = xs.len
|
let xs = P.coeffs ; let n = xs.len
|
||||||
var b = true
|
var b = true
|
||||||
for i in 0..<n:
|
for i in 0..<n:
|
||||||
@ -40,7 +40,7 @@ func polyIsZero*(P: Poly) : bool =
|
|||||||
break
|
break
|
||||||
return b
|
return b
|
||||||
|
|
||||||
func polyIsEqual*(P, Q: Poly) : bool =
|
func polyIsEqual*(P, Q: Poly) : bool =
|
||||||
let xs : seq[Fr] = P.coeffs ; let n = xs.len
|
let xs : seq[Fr] = P.coeffs ; let n = xs.len
|
||||||
let ys : seq[Fr] = Q.coeffs ; let m = ys.len
|
let ys : seq[Fr] = Q.coeffs ; let m = ys.len
|
||||||
var b = true
|
var b = true
|
||||||
@ -106,13 +106,13 @@ func polyMulNaive*(P, Q : Poly): Poly =
|
|||||||
let xs = P.coeffs ; let n1 = xs.len
|
let xs = P.coeffs ; let n1 = xs.len
|
||||||
let ys = Q.coeffs ; let n2 = ys.len
|
let ys = Q.coeffs ; let n2 = ys.len
|
||||||
let N = n1 + n2 - 1
|
let N = n1 + n2 - 1
|
||||||
var zs : seq[Fr] = newSeq[Fr](N)
|
var zs : seq[Fr] = newSeq[Fr](N)
|
||||||
for k in 0..<N:
|
for k in 0..<N:
|
||||||
# 0 <= i <= min(k , n1-1)
|
# 0 <= i <= min(k , n1-1)
|
||||||
# 0 <= j <= min(k , n2-1)
|
# 0 <= j <= min(k , n2-1)
|
||||||
# k = i + j
|
# k = i + j
|
||||||
# 0 >= i = k - j >= k - min(k , n2-1)
|
# 0 >= i = k - j >= k - min(k , n2-1)
|
||||||
# 0 >= j = k - i >= k - min(k , n1-1)
|
# 0 >= j = k - i >= k - min(k , n1-1)
|
||||||
let A : int = max( 0 , k - min(k , n2-1) )
|
let A : int = max( 0 , k - min(k , n2-1) )
|
||||||
let B : int = min( k , n1-1 )
|
let B : int = min( k , n1-1 )
|
||||||
zs[k] = zeroFr
|
zs[k] = zeroFr
|
||||||
@ -124,7 +124,7 @@ func polyMulNaive*(P, Q : Poly): Poly =
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
# multiply two polynomials using FFT
|
# multiply two polynomials using FFT
|
||||||
func polyMulFFT*(P, Q: Poly): Poly =
|
func polyMulFFT*(P, Q: Poly): Poly =
|
||||||
let n1 = P.coeffs.len
|
let n1 = P.coeffs.len
|
||||||
let n2 = Q.coeffs.len
|
let n2 = Q.coeffs.len
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ func polyMulFFT*(P, Q: Poly): Poly =
|
|||||||
let us : seq[Fr] = extendAndForwardNTT( P.coeffs, D )
|
let us : seq[Fr] = extendAndForwardNTT( P.coeffs, D )
|
||||||
let vs : seq[Fr] = extendAndForwardNTT( Q.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 zs : seq[Fr] = collect( newSeq, (for i in 0..<N: us[i]*vs[i] ))
|
||||||
let ws : seq[Fr] = inverseNTT( zs, D )
|
let ws : seq[Fr] = inverseNTT( zs, D )
|
||||||
|
|
||||||
return Poly(coeffs: ws)
|
return Poly(coeffs: ws)
|
||||||
|
|
||||||
@ -143,8 +143,8 @@ func polyMulFFT*(P, Q: Poly): Poly =
|
|||||||
|
|
||||||
# WARNING: this is using the naive implementation!
|
# WARNING: this is using the naive implementation!
|
||||||
func polyMul*(P, Q : Poly): Poly =
|
func polyMul*(P, Q : Poly): Poly =
|
||||||
# return polyMulFFT(P, Q)
|
# return polyMulFFT(P, Q)
|
||||||
return polyMulNaive(P, Q)
|
return polyMulNaive(P, Q)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -160,7 +160,7 @@ func `*`*(P: Poly, s: Fr ): Poly = return polyScale(s, P)
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
# the generalized vanishing polynomial `(a*x^N - b)`
|
# the generalized vanishing polynomial `(a*x^N - b)`
|
||||||
func generalizedVanishingPoly*(N: int, a: Fr, b: Fr): Poly =
|
func generalizedVanishingPoly*(N: int, a: Fr, b: Fr): Poly =
|
||||||
assert( N>=1 )
|
assert( N>=1 )
|
||||||
var cs : seq[Fr] = newSeq[Fr]( N+1 )
|
var cs : seq[Fr] = newSeq[Fr]( N+1 )
|
||||||
cs[0] = negFr(b)
|
cs[0] = negFr(b)
|
||||||
@ -168,31 +168,31 @@ func generalizedVanishingPoly*(N: int, a: Fr, b: Fr): Poly =
|
|||||||
return Poly(coeffs: cs)
|
return Poly(coeffs: cs)
|
||||||
|
|
||||||
# the vanishing polynomial `(x^N - 1)`
|
# the vanishing polynomial `(x^N - 1)`
|
||||||
func vanishingPoly*(N: int): Poly =
|
func vanishingPoly*(N: int): Poly =
|
||||||
return generalizedVanishingPoly(N, oneFr, oneFr)
|
return generalizedVanishingPoly(N, oneFr, oneFr)
|
||||||
|
|
||||||
func vanishingPoly*(D: Domain): Poly =
|
func vanishingPoly*(D: Domain): Poly =
|
||||||
return vanishingPoly(D.domainSize)
|
return vanishingPoly(D.domainSize)
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
QuotRem*[T] = object
|
QuotRem*[T] = object
|
||||||
quot* : T
|
quot* : T
|
||||||
rem* : T
|
rem* : T
|
||||||
|
|
||||||
# divide by the vanishing polynomial `(x^N - 1)`
|
# divide by the vanishing polynomial `(x^N - 1)`
|
||||||
# returns the quotient and remainder
|
# returns the quotient and remainder
|
||||||
func polyQuotRemByVanishing*(P: Poly, N: int): QuotRem[Poly] =
|
func polyQuotRemByVanishing*(P: Poly, N: int): QuotRem[Poly] =
|
||||||
assert( N>=1 )
|
assert( N>=1 )
|
||||||
let deg : int = polyDegree(P)
|
let deg : int = polyDegree(P)
|
||||||
let src : seq[Fr] = P.coeffs
|
let src : seq[Fr] = P.coeffs
|
||||||
var quot : seq[Fr] = newSeq[Fr]( max(1, deg - N + 1) )
|
var quot : seq[Fr] = newSeq[Fr]( max(1, deg - N + 1) )
|
||||||
var rem : seq[Fr] = newSeq[Fr]( N )
|
var rem : seq[Fr] = newSeq[Fr]( N )
|
||||||
|
|
||||||
if deg < N:
|
if deg < N:
|
||||||
rem = src
|
rem = src
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
# compute quotient
|
# compute quotient
|
||||||
@ -212,7 +212,7 @@ func polyQuotRemByVanishing*(P: Poly, N: int): QuotRem[Poly] =
|
|||||||
return QuotRem[Poly]( quot:Poly(coeffs:quot), rem:Poly(coeffs:rem) )
|
return QuotRem[Poly]( quot:Poly(coeffs:quot), rem:Poly(coeffs:rem) )
|
||||||
|
|
||||||
# divide by the vanishing polynomial `(x^N - 1)`
|
# divide by the vanishing polynomial `(x^N - 1)`
|
||||||
func polyDivideByVanishing*(P: Poly, N: int): Poly =
|
func polyDivideByVanishing*(P: Poly, N: int): Poly =
|
||||||
let qr = polyQuotRemByVanishing(P, N)
|
let qr = polyQuotRemByVanishing(P, N)
|
||||||
assert( polyIsZero(qr.rem) )
|
assert( polyIsZero(qr.rem) )
|
||||||
return qr.quot
|
return qr.quot
|
||||||
@ -230,7 +230,7 @@ func lagrangePoly(D: Domain, k: int): Poly =
|
|||||||
for i in 0..<N: cs[i] = invN
|
for i in 0..<N: cs[i] = invN
|
||||||
else:
|
else:
|
||||||
var s : Fr = invN
|
var s : Fr = invN
|
||||||
for i in 0..<N:
|
for i in 0..<N:
|
||||||
cs[i] = s
|
cs[i] = s
|
||||||
s *= omMinusK
|
s *= omMinusK
|
||||||
|
|
||||||
@ -269,48 +269,63 @@ func polyInverseNTT*(ys: seq[Fr], D: Domain): Poly =
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
#[
|
when isMainModule:
|
||||||
|
proc sanityCheckOneHalf*() =
|
||||||
|
let two = oneFr + oneFr
|
||||||
|
let invTwo = oneHalfFr
|
||||||
|
echo(toDecimalFr(two))
|
||||||
|
echo(toDecimalFr(invTwo * two))
|
||||||
|
echo(toHex(invTwo))
|
||||||
|
|
||||||
proc sanityCheckOneHalf*() =
|
proc sanityCheckVanishing*() =
|
||||||
let two = oneFr + oneFr
|
var js : seq[int] = toSeq(101..112)
|
||||||
let invTwo = oneHalfFr
|
let cs : seq[Fr] = map( js, intToFr )
|
||||||
echo(toDecimalFr(two))
|
let P : Poly = Poly( coeffs:cs )
|
||||||
echo(toDecimalFr(invTwo * two))
|
|
||||||
echo(toHex(invTwo))
|
|
||||||
|
|
||||||
#-------------------
|
#-------------------
|
||||||
|
|
||||||
proc sanityCheckVanishing*() =
|
proc sanityCheckVanishing*() =
|
||||||
var js : seq[int] = toSeq(101..112)
|
var js : seq[int] = toSeq(101..112)
|
||||||
let cs : seq[Fr] = map( js, intToFr )
|
let cs : seq[Fr] = map( js, intToFr )
|
||||||
let P : Poly = Poly( coeffs:cs )
|
let P : Poly = Poly( coeffs:cs )
|
||||||
|
|
||||||
echo("degree of P = ",polyDegree(P))
|
let n : int = 5
|
||||||
debugPrintFrSeq("xs", P.coeffs)
|
let QR = polyQuotRemByVanishing(P, n)
|
||||||
|
let Q = QR.quot
|
||||||
|
let R = QR.rem
|
||||||
|
|
||||||
let n : int = 5
|
debugPrintFrSeq("Q", Q.coeffs)
|
||||||
let QR = polyQuotRemByVanishing(P, n)
|
debugPrintFrSeq("R", R.coeffs)
|
||||||
let Q = QR.quot
|
|
||||||
let R = QR.rem
|
|
||||||
|
|
||||||
debugPrintFrSeq("Q", Q.coeffs)
|
let Z : Poly = vanishingPoly(n)
|
||||||
debugPrintFrSeq("R", R.coeffs)
|
let S : Poly = Q * Z + R
|
||||||
|
|
||||||
let Z : Poly = vanishingPoly(n)
|
debugPrintFrSeq("zs", S.coeffs)
|
||||||
let S : Poly = Q * Z + R
|
echo( polyIsEqual(P,S) )
|
||||||
|
|
||||||
debugPrintFrSeq("zs", S.coeffs)
|
proc sanityCheckNTT*() =
|
||||||
echo( polyIsEqual(P,S) )
|
var js : seq[int] = toSeq(101..108)
|
||||||
|
let cs : seq[Fr] = map( js, intToFr )
|
||||||
|
let P : Poly = Poly( coeffs:cs )
|
||||||
|
let D : Domain = createDomain(8)
|
||||||
|
let xs : seq[Fr] = D.enumerateDomain()
|
||||||
|
let ys : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(P,x)) )
|
||||||
|
let zs : seq[Fr] = polyForwardNTT(P ,D)
|
||||||
|
let Q : Poly = polyInverseNTT(zs,D)
|
||||||
|
debugPrintFrSeq("xs", xs)
|
||||||
|
debugPrintFrSeq("ys", ys)
|
||||||
|
debugPrintFrSeq("zs", zs)
|
||||||
|
debugPrintFrSeq("us", Q.coeffs)
|
||||||
|
|
||||||
#-------------------
|
#-------------------
|
||||||
|
|
||||||
proc sanityCheckNTT*() =
|
proc sanityCheckNTT*() =
|
||||||
var js : seq[int] = toSeq(101..108)
|
var js : seq[int] = toSeq(101..108)
|
||||||
let cs : seq[Fr] = map( js, intToFr )
|
let cs : seq[Fr] = map( js, intToFr )
|
||||||
let P : Poly = Poly( coeffs:cs )
|
let P : Poly = Poly( coeffs:cs )
|
||||||
let D : Domain = createDomain(8)
|
let D : Domain = createDomain(8)
|
||||||
let xs : seq[Fr] = D.enumerateDomain()
|
let xs : seq[Fr] = D.enumerateDomain()
|
||||||
let ys : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(P,x)) )
|
let ys : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(P,x)) )
|
||||||
let zs : seq[Fr] = polyForwardNTT(P ,D)
|
let zs : seq[Fr] = polyForwardNTT(P ,D)
|
||||||
let Q : Poly = polyInverseNTT(zs,D)
|
let Q : Poly = polyInverseNTT(zs,D)
|
||||||
debugPrintFrSeq("xs", xs)
|
debugPrintFrSeq("xs", xs)
|
||||||
@ -320,38 +335,36 @@ proc sanityCheckNTT*() =
|
|||||||
|
|
||||||
#-------------------
|
#-------------------
|
||||||
|
|
||||||
proc sanityCheckMulFFT*() =
|
proc sanityCheckMulFFT*() =
|
||||||
var js : seq[int] = toSeq(101..110)
|
var js : seq[int] = toSeq(101..110)
|
||||||
let cs : seq[Fr] = map( js, intToFr )
|
let cs : seq[Fr] = map( js, intToFr )
|
||||||
let P : Poly = Poly( coeffs:cs )
|
let P : Poly = Poly( coeffs:cs )
|
||||||
|
|
||||||
var ks : seq[int] = toSeq(1001..1020)
|
let R1 : Poly = polyMulNaive( P , Q )
|
||||||
let ds : seq[Fr] = map( ks, intToFr )
|
let R2 : Poly = polyMulFFT( P , Q )
|
||||||
let Q : Poly = Poly( coeffs:ds )
|
|
||||||
|
|
||||||
let R1 : Poly = polyMulNaive( P , Q )
|
# debugPrintFrSeq("naive coeffs", R1.coeffs)
|
||||||
let R2 : Poly = polyMulFFT( P , Q )
|
# debugPrintFrSeq("fft coeffs", R2.coeffs)
|
||||||
|
|
||||||
# debugPrintFrSeq("naive coeffs", R1.coeffs)
|
echo( "multiply test = ", polyIsEqual(R1,R2) )
|
||||||
# debugPrintFrSeq("fft coeffs", R2.coeffs)
|
|
||||||
|
|
||||||
echo( "multiply test = ", polyIsEqual(R1,R2) )
|
echo( "multiply test = ", polyIsEqual(R1,R2) )
|
||||||
|
|
||||||
#-------------------
|
#-------------------
|
||||||
|
|
||||||
proc sanityCheckLagrangeBases*() =
|
proc sanityCheckLagrangeBases*() =
|
||||||
let n = 8
|
let n = 8
|
||||||
let D = createDomain(n)
|
let D = createDomain(n)
|
||||||
|
|
||||||
let L : seq[Poly] = collect( newSeq, (for k in 0..<n: lagrangePoly(D,k) ))
|
let L : seq[Poly] = collect( newSeq, (for k in 0..<n: lagrangePoly(D,k) ))
|
||||||
|
|
||||||
let xs = enumerateDomain(D)
|
let xs = enumerateDomain(D)
|
||||||
let ys0 : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(L[0],x) ))
|
let ys0 : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(L[0],x) ))
|
||||||
let ys1 : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(L[1],x) ))
|
let ys1 : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(L[1],x) ))
|
||||||
let ys5 : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(L[5],x) ))
|
let ys5 : seq[Fr] = collect( newSeq, (for x in xs: polyEvalAt(L[5],x) ))
|
||||||
let zs0 : seq[Fr] = collect( newSeq, (for i in 0..<n: deltaFr(0,i) ))
|
let zs0 : seq[Fr] = collect( newSeq, (for i in 0..<n: deltaFr(0,i) ))
|
||||||
let zs1 : seq[Fr] = collect( newSeq, (for i in 0..<n: deltaFr(1,i) ))
|
let zs1 : seq[Fr] = collect( newSeq, (for i in 0..<n: deltaFr(1,i) ))
|
||||||
let zs5 : seq[Fr] = collect( newSeq, (for i in 0..<n: deltaFr(5,i) ))
|
let zs5 : seq[Fr] = collect( newSeq, (for i in 0..<n: deltaFr(5,i) ))
|
||||||
|
|
||||||
echo("==============")
|
echo("==============")
|
||||||
for i in 0..<n: echo("i = ",i, " | y[i] = ",toDecimalFr(ys0[i]), " | z[i] = ",toDecimalFr(zs0[i]))
|
for i in 0..<n: echo("i = ",i, " | y[i] = ",toDecimalFr(ys0[i]), " | z[i] = ",toDecimalFr(zs0[i]))
|
||||||
@ -359,16 +372,16 @@ proc sanityCheckLagrangeBases*() =
|
|||||||
for i in 0..<n: echo("i = ",i, " | y[i] = ",toDecimalFr(ys1[i]), " | z[i] = ",toDecimalFr(zs1[i]))
|
for i in 0..<n: echo("i = ",i, " | y[i] = ",toDecimalFr(ys1[i]), " | z[i] = ",toDecimalFr(zs1[i]))
|
||||||
echo("--------------")
|
echo("--------------")
|
||||||
for i in 0..<n: echo("i = ",i, " | y[i] = ",toDecimalFr(ys5[i]), " | z[i] = ",toDecimalFr(zs5[i]))
|
for i in 0..<n: echo("i = ",i, " | y[i] = ",toDecimalFr(ys5[i]), " | z[i] = ",toDecimalFr(zs5[i]))
|
||||||
|
|
||||||
let zeta = intToFr(123457)
|
let zeta = intToFr(123457)
|
||||||
let us : seq[Fr] = collect( newSeq, (for i in 0..<n: polyEvalAt(L[i],zeta)) )
|
let us : seq[Fr] = collect( newSeq, (for i in 0..<n: polyEvalAt(L[i],zeta)) )
|
||||||
let vs : seq[Fr] = collect( newSeq, (for i in 0..<n: evalLagrangePolyAt(D,i,zeta)) )
|
let vs : seq[Fr] = collect( newSeq, (for i in 0..<n: evalLagrangePolyAt(D,i,zeta)) )
|
||||||
|
|
||||||
echo("==============")
|
echo("==============")
|
||||||
for i in 0..<n: echo("i = ",i, " | u[i] = ",toDecimalFr(us[i]), " | v[i] = ",toDecimalFr(vs[i]))
|
for i in 0..<n: echo("i = ",i, " | u[i] = ",toDecimalFr(us[i]), " | v[i] = ",toDecimalFr(vs[i]))
|
||||||
|
|
||||||
let prefix = "Lagrange basis sanity check = "
|
let prefix = "Lagrange basis sanity check = "
|
||||||
if ( ys0===zs0 and ys1===zs1 and ys5===zs5 and
|
if ( ys0===zs0 and ys1===zs1 and ys5===zs5 and
|
||||||
us===vs ):
|
us===vs ):
|
||||||
echo( prefix & "OK")
|
echo( prefix & "OK")
|
||||||
else:
|
else:
|
||||||
@ -11,8 +11,8 @@
|
|||||||
#
|
#
|
||||||
# nvars = 1 + pub + secret = 1 + npubout + npubin + nprivin + nsecret
|
# nvars = 1 + pub + secret = 1 + npubout + npubin + nprivin + nsecret
|
||||||
#
|
#
|
||||||
# NOTE: Unlike the `.zkey` files, which encode field elements in the
|
# NOTE: Unlike the `.zkey` files, which encode field elements in the
|
||||||
# Montgomery representation, the `.wtns` file encode field elements in
|
# Montgomery representation, the `.wtns` file encode field elements in
|
||||||
# the standard representation!
|
# the standard representation!
|
||||||
#
|
#
|
||||||
|
|
||||||
@ -26,10 +26,10 @@ import ./container
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
Witness* = object
|
Witness* = object
|
||||||
curve* : string
|
curve* : string
|
||||||
r* : BigInt[256]
|
r* : BigInt[256]
|
||||||
nvars* : int
|
nvars* : int
|
||||||
values* : seq[Fr]
|
values* : seq[Fr]
|
||||||
|
|
||||||
@ -37,9 +37,9 @@ type
|
|||||||
|
|
||||||
proc parseSection1_header( stream: Stream, user: var Witness, sectionLen: int ) =
|
proc parseSection1_header( stream: Stream, user: var Witness, sectionLen: int ) =
|
||||||
# echo "\nparsing witness header"
|
# echo "\nparsing witness header"
|
||||||
|
|
||||||
let (n8r, r) = parsePrimeField( stream ) # size of the scalar field
|
let (n8r, r) = parsePrimeField( stream ) # size of the scalar field
|
||||||
user.r = r;
|
user.r = r
|
||||||
|
|
||||||
# echo("r = ",toDecimalBig(r))
|
# echo("r = ",toDecimalBig(r))
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ proc parseSection1_header( stream: Stream, user: var Witness, sectionLen: int )
|
|||||||
user.curve = "bn128"
|
user.curve = "bn128"
|
||||||
|
|
||||||
let nvars = int( stream.readUint32() )
|
let nvars = int( stream.readUint32() )
|
||||||
user.nvars = nvars;
|
user.nvars = nvars
|
||||||
|
|
||||||
# echo("nvars = ",nvars)
|
# echo("nvars = ",nvars)
|
||||||
|
|
||||||
@ -63,14 +63,14 @@ proc parseSection2_witness( stream: Stream, user: var Witness, sectionLen: int )
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc wtnsCallback(stream: Stream, sectId: int, sectLen: int, user: var Witness) =
|
proc wtnsCallback(stream: Stream, sectId: int, sectLen: int, user: var Witness) =
|
||||||
#echo(sectId)
|
#echo(sectId)
|
||||||
case sectId
|
case sectId
|
||||||
of 1: parseSection1_header( stream, user, sectLen )
|
of 1: parseSection1_header( stream, user, sectLen )
|
||||||
of 2: parseSection2_witness( stream, user, sectLen )
|
of 2: parseSection2_witness( stream, user, sectLen )
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc parseWitness* (fname: string): Witness =
|
proc parseWitness* (fname: string): Witness =
|
||||||
var wtns : Witness
|
var wtns : Witness
|
||||||
parseContainer( "wtns", 2, fname, wtns, wtnsCallback, proc (id: int): bool = id == 1 )
|
parseContainer( "wtns", 2, fname, wtns, wtnsCallback, proc (id: int): bool = id == 1 )
|
||||||
parseContainer( "wtns", 2, fname, wtns, wtnsCallback, proc (id: int): bool = id != 1 )
|
parseContainer( "wtns", 2, fname, wtns, wtnsCallback, proc (id: int): bool = id != 1 )
|
||||||
1
tests/config.nims
Normal file
1
tests/config.nims
Normal file
@ -0,0 +1 @@
|
|||||||
|
switch("path", "$projectDir/../src")
|
||||||
@ -1,14 +1,12 @@
|
|||||||
|
|
||||||
import ./groth16
|
import pkg/groth16
|
||||||
import ./witness
|
import pkg/witness
|
||||||
import ./r1cs
|
import pkg/zkey
|
||||||
import ./zkey
|
import pkg/zkey_types
|
||||||
import ./zkey_types
|
|
||||||
import ./fake_setup
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc testProveAndVerify*( zkey_fname, wtns_fname: string): Proof =
|
proc testProveAndVerify*( zkey_fname, wtns_fname: string): Proof =
|
||||||
|
|
||||||
echo("parsing witness & zkey files...")
|
echo("parsing witness & zkey files...")
|
||||||
let witness = parseWitness( wtns_fname)
|
let witness = parseWitness( wtns_fname)
|
||||||
@ -28,7 +26,7 @@ proc testProveAndVerify*( zkey_fname, wtns_fname: string): Proof =
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
proc testFakeSetupAndVerify*( r1cs_fname, wtns_fname: string, flavour=Snarkjs): Proof =
|
proc testFakeSetupAndVerify*( r1cs_fname, wtns_fname: string, flavour=Snarkjs): Proof =
|
||||||
echo("trusted setup flavour = ",flavour)
|
echo("trusted setup flavour = ",flavour)
|
||||||
|
|
||||||
echo("parsing witness & r1cs files...")
|
echo("parsing witness & r1cs files...")
|
||||||
Loading…
x
Reference in New Issue
Block a user