Skip to content

Commit

Permalink
Merge branch 'Consensys:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
liuxiaobleach authored Jul 3, 2024
2 parents 08931db + 7cab7a3 commit 4a33fcc
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 5 deletions.
5 changes: 2 additions & 3 deletions std/evmprecompiles/05-expmod.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/math/emulated"
"github.com/consensys/gnark/std/math/emulated/emparams"
)

// Expmod implements [MODEXP] precompile contract at address 0x05.
Expand All @@ -15,10 +14,10 @@ import (
// the actual length of the inputs.
//
// [MODEXP]: https://ethereum.github.io/execution-specs/autoapi/ethereum/paris/vm/precompiled_contracts/expmod/index.html
func Expmod(api frontend.API, base, exp, modulus *emulated.Element[emparams.Mod1e4096]) *emulated.Element[emparams.Mod1e4096] {
func Expmod[P emulated.FieldParams](api frontend.API, base, exp, modulus *emulated.Element[P]) *emulated.Element[P] {
// x^0 = 1
// x mod 0 = 0
f, err := emulated.NewField[emparams.Mod1e4096](api)
f, err := emulated.NewField[P](api)
if err != nil {
panic(fmt.Sprintf("new field: %v", err))
}
Expand Down
8 changes: 8 additions & 0 deletions std/math/bitslice/opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ func parseOpts(opts ...Option) (*opt, error) {
return o, nil
}

// Option allows to customize the behavior of functions in this package. See
// [WithNbDigits] and [WithUnconstrainedOutputs] for examples.
type Option func(*opt) error

// WithNbDigits sets the bound on the number of digits the input can have. If
// this is not set, then we use standard binary decomposition of the input. If
// it is set and it is less than the width of the native field, then we use
// lookup table based method for bounding the inputs which is more efficient.
func WithNbDigits(nbDigits int) Option {
return func(o *opt) error {
if nbDigits < 1 {
Expand All @@ -29,6 +35,8 @@ func WithNbDigits(nbDigits int) Option {
}
}

// WithUnconstrainedOutputs allows to skip the output decomposition and outputs
// width checks. Can be used when these are performed by the caller.
func WithUnconstrainedOutputs() Option {
return func(o *opt) error {
o.nocheck = true
Expand Down
17 changes: 16 additions & 1 deletion std/math/bitslice/partition.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// Package bitslice allows partitioning variables.
package bitslice

import (
"math/big"

"github.com/consensys/gnark/frontend"
"github.com/consensys/gnark/std/math/bits"
"github.com/consensys/gnark/std/rangecheck"
)

Expand Down Expand Up @@ -40,6 +42,19 @@ func Partition(api frontend.API, v frontend.Variable, split uint, opts ...Option
}
return 0, v
}
// when nbDigits is not set, then we assume the bound is the field size.
// However, in that case the decomposition check is more involved as we need
// to avoid the recomposed value to overflow the field. We do not have good
// methods for avoiding it when using range checker gadget, so we defer it
// to `bits.ToBinary`.
if opt.digits == 0 || opt.digits >= api.Compiler().FieldBitLen() {
bts := bits.ToBinary(api, v)
lowerBts := bts[:split]
upperBts := bts[split:]
lower = bits.FromBinary(api, lowerBts)
upper = bits.FromBinary(api, upperBts)
return lower, upper
}
ret, err := api.Compiler().NewHint(partitionHint, 2, split, v)
if err != nil {
panic(err)
Expand All @@ -58,7 +73,7 @@ func Partition(api frontend.API, v frontend.Variable, split uint, opts ...Option
if opt.digits > 0 {
upperBound = opt.digits
}
rh.Check(upper, upperBound)
rh.Check(upper, upperBound-int(split))
rh.Check(lower, int(split))

m := big.NewInt(1)
Expand Down
15 changes: 14 additions & 1 deletion std/math/bitslice/partition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,21 @@ import (
"github.com/consensys/gnark/test"
)

// TODO: add option for choosing nbDigits

type partitionCircuit struct {
Split uint
In, ExpLower, ExpUpper frontend.Variable

nbDigitsOpt int
}

func (c *partitionCircuit) Define(api frontend.API) error {
lower, upper := Partition(api, c.In, c.Split)
var opts []Option
if c.nbDigitsOpt > 0 {
opts = append(opts, WithNbDigits(c.nbDigitsOpt))
}
lower, upper := Partition(api, c.In, c.Split, opts...)
api.AssertIsEqual(lower, c.ExpLower)
api.AssertIsEqual(upper, c.ExpUpper)
return nil
Expand All @@ -26,3 +34,8 @@ func TestPartition(t *testing.T) {
assert.CheckCircuit(&partitionCircuit{Split: 16}, test.WithValidAssignment(&partitionCircuit{Split: 16, ExpUpper: 0xffff, ExpLower: 0x1234, In: 0xffff1234}))
assert.CheckCircuit(&partitionCircuit{Split: 32}, test.WithValidAssignment(&partitionCircuit{Split: 32, ExpUpper: 0, ExpLower: 0xffff1234, In: 0xffff1234}))
}

func TestIssue1153(t *testing.T) {
assert := test.NewAssert(t)
assert.CheckCircuit(&partitionCircuit{Split: 8, nbDigitsOpt: 16}, test.WithInvalidAssignment(&partitionCircuit{ExpUpper: 0xff1, ExpLower: 0x21, In: 0xff121}))
}
19 changes: 19 additions & 0 deletions std/math/emulated/emparams/emparams.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,22 @@ func (Mod1e512) Modulus() *big.Int {
val, _ := new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)
return val
}

// Mod1e256 provides type parametrization for emulated aritmetic:
// - limbs: 4
// - limb width: 64 bits
//
// The modulus for type parametrisation is 2^256-1.
//
// This is non-prime modulus. It is mainly targeted for using variable-modulus
// operations (ModAdd, ModMul, ModExp, ModAssertIsEqual) for variable modulus
// arithmetic.
type Mod1e256 struct{}

func (Mod1e256) NbLimbs() uint { return 4 }
func (Mod1e256) BitsPerLimb() uint { return 64 }
func (Mod1e256) IsPrime() bool { return false }
func (Mod1e256) Modulus() *big.Int {
val, _ := new(big.Int).SetString("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16)
return val
}

0 comments on commit 4a33fcc

Please sign in to comment.