github.com/consensys/gnark@v0.11.0/backend/groth16/bn254/mpcsetup/phase1.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 "crypto/sha256" 21 "errors" 22 curve "github.com/consensys/gnark-crypto/ecc/bn254" 23 "github.com/consensys/gnark-crypto/ecc/bn254/fr" 24 "math" 25 "math/big" 26 ) 27 28 // Phase1 represents the Phase1 of the MPC described in 29 // https://eprint.iacr.org/2017/1050.pdf 30 // 31 // Also known as "Powers of Tau" 32 type Phase1 struct { 33 Parameters struct { 34 G1 struct { 35 Tau []curve.G1Affine // {[τ⁰]₁, [τ¹]₁, [τ²]₁, …, [τ²ⁿ⁻²]₁} 36 AlphaTau []curve.G1Affine // {α[τ⁰]₁, α[τ¹]₁, α[τ²]₁, …, α[τⁿ⁻¹]₁} 37 BetaTau []curve.G1Affine // {β[τ⁰]₁, β[τ¹]₁, β[τ²]₁, …, β[τⁿ⁻¹]₁} 38 } 39 G2 struct { 40 Tau []curve.G2Affine // {[τ⁰]₂, [τ¹]₂, [τ²]₂, …, [τⁿ⁻¹]₂} 41 Beta curve.G2Affine // [β]₂ 42 } 43 } 44 PublicKeys struct { 45 Tau, Alpha, Beta PublicKey 46 } 47 Hash []byte // sha256 hash 48 } 49 50 // InitPhase1 initialize phase 1 of the MPC. This is called once by the coordinator before 51 // any randomness contribution is made (see Contribute()). 52 func InitPhase1(power int) (phase1 Phase1) { 53 N := int(math.Pow(2, float64(power))) 54 55 // Generate key pairs 56 var tau, alpha, beta fr.Element 57 tau.SetOne() 58 alpha.SetOne() 59 beta.SetOne() 60 phase1.PublicKeys.Tau = newPublicKey(tau, nil, 1) 61 phase1.PublicKeys.Alpha = newPublicKey(alpha, nil, 2) 62 phase1.PublicKeys.Beta = newPublicKey(beta, nil, 3) 63 64 // First contribution use generators 65 _, _, g1, g2 := curve.Generators() 66 phase1.Parameters.G2.Beta.Set(&g2) 67 phase1.Parameters.G1.Tau = make([]curve.G1Affine, 2*N-1) 68 phase1.Parameters.G2.Tau = make([]curve.G2Affine, N) 69 phase1.Parameters.G1.AlphaTau = make([]curve.G1Affine, N) 70 phase1.Parameters.G1.BetaTau = make([]curve.G1Affine, N) 71 for i := 0; i < len(phase1.Parameters.G1.Tau); i++ { 72 phase1.Parameters.G1.Tau[i].Set(&g1) 73 } 74 for i := 0; i < len(phase1.Parameters.G2.Tau); i++ { 75 phase1.Parameters.G2.Tau[i].Set(&g2) 76 phase1.Parameters.G1.AlphaTau[i].Set(&g1) 77 phase1.Parameters.G1.BetaTau[i].Set(&g1) 78 } 79 80 phase1.Parameters.G2.Beta.Set(&g2) 81 82 // Compute hash of Contribution 83 phase1.Hash = phase1.hash() 84 85 return 86 } 87 88 // Contribute contributes randomness to the phase1 object. This mutates phase1. 89 func (phase1 *Phase1) Contribute() { 90 N := len(phase1.Parameters.G2.Tau) 91 92 // Generate key pairs 93 var tau, alpha, beta fr.Element 94 tau.SetRandom() 95 alpha.SetRandom() 96 beta.SetRandom() 97 phase1.PublicKeys.Tau = newPublicKey(tau, phase1.Hash[:], 1) 98 phase1.PublicKeys.Alpha = newPublicKey(alpha, phase1.Hash[:], 2) 99 phase1.PublicKeys.Beta = newPublicKey(beta, phase1.Hash[:], 3) 100 101 // Compute powers of τ, ατ, and βτ 102 taus := powers(tau, 2*N-1) 103 alphaTau := make([]fr.Element, N) 104 betaTau := make([]fr.Element, N) 105 for i := 0; i < N; i++ { 106 alphaTau[i].Mul(&taus[i], &alpha) 107 betaTau[i].Mul(&taus[i], &beta) 108 } 109 110 // Update using previous parameters 111 // TODO @gbotrel working with jacobian points here will help with perf. 112 scaleG1InPlace(phase1.Parameters.G1.Tau, taus) 113 scaleG2InPlace(phase1.Parameters.G2.Tau, taus[0:N]) 114 scaleG1InPlace(phase1.Parameters.G1.AlphaTau, alphaTau) 115 scaleG1InPlace(phase1.Parameters.G1.BetaTau, betaTau) 116 var betaBI big.Int 117 beta.BigInt(&betaBI) 118 phase1.Parameters.G2.Beta.ScalarMultiplication(&phase1.Parameters.G2.Beta, &betaBI) 119 120 // Compute hash of Contribution 121 phase1.Hash = phase1.hash() 122 } 123 124 func VerifyPhase1(c0, c1 *Phase1, c ...*Phase1) error { 125 contribs := append([]*Phase1{c0, c1}, c...) 126 for i := 0; i < len(contribs)-1; i++ { 127 if err := verifyPhase1(contribs[i], contribs[i+1]); err != nil { 128 return err 129 } 130 } 131 return nil 132 } 133 134 // verifyPhase1 checks that a contribution is based on a known previous Phase1 state. 135 func verifyPhase1(current, contribution *Phase1) error { 136 // Compute R for τ, α, β 137 tauR := genR(contribution.PublicKeys.Tau.SG, contribution.PublicKeys.Tau.SXG, current.Hash[:], 1) 138 alphaR := genR(contribution.PublicKeys.Alpha.SG, contribution.PublicKeys.Alpha.SXG, current.Hash[:], 2) 139 betaR := genR(contribution.PublicKeys.Beta.SG, contribution.PublicKeys.Beta.SXG, current.Hash[:], 3) 140 141 // Check for knowledge of toxic parameters 142 if !sameRatio(contribution.PublicKeys.Tau.SG, contribution.PublicKeys.Tau.SXG, contribution.PublicKeys.Tau.XR, tauR) { 143 return errors.New("couldn't verify public key of τ") 144 } 145 if !sameRatio(contribution.PublicKeys.Alpha.SG, contribution.PublicKeys.Alpha.SXG, contribution.PublicKeys.Alpha.XR, alphaR) { 146 return errors.New("couldn't verify public key of α") 147 } 148 if !sameRatio(contribution.PublicKeys.Beta.SG, contribution.PublicKeys.Beta.SXG, contribution.PublicKeys.Beta.XR, betaR) { 149 return errors.New("couldn't verify public key of β") 150 } 151 152 // Check for valid updates using previous parameters 153 if !sameRatio(contribution.Parameters.G1.Tau[1], current.Parameters.G1.Tau[1], tauR, contribution.PublicKeys.Tau.XR) { 154 return errors.New("couldn't verify that [τ]₁ is based on previous contribution") 155 } 156 if !sameRatio(contribution.Parameters.G1.AlphaTau[0], current.Parameters.G1.AlphaTau[0], alphaR, contribution.PublicKeys.Alpha.XR) { 157 return errors.New("couldn't verify that [α]₁ is based on previous contribution") 158 } 159 if !sameRatio(contribution.Parameters.G1.BetaTau[0], current.Parameters.G1.BetaTau[0], betaR, contribution.PublicKeys.Beta.XR) { 160 return errors.New("couldn't verify that [β]₁ is based on previous contribution") 161 } 162 if !sameRatio(contribution.PublicKeys.Tau.SG, contribution.PublicKeys.Tau.SXG, contribution.Parameters.G2.Tau[1], current.Parameters.G2.Tau[1]) { 163 return errors.New("couldn't verify that [τ]₂ is based on previous contribution") 164 } 165 if !sameRatio(contribution.PublicKeys.Beta.SG, contribution.PublicKeys.Beta.SXG, contribution.Parameters.G2.Beta, current.Parameters.G2.Beta) { 166 return errors.New("couldn't verify that [β]₂ is based on previous contribution") 167 } 168 169 // Check for valid updates using powers of τ 170 _, _, g1, g2 := curve.Generators() 171 tauL1, tauL2 := linearCombinationG1(contribution.Parameters.G1.Tau) 172 if !sameRatio(tauL1, tauL2, contribution.Parameters.G2.Tau[1], g2) { 173 return errors.New("couldn't verify valid powers of τ in G₁") 174 } 175 alphaL1, alphaL2 := linearCombinationG1(contribution.Parameters.G1.AlphaTau) 176 if !sameRatio(alphaL1, alphaL2, contribution.Parameters.G2.Tau[1], g2) { 177 return errors.New("couldn't verify valid powers of α(τ) in G₁") 178 } 179 betaL1, betaL2 := linearCombinationG1(contribution.Parameters.G1.BetaTau) 180 if !sameRatio(betaL1, betaL2, contribution.Parameters.G2.Tau[1], g2) { 181 return errors.New("couldn't verify valid powers of α(τ) in G₁") 182 } 183 tau2L1, tau2L2 := linearCombinationG2(contribution.Parameters.G2.Tau) 184 if !sameRatio(contribution.Parameters.G1.Tau[1], g1, tau2L1, tau2L2) { 185 return errors.New("couldn't verify valid powers of τ in G₂") 186 } 187 188 // Check hash of the contribution 189 h := contribution.hash() 190 for i := 0; i < len(h); i++ { 191 if h[i] != contribution.Hash[i] { 192 return errors.New("couldn't verify hash of contribution") 193 } 194 } 195 196 return nil 197 } 198 199 func (phase1 *Phase1) hash() []byte { 200 sha := sha256.New() 201 phase1.writeTo(sha) 202 return sha.Sum(nil) 203 }