github.com/consensys/gnark@v0.11.0/backend/plonk/plonk.go (about) 1 // Copyright 2020 ConsenSys AG 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 // Package plonk implements PLONK Zero Knowledge Proof system. 16 // 17 // # See also 18 // 19 // https://eprint.iacr.org/2019/953 20 package plonk 21 22 import ( 23 "io" 24 25 "github.com/consensys/gnark-crypto/ecc" 26 "github.com/consensys/gnark-crypto/kzg" 27 "github.com/consensys/gnark/backend" 28 "github.com/consensys/gnark/constraint" 29 30 "github.com/consensys/gnark/backend/solidity" 31 "github.com/consensys/gnark/backend/witness" 32 cs_bls12377 "github.com/consensys/gnark/constraint/bls12-377" 33 cs_bls12381 "github.com/consensys/gnark/constraint/bls12-381" 34 cs_bls24315 "github.com/consensys/gnark/constraint/bls24-315" 35 cs_bls24317 "github.com/consensys/gnark/constraint/bls24-317" 36 cs_bn254 "github.com/consensys/gnark/constraint/bn254" 37 cs_bw6633 "github.com/consensys/gnark/constraint/bw6-633" 38 cs_bw6761 "github.com/consensys/gnark/constraint/bw6-761" 39 40 plonk_bls12377 "github.com/consensys/gnark/backend/plonk/bls12-377" 41 plonk_bls12381 "github.com/consensys/gnark/backend/plonk/bls12-381" 42 plonk_bls24315 "github.com/consensys/gnark/backend/plonk/bls24-315" 43 plonk_bls24317 "github.com/consensys/gnark/backend/plonk/bls24-317" 44 plonk_bn254 "github.com/consensys/gnark/backend/plonk/bn254" 45 plonk_bw6633 "github.com/consensys/gnark/backend/plonk/bw6-633" 46 plonk_bw6761 "github.com/consensys/gnark/backend/plonk/bw6-761" 47 48 fr_bls12377 "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" 49 fr_bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" 50 fr_bls24315 "github.com/consensys/gnark-crypto/ecc/bls24-315/fr" 51 fr_bls24317 "github.com/consensys/gnark-crypto/ecc/bls24-317/fr" 52 fr_bn254 "github.com/consensys/gnark-crypto/ecc/bn254/fr" 53 fr_bw6633 "github.com/consensys/gnark-crypto/ecc/bw6-633/fr" 54 fr_bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761/fr" 55 56 kzg_bls12377 "github.com/consensys/gnark-crypto/ecc/bls12-377/kzg" 57 kzg_bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381/kzg" 58 kzg_bls24315 "github.com/consensys/gnark-crypto/ecc/bls24-315/kzg" 59 kzg_bls24317 "github.com/consensys/gnark-crypto/ecc/bls24-317/kzg" 60 kzg_bn254 "github.com/consensys/gnark-crypto/ecc/bn254/kzg" 61 kzg_bw6633 "github.com/consensys/gnark-crypto/ecc/bw6-633/kzg" 62 kzg_bw6761 "github.com/consensys/gnark-crypto/ecc/bw6-761/kzg" 63 64 gnarkio "github.com/consensys/gnark/io" 65 ) 66 67 // Proof represents a Plonk proof generated by plonk.Prove 68 // 69 // it's underlying implementation is curve specific (see gnark/internal/backend) 70 type Proof interface { 71 io.WriterTo 72 io.ReaderFrom 73 74 // Raw methods for faster serialization-deserialization. Does not perform checks on the data. 75 // Only use if you are sure of the data you are reading comes from trusted source. 76 gnarkio.WriterRawTo 77 } 78 79 // ProvingKey represents a plonk ProvingKey 80 // 81 // it's underlying implementation is strongly typed with the curve (see gnark/internal/backend) 82 type ProvingKey interface { 83 io.WriterTo 84 io.ReaderFrom 85 86 // Raw methods for faster serialization-deserialization. Does not perform checks on the data. 87 // Only use if you are sure of the data you are reading comes from trusted source. 88 gnarkio.WriterRawTo 89 gnarkio.UnsafeReaderFrom 90 91 // VerifyingKey returns the corresponding VerifyingKey. 92 VerifyingKey() interface{} 93 } 94 95 // VerifyingKey represents a plonk VerifyingKey 96 // 97 // it's underlying implementation is strongly typed with the curve (see gnark/internal/backend) 98 type VerifyingKey interface { 99 io.WriterTo 100 io.ReaderFrom 101 102 // Raw methods for faster serialization-deserialization. Does not perform checks on the data. 103 // Only use if you are sure of the data you are reading comes from trusted source. 104 gnarkio.WriterRawTo 105 gnarkio.UnsafeReaderFrom 106 107 // VerifyingKey are the methods required for generating the Solidity 108 // verifier contract from the VerifyingKey. This will return an error if not 109 // supported on the CurveID(). 110 solidity.VerifyingKey 111 } 112 113 // Setup prepares the public data associated to a circuit + public inputs. 114 // The kzg SRS must be provided in canonical and lagrange form. 115 // For test purposes, see test/unsafekzg package. With an existing SRS generated through MPC in canonical form, 116 // gnark-crypto offers the ToLagrangeG1 method to convert it to lagrange form. 117 func Setup(ccs constraint.ConstraintSystem, srs, srsLagrange kzg.SRS) (ProvingKey, VerifyingKey, error) { 118 119 switch tccs := ccs.(type) { 120 case *cs_bn254.SparseR1CS: 121 return plonk_bn254.Setup(tccs, *srs.(*kzg_bn254.SRS), *srsLagrange.(*kzg_bn254.SRS)) 122 case *cs_bls12381.SparseR1CS: 123 return plonk_bls12381.Setup(tccs, *srs.(*kzg_bls12381.SRS), *srsLagrange.(*kzg_bls12381.SRS)) 124 case *cs_bls12377.SparseR1CS: 125 return plonk_bls12377.Setup(tccs, *srs.(*kzg_bls12377.SRS), *srsLagrange.(*kzg_bls12377.SRS)) 126 case *cs_bw6761.SparseR1CS: 127 return plonk_bw6761.Setup(tccs, *srs.(*kzg_bw6761.SRS), *srsLagrange.(*kzg_bw6761.SRS)) 128 case *cs_bls24317.SparseR1CS: 129 return plonk_bls24317.Setup(tccs, *srs.(*kzg_bls24317.SRS), *srsLagrange.(*kzg_bls24317.SRS)) 130 case *cs_bls24315.SparseR1CS: 131 return plonk_bls24315.Setup(tccs, *srs.(*kzg_bls24315.SRS), *srsLagrange.(*kzg_bls24315.SRS)) 132 case *cs_bw6633.SparseR1CS: 133 return plonk_bw6633.Setup(tccs, *srs.(*kzg_bw6633.SRS), *srsLagrange.(*kzg_bw6633.SRS)) 134 default: 135 panic("unrecognized SparseR1CS curve type") 136 } 137 138 } 139 140 // Prove generates PLONK proof from a circuit, associated preprocessed public data, and the witness 141 // if the force flag is set: 142 // 143 // will execute all the prover computations, even if the witness is invalid 144 // will produce an invalid proof 145 // internally, the solution vector to the SparseR1CS will be filled with random values which may impact benchmarking 146 func Prove(ccs constraint.ConstraintSystem, pk ProvingKey, fullWitness witness.Witness, opts ...backend.ProverOption) (Proof, error) { 147 148 switch tccs := ccs.(type) { 149 case *cs_bn254.SparseR1CS: 150 return plonk_bn254.Prove(tccs, pk.(*plonk_bn254.ProvingKey), fullWitness, opts...) 151 152 case *cs_bls12381.SparseR1CS: 153 return plonk_bls12381.Prove(tccs, pk.(*plonk_bls12381.ProvingKey), fullWitness, opts...) 154 155 case *cs_bls12377.SparseR1CS: 156 return plonk_bls12377.Prove(tccs, pk.(*plonk_bls12377.ProvingKey), fullWitness, opts...) 157 158 case *cs_bw6761.SparseR1CS: 159 return plonk_bw6761.Prove(tccs, pk.(*plonk_bw6761.ProvingKey), fullWitness, opts...) 160 161 case *cs_bw6633.SparseR1CS: 162 return plonk_bw6633.Prove(tccs, pk.(*plonk_bw6633.ProvingKey), fullWitness, opts...) 163 164 case *cs_bls24317.SparseR1CS: 165 return plonk_bls24317.Prove(tccs, pk.(*plonk_bls24317.ProvingKey), fullWitness, opts...) 166 167 case *cs_bls24315.SparseR1CS: 168 return plonk_bls24315.Prove(tccs, pk.(*plonk_bls24315.ProvingKey), fullWitness, opts...) 169 170 default: 171 panic("unrecognized SparseR1CS curve type") 172 } 173 } 174 175 // Verify verifies a PLONK proof, from the proof, preprocessed public data, and public witness. 176 func Verify(proof Proof, vk VerifyingKey, publicWitness witness.Witness, opts ...backend.VerifierOption) error { 177 178 switch _proof := proof.(type) { 179 180 case *plonk_bn254.Proof: 181 w, ok := publicWitness.Vector().(fr_bn254.Vector) 182 if !ok { 183 return witness.ErrInvalidWitness 184 } 185 return plonk_bn254.Verify(_proof, vk.(*plonk_bn254.VerifyingKey), w, opts...) 186 187 case *plonk_bls12381.Proof: 188 w, ok := publicWitness.Vector().(fr_bls12381.Vector) 189 if !ok { 190 return witness.ErrInvalidWitness 191 } 192 return plonk_bls12381.Verify(_proof, vk.(*plonk_bls12381.VerifyingKey), w, opts...) 193 194 case *plonk_bls12377.Proof: 195 w, ok := publicWitness.Vector().(fr_bls12377.Vector) 196 if !ok { 197 return witness.ErrInvalidWitness 198 } 199 return plonk_bls12377.Verify(_proof, vk.(*plonk_bls12377.VerifyingKey), w, opts...) 200 201 case *plonk_bw6761.Proof: 202 w, ok := publicWitness.Vector().(fr_bw6761.Vector) 203 if !ok { 204 return witness.ErrInvalidWitness 205 } 206 return plonk_bw6761.Verify(_proof, vk.(*plonk_bw6761.VerifyingKey), w, opts...) 207 208 case *plonk_bw6633.Proof: 209 w, ok := publicWitness.Vector().(fr_bw6633.Vector) 210 if !ok { 211 return witness.ErrInvalidWitness 212 } 213 return plonk_bw6633.Verify(_proof, vk.(*plonk_bw6633.VerifyingKey), w, opts...) 214 215 case *plonk_bls24317.Proof: 216 w, ok := publicWitness.Vector().(fr_bls24317.Vector) 217 if !ok { 218 return witness.ErrInvalidWitness 219 } 220 return plonk_bls24317.Verify(_proof, vk.(*plonk_bls24317.VerifyingKey), w, opts...) 221 222 case *plonk_bls24315.Proof: 223 w, ok := publicWitness.Vector().(fr_bls24315.Vector) 224 if !ok { 225 return witness.ErrInvalidWitness 226 } 227 return plonk_bls24315.Verify(_proof, vk.(*plonk_bls24315.VerifyingKey), w, opts...) 228 229 default: 230 panic("unrecognized proof type") 231 } 232 } 233 234 // NewCS instantiate a concrete curved-typed SparseR1CS and return a ConstraintSystem interface 235 // This method exists for (de)serialization purposes 236 func NewCS(curveID ecc.ID) constraint.ConstraintSystem { 237 var r1cs constraint.ConstraintSystem 238 switch curveID { 239 case ecc.BN254: 240 r1cs = &cs_bn254.SparseR1CS{} 241 case ecc.BLS12_377: 242 r1cs = &cs_bls12377.SparseR1CS{} 243 case ecc.BLS12_381: 244 r1cs = &cs_bls12381.SparseR1CS{} 245 case ecc.BW6_761: 246 r1cs = &cs_bw6761.SparseR1CS{} 247 case ecc.BLS24_317: 248 r1cs = &cs_bls24317.SparseR1CS{} 249 case ecc.BLS24_315: 250 r1cs = &cs_bls24315.SparseR1CS{} 251 case ecc.BW6_633: 252 r1cs = &cs_bw6633.SparseR1CS{} 253 default: 254 panic("not implemented") 255 } 256 return r1cs 257 } 258 259 // NewProvingKey instantiates a curve-typed ProvingKey and returns an interface 260 // This function exists for serialization purposes 261 func NewProvingKey(curveID ecc.ID) ProvingKey { 262 var pk ProvingKey 263 switch curveID { 264 case ecc.BN254: 265 pk = &plonk_bn254.ProvingKey{} 266 case ecc.BLS12_377: 267 pk = &plonk_bls12377.ProvingKey{} 268 case ecc.BLS12_381: 269 pk = &plonk_bls12381.ProvingKey{} 270 case ecc.BW6_761: 271 pk = &plonk_bw6761.ProvingKey{} 272 case ecc.BLS24_317: 273 pk = &plonk_bls24317.ProvingKey{} 274 case ecc.BLS24_315: 275 pk = &plonk_bls24315.ProvingKey{} 276 case ecc.BW6_633: 277 pk = &plonk_bw6633.ProvingKey{} 278 default: 279 panic("not implemented") 280 } 281 282 return pk 283 } 284 285 // NewProof instantiates a curve-typed ProvingKey and returns an interface 286 // This function exists for serialization purposes 287 func NewProof(curveID ecc.ID) Proof { 288 var proof Proof 289 switch curveID { 290 case ecc.BN254: 291 proof = &plonk_bn254.Proof{} 292 case ecc.BLS12_377: 293 proof = &plonk_bls12377.Proof{} 294 case ecc.BLS12_381: 295 proof = &plonk_bls12381.Proof{} 296 case ecc.BW6_761: 297 proof = &plonk_bw6761.Proof{} 298 case ecc.BLS24_317: 299 proof = &plonk_bls24317.Proof{} 300 case ecc.BLS24_315: 301 proof = &plonk_bls24315.Proof{} 302 case ecc.BW6_633: 303 proof = &plonk_bw6633.Proof{} 304 default: 305 panic("not implemented") 306 } 307 308 return proof 309 } 310 311 // NewVerifyingKey instantiates a curve-typed VerifyingKey and returns an interface 312 // This function exists for serialization purposes 313 func NewVerifyingKey(curveID ecc.ID) VerifyingKey { 314 var vk VerifyingKey 315 switch curveID { 316 case ecc.BN254: 317 vk = &plonk_bn254.VerifyingKey{} 318 case ecc.BLS12_377: 319 vk = &plonk_bls12377.VerifyingKey{} 320 case ecc.BLS12_381: 321 vk = &plonk_bls12381.VerifyingKey{} 322 case ecc.BW6_761: 323 vk = &plonk_bw6761.VerifyingKey{} 324 case ecc.BLS24_317: 325 vk = &plonk_bls24317.VerifyingKey{} 326 case ecc.BLS24_315: 327 vk = &plonk_bls24315.VerifyingKey{} 328 case ecc.BW6_633: 329 vk = &plonk_bw6633.VerifyingKey{} 330 default: 331 panic("not implemented") 332 } 333 334 return vk 335 } 336 337 // SRSSize returns the required size of the kzg SRS for a given constraint system 338 // Note that the SRS size in Lagrange form is a power of 2, 339 // and the SRS size in canonical form need few extra elements (3) to account for the blinding factors 340 func SRSSize(ccs constraint.ConstraintSystem) (sizeCanonical, sizeLagrange int) { 341 nbConstraints := ccs.GetNbConstraints() 342 sizeSystem := nbConstraints + ccs.GetNbPublicVariables() 343 344 sizeLagrange = int(ecc.NextPowerOfTwo(uint64(sizeSystem))) 345 sizeCanonical = sizeLagrange + 3 346 347 return 348 }