github.com/consensys/gnark-crypto@v0.14.0/ecc/bw6-633/fr/iop/quotient.go (about) 1 // Copyright 2020 Consensys Software Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Code generated by consensys/gnark-crypto DO NOT EDIT 16 17 package iop 18 19 import ( 20 "math/big" 21 "math/bits" 22 23 "github.com/consensys/gnark-crypto/internal/parallel" 24 25 "github.com/consensys/gnark-crypto/ecc/bw6-633/fr" 26 "github.com/consensys/gnark-crypto/ecc/bw6-633/fr/fft" 27 ) 28 29 // DivideByXMinusOne 30 // The input must be in LagrangeCoset. 31 // The result is in Canonical Regular. 32 func DivideByXMinusOne(a *Polynomial, domains [2]*fft.Domain) (*Polynomial, error) { 33 34 // check that the basis is LagrangeCoset 35 if a.Basis != LagrangeCoset { 36 return nil, ErrMustBeLagrangeCoset 37 } 38 39 // prepare the evaluations of x^n-1 on the big domain's coset 40 xnMinusOneInverseLagrangeCoset := evaluateXnMinusOneDomainBigCoset(domains) 41 42 rho := a.coefficients.Len() / a.size 43 44 nbElmts := a.coefficients.Len() 45 46 coeffs := make([]fr.Element, a.coefficients.Len()) 47 res := NewPolynomial(&coeffs, Form{Layout: BitReverse, Basis: LagrangeCoset}) 48 res.size = a.size 49 res.blindedSize = a.blindedSize 50 51 nn := uint64(64 - bits.TrailingZeros(uint(nbElmts))) 52 parallel.Execute(a.coefficients.Len(), func(start, end int) { 53 for i := start; i < end; i++ { 54 iRev := bits.Reverse64(uint64(i)) >> nn 55 c := a.GetCoeff(i) 56 (*res.coefficients)[iRev]. 57 Mul(&c, &xnMinusOneInverseLagrangeCoset[i%rho]) 58 } 59 }) 60 61 res.ToCanonical(domains[1]) 62 63 return res, nil 64 65 } 66 67 // evaluateXnMinusOneDomainBigCoset evaluates Xᵐ-1 on DomainBig coset 68 func evaluateXnMinusOneDomainBigCoset(domains [2]*fft.Domain) []fr.Element { 69 70 ratio := domains[1].Cardinality / domains[0].Cardinality 71 72 res := make([]fr.Element, ratio) 73 74 expo := big.NewInt(int64(domains[0].Cardinality)) 75 res[0].Exp(domains[1].FrMultiplicativeGen, expo) 76 77 var t fr.Element 78 t.Exp(domains[1].Generator, big.NewInt(int64(domains[0].Cardinality))) 79 80 one := fr.One() 81 82 for i := 1; i < int(ratio); i++ { 83 res[i].Mul(&res[i-1], &t) 84 res[i-1].Sub(&res[i-1], &one) 85 } 86 res[len(res)-1].Sub(&res[len(res)-1], &one) 87 88 res = fr.BatchInvert(res) 89 90 return res 91 }