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  }