github.com/consensys/gnark@v0.11.0/backend/solidity/solidity.go (about)

     1  package solidity
     2  
     3  import (
     4  	"fmt"
     5  	"hash"
     6  
     7  	"github.com/consensys/gnark/backend"
     8  	"golang.org/x/crypto/sha3"
     9  )
    10  
    11  // ExportOption defines option for altering the behavior of the prover in
    12  // Prove, ReadAndProve and IsSolved methods. See the descriptions of functions
    13  // returning instances of this type for implemented options.
    14  type ExportOption func(*ExportConfig) error
    15  
    16  // ExportConfig is the configuration for the prover with the options applied.
    17  type ExportConfig struct {
    18  	PragmaVersion string
    19  	HashToFieldFn hash.Hash
    20  }
    21  
    22  // NewExportConfig returns a default ExportConfig with given export options opts
    23  // applied.
    24  func NewExportConfig(opts ...ExportOption) (ExportConfig, error) {
    25  	config := ExportConfig{
    26  		// we set default pragma version to 0.8.0+ to avoid needing to sync Solidity CI all the time
    27  		PragmaVersion: "^0.8.0",
    28  	}
    29  	for _, option := range opts {
    30  		if err := option(&config); err != nil {
    31  			return ExportConfig{}, err
    32  		}
    33  	}
    34  	return config, nil
    35  }
    36  
    37  // WithPragmaVersion changes the pragma version used in the solidity verifier.
    38  func WithPragmaVersion(version string) ExportOption {
    39  	return func(cfg *ExportConfig) error {
    40  		cfg.PragmaVersion = version
    41  		return nil
    42  	}
    43  }
    44  
    45  // WithHashToFieldFunction changes the hash function used for hashing
    46  // bytes to field. If not set then the default hash function based on RFC 9380
    47  // is used. Used mainly for compatibility between different systems and
    48  // efficient recursion.
    49  func WithHashToFieldFunction(hFunc hash.Hash) ExportOption {
    50  	return func(cfg *ExportConfig) error {
    51  		cfg.HashToFieldFn = hFunc
    52  		return nil
    53  	}
    54  }
    55  
    56  // WithProverTargetSolidityVerifier returns a prover option that sets all the
    57  // necessary prover options which are suitable for verifying the proofs in the
    58  // Solidity verifier.
    59  //
    60  // For PLONK this is a no-op option as the Solidity verifier is directly
    61  // compatible with the default prover options. Regardless, it is recommended to
    62  // use this option for consistency and possible future changes in the Solidity
    63  // verifier.
    64  //
    65  // For Groth16 this option sets the hash function used for hashing bytes to
    66  // field to [sha3.NewLegacyKeccak256] as the Solidity verifier does not support
    67  // the standard hash-to-field function. We use legacy Keccak256 in Solidity for
    68  // the cheapest gas usage.
    69  func WithProverTargetSolidityVerifier(bid backend.ID) backend.ProverOption {
    70  	switch bid {
    71  	case backend.GROTH16:
    72  		// Solidity verifier does not support standard hash-to-field function.
    73  		// Choose efficient one.
    74  		return backend.WithProverHashToFieldFunction(sha3.NewLegacyKeccak256())
    75  	case backend.PLONK:
    76  		// default hash function works for PLONK. We just have to return a no-op option
    77  		return func(*backend.ProverConfig) error {
    78  			return nil
    79  		}
    80  	default:
    81  		return func(*backend.ProverConfig) error {
    82  			return fmt.Errorf("unsupported backend ID: %s", bid)
    83  		}
    84  	}
    85  }
    86  
    87  // WithVerifierTargetSolidityVerifier returns a verifier option that sets all
    88  // the necessary verifier options which are suitable for verifying the proofs
    89  // targeted for the Solidity verifier. See the comments in
    90  // [WithProverTargetSolidityVerifier].
    91  func WithVerifierTargetSolidityVerifier(bid backend.ID) backend.VerifierOption {
    92  	switch bid {
    93  	case backend.GROTH16:
    94  		// Solidity verifier does not support standard hash-to-field function.
    95  		// Choose efficient one.
    96  		return backend.WithVerifierHashToFieldFunction(sha3.NewLegacyKeccak256())
    97  	case backend.PLONK:
    98  		// default hash function works for PLONK. We just have to return a no-op option
    99  		return func(*backend.VerifierConfig) error {
   100  			return nil
   101  		}
   102  	default:
   103  		return func(*backend.VerifierConfig) error {
   104  			return fmt.Errorf("unsupported backend ID: %s", bid)
   105  		}
   106  	}
   107  }