Browse Source

more efficient matrix transpose

pull/8/head
mottla 5 years ago
parent
commit
023d661571
2 changed files with 18 additions and 19 deletions
  1. +10
    -11
      circuitcompiler/Programm.go
  2. +8
    -8
      r1csqap/r1csqap.go

+ 10
- 11
circuitcompiler/Programm.go

@ -6,7 +6,6 @@ import (
"github.com/arnaucube/go-snark/bn128" "github.com/arnaucube/go-snark/bn128"
"github.com/arnaucube/go-snark/fields" "github.com/arnaucube/go-snark/fields"
"github.com/arnaucube/go-snark/r1csqap" "github.com/arnaucube/go-snark/r1csqap"
"hash"
"math/big" "math/big"
"sync" "sync"
) )
@ -26,18 +25,19 @@ type Program struct {
functions map[string]*Circuit functions map[string]*Circuit
globalInputs []string globalInputs []string
arithmeticEnvironment utils //find a better name arithmeticEnvironment utils //find a better name
sha256Hasher hash.Hash
//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. //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.
//value 1 : map //value 1 : map
// with key variable name // with key variable name
// with value variable name + hash Chain // with value variable name + hash Chain
//this datastructure is nice but maybe ill replace it later with something less confusing //this datastructure is nice but maybe ill replace it later with something less confusing
//it serves the elementary purpose of not computing a variable a second time
//it serves the elementary purpose of not computing a variable a second time.
//it boosts parse time
computedInContext map[string]map[string]string computedInContext map[string]map[string]string
//to reduce the number of multiplication gates, we store each factor signature, and the variable name, //to reduce the number of multiplication gates, we store each factor signature, and the variable name,
//so each time a variable is computed, that happens to have the very same factors, we reuse the former gate
//so each time a variable is computed, that happens to have the very same factors, we reuse the former
//it boost setup and proof time
computedFactors map[string]string computedFactors map[string]string
} }
@ -239,7 +239,7 @@ func mul2DVector(a, b [2]int) [2]int {
func factorsSignature(leftFactors, rightFactors []factor) string { func factorsSignature(leftFactors, rightFactors []factor) string {
hasher.Reset() hasher.Reset()
//not using a kommutative operation here would be better. since a * b = b * a, but H(a,b) != H(b,a)
//using a commutative operation here would be better. since a * b = b * a, but H(a,b) != H(b,a)
//could use (g^a)^b == (g^b)^a where g is a generator of some prime field where the dicrete log is known to be hard //could use (g^a)^b == (g^b)^a where g is a generator of some prime field where the dicrete log is known to be hard
for _, facLeft := range leftFactors { for _, facLeft := range leftFactors {
hasher.Write([]byte(facLeft.String())) hasher.Write([]byte(facLeft.String()))
@ -250,6 +250,8 @@ func factorsSignature(leftFactors, rightFactors []factor) string {
return string(hasher.Sum(nil))[:16] return string(hasher.Sum(nil))[:16]
} }
//multiplies factor elements and returns the result
//in case the factors do not hold any constants and all inputs are distinct, the output will be the concatenation of left+right
func mulFactors(leftFactors, rightFactors []factor) (result []factor) { func mulFactors(leftFactors, rightFactors []factor) (result []factor) {
for _, facLeft := range leftFactors { for _, facLeft := range leftFactors {
@ -284,7 +286,7 @@ func mulFactors(leftFactors, rightFactors []factor) (result []factor) {
//continue //continue
} }
panic("unexpected")
panic("unexpected. If this errror is thrown, its probably brcause a true multiplication gate has been skipped and treated as on with constant multiplication or addition ")
} }
@ -448,7 +450,6 @@ func NewProgram() (p *Program) {
functions: map[string]*Circuit{}, functions: map[string]*Circuit{},
globalInputs: []string{"one"}, globalInputs: []string{"one"},
arithmeticEnvironment: prepareUtils(), arithmeticEnvironment: prepareUtils(),
sha256Hasher: sha256.New(),
} }
return return
} }
@ -529,10 +530,6 @@ func fractionToField(in [2]int) *big.Int {
//asserts that R1CS has been computed and is stored in the program p memory calling this function //asserts that R1CS has been computed and is stored in the program p memory calling this function
func CalculateWitness(input []*big.Int, r1cs R1CS) (witness []*big.Int) { func CalculateWitness(input []*big.Int, r1cs R1CS) (witness []*big.Int) {
//if len(p.globalInputs)-1 != len(input) {
// panic("input do not match the required inputs")
//}
witness = r1csqap.ArrayOfBigZeros(len(r1cs.A[0])) witness = r1csqap.ArrayOfBigZeros(len(r1cs.A[0]))
set := make([]bool, len(witness)) set := make([]bool, len(witness))
witness[0] = big.NewInt(int64(1)) witness[0] = big.NewInt(int64(1))
@ -594,7 +591,9 @@ func CalculateWitness(input []*big.Int, r1cs R1CS) (witness []*big.Int) {
b := sumRight.Int64() b := sumRight.Int64()
c := sumOut.Int64() c := sumOut.Int64()
set[index] = true set[index] = true
//TODO replace with proper multiplication of b^-1 within the finite field
witness[index] = big.NewInt(c / b) witness[index] = big.NewInt(c / b)
//Utils.FqR.Mul(sumOut, Utils.FqR.Inverse(sumRight))
} }
} }

+ 8
- 8
r1csqap/r1csqap.go

@ -1,7 +1,6 @@
package r1csqap package r1csqap
import ( import (
"bytes"
"math/big" "math/big"
"github.com/arnaucube/go-snark/fields" "github.com/arnaucube/go-snark/fields"
@ -9,13 +8,14 @@ import (
// Transpose transposes the *big.Int matrix // Transpose transposes the *big.Int matrix
func Transpose(matrix [][]*big.Int) [][]*big.Int { func Transpose(matrix [][]*big.Int) [][]*big.Int {
var r [][]*big.Int
for i := 0; i < len(matrix[0]); i++ {
var row []*big.Int
for j := 0; j < len(matrix); j++ {
row = append(row, matrix[j][i])
r := make([][]*big.Int, len(matrix[0]))
for x, _ := range r {
r[x] = make([]*big.Int, len(matrix))
}
for y, s := range matrix {
for x, e := range s {
r[x][y] = e
} }
r = append(r, row)
} }
return r return r
} }
@ -34,7 +34,7 @@ func BigArraysEqual(a, b []*big.Int) bool {
return false return false
} }
for i := 0; i < len(a); i++ { for i := 0; i < len(a); i++ {
if !bytes.Equal(a[i].Bytes(), b[i].Bytes()) {
if a[i].Cmp(b[i]) != 0 {
return false return false
} }
} }

Loading…
Cancel
Save