You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.5 KiB

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