diff --git a/hash_test.go b/hash_test.go index 1bf60e6..43aec20 100644 --- a/hash_test.go +++ b/hash_test.go @@ -1,7 +1,6 @@ package arbo import ( - "crypto/rand" "encoding/hex" "math/big" "testing" @@ -68,24 +67,3 @@ func TestHashMiMC(t *testing.T) { qt.Equals, "f881f34991492d823e02565c778b824bac5eacef6340b70ee90a8966a2e63900") } - -func TestHashMoreThan32BytesMiMC(t *testing.T) { - c := qt.New(t) - - // create a random 257 bytes - b := make([]byte, 257) - _, err := rand.Read(b) - c.Assert(err, qt.IsNil) - - // MiMC hash bn254 - mimcbn254 := &HashMiMC_BN254{} - h, err := mimcbn254.Hash(b) - c.Assert(err, qt.IsNil) - c.Assert(len(h), qt.Equals, 32) - - // MiMC hash bls12377 - mimcbls12377 := &HashMiMC_BLS12_377{} - h, err = mimcbls12377.Hash(b) - c.Assert(err, qt.IsNil) - c.Assert(len(h), qt.Equals, 32) -} diff --git a/testvectors/gnark/test_test.go b/testvectors/gnark/test_test.go new file mode 100644 index 0000000..114e517 --- /dev/null +++ b/testvectors/gnark/test_test.go @@ -0,0 +1,43 @@ +package testgnark + +import ( + "math/big" + "testing" + + "github.com/consensys/gnark-crypto/ecc" + "github.com/consensys/gnark/backend" + "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/std/hash/mimc" + "github.com/consensys/gnark/test" + "github.com/vocdoni/arbo" +) + +type hashTestCircuit struct { + Values [2]frontend.Variable + Hash frontend.Variable +} + +func (c *hashTestCircuit) Define(api frontend.API) error { + hFn, err := mimc.NewMiMC(api) + if err != nil { + return err + } + + hFn.Write(c.Values[:]...) + api.AssertIsEqual(hFn.Sum(), c.Hash) + return nil +} + +func TestTest(t *testing.T) { + veryBigValue := new(big.Int).Mul(arbo.BLS12377BaseField, big.NewInt(17)) + veryBigValue2 := new(big.Int).Mul(arbo.BLS12377BaseField, big.NewInt(6)) + t.Log(veryBigValue, arbo.BigToFF(arbo.BN254BaseField, veryBigValue)) + t.Log(veryBigValue2, arbo.BigToFF(arbo.BN254BaseField, veryBigValue2)) + expected, _ := new(big.Int).SetString("708643117794185380623831897010742343910909883113872061615868952391691465348", 10) + + assert := test.NewAssert(t) + assert.SolvingSucceeded(&hashTestCircuit{}, &hashTestCircuit{ + Values: [2]frontend.Variable{veryBigValue, veryBigValue2}, + Hash: expected, + }, test.WithCurves(ecc.BN254), test.WithBackends(backend.GROTH16)) +} diff --git a/tree_big.go b/tree_big.go index 67f9d28..d27483a 100644 --- a/tree_big.go +++ b/tree_big.go @@ -122,7 +122,11 @@ func (t *Tree) GetBigInt(k *big.Int) (*big.Int, []*big.Int, error) { if err != nil { return nil, nil, err } - return t.leafToBigInts(bk, bv) + bFullValue, err := t.valuesdb.Get(bk) + if err != nil { + return nil, nil, err + } + return t.leafToBigInts(bk, bv, bFullValue) } // GenProofBigInts generates a proof for a key as a big.Int. It converts the @@ -167,22 +171,29 @@ func (t *Tree) maxKeyLen() int { // into a big.Int key and a slice of big.Int values, it gets the full value // from the valuesdb and checks if it matches the value of the leaf node. It // returns the original key and values or an error if the values don't match. -func (t *Tree) leafToBigInts(key, value []byte) (*big.Int, []*big.Int, error) { - bFullValue, err := t.valuesdb.Get(key) - if err != nil { - return nil, nil, err - } +func (t *Tree) leafToBigInts(key, value, fullValue []byte) (*big.Int, []*big.Int, error) { // reverse the process of values encoding - values := fullValueToValues(bFullValue) + values := fullValueToValues(fullValue) // recalculate the value to check if it matches the stored value expectedFullValue, err := valuesToFullValue(values) if err != nil { return nil, nil, err } // check if the value of the leaf node matches the stored value - if !bytes.Equal(expectedFullValue, bFullValue) { + if !bytes.Equal(expectedFullValue, fullValue) { return nil, nil, fmt.Errorf("LeafToBigInt: expectedFullValue != value") } + // reencode the leaf value of the tree to check if it matches the value + encodedValues, err := encodeBigIntValues(t.HashFunction(), values...) + if err != nil { + return nil, nil, err + } + // check if the value of the leaf node matches the value used to build the + // tree + if !bytes.Equal(encodedValues, value) { + return nil, nil, fmt.Errorf("LeafToBigInt: encodedValues != value") + } + // convert the bytes of the key to a big.Int return BytesToBigInt(key), values, nil } diff --git a/tree_big_test.go b/tree_big_test.go index aad73d3..a338586 100644 --- a/tree_big_test.go +++ b/tree_big_test.go @@ -265,15 +265,3 @@ func benchmarkAddBatchBigInt(b *testing.B, hashFunc HashFunction, keys []*big.In tree.valuesdb.Close() //nolint:errcheck } } - -func TestEncodeBigIntValues(t *testing.T) { - c := qt.New(t) - - veryBigValue := new(big.Int).Mul(BLS12377BaseField, big.NewInt(17)) - veryBigValue2 := new(big.Int).Mul(BLS12377BaseField, big.NewInt(6)) - res, err := encodeBigIntValues(HashFunctionMiMC_BN254, veryBigValue, veryBigValue2) - c.Assert(err, qt.IsNil) - - c.Log(res) - c.Log(new(big.Int).SetBytes(res)) -}