Browse Source

changed signal order : [1,inputs..,outputs...,trace...]

Improved performance
pull/8/head
mottla 5 years ago
parent
commit
5c59496144
5 changed files with 36 additions and 47 deletions
  1. +19
    -4
      circuitcompiler/Programm.go
  2. +1
    -1
      circuitcompiler/Programm_test.go
  3. +8
    -2
      r1csqap/r1csqap.go
  4. +4
    -33
      snark.go
  5. +4
    -7
      snark_test.go

+ 19
- 4
circuitcompiler/Programm.go

@ -24,6 +24,7 @@ type R1CS struct {
type Program struct {
functions map[string]*Circuit
globalInputs []string
globalOutput map[string]bool
arithmeticEnvironment utils //find a better name
//key 1: the hash chain indicating from where the variable is called H( H(main(a,b)) , doSomething(x,z) ), where H is a hash function.
@ -67,6 +68,10 @@ func (p *Program) BuildConstraintTrees() {
for _, in := range p.getMainCircuit().Inputs {
p.globalInputs = append(p.globalInputs, in)
}
for key, _ := range p.globalOutput {
p.globalInputs = append(p.globalInputs, key)
}
//TODO do the same with the outputs
var wg = sync.WaitGroup{}
//we build the parse trees concurrently! because we can! go rocks
@ -193,8 +198,14 @@ func (p *Program) r1CSRecursiveBuild(currentCircuit *Circuit, node *gate, hashTr
out := hashTogether(leftHash, rightHash)
rootGate.value.V1 = rootGate.value.V1 + string(leftHash[:10])
rootGate.value.V2 = rootGate.value.V2 + string(rightHash[:10])
rootGate.value.Out = rootGate.value.Out + string(out[:10])
//note we only check for existence, but not for truth.
if _, ex := p.globalOutput[rootGate.value.Out]; !ex {
rootGate.value.Out = rootGate.value.Out + string(out[:10])
}
p.computedInContext[string(hashTraceBuildup)][node.value.Out] = rootGate.value.Out
p.computedFactors[sig] = rootGate.value.Out
*orderedmGates = append(*orderedmGates, *rootGate)
@ -449,6 +460,7 @@ func NewProgram() (p *Program) {
p = &Program{
functions: map[string]*Circuit{},
globalInputs: []string{"one"},
globalOutput: map[string]bool{"main": true},
arithmeticEnvironment: prepareUtils(),
}
return
@ -458,7 +470,7 @@ func NewProgram() (p *Program) {
func (p *Program) GenerateReducedR1CS(mGates []gate) (r1CS R1CS) {
// from flat code to R1CS
offset := len(p.globalInputs)
offset := len(p.globalInputs) - len(p.globalOutput)
// one + in1 +in2+... + gate1 + gate2 .. + out
size := offset + len(mGates)
indexMap := make(map[string]int)
@ -467,8 +479,11 @@ func (p *Program) GenerateReducedR1CS(mGates []gate) (r1CS R1CS) {
indexMap[v] = i
}
for i, v := range mGates {
indexMap[v.value.Out] = i + offset
for _, v := range mGates {
if _, ex := indexMap[v.value.Out]; !ex {
indexMap[v.value.Out] = len(indexMap)
}
}
for _, g := range mGates {

+ 1
- 1
circuitcompiler/Programm_test.go

@ -154,7 +154,7 @@ func TestNewProgramm(t *testing.T) {
w := CalculateWitness(inputs, r1cs)
fmt.Println("witness")
fmt.Println(w)
assert.Equal(t, io.result, w[len(w)-1])
assert.Equal(t, io.result, w[len(program.globalInputs)-1])
}
}

+ 8
- 2
r1csqap/r1csqap.go

@ -6,6 +6,8 @@ import (
"github.com/arnaucube/go-snark/fields"
)
var bigZero = big.NewInt(int64(0))
// Transpose transposes the *big.Int matrix
func Transpose(matrix [][]*big.Int) [][]*big.Int {
r := make([][]*big.Int, len(matrix[0]))
@ -22,7 +24,7 @@ func Transpose(matrix [][]*big.Int) [][]*big.Int {
// ArrayOfBigZeros creates a *big.Int array with n elements to zero
func ArrayOfBigZeros(num int) []*big.Int {
bigZero := big.NewInt(int64(0))
var r = make([]*big.Int, num, num)
for i := 0; i < num; i++ {
r[i] = bigZero
@ -155,7 +157,11 @@ func (pf PolynomialField) LagrangeInterpolation(v []*big.Int) []*big.Int {
// https://en.wikipedia.org/wiki/Lagrange_polynomial
var r []*big.Int
for i := 0; i < len(v); i++ {
r = pf.Add(r, pf.NewPolZeroAt(i+1, len(v), v[i]))
//NOTE this comparison gives a huge performance boost
if v[i].Cmp(bigZero) != 0 {
r = pf.Add(r, pf.NewPolZeroAt(i+1, len(v), v[i]))
}
//r = pf.Mul(v[i], pf.NewPolZeroAt(i+1, len(v), v[i]))
}
//

+ 4
- 33
snark.go

@ -2,7 +2,6 @@ package snark
import (
"fmt"
"github.com/arnaucube/go-snark/circuitcompiler"
"math/big"
"os"
@ -91,7 +90,7 @@ func prepareUtils() utils {
}
// GenerateTrustedSetup generates the Trusted Setup from a compiled Circuit. The Setup.Toxic sub data structure must be destroyed
func GenerateTrustedSetup(witnessLength int, alphas, betas, gammas [][]*big.Int) (Setup, error) {
func GenerateTrustedSetup(inputs int, alphas, betas, gammas [][]*big.Int) (Setup, error) {
var setup Setup
var err error
@ -174,13 +173,13 @@ func GenerateTrustedSetup(witnessLength int, alphas, betas, gammas [][]*big.Int)
setup.Vk.G2Kg = Utils.Bn.G2.MulScalar(Utils.Bn.G2.G, setup.Toxic.Kgamma)
// for i := 0; i < circuit.NVars; i++ {
for i := 0; i < witnessLength; i++ {
for i := 0; i < len(alphas); i++ {
at := Utils.PF.Eval(alphas[i], setup.Toxic.T)
// rhoAat := Utils.Bn.Fq1.Mul(setup.Toxic.RhoA, at)
rhoAat := Utils.FqR.Mul(setup.Toxic.RhoA, at)
a := Utils.Bn.G1.MulScalar(Utils.Bn.G1.G, rhoAat)
setup.Pk.A = append(setup.Pk.A, a)
if i <= 4 {
if i < inputs {
setup.Vk.IC = append(setup.Vk.IC, a)
}
@ -322,7 +321,7 @@ func VerifyProof(setup Setup, proof Proof, publicSignals []*big.Int, debug bool)
// Vkx, to then calculate Vkx+piA
vkxpia := setup.Vk.IC[0]
for i := 0; i < len(publicSignals); i++ {
vkxpia = Utils.Bn.G1.Add(vkxpia, Utils.Bn.G1.MulScalar(setup.Vk.IC[i+1], publicSignals[i]))
vkxpia = Utils.Bn.G1.Add(vkxpia, Utils.Bn.G1.MulScalar(setup.Vk.IC[i], publicSignals[i]))
}
// e(Vkx+piA, piB) == e(piH, Vkz) * e(piC, g2)
@ -355,31 +354,3 @@ func VerifyProof(setup Setup, proof Proof, publicSignals []*big.Int, debug bool)
return true
}
//TODO this is just a workaround to place the output after the input signals. Will be removed once the handling of private variables is already considered in the lexer
func moveOutputToBegining(r1cs circuitcompiler.R1CS) (r circuitcompiler.R1CS) {
return r1cs
// activating this part, causes a huge messup I want to deal with a bit later
tmpA, tmpB, tmpC := [][]*big.Int{}, [][]*big.Int{}, [][]*big.Int{}
tmpA = append(tmpA, r1cs.A[len(r1cs.A)-1])
tmpA = append(tmpA, r1cs.A[:len(r1cs.A)-1]...)
tmpB = append(tmpB, r1cs.B[len(r1cs.B)-1])
tmpB = append(tmpB, r1cs.B[:len(r1cs.B)-1]...)
tmpC = append(tmpC, r1cs.C[len(r1cs.C)-1])
tmpC = append(tmpC, r1cs.C[:len(r1cs.C)-1]...)
return circuitcompiler.R1CS{A: tmpA, B: tmpB, C: tmpC}
}
//TODO this is just a workaround to place the output after the input signals. Will be removed once the handling of private variables is already considered in the lexer
func moveWitnessOutputAfterInputs(numberOfInputs int, witness []*big.Int) (w []*big.Int) {
return witness
// activating this part, causes a huge messup I want to deal with a bit later
wtmp := append(witness[:numberOfInputs], witness[len(witness)-1])
wtmp = append(wtmp, witness[numberOfInputs:len(witness)-2]...)
return wtmp
}

+ 4
- 7
snark_test.go

@ -143,7 +143,7 @@ func TestGenerateAndVerifyProof(t *testing.T) {
fmt.Println("generating R1CS")
//NOTE MOVE DOES NOTHING CURRENTLY
r1cs := moveOutputToBegining(program.GenerateReducedR1CS(gates))
r1cs := program.GenerateReducedR1CS(gates)
//[[0 1 0 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0] [0 0 0 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 0 0]]
//[[0 0 1 0 0 0 0 0 0 0] [0 0 0 0 1 0 0 0 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 0 0 0 0 5 0]]
//[[0 0 0 0 0 1 0 0 0 0] [0 0 0 0 0 0 1 0 0 0] [0 0 0 0 0 0 0 1 0 0] [0 0 0 0 0 0 0 1 0 0] [0 0 0 0 0 0 0 0 0 1]]
@ -163,7 +163,7 @@ func TestGenerateAndVerifyProof(t *testing.T) {
before := time.Now()
//calculate trusted setup
setup, err := GenerateTrustedSetup(len(alphas[0]), alphas, betas, gammas)
setup, err := GenerateTrustedSetup(program.GlobalInputCount(), alphas, betas, gammas)
fmt.Println("Generate CRS time elapsed:", time.Since(before))
assert.Nil(t, err)
fmt.Println("\nt:", setup.Toxic.T)
@ -175,11 +175,8 @@ func TestGenerateAndVerifyProof(t *testing.T) {
fmt.Println(inputs)
w := circuitcompiler.CalculateWitness(inputs, r1cs)
fmt.Println("\nwitness", w)
//NOTE MOVE DOES NOTHING
w = moveWitnessOutputAfterInputs(program.GlobalInputCount(), w)
fmt.Println("\nwitness Reordered ", w)
assert.Equal(t, io.result, w[len(w)-1])
assert.Equal(t, io.result, w[program.GlobalInputCount()-1])
ax, bx, cx, px := Utils.PF.CombinePolynomials(w, alphas, betas, gammas)
fmt.Println("ax length", len(ax))
@ -219,7 +216,7 @@ func TestGenerateAndVerifyProof(t *testing.T) {
assert.Nil(t, err)
before = time.Now()
assert.True(t, VerifyProof(setup, proof, append(w[1:program.GlobalInputCount()], w[len(w)-1]), true))
assert.True(t, VerifyProof(setup, proof, w[:program.GlobalInputCount()], true))
fmt.Println("verify proof time elapsed:", time.Since(before))
}

Loading…
Cancel
Save