github.com/consensys/gnark-crypto@v0.14.0/internal/generator/iop/template/quotient.go.tmpl (about) 1 import ( 2 "math/big" 3 "math/bits" 4 5 "github.com/consensys/gnark-crypto/internal/parallel" 6 7 "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr" 8 "github.com/consensys/gnark-crypto/ecc/{{ .Name }}/fr/fft" 9 ) 10 11 // DivideByXMinusOne 12 // The input must be in LagrangeCoset. 13 // The result is in Canonical Regular. 14 func DivideByXMinusOne(a *Polynomial, domains [2]*fft.Domain) (*Polynomial, error) { 15 16 // check that the basis is LagrangeCoset 17 if a.Basis != LagrangeCoset { 18 return nil, ErrMustBeLagrangeCoset 19 } 20 21 // prepare the evaluations of x^n-1 on the big domain's coset 22 xnMinusOneInverseLagrangeCoset := evaluateXnMinusOneDomainBigCoset(domains) 23 24 rho := a.coefficients.Len() / a.size 25 26 nbElmts := a.coefficients.Len() 27 28 coeffs := make([]fr.Element, a.coefficients.Len()) 29 res := NewPolynomial(&coeffs, Form{Layout: BitReverse, Basis: LagrangeCoset}) 30 res.size = a.size 31 res.blindedSize = a.blindedSize 32 33 nn := uint64(64 - bits.TrailingZeros(uint(nbElmts))) 34 parallel.Execute(a.coefficients.Len(), func(start, end int){ 35 for i := start; i < end; i++ { 36 iRev := bits.Reverse64(uint64(i)) >> nn 37 c := a.GetCoeff(i) 38 (*res.coefficients)[iRev]. 39 Mul(&c, &xnMinusOneInverseLagrangeCoset[i%rho]) 40 } 41 }) 42 43 44 res.ToCanonical(domains[1]) 45 46 return res, nil 47 48 } 49 50 // evaluateXnMinusOneDomainBigCoset evaluates Xᵐ-1 on DomainBig coset 51 func evaluateXnMinusOneDomainBigCoset(domains [2]*fft.Domain) []fr.Element { 52 53 ratio := domains[1].Cardinality / domains[0].Cardinality 54 55 res := make([]fr.Element, ratio) 56 57 expo := big.NewInt(int64(domains[0].Cardinality)) 58 res[0].Exp(domains[1].FrMultiplicativeGen, expo) 59 60 var t fr.Element 61 t.Exp(domains[1].Generator, big.NewInt(int64(domains[0].Cardinality))) 62 63 one := fr.One() 64 65 for i := 1; i < int(ratio); i++ { 66 res[i].Mul(&res[i-1], &t) 67 res[i-1].Sub(&res[i-1], &one) 68 } 69 res[len(res)-1].Sub(&res[len(res)-1], &one) 70 71 res = fr.BatchInvert(res) 72 73 return res 74 }