github.com/consensys/gnark@v0.11.0/backend/groth16/bn254/mpcsetup/utils.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 "bytes" 21 "math/big" 22 "math/bits" 23 "runtime" 24 25 "github.com/consensys/gnark-crypto/ecc" 26 curve "github.com/consensys/gnark-crypto/ecc/bn254" 27 "github.com/consensys/gnark-crypto/ecc/bn254/fr" 28 "github.com/consensys/gnark/internal/utils" 29 ) 30 31 type PublicKey struct { 32 SG curve.G1Affine 33 SXG curve.G1Affine 34 XR curve.G2Affine 35 } 36 37 func newPublicKey(x fr.Element, challenge []byte, dst byte) PublicKey { 38 var pk PublicKey 39 _, _, g1, _ := curve.Generators() 40 41 var s fr.Element 42 var sBi big.Int 43 s.SetRandom() 44 s.BigInt(&sBi) 45 pk.SG.ScalarMultiplication(&g1, &sBi) 46 47 // compute x*sG1 48 var xBi big.Int 49 x.BigInt(&xBi) 50 pk.SXG.ScalarMultiplication(&pk.SG, &xBi) 51 52 // generate R based on sG1, sxG1, challenge, and domain separation tag (tau, alpha or beta) 53 R := genR(pk.SG, pk.SXG, challenge, dst) 54 55 // compute x*spG2 56 pk.XR.ScalarMultiplication(&R, &xBi) 57 return pk 58 } 59 60 func bitReverse[T any](a []T) { 61 n := uint64(len(a)) 62 nn := uint64(64 - bits.TrailingZeros64(n)) 63 64 for i := uint64(0); i < n; i++ { 65 irev := bits.Reverse64(i) >> nn 66 if irev > i { 67 a[i], a[irev] = a[irev], a[i] 68 } 69 } 70 } 71 72 // Returns [1, a, a², ..., aⁿ⁻¹ ] in Montgomery form 73 func powers(a fr.Element, n int) []fr.Element { 74 result := make([]fr.Element, n) 75 result[0] = fr.NewElement(1) 76 for i := 1; i < n; i++ { 77 result[i].Mul(&result[i-1], &a) 78 } 79 return result 80 } 81 82 // Returns [aᵢAᵢ, ...] in G1 83 func scaleG1InPlace(A []curve.G1Affine, a []fr.Element) { 84 utils.Parallelize(len(A), func(start, end int) { 85 var tmp big.Int 86 for i := start; i < end; i++ { 87 a[i].BigInt(&tmp) 88 A[i].ScalarMultiplication(&A[i], &tmp) 89 } 90 }) 91 } 92 93 // Returns [aᵢAᵢ, ...] in G2 94 func scaleG2InPlace(A []curve.G2Affine, a []fr.Element) { 95 utils.Parallelize(len(A), func(start, end int) { 96 var tmp big.Int 97 for i := start; i < end; i++ { 98 a[i].BigInt(&tmp) 99 A[i].ScalarMultiplication(&A[i], &tmp) 100 } 101 }) 102 } 103 104 // Check e(a₁, a₂) = e(b₁, b₂) 105 func sameRatio(a1, b1 curve.G1Affine, a2, b2 curve.G2Affine) bool { 106 if !a1.IsInSubGroup() || !b1.IsInSubGroup() || !a2.IsInSubGroup() || !b2.IsInSubGroup() { 107 panic("invalid point not in subgroup") 108 } 109 var na2 curve.G2Affine 110 na2.Neg(&a2) 111 res, err := curve.PairingCheck( 112 []curve.G1Affine{a1, b1}, 113 []curve.G2Affine{na2, b2}) 114 if err != nil { 115 panic(err) 116 } 117 return res 118 } 119 120 // returns a = ∑ rᵢAᵢ, b = ∑ rᵢBᵢ 121 func merge(A, B []curve.G1Affine) (a, b curve.G1Affine) { 122 nc := runtime.NumCPU() 123 r := make([]fr.Element, len(A)) 124 for i := 0; i < len(A); i++ { 125 r[i].SetRandom() 126 } 127 a.MultiExp(A, r, ecc.MultiExpConfig{NbTasks: nc / 2}) 128 b.MultiExp(B, r, ecc.MultiExpConfig{NbTasks: nc / 2}) 129 return 130 } 131 132 // L1 = ∑ rᵢAᵢ, L2 = ∑ rᵢAᵢ₊₁ in G1 133 func linearCombinationG1(A []curve.G1Affine) (L1, L2 curve.G1Affine) { 134 nc := runtime.NumCPU() 135 n := len(A) 136 r := make([]fr.Element, n-1) 137 for i := 0; i < n-1; i++ { 138 r[i].SetRandom() 139 } 140 L1.MultiExp(A[:n-1], r, ecc.MultiExpConfig{NbTasks: nc / 2}) 141 L2.MultiExp(A[1:], r, ecc.MultiExpConfig{NbTasks: nc / 2}) 142 return 143 } 144 145 // L1 = ∑ rᵢAᵢ, L2 = ∑ rᵢAᵢ₊₁ in G2 146 func linearCombinationG2(A []curve.G2Affine) (L1, L2 curve.G2Affine) { 147 nc := runtime.NumCPU() 148 n := len(A) 149 r := make([]fr.Element, n-1) 150 for i := 0; i < n-1; i++ { 151 r[i].SetRandom() 152 } 153 L1.MultiExp(A[:n-1], r, ecc.MultiExpConfig{NbTasks: nc / 2}) 154 L2.MultiExp(A[1:], r, ecc.MultiExpConfig{NbTasks: nc / 2}) 155 return 156 } 157 158 // Generate R in G₂ as Hash(gˢ, gˢˣ, challenge, dst) 159 func genR(sG1, sxG1 curve.G1Affine, challenge []byte, dst byte) curve.G2Affine { 160 var buf bytes.Buffer 161 buf.Grow(len(challenge) + curve.SizeOfG1AffineUncompressed*2) 162 buf.Write(sG1.Marshal()) 163 buf.Write(sxG1.Marshal()) 164 buf.Write(challenge) 165 spG2, err := curve.HashToG2(buf.Bytes(), []byte{dst}) 166 if err != nil { 167 panic(err) 168 } 169 return spG2 170 }