github.com/consensys/gnark-crypto@v0.14.0/internal/generator/sis/template/fft.go.tmpl (about) 1 import ( 2 "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" 3 "math/big" 4 ) 5 6 // FFT64 is generated by gnark-crypto and contains the unrolled code for FFT (DIF) on 64 elements 7 // equivalent code: r.Domain.FFT(k, fft.DIF, fft.OnCoset(), fft.WithNbTasks(1)) 8 // twiddlesCoset must be pre-computed from twiddles and coset table, see PrecomputeTwiddlesCoset 9 func FFT64(a []fr.Element, twiddlesCoset []fr.Element) { 10 11 {{- /* notes: 12 this function can be updated with larger n 13 nbSteps must be updated too such as 1 << nbSteps == n 14 butterflies and multiplication are separated for size n = 8, must check perf for larger n 15 */}} 16 {{$tIndex := 0}} 17 {{ $n := 64}} 18 {{ $m := div $n 2}} 19 {{ $split := 1}} 20 {{ $split = div $split 1}} 21 {{- range $step := reverse (iterate 0 6)}} 22 23 {{- $offset := 0}} 24 {{- range $s := iterate 0 $split}} 25 {{- range $i := iterate 0 $m}} 26 {{- $j := add $i $offset}} 27 {{- $k := add $j $m}} 28 a[{{$k}}].Mul(&a[{{$k}}], &twiddlesCoset[{{$tIndex}}]) 29 {{- end}} 30 {{- $offset = add $offset $n}} 31 {{- $tIndex = add $tIndex 1}} 32 {{- end}} 33 34 {{- $offset := 0}} 35 {{- range $s := iterate 0 $split}} 36 {{- range $i := iterate 0 $m}} 37 {{- $j := add $i $offset}} 38 {{- $k := add $j $m}} 39 fr.Butterfly(&a[{{$j}}], &a[{{$k}}]) 40 {{- end}} 41 {{- $offset = add $offset $n}} 42 {{- end}} 43 44 {{- $n = div $n 2}} 45 {{- $m = div $n 2}} 46 {{- $split = mul $split 2}} 47 {{- end}} 48 } 49 50 // PrecomputeTwiddlesCoset precomputes twiddlesCoset from twiddles and coset table 51 // it then return all elements in the correct order for the unrolled FFT. 52 func PrecomputeTwiddlesCoset(generator, shifter fr.Element) []fr.Element { 53 toReturn := make([]fr.Element, 63) 54 var r, s fr.Element 55 e := new(big.Int) 56 {{ $n := 64}} 57 {{ $m := div $n 2}} 58 {{ $split := 1}} 59 {{ $split = div $split 1}} 60 {{ $j := 0}} 61 {{- range $step := reverse (iterate 0 6)}} 62 s = shifter 63 for k:=0; k <{{$step}};k++ { 64 s.Square(&s) 65 } 66 67 {{- $offset := 0}} 68 {{- range $s := iterate 0 $split}} 69 {{- $exp := bitReverse $split $s}} 70 {{- if eq $exp 0}} 71 toReturn[{{$j}}] = s 72 {{- else}} 73 r.Exp(generator, e.SetUint64(uint64(1<<{{$step}} * {{$exp}}))) 74 toReturn[{{$j}}].Mul(&r, &s) 75 {{- end}} 76 {{- $j = add $j 1}} 77 {{- end}} 78 79 {{- $split = mul $split 2}} 80 {{- end}} 81 return toReturn 82 }