github.com/consensys/gnark@v0.11.0/backend/backend.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 backend implements Zero Knowledge Proof systems: it consumes circuit compiled with gnark/frontend.
    16  package backend
    17  
    18  import (
    19  	"crypto/sha256"
    20  	"hash"
    21  
    22  	"github.com/consensys/gnark/constraint/solver"
    23  )
    24  
    25  // ID represent a unique ID for a proving scheme
    26  type ID uint16
    27  
    28  const (
    29  	UNKNOWN ID = iota
    30  	GROTH16
    31  	PLONK
    32  )
    33  
    34  // Implemented return the list of proof systems implemented in gnark
    35  func Implemented() []ID {
    36  	return []ID{GROTH16, PLONK}
    37  }
    38  
    39  // String returns the string representation of a proof system
    40  func (id ID) String() string {
    41  	switch id {
    42  	case GROTH16:
    43  		return "groth16"
    44  	case PLONK:
    45  		return "plonk"
    46  	default:
    47  		return "unknown"
    48  	}
    49  }
    50  
    51  // ProverOption defines option for altering the behavior of the prover in
    52  // Prove, ReadAndProve and IsSolved methods. See the descriptions of functions
    53  // returning instances of this type for implemented options.
    54  type ProverOption func(*ProverConfig) error
    55  
    56  // ProverConfig is the configuration for the prover with the options applied.
    57  type ProverConfig struct {
    58  	SolverOpts     []solver.Option
    59  	HashToFieldFn  hash.Hash
    60  	ChallengeHash  hash.Hash
    61  	KZGFoldingHash hash.Hash
    62  	Accelerator    string
    63  	StatisticalZK  bool
    64  }
    65  
    66  // NewProverConfig returns a default ProverConfig with given prover options opts
    67  // applied.
    68  func NewProverConfig(opts ...ProverOption) (ProverConfig, error) {
    69  	opt := ProverConfig{
    70  		// we cannot initialize HashToFieldFn here as we use different domain
    71  		// separation tags for PLONK and Groth16
    72  		ChallengeHash:  sha256.New(),
    73  		KZGFoldingHash: sha256.New(),
    74  	}
    75  	for _, option := range opts {
    76  		if err := option(&opt); err != nil {
    77  			return ProverConfig{}, err
    78  		}
    79  	}
    80  	return opt, nil
    81  }
    82  
    83  // WithSolverOptions specifies the constraint system solver options.
    84  func WithSolverOptions(solverOpts ...solver.Option) ProverOption {
    85  	return func(opt *ProverConfig) error {
    86  		opt.SolverOpts = solverOpts
    87  		return nil
    88  	}
    89  }
    90  
    91  // WithProverHashToFieldFunction changes the hash function used for hashing
    92  // bytes to field. If not set then the default hash function based on RFC 9380
    93  // is used. Used mainly for compatibility between different systems and
    94  // efficient recursion.
    95  func WithProverHashToFieldFunction(hFunc hash.Hash) ProverOption {
    96  	return func(cfg *ProverConfig) error {
    97  		cfg.HashToFieldFn = hFunc
    98  		return nil
    99  	}
   100  }
   101  
   102  // WithProverChallengeHashFunction sets the hash function used for computing
   103  // non-interactive challenges in Fiat-Shamir heuristic. If not set then by
   104  // default SHA2-256 is used. Used mainly for compatibility between different
   105  // systems and efficient recursion.
   106  func WithProverChallengeHashFunction(hFunc hash.Hash) ProverOption {
   107  	return func(pc *ProverConfig) error {
   108  		pc.ChallengeHash = hFunc
   109  		return nil
   110  	}
   111  }
   112  
   113  // WithProverKZGFoldingHashFunction sets the hash function used for computing
   114  // the challenge when folding the KZG opening proofs. If not set then by default
   115  // SHA2-256 is used. Used mainly for compatibility between different systems and
   116  // efficient recursion.
   117  func WithProverKZGFoldingHashFunction(hFunc hash.Hash) ProverOption {
   118  	return func(pc *ProverConfig) error {
   119  		pc.KZGFoldingHash = hFunc
   120  		return nil
   121  	}
   122  }
   123  
   124  // WithIcicleAcceleration requests to use [ICICLE] GPU proving backend for the
   125  // prover. This option requires that the program is compiled with `icicle` build
   126  // tag and the ICICLE dependencies are properly installed. See [ICICLE] for
   127  // installation description.
   128  //
   129  // [ICICLE]: https://github.com/ingonyama-zk/icicle
   130  func WithIcicleAcceleration() ProverOption {
   131  	return func(pc *ProverConfig) error {
   132  		pc.Accelerator = "icicle"
   133  		return nil
   134  	}
   135  }
   136  
   137  // WithStatisticalZeroKnowledge ensures that statistical zero knowledgeness is achieved.
   138  // This option makes the prover more memory costly, as there are 3 more size n (size of the circuit)
   139  // allocations.
   140  func WithStatisticalZeroKnowledge() ProverOption {
   141  	return func(pc *ProverConfig) error {
   142  		pc.StatisticalZK = true
   143  		return nil
   144  	}
   145  }
   146  
   147  // VerifierOption defines option for altering the behavior of the verifier. See
   148  // the descriptions of functions returning instances of this type for
   149  // implemented options.
   150  type VerifierOption func(*VerifierConfig) error
   151  
   152  // VerifierConfig is the configuration for the verifier with the options applied.
   153  type VerifierConfig struct {
   154  	HashToFieldFn  hash.Hash
   155  	ChallengeHash  hash.Hash
   156  	KZGFoldingHash hash.Hash
   157  }
   158  
   159  // NewVerifierConfig returns a default [VerifierConfig] with given verifier
   160  // options applied.
   161  func NewVerifierConfig(opts ...VerifierOption) (VerifierConfig, error) {
   162  	opt := VerifierConfig{
   163  		// we cannot initialize HashToFieldFn here as we use different domain
   164  		// separation tags for PLONK and Groth16
   165  		ChallengeHash:  sha256.New(),
   166  		KZGFoldingHash: sha256.New(),
   167  	}
   168  	for _, option := range opts {
   169  		if err := option(&opt); err != nil {
   170  			return VerifierConfig{}, err
   171  		}
   172  	}
   173  	return opt, nil
   174  }
   175  
   176  // WithVerifierHashToFieldFunction changes the hash function used for hashing
   177  // bytes to field. If not set then the default hash function based on RFC 9380
   178  // is used. Used mainly for compatibility between different systems and
   179  // efficient recursion.
   180  func WithVerifierHashToFieldFunction(hFunc hash.Hash) VerifierOption {
   181  	return func(cfg *VerifierConfig) error {
   182  		cfg.HashToFieldFn = hFunc
   183  		return nil
   184  	}
   185  }
   186  
   187  // WithVerifierChallengeHashFunction sets the hash function used for computing
   188  // non-interactive challenges in Fiat-Shamir heuristic. If not set then by
   189  // default SHA2-256 is used. Used mainly for compatibility between different
   190  // systems and efficient recursion.
   191  func WithVerifierChallengeHashFunction(hFunc hash.Hash) VerifierOption {
   192  	return func(pc *VerifierConfig) error {
   193  		pc.ChallengeHash = hFunc
   194  		return nil
   195  	}
   196  }
   197  
   198  // WithVerifierKZGFoldingHashFunction sets the hash function used for computing
   199  // the challenge when folding the KZG opening proofs. If not set then by default
   200  // SHA2-256 is used. Used mainly for compatibility between different systems and
   201  // efficient recursion.
   202  func WithVerifierKZGFoldingHashFunction(hFunc hash.Hash) VerifierOption {
   203  	return func(pc *VerifierConfig) error {
   204  		pc.KZGFoldingHash = hFunc
   205  		return nil
   206  	}
   207  }