Skip to content

Commit

Permalink
limit the number of mimc input hash to 62
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasmenendez committed Jan 31, 2025
1 parent c153c12 commit 569f993
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 2 deletions.
12 changes: 11 additions & 1 deletion emulated/bn254/twistededwards/mimc7/mimc.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package mimc7

import (
"fmt"

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

// maxInputs constant is the maximum number of inputs that the MiMC hash
// function can take. Experimentally, the maximum number of inputs is 62.
const maxInputs = 62

type MiMC struct {
params []emulated.Element[sw_bn254.ScalarField] // slice containing constants for the encryption rounds
h emulated.Element[sw_bn254.ScalarField] // current vector in the Miyaguchi–Preneel scheme
Expand All @@ -28,8 +34,12 @@ func NewMiMC(api frontend.API) (MiMC, error) {
}

// Write adds more data to the running hash.
func (h *MiMC) Write(data ...emulated.Element[sw_bn254.ScalarField]) {
func (h *MiMC) Write(data ...emulated.Element[sw_bn254.ScalarField]) error {
if len(h.data)+len(data) > maxInputs {
return fmt.Errorf("too many inputs. Max inputs is %d", maxInputs)
}
h.data = append(h.data, data...)
return nil
}

// Reset resets the Hash to its initial state.
Expand Down
75 changes: 74 additions & 1 deletion emulated/bn254/twistededwards/mimc7/mimc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import (
"github.com/consensys/gnark/test"
qt "github.com/frankban/quicktest"
"github.com/iden3/go-iden3-crypto/mimc7"
"github.com/vocdoni/arbo"
"go.vocdoni.io/dvote/util"
)

type testMiMCCircuit struct {
Expand All @@ -29,7 +31,10 @@ func (circuit *testMiMCCircuit) Define(api frontend.API) error {
if err != nil {
return err
}
mimc.Write(circuit.Preimage)
if err := mimc.Write(circuit.Preimage); err != nil {
api.Println(err.Error())
api.AssertIsEqual(1, 0)
}
mimc.AssertSumIsEqual(circuit.Hash)
return nil
}
Expand All @@ -53,6 +58,74 @@ func TestMiMC(t *testing.T) {
fmt.Println("solving tooks", time.Since(now))
}

type testMaxInputsMiMCCircuit struct {
Hash emulated.Element[sw_bn254.ScalarField] `gnark:",public"`
Preimages [maxInputs]emulated.Element[sw_bn254.ScalarField]
}

func (circuit *testMaxInputsMiMCCircuit) Define(api frontend.API) error {
mimc, err := NewMiMC(api)
if err != nil {
return err
}
if err := mimc.Write(circuit.Preimages[:]...); err != nil {
api.Println(err.Error())
api.AssertIsEqual(1, 0)
}
mimc.AssertSumIsEqual(circuit.Hash)
return nil
}

type testLimitInputsMiMCCircuit struct {
Preimages [maxInputs + 1]emulated.Element[sw_bn254.ScalarField]
}

func (circuit *testLimitInputsMiMCCircuit) Define(api frontend.API) error {
mimc, err := NewMiMC(api)
if err != nil {
return err
}
if err := mimc.Write(circuit.Preimages[:]...); err == nil {
api.Println("too many inputs expected")
api.AssertIsEqual(1, 0)
}
return nil
}

func TestMaxAndLimitInputsMiMC(t *testing.T) {
c := qt.New(t)
// generate a random inputs
input := arbo.BigToFF(arbo.BN254BaseField, new(big.Int).SetBytes(util.RandomBytes(32)))
inputs := []*big.Int{}
emulatedInputs := [maxInputs]emulated.Element[sw_bn254.ScalarField]{}
limitEmulatedInputs := [maxInputs + 1]emulated.Element[sw_bn254.ScalarField]{}
for i := 0; i < maxInputs; i++ {
inputs = append(inputs, input)
emulatedInputs[i] = emulated.ValueOf[sw_bn254.ScalarField](input)
limitEmulatedInputs[i] = emulated.ValueOf[sw_bn254.ScalarField](input)
}
limitEmulatedInputs[maxInputs] = emulated.ValueOf[sw_bn254.ScalarField](input)

c.Run("max inputs", func(c *qt.C) {
// hash the max inputs
maxHash, err := mimc7.Hash(inputs, nil)
c.Assert(err, qt.IsNil)
// run the test
assert := test.NewAssert(t)
assert.SolvingSucceeded(&testMaxInputsMiMCCircuit{}, &testMaxInputsMiMCCircuit{
Preimages: emulatedInputs,
Hash: emulated.ValueOf[sw_bn254.ScalarField](maxHash),
}, test.WithCurves(ecc.BLS12_377), test.WithBackends(backend.GROTH16))
})

c.Run("limit inputs", func(c *qt.C) {
assert := test.NewAssert(t)
assert.SolvingSucceeded(&testLimitInputsMiMCCircuit{}, &testLimitInputsMiMCCircuit{
Preimages: limitEmulatedInputs,
}, test.WithCurves(ecc.BLS12_377), test.WithBackends(backend.GROTH16))
})
}

func printConstrains(placeholder frontend.Circuit) error {
// compile circuit
p := profile.Start()
Expand Down

0 comments on commit 569f993

Please sign in to comment.