github.com/consensys/gnark@v0.11.0/backend/groth16/bn254/mpcsetup/lagrange.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 gnark DO NOT EDIT 16 17 package mpcsetup 18 19 import ( 20 "math/big" 21 "math/bits" 22 "runtime" 23 24 "github.com/consensys/gnark-crypto/ecc" 25 curve "github.com/consensys/gnark-crypto/ecc/bn254" 26 "github.com/consensys/gnark-crypto/ecc/bn254/fr" 27 "github.com/consensys/gnark-crypto/ecc/bn254/fr/fft" 28 "github.com/consensys/gnark/internal/utils" 29 ) 30 31 // TODO use gnark-crypto for this op 32 func lagrangeCoeffsG1(powers []curve.G1Affine, size int) []curve.G1Affine { 33 coeffs := make([]curve.G1Affine, size) 34 copy(coeffs, powers[:size]) 35 domain := fft.NewDomain(uint64(size)) 36 numCPU := uint64(runtime.NumCPU()) 37 maxSplits := bits.TrailingZeros64(ecc.NextPowerOfTwo(numCPU)) 38 39 twiddlesInv, _ := domain.TwiddlesInv() 40 difFFTG1(coeffs, twiddlesInv, 0, maxSplits, nil) 41 bitReverse(coeffs) 42 43 var invBigint big.Int 44 domain.CardinalityInv.BigInt(&invBigint) 45 46 utils.Parallelize(size, func(start, end int) { 47 for i := start; i < end; i++ { 48 coeffs[i].ScalarMultiplication(&coeffs[i], &invBigint) 49 } 50 }) 51 return coeffs 52 } 53 54 // TODO use gnark-crypto for this op 55 func lagrangeCoeffsG2(powers []curve.G2Affine, size int) []curve.G2Affine { 56 coeffs := make([]curve.G2Affine, size) 57 copy(coeffs, powers[:size]) 58 domain := fft.NewDomain(uint64(size)) 59 numCPU := uint64(runtime.NumCPU()) 60 maxSplits := bits.TrailingZeros64(ecc.NextPowerOfTwo(numCPU)) 61 62 twiddlesInv, _ := domain.TwiddlesInv() 63 difFFTG2(coeffs, twiddlesInv, 0, maxSplits, nil) 64 bitReverse(coeffs) 65 66 var invBigint big.Int 67 domain.CardinalityInv.BigInt(&invBigint) 68 69 utils.Parallelize(size, func(start, end int) { 70 for i := start; i < end; i++ { 71 coeffs[i].ScalarMultiplication(&coeffs[i], &invBigint) 72 } 73 }) 74 return coeffs 75 } 76 77 func butterflyG1(a *curve.G1Affine, b *curve.G1Affine) { 78 t := *a 79 a.Add(a, b) 80 b.Sub(&t, b) 81 } 82 83 func butterflyG2(a *curve.G2Affine, b *curve.G2Affine) { 84 t := *a 85 a.Add(a, b) 86 b.Sub(&t, b) 87 } 88 89 // kerDIF8 is a kernel that process a FFT of size 8 90 func kerDIF8G1(a []curve.G1Affine, twiddles [][]fr.Element, stage int) { 91 butterflyG1(&a[0], &a[4]) 92 butterflyG1(&a[1], &a[5]) 93 butterflyG1(&a[2], &a[6]) 94 butterflyG1(&a[3], &a[7]) 95 96 var twiddle big.Int 97 twiddles[stage+0][1].BigInt(&twiddle) 98 a[5].ScalarMultiplication(&a[5], &twiddle) 99 twiddles[stage+0][2].BigInt(&twiddle) 100 a[6].ScalarMultiplication(&a[6], &twiddle) 101 twiddles[stage+0][3].BigInt(&twiddle) 102 a[7].ScalarMultiplication(&a[7], &twiddle) 103 butterflyG1(&a[0], &a[2]) 104 butterflyG1(&a[1], &a[3]) 105 butterflyG1(&a[4], &a[6]) 106 butterflyG1(&a[5], &a[7]) 107 twiddles[stage+1][1].BigInt(&twiddle) 108 a[3].ScalarMultiplication(&a[3], &twiddle) 109 twiddles[stage+1][1].BigInt(&twiddle) 110 a[7].ScalarMultiplication(&a[7], &twiddle) 111 butterflyG1(&a[0], &a[1]) 112 butterflyG1(&a[2], &a[3]) 113 butterflyG1(&a[4], &a[5]) 114 butterflyG1(&a[6], &a[7]) 115 } 116 117 // kerDIF8 is a kernel that process a FFT of size 8 118 func kerDIF8G2(a []curve.G2Affine, twiddles [][]fr.Element, stage int) { 119 butterflyG2(&a[0], &a[4]) 120 butterflyG2(&a[1], &a[5]) 121 butterflyG2(&a[2], &a[6]) 122 butterflyG2(&a[3], &a[7]) 123 124 var twiddle big.Int 125 twiddles[stage+0][1].BigInt(&twiddle) 126 a[5].ScalarMultiplication(&a[5], &twiddle) 127 twiddles[stage+0][2].BigInt(&twiddle) 128 a[6].ScalarMultiplication(&a[6], &twiddle) 129 twiddles[stage+0][3].BigInt(&twiddle) 130 a[7].ScalarMultiplication(&a[7], &twiddle) 131 butterflyG2(&a[0], &a[2]) 132 butterflyG2(&a[1], &a[3]) 133 butterflyG2(&a[4], &a[6]) 134 butterflyG2(&a[5], &a[7]) 135 twiddles[stage+1][1].BigInt(&twiddle) 136 a[3].ScalarMultiplication(&a[3], &twiddle) 137 twiddles[stage+1][1].BigInt(&twiddle) 138 a[7].ScalarMultiplication(&a[7], &twiddle) 139 butterflyG2(&a[0], &a[1]) 140 butterflyG2(&a[2], &a[3]) 141 butterflyG2(&a[4], &a[5]) 142 butterflyG2(&a[6], &a[7]) 143 } 144 145 func difFFTG1(a []curve.G1Affine, twiddles [][]fr.Element, stage, maxSplits int, chDone chan struct{}) { 146 if chDone != nil { 147 defer close(chDone) 148 } 149 150 n := len(a) 151 if n == 1 { 152 return 153 } else if n == 8 { 154 kerDIF8G1(a, twiddles, stage) 155 return 156 } 157 m := n >> 1 158 159 butterflyG1(&a[0], &a[m]) 160 161 var twiddle big.Int 162 for i := 1; i < m; i++ { 163 butterflyG1(&a[i], &a[i+m]) 164 twiddles[stage][i].BigInt(&twiddle) 165 a[i+m].ScalarMultiplication(&a[i+m], &twiddle) 166 } 167 168 if m == 1 { 169 return 170 } 171 172 nextStage := stage + 1 173 if stage < maxSplits { 174 chDone := make(chan struct{}, 1) 175 go difFFTG1(a[m:n], twiddles, nextStage, maxSplits, chDone) 176 difFFTG1(a[0:m], twiddles, nextStage, maxSplits, nil) 177 <-chDone 178 } else { 179 difFFTG1(a[0:m], twiddles, nextStage, maxSplits, nil) 180 difFFTG1(a[m:n], twiddles, nextStage, maxSplits, nil) 181 } 182 } 183 func difFFTG2(a []curve.G2Affine, twiddles [][]fr.Element, stage, maxSplits int, chDone chan struct{}) { 184 if chDone != nil { 185 defer close(chDone) 186 } 187 188 n := len(a) 189 if n == 1 { 190 return 191 } else if n == 8 { 192 kerDIF8G2(a, twiddles, stage) 193 return 194 } 195 m := n >> 1 196 197 butterflyG2(&a[0], &a[m]) 198 199 var twiddle big.Int 200 for i := 1; i < m; i++ { 201 butterflyG2(&a[i], &a[i+m]) 202 twiddles[stage][i].BigInt(&twiddle) 203 a[i+m].ScalarMultiplication(&a[i+m], &twiddle) 204 } 205 206 if m == 1 { 207 return 208 } 209 210 nextStage := stage + 1 211 if stage < maxSplits { 212 chDone := make(chan struct{}, 1) 213 go difFFTG2(a[m:n], twiddles, nextStage, maxSplits, chDone) 214 difFFTG2(a[0:m], twiddles, nextStage, maxSplits, nil) 215 <-chDone 216 } else { 217 difFFTG2(a[0:m], twiddles, nextStage, maxSplits, nil) 218 difFFTG2(a[m:n], twiddles, nextStage, maxSplits, nil) 219 } 220 }