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  }