arnaucube
arnaucube/go-merkletree-iden3Public Self-hosted repository
go-merkletree-iden3/utils.go
utils.goRaw
 1package merkletree
 2
 3import (
 4	"fmt"
 5	"math/big"
 6
 7	cryptoConstants "github.com/iden3/go-iden3-crypto/constants"
 8	"github.com/iden3/go-iden3-crypto/poseidon"
 9)
10
11// HashElems performs a poseidon hash over the array of ElemBytes.
12// Uses poseidon.PoseidonHash to be compatible with the circom circuits
13// implementations.
14// The maxim slice input size is poseidon.T
15func HashElems(elems ...*big.Int) (*Hash, error) {
16	if len(elems) > poseidon.T {
17		return nil, fmt.Errorf("HashElems input can not be bigger than %v", poseidon.T)
18	}
19
20	bi, err := BigIntsToPoseidonInput(elems...)
21	if err != nil {
22		return nil, err
23	}
24
25	poseidonHash, err := poseidon.PoseidonHash(bi)
26	if err != nil {
27		fmt.Println("ERR HashElems PoseidonHash")
28		fmt.Println("e", bi[0])
29		fmt.Println("q", cryptoConstants.Q)
30		return nil, err
31	}
32	return NewHashFromBigInt(poseidonHash), nil
33}
34
35// HashElemsKey performs a poseidon hash over the array of ElemBytes.
36func HashElemsKey(key *big.Int, elems ...*big.Int) (*Hash, error) {
37	if len(elems) > poseidon.T-1 {
38		return nil, fmt.Errorf("HashElemsKey input can not be bigger than %v", poseidon.T-1)
39	}
40	if key == nil {
41		key = new(big.Int).SetInt64(0)
42	}
43	bi, err := BigIntsToPoseidonInput(elems...)
44	if err != nil {
45		return nil, err
46	}
47	copy(bi[len(elems):], []*big.Int{key})
48	poseidonHash, err := poseidon.PoseidonHash(bi)
49	if err != nil {
50		return nil, err
51	}
52	return NewHashFromBigInt(poseidonHash), nil
53}
54
55func BigIntsToPoseidonInput(bigints ...*big.Int) ([poseidon.T]*big.Int, error) {
56	z := big.NewInt(0)
57	b := [poseidon.T]*big.Int{z, z, z, z, z, z}
58	copy(b[:poseidon.T], bigints[:])
59
60	return b, nil
61}