@ -2,7 +2,6 @@ package snark
import (
"bytes"
"encoding/json"
"fmt"
"math/big"
"strings"
@ -35,9 +34,9 @@ func TestZkFromFlatCircuitCode(t *testing.T) {
parser := circuitcompiler . NewParser ( strings . NewReader ( flatCode ) )
circuit , err := parser . Parse ( )
assert . Nil ( t , err )
fmt . Println ( "\ncircuit data:" , circuit )
circuitJson , _ := json . Marshal ( circuit )
fmt . Println ( "circuit:" , string ( circuitJson ) )
// fmt.Println("\ncircuit data:", circuit)
// circuitJson, _ := json.Marshal(circuit)
// fmt.Println("circuit:", string(circuitJson))
b3 := big . NewInt ( int64 ( 3 ) )
privateInputs := [ ] * big . Int { b3 }
@ -47,8 +46,6 @@ func TestZkFromFlatCircuitCode(t *testing.T) {
// wittness
w , err := circuit . CalculateWitness ( privateInputs , publicSignals )
assert . Nil ( t , err )
fmt . Println ( "\n" , circuit . Signals )
fmt . Println ( "witness" , w )
// flat code to R1CS
fmt . Println ( "\ngenerating R1CS from flat code" )
@ -59,25 +56,23 @@ func TestZkFromFlatCircuitCode(t *testing.T) {
fmt . Println ( "c:" , c )
// R1CS to QAP
// TODO zxQAP is not used and is an old impl, bad calculated. TODO remove
// TODO zxQAP is not used and is an old impl, TODO remove
alphas , betas , gammas , zxQAP := Utils . PF . R1CSToQAP ( a , b , c )
fmt . Println ( "qap" )
fmt . Println ( "alphas" , len ( alphas ) )
fmt . Println ( "alphas[1]" , alphas [ 1 ] )
fmt . Println ( "betas" , len ( betas ) )
fmt . Println ( "gammas" , len ( gammas ) )
fmt . Println ( "zx length" , len ( zxQAP ) )
assert . Equal ( t , 8 , len ( alphas ) )
assert . Equal ( t , 8 , len ( alphas ) )
assert . Equal ( t , 8 , len ( alphas ) )
assert . Equal ( t , 7 , len ( zxQAP ) )
assert . True ( t , ! bytes . Equal ( alphas [ 1 ] [ 1 ] . Bytes ( ) , big . NewInt ( int64 ( 0 ) ) . Bytes ( ) ) )
ax , bx , cx , px := Utils . PF . CombinePolynomials ( w , alphas , betas , gammas )
fmt . Println ( "ax length" , len ( ax ) )
fmt . Println ( "bx length" , len ( bx ) )
fmt . Println ( "cx length" , len ( cx ) )
fmt . Println ( "px length" , len ( px ) )
fmt . Println ( "px[last]" , px [ 0 ] )
assert . Equal ( t , 7 , len ( ax ) )
assert . Equal ( t , 7 , len ( bx ) )
assert . Equal ( t , 7 , len ( cx ) )
assert . Equal ( t , 13 , len ( px ) )
hxQAP := Utils . PF . DivisorPolynomial ( px , zxQAP )
fmt . Println ( "hx length" , len ( hxQAP ) )
assert . Equal ( t , 7 , len ( hxQAP ) )
// hx==px/zx so px==hx*zx
assert . Equal ( t , px , Utils . PF . Mul ( hxQAP , zxQAP ) )
@ -98,11 +93,10 @@ func TestZkFromFlatCircuitCode(t *testing.T) {
fmt . Println ( "\nt:" , setup . Toxic . T )
// zx and setup.Pk.Z should be the same (currently not, the correct one is the calculation used inside GenerateTrustedSetup function), the calculation is repeated. TODO avoid repeating calculation
// assert.Equal(t, zxQAP, setup.Pk.Z)
assert . Equal ( t , zxQAP , setup . Pk . Z )
fmt . Println ( "hx pk.z" , hxQAP )
hx := Utils . PF . DivisorPolynomial ( px , setup . Pk . Z )
fmt . Println ( "hx pk.z" , hx )
assert . Equal ( t , hx , hxQAP )
// assert.Equal(t, hxQAP, hx)
div , rem = Utils . PF . Div ( px , setup . Pk . Z )
assert . Equal ( t , hx , div )
@ -116,9 +110,6 @@ func TestZkFromFlatCircuitCode(t *testing.T) {
assert . Equal ( t , len ( hx ) , len ( px ) - len ( setup . Pk . Z ) + 1 )
assert . Equal ( t , len ( hxQAP ) , len ( px ) - len ( zxQAP ) + 1 )
// fmt.Println("pk.Z", len(setup.Pk.Z))
// fmt.Println("zxQAP", len(zxQAP))
proof , err := GenerateProofs ( * circuit , setup , w , px )
assert . Nil ( t , err )
@ -126,8 +117,8 @@ func TestZkFromFlatCircuitCode(t *testing.T) {
// fmt.Println(proof)
// fmt.Println("public signals:", proof.PublicSignals)
fmt . Println ( "\n" , circuit . Signals )
fmt . Println ( "\n witness" , w )
fmt . Println ( "\nsignals: " , circuit . Signals )
fmt . Println ( "witness: " , w )
b35Verif := big . NewInt ( int64 ( 35 ) )
publicSignalsVerif := [ ] * big . Int { b35Verif }
before := time . Now ( )
@ -147,16 +138,12 @@ func TestZkMultiplication(t *testing.T) {
equals ( c , d )
out = 1 * 1
`
fmt . Print ( "\nflat code of the circuit:" )
fmt . Println ( flatCode )
fmt . Println ( "flat code" , flatCode )
// parse the code
parser := circuitcompiler . NewParser ( strings . NewReader ( flatCode ) )
circuit , err := parser . Parse ( )
assert . Nil ( t , err )
fmt . Println ( "\ncircuit data:" , circuit )
circuitJson , _ := json . Marshal ( circuit )
fmt . Println ( "circuit:" , string ( circuitJson ) )
b3 := big . NewInt ( int64 ( 3 ) )
b4 := big . NewInt ( int64 ( 4 ) )
@ -167,8 +154,6 @@ func TestZkMultiplication(t *testing.T) {
// wittness
w , err := circuit . CalculateWitness ( privateInputs , publicSignals )
assert . Nil ( t , err )
fmt . Println ( "\n" , circuit . Signals )
fmt . Println ( "witness" , w )
// flat code to R1CS
fmt . Println ( "\ngenerating R1CS from flat code" )
@ -179,25 +164,22 @@ func TestZkMultiplication(t *testing.T) {
fmt . Println ( "c:" , c )
// R1CS to QAP
// TODO zxQAP is not used and is an old impl, bad calculated . TODO remove
// TODO zxQAP is not used and is an old impl. TODO remove
alphas , betas , gammas , zxQAP := Utils . PF . R1CSToQAP ( a , b , c )
fmt . Println ( "qap" )
fmt . Println ( "alphas" , len ( alphas ) )
fmt . Println ( "alphas[1]" , alphas [ 1 ] )
fmt . Println ( "betas" , len ( betas ) )
fmt . Println ( "gammas" , len ( gammas ) )
fmt . Println ( "zx length" , len ( zxQAP ) )
assert . Equal ( t , 6 , len ( alphas ) )
assert . Equal ( t , 6 , len ( betas ) )
assert . Equal ( t , 6 , len ( betas ) )
assert . Equal ( t , 5 , len ( zxQAP ) )
assert . True ( t , ! bytes . Equal ( alphas [ 1 ] [ 1 ] . Bytes ( ) , big . NewInt ( int64 ( 0 ) ) . Bytes ( ) ) )
ax , bx , cx , px := Utils . PF . CombinePolynomials ( w , alphas , betas , gammas )
fmt . Println ( "ax length" , len ( ax ) )
fmt . Println ( "bx length" , len ( bx ) )
fmt . Println ( "cx length" , len ( cx ) )
fmt . Println ( "px length" , len ( px ) )
fmt . Println ( "px[last]" , px [ 0 ] )
assert . Equal ( t , 4 , len ( ax ) )
assert . Equal ( t , 4 , len ( bx ) )
assert . Equal ( t , 4 , len ( cx ) )
assert . Equal ( t , 7 , len ( px ) )
hxQAP := Utils . PF . DivisorPolynomial ( px , zxQAP )
fmt . Println ( "hx length" , len ( hxQAP ) )
assert . Equal ( t , 3 , len ( hxQAP ) )
// hx==px/zx so px==hx*zx
assert . Equal ( t , px , Utils . PF . Mul ( hxQAP , zxQAP ) )
@ -215,15 +197,15 @@ func TestZkMultiplication(t *testing.T) {
// calculate trusted setup
setup , err := GenerateTrustedSetup ( len ( w ) , * circuit , alphas , betas , gammas )
assert . Nil ( t , err )
fmt . Println ( "\nt:" , setup . Toxic . T )
// fmt.Println("\nt:", setup.Toxic.T)
// zx and setup.Pk.Z should be the same (currently not, the correct one is the calculation used inside GenerateTrustedSetup function), the calculation is repeated. TODO avoid repeating calculation
// assert.Equal(t, zxQAP, setup.Pk.Z)
assert . Equal ( t , zxQAP , setup . Pk . Z )
fmt . Println ( "hx pk.z" , hxQAP )
hx := Utils . PF . DivisorPolynomial ( px , setup . Pk . Z )
fmt . Println ( "hx pk.z" , hx )
// assert.Equal(t, hxQAP, hx)
assert . Equal ( t , 3 , len ( hx ) )
assert . Equal ( t , hx , hxQAP )
div , rem = Utils . PF . Div ( px , setup . Pk . Z )
assert . Equal ( t , hx , div )
assert . Equal ( t , rem , r1csqap . ArrayOfBigZeros ( 4 ) )
@ -236,9 +218,6 @@ func TestZkMultiplication(t *testing.T) {
assert . Equal ( t , len ( hx ) , len ( px ) - len ( setup . Pk . Z ) + 1 )
assert . Equal ( t , len ( hxQAP ) , len ( px ) - len ( zxQAP ) + 1 )
// fmt.Println("pk.Z", len(setup.Pk.Z))
// fmt.Println("zxQAP", len(zxQAP))
proof , err := GenerateProofs ( * circuit , setup , w , px )
assert . Nil ( t , err )
@ -247,7 +226,7 @@ func TestZkMultiplication(t *testing.T) {
// fmt.Println("public signals:", proof.PublicSignals)
fmt . Println ( "\n" , circuit . Signals )
fmt . Println ( "\n witness" , w )
fmt . Println ( "witness" , w )
b12Verif := big . NewInt ( int64 ( 12 ) )
publicSignalsVerif := [ ] * big . Int { b12Verif }
before := time . Now ( )
@ -260,80 +239,20 @@ func TestZkMultiplication(t *testing.T) {
assert . True ( t , ! VerifyProof ( * circuit , setup , proof , wrongPublicSignalsVerif , true ) )
}
/ *
func TestZkFromHardcodedR1CS ( t * testing . T ) {
b0 := big . NewInt ( int64 ( 0 ) )
b1 := big . NewInt ( int64 ( 1 ) )
b3 := big . NewInt ( int64 ( 3 ) )
b5 := big . NewInt ( int64 ( 5 ) )
b9 := big . NewInt ( int64 ( 9 ) )
b27 := big . NewInt ( int64 ( 27 ) )
b30 := big . NewInt ( int64 ( 30 ) )
b35 := big . NewInt ( int64 ( 35 ) )
a := [ ] [ ] * big . Int {
[ ] * big . Int { b0 , b0 , b1 , b0 , b0 , b0 } ,
[ ] * big . Int { b0 , b0 , b0 , b1 , b0 , b0 } ,
[ ] * big . Int { b0 , b0 , b1 , b0 , b1 , b0 } ,
[ ] * big . Int { b5 , b0 , b0 , b0 , b0 , b1 } ,
}
b := [ ] [ ] * big . Int {
[ ] * big . Int { b0 , b0 , b1 , b0 , b0 , b0 } ,
[ ] * big . Int { b0 , b0 , b1 , b0 , b0 , b0 } ,
[ ] * big . Int { b1 , b0 , b0 , b0 , b0 , b0 } ,
[ ] * big . Int { b1 , b0 , b0 , b0 , b0 , b0 } ,
}
c := [ ] [ ] * big . Int {
[ ] * big . Int { b0 , b0 , b0 , b1 , b0 , b0 } ,
[ ] * big . Int { b0 , b0 , b0 , b0 , b1 , b0 } ,
[ ] * big . Int { b0 , b0 , b0 , b0 , b0 , b1 } ,
[ ] * big . Int { b0 , b1 , b0 , b0 , b0 , b0 } ,
}
alphas , betas , gammas , zx := Utils . PF . R1CSToQAP ( a , b , c )
// wittness = 1, 35, 3, 9, 27, 30
w := [ ] * big . Int { b1 , b35 , b3 , b9 , b27 , b30 }
circuit := circuitcompiler . Circuit {
NVars : 6 ,
NPublic : 1 ,
NSignals : len ( w ) ,
}
ax , bx , cx , px := Utils . PF . CombinePolynomials ( w , alphas , betas , gammas )
hx := Utils . PF . DivisorPolynomial ( px , zx )
// hx==px/zx so px==hx*zx
assert . Equal ( t , px , Utils . PF . Mul ( hx , zx ) )
// p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
abc := Utils . PF . Sub ( Utils . PF . Mul ( ax , bx ) , cx )
assert . Equal ( t , abc , px )
hz := Utils . PF . Mul ( hx , zx )
assert . Equal ( t , abc , hz )
div , rem := Utils . PF . Div ( px , zx )
assert . Equal ( t , hx , div )
assert . Equal ( t , rem , r1csqap . ArrayOfBigZeros ( 4 ) )
// calculate trusted setup
setup , err := GenerateTrustedSetup ( len ( w ) , circuit , alphas , betas , gammas , zx )
assert . Nil ( t , err )
// piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t)
proof , err := GenerateProofs ( circuit , setup , hx , w )
assert . Nil ( t , err )
// assert.True(t, VerifyProof(circuit, setup, proof, true))
publicSignals := [ ] * big . Int { b35 }
assert . True ( t , VerifyProof ( circuit , setup , proof , publicSignals , true ) )
}
func TestZkMultiplication ( t * testing . T ) {
// compile circuit and get the R1CS
func TestMinimalFlow ( t * testing . T ) {
// circuit function
// y = x^3 + x + 5
flatCode := `
func test ( a , b ) :
out = a * b
func test ( private s0 , public s1 ) :
s2 = s0 * s0
s3 = s2 * s0
s4 = s3 + s0
s5 = s4 + 5
equals ( s1 , s5 )
out = 1 * 1
`
fmt . Print ( "\nflat code of the circuit:" )
fmt . Println ( flatCode )
// parse the code
parser := circuitcompiler . NewParser ( strings . NewReader ( flatCode ) )
@ -341,46 +260,70 @@ func TestZkMultiplication(t *testing.T) {
assert . Nil ( t , err )
b3 := big . NewInt ( int64 ( 3 ) )
b4 := big . NewInt ( int64 ( 4 ) )
inputs := [ ] * big . Int { b3 , b4 }
privateInputs := [ ] * big . Int { b3 }
b35 := big . NewInt ( int64 ( 35 ) )
publicSignals := [ ] * big . Int { b35 }
// wittness
w , err := circuit . CalculateWitness ( inputs )
w , err := circuit . CalculateWitness ( pr ivateI nputs , publicSignal s)
assert . Nil ( t , err )
// flat code to R1CS
fmt . Println ( "\ngenerating R1CS from flat code" )
a , b , c := circuit . GenerateR1CS ( )
fmt . Println ( "\nR1CS:" )
fmt . Println ( "a:" , a )
fmt . Println ( "b:" , b )
fmt . Println ( "c:" , c )
// R1CS to QAP
alphas , betas , gammas , zx := Utils . PF . R1CSToQAP ( a , b , c )
// TODO zxQAP is not used and is an old impl, TODO remove
alphas , betas , gammas , _ := Utils . PF . R1CSToQAP ( a , b , c )
fmt . Println ( "qap" )
assert . Equal ( t , 8 , len ( alphas ) )
assert . Equal ( t , 8 , len ( alphas ) )
assert . Equal ( t , 8 , len ( alphas ) )
assert . True ( t , ! bytes . Equal ( alphas [ 1 ] [ 1 ] . Bytes ( ) , big . NewInt ( int64 ( 0 ) ) . Bytes ( ) ) )
ax , bx , cx , px := Utils . PF . CombinePolynomials ( w , alphas , betas , gammas )
assert . Equal ( t , 7 , len ( ax ) )
assert . Equal ( t , 7 , len ( bx ) )
assert . Equal ( t , 7 , len ( cx ) )
assert . Equal ( t , 13 , len ( px ) )
hx := Utils . PF . DivisorPolynomial ( px , zx )
// calculate trusted setup
setup , err := GenerateTrustedSetup ( len ( w ) , * circuit , alphas , betas , gammas )
assert . Nil ( t , err )
fmt . Println ( "\nt:" , setup . Toxic . T )
// hx==px/zx so px==hx*zx
assert . Equal ( t , px , Utils . PF . Mul ( hx , zx ) )
hx := Utils . PF . DivisorPolynomial ( px , setup . Pk . Z )
div , rem := Utils . PF . Div ( px , setup . Pk . Z )
assert . Equal ( t , hx , div )
assert . Equal ( t , rem , r1csqap . ArrayOfBigZeros ( 6 ) )
// p(x) = a(x) * b(x) - c(x) == h(x) * z(x)
abc := Utils . PF . Sub ( Utils . PF . Mul ( ax , bx ) , cx )
assert . Equal ( t , abc , px )
hz := Utils . PF . Mul ( hx , zx )
assert . Equal ( t , abc , hz )
// hx==px/zx so px==hx*zx
assert . Equal ( t , px , Utils . PF . Mul ( hx , setup . Pk . Z ) )
div , rem := Utils . PF . Div ( px , zx )
assert . Equal ( t , hx , div )
assert . Equal ( t , rem , r1csqap . ArrayOfBigZeros ( 1 ) )
// check length of polynomials H(x) and Z(x)
assert . Equal ( t , len ( hx ) , len ( px ) - len ( setup . Pk . Z ) + 1 )
// calculate trusted setup
setup , err := GenerateTrustedSetup ( len ( w ) , * circuit , alphas , betas , gammas , zx )
proof , err := GenerateProofs ( * circuit , setup , w , px )
assert . Nil ( t , err )
// piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t)
proof , err := GenerateProofs ( * circuit , setup , hx , w )
assert . Nil ( t , err )
// fmt.Println("\n proofs:")
// fmt.Println(proof)
// assert.True(t, VerifyProof(*circuit, setup, proof, false))
b35 := big . NewInt ( int64 ( 35 ) )
publicSignals := [ ] * big . Int { b35 }
assert . True ( t , VerifyProof ( * circuit , setup , proof , publicSignals , true ) )
// fmt.Println("public signals:", proof.PublicSignals)
fmt . Println ( "\nsignals:" , circuit . Signals )
fmt . Println ( "witness:" , w )
b35Verif := big . NewInt ( int64 ( 35 ) )
publicSignalsVerif := [ ] * big . Int { b35Verif }
before := time . Now ( )
assert . True ( t , VerifyProof ( * circuit , setup , proof , publicSignalsVerif , true ) )
fmt . Println ( "verify proof time elapsed:" , time . Since ( before ) )
// check that with another public input the verification returns false
bOtherWrongPublic := big . NewInt ( int64 ( 34 ) )
wrongPublicSignalsVerif := [ ] * big . Int { bOtherWrongPublic }
assert . True ( t , ! VerifyProof ( * circuit , setup , proof , wrongPublicSignalsVerif , true ) )
}
* /