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}