diff --git a/goldilocks/.gitignore b/goldilocks/.gitignore new file mode 100644 index 0000000..dca82ea --- /dev/null +++ b/goldilocks/.gitignore @@ -0,0 +1 @@ +gnark.pprof \ No newline at end of file diff --git a/goldilocks/base.go b/goldilocks/base.go index f3c4ef5..c4aff35 100644 --- a/goldilocks/base.go +++ b/goldilocks/base.go @@ -77,12 +77,14 @@ func NegOne() GoldilocksVariable { // The chip used for Goldilocks field operations. type GoldilocksApi struct { - api frontend.API + api frontend.API + rangeChecker frontend.Rangechecker } // Creates a new Goldilocks chip. func NewGoldilocksApi(api frontend.API) *GoldilocksApi { - return &GoldilocksApi{api: api} + rangeChecker := rangecheck.New(api) + return &GoldilocksApi{api: api, rangeChecker: rangeChecker} } // Adds two field elements such that x + y = z within the Golidlocks field. @@ -182,8 +184,7 @@ func (p *GoldilocksApi) Reduce(x GoldilocksVariable) GoldilocksVariable { } quotient := result[0] - rangeCheckNbBits := RANGE_CHECK_NB_BITS - p.api.ToBinary(quotient, rangeCheckNbBits) + p.rangeChecker.Check(quotient, RANGE_CHECK_NB_BITS) remainder := NewVariable(result[1]) p.RangeCheck(remainder) @@ -205,7 +206,7 @@ func (p *GoldilocksApi) ReduceWithMaxBits(x GoldilocksVariable, maxNbBits uint64 } quotient := result[0] - p.api.ToBinary(quotient, int(maxNbBits)) + p.rangeChecker.Check(quotient, int(maxNbBits)) remainder := NewVariable(result[1]) p.RangeCheck(remainder) diff --git a/goldilocks/base_test.go b/goldilocks/base_test.go index 44d3ec0..c554f72 100644 --- a/goldilocks/base_test.go +++ b/goldilocks/base_test.go @@ -1,12 +1,16 @@ package goldilocks import ( + "fmt" "math/big" + "os" "testing" "github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark/backend" "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/frontend/cs/scs" + "github.com/consensys/gnark/profile" "github.com/consensys/gnark/test" ) @@ -39,6 +43,43 @@ func TestGoldilocksRangeCheck(t *testing.T) { assert.ProverSucceeded(&circuit, &witness, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16)) } +type TestGoldilocksRangeCheckBenchmarkCircuit struct { + X []frontend.Variable +} + +func (c *TestGoldilocksRangeCheckBenchmarkCircuit) Define(api frontend.API) error { + glApi := NewGoldilocksApi(api) + for _, x := range c.X { + glApi.RangeCheck(NewVariable(x)) + } + return nil +} + +func BenchmarkGoldilocksRangeCheck(b *testing.B) { + var sizes = []int{5, 10, 15} + for i := 0; i < len(sizes); i++ { + var circuit, witness TestGoldilocksRangeCheckBenchmarkCircuit + circuit.X = make([]frontend.Variable, 2<