|
|
@ -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...) |
|
|
|
} |