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	"github.com/iden3/go-iden3-crypto/poseidon"
 8)
 9
10// HashElems performs a poseidon hash over the array of ElemBytes.
11// Uses poseidon.PoseidonHash to be compatible with the circom circuits
12// implementations.
13// The maxim slice input size is poseidon.T
14func HashElems(elems ...*big.Int) (*Hash, error) {
15	if len(elems) > poseidon.T {
16		return nil, fmt.Errorf("HashElems input can not be bigger than %v", poseidon.T)
17	}
18
19	bi, err := BigIntsToPoseidonInput(elems...)
20	if err != nil {
21		return nil, err
22	}
23
24	poseidonHash, err := poseidon.PoseidonHash(bi)
25	if err != nil {
26		return nil, err
27	}
28	return NewHashFromBigInt(poseidonHash), nil
29}
30
31// HashElemsKey performs a poseidon hash over the array of ElemBytes.
32func HashElemsKey(key *big.Int, elems ...*big.Int) (*Hash, error) {
33	if len(elems) > poseidon.T-1 {
34		return nil, fmt.Errorf("HashElemsKey input can not be bigger than %v", poseidon.T-1)
35	}
36	if key == nil {
37		key = new(big.Int).SetInt64(0)
38	}
39	bi, err := BigIntsToPoseidonInput(elems...)
40	if err != nil {
41		return nil, err
42	}
43	copy(bi[len(elems):], []*big.Int{key})
44	poseidonHash, err := poseidon.PoseidonHash(bi)
45	if err != nil {
46		return nil, err
47	}
48	return NewHashFromBigInt(poseidonHash), nil
49}
50
51// BigIntsToPoseidonInput takes *big.Ints and returns a fixed-length array of the size `poseidon.T`
52func BigIntsToPoseidonInput(bigints ...*big.Int) ([poseidon.T]*big.Int, error) {
53	z := big.NewInt(0)
54	b := [poseidon.T]*big.Int{z, z, z, z, z, z}
55	copy(b[:poseidon.T], bigints[:])
56
57	return b, nil
58}