github.com/consensys/gnark-crypto@v0.14.0/internal/generator/ecc/template/multiexp_jacobian.go.tmpl (about) 1 {{ $G1TAffine := print (toUpper .G1.PointName) "Affine" }} 2 {{ $G1TJacobian := print (toUpper .G1.PointName) "Jac" }} 3 {{ $G1TJacobianExtended := print (toLower .G1.PointName) "JacExtended" }} 4 5 {{ $G2TAffine := print (toUpper .G2.PointName) "Affine" }} 6 {{ $G2TJacobian := print (toUpper .G2.PointName) "Jac" }} 7 {{ $G2TJacobianExtended := print (toLower .G2.PointName) "JacExtended" }} 8 9 10 11 {{ template "multiexp" dict "PointName" .G1.PointName "UPointName" (toUpper .G1.PointName) "TAffine" $G1TAffine "TJacobian" $G1TJacobian "TJacobianExtended" $G1TJacobianExtended "FrNbWords" .Fr.NbWords "CRange" .G1.CRange }} 12 {{- if ne .Name "secp256k1"}} 13 {{ template "multiexp" dict "PointName" .G2.PointName "UPointName" (toUpper .G2.PointName) "TAffine" $G2TAffine "TJacobian" $G2TJacobian "TJacobianExtended" $G2TJacobianExtended "FrNbWords" .Fr.NbWords "CRange" .G2.CRange }} 14 {{- end}} 15 16 17 18 {{define "multiexp" }} 19 20 func processChunk{{ $.UPointName }}Jacobian[B ib{{ $.TJacobianExtended }}](chunk uint64, 21 chRes chan<- {{ $.TJacobianExtended }}, 22 c uint64, 23 points []{{ $.TAffine }}, 24 digits []uint16, 25 sem chan struct{}) { 26 27 if sem != nil { 28 // if we are limited, wait for a token in the semaphore 29 <-sem 30 } 31 32 var buckets B 33 for i := 0 ; i < len(buckets); i++ { 34 buckets[i].setInfinity() 35 } 36 37 // for each scalars, get the digit corresponding to the chunk we're processing. 38 for i, digit := range digits { 39 if digit == 0 { 40 continue 41 } 42 43 // if msbWindow bit is set, we need to subtract 44 if digit & 1 == 0 { 45 // add 46 buckets[(digit>>1)-1].addMixed(&points[i]) 47 } else { 48 // sub 49 buckets[(digit>>1)].subMixed(&points[i]) 50 } 51 } 52 53 54 // reduce buckets into total 55 // total = bucket[0] + 2*bucket[1] + 3*bucket[2] ... + n*bucket[n-1] 56 57 var runningSum, total {{ $.TJacobianExtended }} 58 runningSum.setInfinity() 59 total.setInfinity() 60 for k := len(buckets) - 1; k >= 0; k-- { 61 if !buckets[k].IsInfinity() { 62 runningSum.add(&buckets[k]) 63 } 64 total.add(&runningSum) 65 } 66 67 if sem != nil { 68 // release a token to the semaphore 69 // before sending to chRes 70 sem <- struct{}{} 71 } 72 73 chRes <- total 74 } 75 76 // we declare the buckets as fixed-size array types 77 // this allow us to allocate the buckets on the stack 78 {{- range $c := $.CRange}} 79 type bucket{{ $.TJacobianExtended }}C{{$c}} [{{nbBuckets $c}}]{{ $.TJacobianExtended }} 80 {{- end}} 81 82 type ib{{ $.TJacobianExtended }} interface { 83 {{- range $i, $c := $.CRange}} 84 bucket{{ $.TJacobianExtended }}C{{$c}} {{- if not (last $i $.CRange)}} | {{- end}} 85 {{- end}} 86 } 87 88 {{end }}