github.com/consensys/gnark@v0.11.0/frontend/api.go (about)

     1  /*
     2  Copyright © 2021 ConsenSys Software Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package frontend
    18  
    19  import (
    20  	"math/big"
    21  
    22  	"github.com/consensys/gnark/constraint/solver"
    23  )
    24  
    25  // API represents the available functions to circuit developers
    26  type API interface {
    27  	// ---------------------------------------------------------------------------------------------
    28  	// Arithmetic
    29  
    30  	// Add returns res = i1+i2+...in
    31  	Add(i1, i2 Variable, in ...Variable) Variable
    32  
    33  	// MulAcc sets and return a = a + (b*c).
    34  	//
    35  	// ! The method may mutate a without allocating a new result. If the input
    36  	// is used elsewhere, then first initialize new variable, for example by
    37  	// doing:
    38  	//
    39  	//     acopy := api.Mul(a, 1)
    40  	//     acopy = MulAcc(acopy, b, c)
    41  	//
    42  	// ! But it may not modify a, always use MulAcc(...) result for correctness.
    43  	MulAcc(a, b, c Variable) Variable
    44  
    45  	// Neg returns -i
    46  	Neg(i1 Variable) Variable
    47  
    48  	// Sub returns res = i1 - i2 - ...in
    49  	Sub(i1, i2 Variable, in ...Variable) Variable
    50  
    51  	// Mul returns res = i1 * i2 * ... in
    52  	Mul(i1, i2 Variable, in ...Variable) Variable
    53  
    54  	// DivUnchecked returns i1 / i2 . if i1 == i2 == 0, returns 0
    55  	DivUnchecked(i1, i2 Variable) Variable
    56  
    57  	// Div returns i1 / i2
    58  	Div(i1, i2 Variable) Variable
    59  
    60  	// Inverse returns res = 1 / i1
    61  	Inverse(i1 Variable) Variable
    62  
    63  	// ---------------------------------------------------------------------------------------------
    64  	// Bit operations
    65  	// TODO @gbotrel move bit operations in std/math/bits
    66  
    67  	// ToBinary unpacks a Variable in binary,
    68  	// n is the number of bits to select (starting from lsb)
    69  	// n default value is fr.Bits the number of bits needed to represent a field element
    70  	//
    71  	// The result in little endian (first bit= lsb)
    72  	ToBinary(i1 Variable, n ...int) []Variable
    73  
    74  	// FromBinary packs b, seen as a fr.Element in little endian
    75  	FromBinary(b ...Variable) Variable
    76  
    77  	// Xor returns a ^ b
    78  	// a and b must be 0 or 1
    79  	Xor(a, b Variable) Variable
    80  
    81  	// Or returns a | b
    82  	// a and b must be 0 or 1
    83  	Or(a, b Variable) Variable
    84  
    85  	// Or returns a & b
    86  	// a and b must be 0 or 1
    87  	And(a, b Variable) Variable
    88  
    89  	// ---------------------------------------------------------------------------------------------
    90  	// Conditionals
    91  
    92  	// Select if b is true, yields i1 else yields i2
    93  	Select(b Variable, i1, i2 Variable) Variable
    94  
    95  	// Lookup2 performs a 2-bit lookup between i1, i2, i3, i4 based on bits b0
    96  	// and b1. Returns i0 if b0=b1=0, i1 if b0=1 and b1=0, i2 if b0=0 and b1=1
    97  	// and i3 if b0=b1=1.
    98  	Lookup2(b0, b1 Variable, i0, i1, i2, i3 Variable) Variable
    99  
   100  	// IsZero returns 1 if a is zero, 0 otherwise
   101  	IsZero(i1 Variable) Variable
   102  
   103  	// Cmp returns:
   104  	//  * 1 if i1>i2,
   105  	//  * 0 if i1=i2,
   106  	//  * -1 if i1<i2.
   107  	//
   108  	// If the absolute difference between the variables i1 and i2 is known, then
   109  	// it is more efficient to use the bounded methods in package
   110  	// [github.com/consensys/gnark/std/math/bits].
   111  	Cmp(i1, i2 Variable) Variable
   112  
   113  	// ---------------------------------------------------------------------------------------------
   114  	// Assertions
   115  
   116  	// AssertIsEqual fails if i1 != i2
   117  	AssertIsEqual(i1, i2 Variable)
   118  
   119  	// AssertIsDifferent fails if i1 == i2
   120  	AssertIsDifferent(i1, i2 Variable)
   121  
   122  	// AssertIsBoolean fails if v != 0 and v != 1
   123  	AssertIsBoolean(i1 Variable)
   124  	// AssertIsCrumb fails if v ∉ {0,1,2,3} (crumb is a 2-bit variable; see https://en.wikipedia.org/wiki/Units_of_information)
   125  	AssertIsCrumb(i1 Variable)
   126  
   127  	// AssertIsLessOrEqual fails if v > bound.
   128  	//
   129  	// If the absolute difference between the variables b and bound is known, then
   130  	// it is more efficient to use the bounded methods in package
   131  	// [github.com/consensys/gnark/std/math/bits].
   132  	AssertIsLessOrEqual(v Variable, bound Variable)
   133  
   134  	// Println behaves like fmt.Println but accepts cd.Variable as parameter
   135  	// whose value will be resolved at runtime when computed by the solver
   136  	Println(a ...Variable)
   137  
   138  	// Compiler returns the compiler object for advanced circuit development
   139  	Compiler() Compiler
   140  
   141  	// Deprecated APIs
   142  
   143  	// NewHint is a shortcut to api.Compiler().NewHint()
   144  	// Deprecated: use api.Compiler().NewHint() instead
   145  	NewHint(f solver.Hint, nbOutputs int, inputs ...Variable) ([]Variable, error)
   146  
   147  	// ConstantValue is a shortcut to api.Compiler().ConstantValue()
   148  	// Deprecated: use api.Compiler().ConstantValue() instead
   149  	ConstantValue(v Variable) (*big.Int, bool)
   150  }
   151  
   152  // BatchInvert returns a slice of variables containing the inverse of each element in i1
   153  // This is a temporary API, do not use it in your circuit
   154  type BatchInverter interface {
   155  	// BatchInvert returns a slice of variables containing the inverse of each element in i1
   156  	// This is a temporary API, do not use it in your circuit
   157  	BatchInvert(i1 []Variable) []Variable
   158  }
   159  
   160  type PlonkAPI interface {
   161  	// EvaluatePlonkExpression returns res = qL.a + qR.b + qM.ab + qC
   162  	EvaluatePlonkExpression(a, b Variable, qL, qR, qM, qC int) Variable
   163  
   164  	// AddPlonkConstraint asserts qL.a + qR.b + qM.ab + qO.o + qC
   165  	AddPlonkConstraint(a, b, o Variable, qL, qR, qO, qM, qC int)
   166  }