arnaucube
arnaucube/go-snarkPublic Self-hosted repository
minimal clean & update tests
arnaucube arnaucube@gmail.com
Sun, 12 May 2019 17:13:58 +0200
commit

8ad8ae35f7a1aca26973eee744e2a231b20cc475

parent

7a6062e3f1db344906c0cd05f0ce558bb43fb3bf

M README.md → README.md

@@ -43,11 +43,13 @@ Example:

```go // compile circuit and get the R1CS flatCode := ` -func test(x): - aux = x*x - y = aux*x - z = x + y - out = z + 5 +func test(private s0, public s1): + s2 = s0 * s0 + s3 = s2 * s0 + s4 = s3 + s0 + s5 = s4 + 5 + equals(s1, s5) + out = 1 * 1 ` // parse the code

@@ -56,15 +58,19 @@ circuit, err := parser.Parse()

assert.Nil(t, err) fmt.Println(circuit) -// witness + b3 := big.NewInt(int64(3)) -inputs := []*big.Int{b3} -w := circuit.CalculateWitness(inputs) -fmt.Println("\nwitness", w) -/* -now we have the witness: -w = [1 3 35 9 27 30] -*/ +privateInputs := []*big.Int{b3} +b35 := big.NewInt(int64(35)) +publicSignals := []*big.Int{b35} + +// witness +w, err := circuit.CalculateWitness(privateInputs, publicSignals) +assert.Nil(t, err) +fmt.Println("witness", w) + +// now we have the witness: +// w = [1 35 3 9 27 30 35 1] // flat code to R1CS fmt.Println("generating R1CS from flat code")

@@ -72,42 +78,27 @@ a, b, c := circuit.GenerateR1CS()

/* now we have the R1CS from the circuit: -a == [[0 1 0 0 0 0] [0 0 0 1 0 0] [0 1 0 0 1 0] [5 0 0 0 0 1]] -b == [[0 1 0 0 0 0] [0 1 0 0 0 0] [1 0 0 0 0 0] [1 0 0 0 0 0]] -c == [[0 0 0 1 0 0] [0 0 0 0 1 0] [0 0 0 0 0 1] [0 0 1 0 0 0]] +a: [[0 0 1 0 0 0 0 0] [0 0 0 1 0 0 0 0] [0 0 1 0 1 0 0 0] [5 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 1 0 0 0 0 0 0] [1 0 0 0 0 0 0 0]] +b: [[0 0 1 0 0 0 0 0] [0 0 1 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0] [1 0 0 0 0 0 0 0]] +c: [[0 0 0 1 0 0 0 0] [0 0 0 0 1 0 0 0] [0 0 0 0 0 1 0 0] [0 0 0 0 0 0 1 0] [0 1 0 0 0 0 0 0] [0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 1]] */ -alphas, betas, gammas, zx := snark.Utils.PF.R1CSToQAP(a, b, c) +alphas, betas, gammas, _ := snark.Utils.PF.R1CSToQAP(a, b, c) -ax, bx, cx, px := snark.Utils.PF.CombinePolynomials(w, alphas, betas, gammas) +ax, bx, cx, px := Utils.PF.CombinePolynomials(w, alphas, betas, gammas) -hx := snark.Utils.PF.DivisorPolinomial(px, zx) +// calculate trusted setup +setup, err := GenerateTrustedSetup(len(w), *circuit, alphas, betas, gammas) -// hx==px/zx so px==hx*zx -assert.Equal(t, px, snark.Utils.PF.Mul(hx, zx)) +hx := Utils.PF.DivisorPolynomial(px, setup.Pk.Z) -// p(x) = a(x) * b(x) - c(x) == h(x) * z(x) -abc := snark.Utils.PF.Sub(pf.Mul(ax, bx), cx) -assert.Equal(t, abc, px) -hz := snark.Utils.PF.Mul(hx, zx) -assert.Equal(t, abc, hz) - -div, rem := snark.Utils.PF.Div(px, zx) -assert.Equal(t, hx, div) -assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(4)) - -// calculate trusted setup -setup, err := snark.GenerateTrustedSetup(len(w), circuit, alphas, betas, gammas, zx) -assert.Nil(t, err) -fmt.Println("t", setup.Toxic.T) - -// piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t) -proof, err := snark.GenerateProofs(circuit, setup, hx, w) -assert.Nil(t, err) +proof, err := GenerateProofs(*circuit, setup, w, px) -assert.True(t, snark.VerifyProof(circuit, setup, proof)) +b35Verif := big.NewInt(int64(35)) +publicSignalsVerif := []*big.Int{b35Verif} +assert.True(t, VerifyProof(*circuit, setup, proof, publicSignalsVerif, true)) ``` ### CLI usage

@@ -115,16 +106,24 @@

#### Compile circuit Having a circuit file `test.circuit`: ``` -func test(x): - aux = x*x - y = aux*x - z = x + y - out = z + 5 +func test(private s0, public s1): + s2 = s0 * s0 + s3 = s2 * s0 + s4 = s3 + s0 + s5 = s4 + 5 + equals(s1, s5) + out = 1 * 1 ``` -And a inputs file `inputs.json` +And a private inputs file `privateInputs.json` ``` [ 3 +] +``` +And a public inputs file `publicInputs.json` +``` +[ + 35 ] ```

@@ -144,7 +143,7 @@ This will create the file `trustedsetup.json` with the TrustedSetup data, and also a `toxic.json` file, with the parameters to delete from the `Trusted Setup`.

#### Generate Proofs -Assumming that we have the `compiledcircuit.json` and the `trustedsetup.json`, we can now generate the `Proofs` with the following command: +Assumming that we have the `compiledcircuit.json`, `trustedsetup.json`, `privateInputs.json` and the `publicInputs.json` we can now generate the `Proofs` with the following command: ``` > go-snark-cli genproofs ```

@@ -152,7 +151,7 @@

This will store the file `proofs.json`, that contains all the SNARK proofs. #### Verify Proofs -Having the `proofs.json`, `compiledcircuit.json`, `trustedsetup.json` files, we can now verify the `Pairings` of the proofs, in order to verify the proofs. +Having the `proofs.json`, `compiledcircuit.json`, `trustedsetup.json` `publicInputs.json` files, we can now verify the `Pairings` of the proofs, in order to verify the proofs. ``` > go-snark-cli verify ```
M circuitcompiler/circuit.go → circuitcompiler/circuit.go

@@ -2,7 +2,6 @@ package circuitcompiler

import ( "errors" - "fmt" "math/big" "strconv"

@@ -96,10 +95,9 @@ bConstraint := r1csqap.ArrayOfBigZeros(len(circ.Signals))

cConstraint := r1csqap.ArrayOfBigZeros(len(circ.Signals)) // if existInArray(constraint.Out) { - if used[constraint.Out] { - // panic(errors.New("out variable already used: " + constraint.Out)) - fmt.Println("variable already used") - } + // if used[constraint.Out] { + // panic(errors.New("out variable already used: " + constraint.Out)) + // } used[constraint.Out] = true if constraint.Op == "in" { for i := 0; i <= len(circ.PublicInputs); i++ {

@@ -152,7 +150,7 @@ }

type Inputs struct { Private []*big.Int - Publics []*big.Int + Public []*big.Int } // CalculateWitness calculates the Witness of a Circuit based on the given inputs

@@ -167,12 +165,9 @@ }

w := r1csqap.ArrayOfBigZeros(len(circ.Signals)) w[0] = big.NewInt(int64(1)) for i, input := range publicInputs { - fmt.Println(i + 1) - fmt.Println(input) w[i+1] = input } for i, input := range privateInputs { - fmt.Println(i + len(publicInputs) + 1) w[i+len(publicInputs)+1] = input } for _, constraint := range circ.Constraints {
M circuitcompiler/circuit_test.go → circuitcompiler/circuit_test.go

@@ -1,8 +1,6 @@

package circuitcompiler import ( - "encoding/json" - "fmt" "math/big" "strings" "testing"

@@ -11,74 +9,62 @@ "github.com/stretchr/testify/assert"

) func TestCircuitParser(t *testing.T) { - /* - input: - def test(): - y = x**3 - return x + y + 5 - - flattened: - m1 = s1 * s1 - m2 = m1 * s1 - m3 = m2 + s1 - out = m3 + 5 - - */ - - // flat code, where er is expected_result - // equals(s5, s1) - // s1 = s5 * 1 + // y = x^3 + x + 5 flat := ` func test(private s0, public s1): - s2 = s0*s0 - s3 = s2*s0 - s4 = s0 + s3 + s2 = s0 * s0 + s3 = s2 * s0 + s4 = s3 + s0 s5 = s4 + 5 - s5 = s1 * one + equals(s1, s5) out = 1 * 1 ` parser := NewParser(strings.NewReader(flat)) circuit, err := parser.Parse() assert.Nil(t, err) - fmt.Println("circuit parsed: ", circuit) // flat code to R1CS - fmt.Println("generating R1CS from flat code") a, b, c := circuit.GenerateR1CS() - fmt.Println("private inputs: ", circuit.PrivateInputs) - fmt.Println("public inputs: ", circuit.PublicInputs) + assert.Equal(t, "s0", circuit.PrivateInputs[0]) + assert.Equal(t, "s1", circuit.PublicInputs[0]) - fmt.Println("signals:", circuit.Signals) + assert.Equal(t, []string{"one", "s1", "s0", "s2", "s3", "s4", "s5", "out"}, circuit.Signals) // expected result - // b0 := big.NewInt(int64(0)) - // b1 := big.NewInt(int64(1)) - // b5 := big.NewInt(int64(5)) - // aExpected := [][]*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}, - // } - // bExpected := [][]*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}, - // } - // cExpected := [][]*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}, - // } - // - // assert.Equal(t, aExpected, a) - // assert.Equal(t, bExpected, b) - // assert.Equal(t, cExpected, c) - fmt.Println(a) - fmt.Println(b) - fmt.Println(c) + b0 := big.NewInt(int64(0)) + b1 := big.NewInt(int64(1)) + b5 := big.NewInt(int64(5)) + aExpected := [][]*big.Int{ + []*big.Int{b0, b0, b1, b0, b0, b0, b0, b0}, + []*big.Int{b0, b0, b0, b1, b0, b0, b0, b0}, + []*big.Int{b0, b0, b1, b0, b1, b0, b0, b0}, + []*big.Int{b5, b0, b0, b0, b0, b1, b0, b0}, + []*big.Int{b0, b0, b0, b0, b0, b0, b1, b0}, + []*big.Int{b0, b1, b0, b0, b0, b0, b0, b0}, + []*big.Int{b1, b0, b0, b0, b0, b0, b0, b0}, + } + bExpected := [][]*big.Int{ + []*big.Int{b0, b0, b1, b0, b0, b0, b0, b0}, + []*big.Int{b0, b0, b1, b0, b0, b0, b0, b0}, + []*big.Int{b1, b0, b0, b0, b0, b0, b0, b0}, + []*big.Int{b1, b0, b0, b0, b0, b0, b0, b0}, + []*big.Int{b1, b0, b0, b0, b0, b0, b0, b0}, + []*big.Int{b1, b0, b0, b0, b0, b0, b0, b0}, + []*big.Int{b1, b0, b0, b0, b0, b0, b0, b0}, + } + cExpected := [][]*big.Int{ + []*big.Int{b0, b0, b0, b1, b0, b0, b0, b0}, + []*big.Int{b0, b0, b0, b0, b1, b0, b0, b0}, + []*big.Int{b0, b0, b0, b0, b0, b1, b0, b0}, + []*big.Int{b0, b0, b0, b0, b0, b0, b1, b0}, + []*big.Int{b0, b1, b0, b0, b0, b0, b0, b0}, + []*big.Int{b0, b0, b0, b0, b0, b0, b1, b0}, + []*big.Int{b0, b0, b0, b0, b0, b0, b0, b1}, + } + + assert.Equal(t, aExpected, a) + assert.Equal(t, bExpected, b) + assert.Equal(t, cExpected, c) b3 := big.NewInt(int64(3)) privateInputs := []*big.Int{b3}

@@ -87,10 +73,14 @@ publicInputs := []*big.Int{b35}

// Calculate Witness w, err := circuit.CalculateWitness(privateInputs, publicInputs) assert.Nil(t, err) - fmt.Println("w", w) + b9 := big.NewInt(int64(9)) + b27 := big.NewInt(int64(27)) + b30 := big.NewInt(int64(30)) + wExpected := []*big.Int{b1, b35, b3, b9, b27, b30, b35, b1} + assert.Equal(t, wExpected, w) - circuitJson, _ := json.Marshal(circuit) - fmt.Println("circuit:", string(circuitJson)) + // circuitJson, _ := json.Marshal(circuit) + // fmt.Println("circuit:", string(circuitJson)) assert.Equal(t, circuit.NPublic, 1) assert.Equal(t, len(circuit.PublicInputs), 1)
M circuitcompiler/parser.go → circuitcompiler/parser.go

@@ -101,8 +101,6 @@ rgx := regexp.MustCompile(`\((.*?)\)`)

insideParenthesis := rgx.FindStringSubmatch(line) varsString := strings.Replace(insideParenthesis[1], " ", "", -1) params := strings.Split(varsString, ",") - fmt.Println("params", params) - // TODO c.V1 = params[0] c.V2 = params[1] return c, nil

@@ -162,7 +160,6 @@ constraint, err := p.parseLine()

if err != nil { break } - fmt.Println(constraint) if constraint.Literal == "func" { // one constraint for each input for _, in := range constraint.PublicInputs {

@@ -189,8 +186,6 @@ circuit.PrivateInputs = constraint.PrivateInputs

continue } if constraint.Literal == "equals" { - // TODO - fmt.Println("circuit.Signals", circuit.Signals) constr1 := &Constraint{ Op: "*", V1: constraint.V2,
M cli/main.go → cli/main.go

@@ -80,18 +80,22 @@ circuit, err := parser.Parse()

panicErr(err) fmt.Println("\ncircuit data:", circuit) - // read inputs file - inputsFile, err := ioutil.ReadFile("inputs.json") + // read privateInputs file + privateInputsFile, err := ioutil.ReadFile("privateInputs.json") + panicErr(err) + // read publicInputs file + publicInputsFile, err := ioutil.ReadFile("publicInputs.json") panicErr(err) // parse inputs from inputsFile - // var inputs []*big.Int var inputs circuitcompiler.Inputs - json.Unmarshal([]byte(string(inputsFile)), &inputs) + err = json.Unmarshal([]byte(string(privateInputsFile)), &inputs.Private) + panicErr(err) + err = json.Unmarshal([]byte(string(publicInputsFile)), &inputs.Public) panicErr(err) // calculate wittness - w, err := circuit.CalculateWitness(inputs.Private) + w, err := circuit.CalculateWitness(inputs.Private, inputs.Public) panicErr(err) fmt.Println("\nwitness", w)

@@ -175,18 +179,18 @@ var inputs circuitcompiler.Inputs

json.Unmarshal([]byte(string(inputsFile)), &inputs) panicErr(err) // calculate wittness - w, err := circuit.CalculateWitness(inputs.Private) + w, err := circuit.CalculateWitness(inputs.Private, inputs.Public) panicErr(err) // R1CS to QAP - alphas, betas, gammas, zx := snark.Utils.PF.R1CSToQAP(circuit.R1CS.A, circuit.R1CS.B, circuit.R1CS.C) + alphas, betas, gammas, _ := snark.Utils.PF.R1CSToQAP(circuit.R1CS.A, circuit.R1CS.B, circuit.R1CS.C) fmt.Println("qap") fmt.Println(alphas) fmt.Println(betas) fmt.Println(gammas) // calculate trusted setup - setup, err := snark.GenerateTrustedSetup(len(w), circuit, alphas, betas, gammas, zx) + setup, err := snark.GenerateTrustedSetup(len(w), circuit, alphas, betas, gammas) panicErr(err) fmt.Println("\nt:", setup.Toxic.T)

@@ -225,16 +229,21 @@ var trustedsetup snark.Setup

json.Unmarshal([]byte(string(trustedsetupFile)), &trustedsetup) panicErr(err) - // read inputs file - inputsFile, err := ioutil.ReadFile("inputs.json") + // read privateInputs file + privateInputsFile, err := ioutil.ReadFile("privateInputs.json") + panicErr(err) + // read publicInputs file + publicInputsFile, err := ioutil.ReadFile("publicInputs.json") panicErr(err) // parse inputs from inputsFile - // var inputs []*big.Int var inputs circuitcompiler.Inputs - json.Unmarshal([]byte(string(inputsFile)), &inputs) + err = json.Unmarshal([]byte(string(privateInputsFile)), &inputs.Private) + panicErr(err) + err = json.Unmarshal([]byte(string(publicInputsFile)), &inputs.Public) panicErr(err) + // calculate wittness - w, err := circuit.CalculateWitness(inputs.Private) + w, err := circuit.CalculateWitness(inputs.Private, inputs.Public) panicErr(err) fmt.Println("\nwitness", w)

@@ -293,7 +302,13 @@ var trustedsetup snark.Setup

json.Unmarshal([]byte(string(trustedsetupFile)), &trustedsetup) panicErr(err) - // TODO read publicSignals from file + // read publicInputs file + publicInputsFile, err := ioutil.ReadFile("publicInputs.json") + panicErr(err) + var publicSignals []*big.Int + err = json.Unmarshal([]byte(string(publicInputsFile)), &publicSignals) + panicErr(err) + verified := snark.VerifyProof(circuit, trustedsetup, proof, publicSignals, true) if !verified { fmt.Println("ERROR: proofs not verified")
M snark.go → snark.go

@@ -105,8 +105,6 @@ // }

// } // } - fmt.Println("alphas[1]", alphas[1]) - // generate random t value setup.Toxic.T, err = Utils.FqR.Rand() if err != nil {

@@ -226,7 +224,6 @@ big.NewInt(int64(i))),

big.NewInt(int64(1)), }) } - fmt.Println("zpol", zpol) setup.Pk.Z = zpol zt := Utils.PF.Eval(zpol, setup.Toxic.T)

@@ -243,7 +240,6 @@ gt1 = append(gt1, Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, tEncr))

// tEncr = Utils.Bn.Fq1.Mul(tEncr, setup.Toxic.T) tEncr = Utils.FqR.Mul(tEncr, setup.Toxic.T) } - fmt.Println("len(G1T)", len(gt1)) setup.G1T = gt1 return setup, nil

@@ -293,6 +289,7 @@ // e(piA, Va) == e(piA', g2)

pairingPiaVa := Utils.Bn.Pairing(proof.PiA, setup.Vk.Vka) pairingPiapG2 := Utils.Bn.Pairing(proof.PiAp, Utils.Bn.G2.G) if !Utils.Bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) { + fmt.Println("❌ e(piA, Va) == e(piA', g2), valid knowledge commitment for A") return false } if debug {

@@ -303,6 +300,7 @@ // e(Vb, piB) == e(piB', g2)

pairingVbPib := Utils.Bn.Pairing(setup.Vk.Vkb, proof.PiB) pairingPibpG2 := Utils.Bn.Pairing(proof.PiBp, Utils.Bn.G2.G) if !Utils.Bn.Fq12.Equal(pairingVbPib, pairingPibpG2) { + fmt.Println("❌ e(Vb, piB) == e(piB', g2), valid knowledge commitment for B") return false } if debug {

@@ -313,6 +311,7 @@ // e(piC, Vc) == e(piC', g2)

pairingPicVc := Utils.Bn.Pairing(proof.PiC, setup.Vk.Vkc) pairingPicpG2 := Utils.Bn.Pairing(proof.PiCp, Utils.Bn.G2.G) if !Utils.Bn.Fq12.Equal(pairingPicVc, pairingPicpG2) { + fmt.Println("❌ e(piC, Vc) == e(piC', g2), valid knowledge commitment for C") return false } if debug {

@@ -322,7 +321,6 @@

// Vkx, to then calculate Vkx+piA vkxpia := setup.Vk.IC[0] for i := 0; i < len(publicSignals); i++ { - fmt.Println("pub sig", publicSignals[i]) vkxpia = Utils.Bn.G1.Add(vkxpia, Utils.Bn.G1.MulScalar(setup.Vk.IC[i+1], publicSignals[i])) }

@@ -332,6 +330,7 @@ Utils.Bn.Pairing(Utils.Bn.G1.Add(vkxpia, proof.PiA), proof.PiB), // TODO Add(vkxpia, proof.PiA) can go outside in order to save computation, as is reused later

Utils.Bn.Fq12.Mul( Utils.Bn.Pairing(proof.PiH, setup.Vk.Vkz), Utils.Bn.Pairing(proof.PiC, Utils.Bn.G2.G))) { + fmt.Println("❌ e(Vkx+piA, piB) == e(piH, Vkz) * e(piC, g2), QAP disibility checked") return false } if debug {

@@ -346,6 +345,7 @@ pairingG1KbgPiB := Utils.Bn.Pairing(setup.Vk.G1Kbg, proof.PiB)

pairingL := Utils.Bn.Fq12.Mul(pairingPiACG2Kbg, pairingG1KbgPiB) pairingR := Utils.Bn.Pairing(proof.PiKp, setup.Vk.G2Kg) if !Utils.Bn.Fq12.Equal(pairingL, pairingR) { + fmt.Println("❌ e(Vkx+piA+piC, g2KbetaKgamma) * e(g1KbetaKgamma, piB) == e(piK, g2Kgamma)") return false } if debug {
M snark_test.go → snark_test.go

@@ -2,7 +2,6 @@ package snark

import ( "bytes" - "encoding/json" "fmt" "math/big" "strings"

@@ -35,9 +34,9 @@ // 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)) + // 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 @@

// 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 @@ fmt.Println("b:", b)

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 @@ assert.Nil(t, err)

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)

@@ -115,9 +109,6 @@

// check length of polynomials H(x) and Z(x) 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 @@ // fmt.Println("\n proofs:")

// fmt.Println(proof) // fmt.Println("public signals:", proof.PublicSignals) - fmt.Println("\n", circuit.Signals) - fmt.Println("\nwitness", 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 @@ d = a * b

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 @@

// 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 @@ fmt.Println("b:", b)

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 @@

// 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 @@ // check length of polynomials H(x) and Z(x)

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 @@ // fmt.Println(proof)

// fmt.Println("public signals:", proof.PublicSignals) fmt.Println("\n", circuit.Signals) - fmt.Println("\nwitness", w) + fmt.Println("witness", w) b12Verif := big.NewInt(int64(12)) publicSignalsVerif := []*big.Int{b12Verif} before := time.Now()

@@ -260,80 +239,20 @@ wrongPublicSignalsVerif := []*big.Int{bOtherWrongPublic}

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 @@ circuit, err := parser.Parse()

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(privateInputs, publicSignals) 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 := 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)) // hx==px/zx so px==hx*zx - assert.Equal(t, px, Utils.PF.Mul(hx, zx)) + assert.Equal(t, px, Utils.PF.Mul(hx, setup.Pk.Z)) - // 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) + // check length of polynomials H(x) and Z(x) + assert.Equal(t, len(hx), len(px)-len(setup.Pk.Z)+1) - div, rem := Utils.PF.Div(px, zx) - assert.Equal(t, hx, div) - assert.Equal(t, rem, r1csqap.ArrayOfBigZeros(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)) } -*/