solver

package
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2023 License: Apache-2.0 Imports: 8 Imported by: 58

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetHintName

func GetHintName(fn Hint) string

func InvZeroHint

func InvZeroHint(q *big.Int, inputs []*big.Int, results []*big.Int) error

InvZeroHint computes the value 1/a for the single input a. If a == 0, returns 0.

func RegisterHint

func RegisterHint(hintFns ...Hint)

RegisterHint registers a hint function in the global registry.

func RegisterNamedHint

func RegisterNamedHint(hintFn Hint, key HintID)

Types

type Config

type Config struct {
	HintFunctions map[HintID]Hint // defaults to all built-in hint functions
	Logger        zerolog.Logger  // defaults to gnark.Logger
}

Config is the configuration for the solver with the options applied.

func NewConfig

func NewConfig(opts ...Option) (Config, error)

NewConfig returns a default SolverConfig with given prover options opts applied.

type Hint

type Hint func(field *big.Int, inputs []*big.Int, outputs []*big.Int) error

Hint allows to define computations outside of a circuit.

It defines an annotated hint function; the number of inputs and outputs injected at solving time is defined in the circuit (compile time).

For example:

b := api.NewHint(hint, 2, a)
--> at solving time, hint is going to be invoked with 1 input (a) and is expected to return 2 outputs
b[0] and b[1].

Usually, it is expected that computations in circuits are performed on variables. However, in some cases defining the computations in circuits may be complicated or computationally expensive. By using hints, the computations are performed outside of the circuit on integers (compared to the frontend.Variable values inside the circuits) and the result of a hint function is assigned to a newly created variable in a circuit.

As the computations are performed outside of the circuit, then the correctness of the result is not guaranteed. This also means that the result of a hint function is unconstrained by default, leading to failure while composing circuit proof. Thus, it is the circuit developer responsibility to verify the correctness hint result by adding necessary constraints in the circuit.

As an example, lets say the hint function computes a factorization of a semiprime n:

p, q <- hint(n) st. p * q = n

into primes p and q. Then, the circuit developer needs to assert in the circuit that p*q indeed equals to n:

n == p * q.

However, if the hint function is incorrectly defined (e.g. in the previous example, it returns 1 and n instead of p and q), then the assertion may still hold, but the constructed proof is semantically invalid. Thus, the user constructing the proof must be extremely cautious when using hints.

Using hint functions in circuits

To use a hint function in a circuit, the developer first needs to define a hint function hintFn according to the Function interface. Then, in a circuit, the developer applies the hint function with frontend.API.NewHint(hintFn, vars...), where vars are the variables the hint function will be applied to (and correspond to the argument inputs in the Function type) which returns a new unconstrained variable. The returned variables must be constrained using frontend.API.Assert[.*] methods.

As explained, the hints are essentially black boxes from the circuit point of view and thus the defined hints in circuits are not used when constructing a proof. To allow the particular hint functions to be used during proof construction, the user needs to supply a solver.Option indicating the enabled hints. Such options can be obtained by a call to solver.WithHints(hintFns...), where hintFns are the corresponding hint functions.

Using hint functions in gadgets

Similar considerations apply for hint functions used in gadgets as in user-defined circuits. However, listing all hint functions used in a particular gadget for constructing solver.Option puts high overhead for the user to enable all necessary hints.

For that, this package also provides a registry of trusted hint functions. When a gadget registers a hint function, then it is automatically enabled during proof computation and the prover does not need to provide a corresponding proving option.

In the init() method of the gadget, call the method RegisterHint(hintFn) function on the hint function hintFn to register a hint function in the package registry.

func GetRegisteredHint

func GetRegisteredHint(key HintID) Hint

func GetRegisteredHints

func GetRegisteredHints() []Hint

GetRegisteredHints returns all registered hint functions.

type HintID

type HintID uint32

HintID is a unique identifier for a hint function used for lookup.

func GetHintID

func GetHintID(fn Hint) HintID

GetHintID is a reference function for computing the hint ID based on a function name

type Option

type Option func(*Config) error

Option defines option for altering the behavior of a constraint system solver (Solve() method). See the descriptions of functions returning instances of this type for implemented options.

func OverrideHint

func OverrideHint(id HintID, f Hint) Option

OverrideHint forces the solver to use provided hint function for given id.

func WithHints

func WithHints(hintFunctions ...Hint) Option

WithHints is a solver option that specifies additional hint functions to be used by the constraint solver.

func WithLogger

func WithLogger(l zerolog.Logger) Option

WithLogger is a prover option that specifies zerolog.Logger as a destination for the logs printed by api.Println(). By default, uses gnark/logger. zerolog.Nop() will disable logging

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL