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.

62 lines
1.7 KiB

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