Add polynomials arithmetic in goff

Polynomials and ifft moved to goff (iden3/go-iden3-crypto/ff) instead of *big.Int.

Benchmarks:

- Before:
BenchmarkArithmetic/polynomialSub-4         	    2774	    441063 ns/op
BenchmarkArithmetic/polynomialMul-4         	       1	1135732757 ns/op
BenchmarkArithmetic/polynomialDiv-4         	     768	   1425192 ns/op
BenchmarkGenerateProof-4                    	       1	2844488975 ns/op

- With this commit:
BenchmarkArithmetic/polynomialSubE-4        	   23097	     54152 ns/op
BenchmarkArithmetic/polynomialMulE-4        	      25	  44914327 ns/op
BenchmarkArithmetic/polynomialDivE-4        	    8703	    132573 ns/op
BenchmarkGenerateProof-4                    	       1	1530398526 ns/op
This commit is contained in:
arnaucube
2020-04-20 12:37:49 +02:00
parent 3f5f8e2318
commit 324c817d42
7 changed files with 178 additions and 33 deletions

View File

@@ -3,11 +3,13 @@ package prover
import (
"math"
"math/big"
"github.com/iden3/go-iden3-crypto/ff"
)
type rootsT struct {
roots [][]*big.Int
w []*big.Int
roots [][]*ff.Element
w []*ff.Element
}
func newRootsT() rootsT {
@@ -19,15 +21,15 @@ func newRootsT() rootsT {
s++
rem = new(big.Int).Rsh(rem, 1)
}
roots.w = make([]*big.Int, s+1)
roots.w[s] = fExp(big.NewInt(5), rem)
roots.w = make([]*ff.Element, s+1)
roots.w[s] = ff.NewElement().SetBigInt(fExp(big.NewInt(5), rem))
n := s - 1
for n >= 0 {
roots.w[n] = fMul(roots.w[n+1], roots.w[n+1])
roots.w[n] = ff.NewElement().Mul(roots.w[n+1], roots.w[n+1])
n--
}
roots.roots = make([][]*big.Int, 50) // TODO WIP
roots.roots = make([][]*ff.Element, 50) // TODO WIP
roots.setRoots(15)
return roots
@@ -35,25 +37,25 @@ func newRootsT() rootsT {
func (roots rootsT) setRoots(n int) {
for i := n; i >= 0 && nil == roots.roots[i]; i-- { // TODO tmp i<=len(r)
r := big.NewInt(1)
r := ff.NewElement().SetBigInt(big.NewInt(1))
nroots := 1 << i
var rootsi []*big.Int
var rootsi []*ff.Element
for j := 0; j < nroots; j++ {
rootsi = append(rootsi, r)
r = fMul(r, roots.w[i])
r = ff.NewElement().Mul(r, roots.w[i])
}
roots.roots[i] = rootsi
}
}
func fft(roots rootsT, pall []*big.Int, bits, offset, step int) []*big.Int {
func fft(roots rootsT, pall []*ff.Element, bits, offset, step int) []*ff.Element {
n := 1 << bits
if n == 1 {
return []*big.Int{pall[offset]}
return []*ff.Element{pall[offset]}
} else if n == 2 {
return []*big.Int{
fAdd(pall[offset], pall[offset+step]), // TODO tmp
fSub(pall[offset], pall[offset+step]),
return []*ff.Element{
ff.NewElement().Add(pall[offset], pall[offset+step]), // TODO tmp
ff.NewElement().Sub(pall[offset], pall[offset+step]),
}
}
@@ -61,17 +63,16 @@ func fft(roots rootsT, pall []*big.Int, bits, offset, step int) []*big.Int {
p1 := fft(roots, pall, bits-1, offset, step*2)
p2 := fft(roots, pall, bits-1, offset+step, step*2)
// var out []*big.Int
out := make([]*big.Int, n)
out := make([]*ff.Element, n)
for i := 0; i < ndiv2; i++ {
// fmt.Println(i, len(roots.roots))
out[i] = fAdd(p1[i], fMul(roots.roots[bits][i], p2[i]))
out[i+ndiv2] = fSub(p1[i], fMul(roots.roots[bits][i], p2[i]))
out[i] = ff.NewElement().Add(p1[i], ff.NewElement().Mul(roots.roots[bits][i], p2[i]))
out[i+ndiv2] = ff.NewElement().Sub(p1[i], ff.NewElement().Mul(roots.roots[bits][i], p2[i]))
}
return out
}
func ifft(p []*big.Int) []*big.Int {
func ifft(p []*ff.Element) []*ff.Element {
if len(p) <= 1 {
return p
}
@@ -82,20 +83,20 @@ func ifft(p []*big.Int) []*big.Int {
ep := extend(p, m)
res := fft(roots, ep, int(bits), 0, 1)
twoinvm := fInv(fMul(big.NewInt(1), big.NewInt(int64(m))))
twoinvm := ff.NewElement().SetBigInt(fInv(fMul(big.NewInt(1), big.NewInt(int64(m)))))
var resn []*big.Int
var resn []*ff.Element
for i := 0; i < m; i++ {
resn = append(resn, fMul(res[(m-i)%m], twoinvm))
resn = append(resn, ff.NewElement().Mul(res[(m-i)%m], twoinvm))
}
return resn
}
func extend(p []*big.Int, e int) []*big.Int {
func extend(p []*ff.Element, e int) []*ff.Element {
if e == len(p) {
return p
}
z := arrayOfZeroes(e - len(p))
z := arrayOfZeroesE(e - len(p))
return append(p, z...)
}