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}