frontend

package
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2021 License: Apache-2.0 Imports: 27 Imported by: 710

Documentation

Overview

Package frontend contains the object and logic to define and compile gnark circuits

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FromInterface added in v0.4.0

func FromInterface(i1 interface{}) big.Int

FromInterface converts an interface to a big.Int element interface must implement ToBigIntRegular(res *big.Int) *big.Int (which is the case for field generated by goff) or be uint64, int, string, []byte or big.Int it panics if the input is invalid

func IgnoreUnconstrainedInputs added in v0.5.2

func IgnoreUnconstrainedInputs(opt *CompileOption) error

IgnoreUnconstrainedInputs when set, the Compile function doesn't check for unconstrained inputs

func WithCapacity added in v0.5.2

func WithCapacity(capacity int) func(opt *CompileOption) error

WithOutput is a Compile option that specifies the estimated capacity needed for internal variables and constraints

Types

type API added in v0.5.2

type API interface {

	// Add returns res = i1+i2+...in
	Add(i1, i2 interface{}, in ...interface{}) Variable

	// Sub returns res = i1 - i2 - ...in
	Sub(i1, i2 interface{}, in ...interface{}) Variable

	// Neg returns -i
	Neg(i1 interface{}) Variable

	// Mul returns res = i1 * i2 * ... in
	Mul(i1, i2 interface{}, in ...interface{}) Variable

	// DivUnchecked returns i1 / i2 . if i1 == i2 == 0, returns 0
	DivUnchecked(i1, i2 interface{}) Variable

	// Div returns i1 / i2
	Div(i1, i2 interface{}) Variable

	// Inverse returns res = 1 / i1
	Inverse(i1 interface{}) Variable

	// ToBinary unpacks a variable in binary,
	// n is the number of bits to select (starting from lsb)
	// n default value is fr.Bits the number of bits needed to represent a field element
	//
	// The result in in little endian (first bit= lsb)
	ToBinary(i1 interface{}, n ...int) []Variable

	// FromBinary packs b, seen as a fr.Element in little endian
	FromBinary(b ...Variable) Variable

	// Xor returns a ^ b
	// a and b must be 0 or 1
	Xor(a, b Variable) Variable

	// Or returns a | b
	// a and b must be 0 or 1
	Or(a, b Variable) Variable

	// Or returns a & b
	// a and b must be 0 or 1
	And(a, b Variable) Variable

	// Select if b is true, yields i1 else yields i2
	Select(b interface{}, i1, i2 interface{}) Variable

	// IsZero returns 1 if a is zero, 0 otherwise
	IsZero(i1 interface{}) Variable

	// AssertIsEqual fails if i1 != i2
	AssertIsEqual(i1, i2 interface{})

	// AssertIsDifferent fails if i1 == i2
	AssertIsDifferent(i1, i2 interface{})

	// AssertIsBoolean fails if v != 0 || v != 1
	AssertIsBoolean(i1 interface{})

	// AssertIsLessOrEqual fails if  v > bound
	AssertIsLessOrEqual(v Variable, bound interface{})

	// Println behaves like fmt.Println but accepts frontend.Variable as parameter
	// whose value will be resolved at runtime when computed by the solver
	Println(a ...interface{})

	// Constant returns a frontend.Variable representing a known value at compile time
	Constant(input interface{}) Variable

	// NewHint initialize a variable whose value will be evaluated using the provided hint function at run time
	//
	// hint function is provided at proof creation time and must match the hintID
	// inputs must be either variables or convertible to big int
	// /!\ warning /!\
	// this doesn't add any constraint to the newly created wire
	// from the backend point of view, it's equivalent to a user-supplied witness
	// except, the solver is going to assign it a value, not the caller
	NewHint(f hint.Function, inputs ...interface{}) Variable
}

API represents the available functions to circuit developers

type Circuit

type Circuit interface {
	// Define declares the circuit's Constraints
	Define(curveID ecc.ID, api API) error
}

Circuit must be implemented by user-defined circuits

the tag format is as follow:

type MyCircuit struct {
	Y frontend.Variable `gnark:"name,option"`
}

if empty, default resolves to variable name (here "Y") and secret visibility similarly to json or xml struct tags, these are valid:

`gnark:",public"` or `gnark:"-"`

using "-" marks the variable as ignored by the Compile method. This can be useful when you need to declare variables as aliases that are already allocated. For example

type MyCircuit struct {
	Y frontend.Variable `gnark:",public"`
	Z frontend.Variable `gnark:"-"`
}

it is then the developer responsability to do circuit.Z = circuit.Y in the Define() method

type CompileOption added in v0.5.2

type CompileOption struct {
	// contains filtered or unexported fields
}

CompileOption enables to set optional argument to call of frontend.Compile()

type CompiledConstraintSystem added in v0.4.0

type CompiledConstraintSystem interface {
	io.WriterTo
	io.ReaderFrom

	// GetNbVariables return number of internal, secret and public variables
	GetNbVariables() (internal, secret, public int)
	GetNbConstraints() int
	GetNbCoefficients() int

	CurveID() ecc.ID
	FrSize() int

	// ToHTML generates a human readable representation of the constraint system
	ToHTML(w io.Writer) error
}

CompiledConstraintSystem ...

func Compile

func Compile(curveID ecc.ID, zkpID backend.ID, circuit Circuit, opts ...func(opt *CompileOption) error) (ccs CompiledConstraintSystem, err error)

Compile will generate a CompiledConstraintSystem from the given circuit

1. it will first allocate the user inputs (see type Tag for more info) example:

type MyCircuit struct {
	Y frontend.Variable `gnark:"exponent,public"`
}

in that case, Compile() will allocate one public variable with id "exponent"

2. it then calls circuit.Define(curveID, constraintSystem) to build the internal constraint system from the declarative code

  1. finally, it converts that to a CompiledConstraintSystem. if zkpID == backend.GROTH16 --> R1CS if zkpID == backend.PLONK --> SparseR1CS

initialCapacity is an optional parameter that reserves memory in slices it should be set to the estimated number of constraints in the circuit, if known.

type Variable

type Variable struct {
	WitnessValue interface{} // witness usage only
	// contains filtered or unexported fields
}

Variable of a circuit represents a Variable to a circuit, plus the linear combination leading to it. the linExp is always non empty, the PartialVariabl can be unset. It is set and allocated in the circuit when there is no other choice (to avoid wasting wires doing only linear expressions)

func Value added in v0.5.2

func Value(value interface{}) Variable

Value returned a Variable with an assigned value This is to be used in the context of witness creation only and will triger an error if used inside a circuit Define(...) method This is syntatic sugar for: frontend.Variable{WitnessValue: value}

func (*Variable) Assign

func (v *Variable) Assign(value interface{})

Assign v = value . This must called when using a Circuit as a witness data structure

Prefer the use of variable.WitnessValue = value

func (*Variable) GetWitnessValue added in v0.5.2

func (v *Variable) GetWitnessValue(curveID ecc.ID) big.Int

GetWitnessValue returns the assigned value to the variable the value is converted to a field element (mod curveID base field modulus) then converted to a big.Int if it is not set this panics

Jump to

Keyboard shortcuts

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