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.

122 lines
3.3 KiB

  1. package arbo
  2. import (
  3. "crypto/sha256"
  4. "math/big"
  5. "github.com/iden3/go-iden3-crypto/poseidon"
  6. "golang.org/x/crypto/blake2b"
  7. )
  8. var (
  9. // TypeHashSha256 represents the label for the HashFunction of Sha256
  10. TypeHashSha256 = []byte("sha256")
  11. // TypeHashPoseidon represents the label for the HashFunction of
  12. // Poseidon
  13. TypeHashPoseidon = []byte("poseidon")
  14. // TypeHashBlake2b represents the label for the HashFunction of Blake2b
  15. TypeHashBlake2b = []byte("blake2b")
  16. // HashFunctionSha256 contains the HashSha256 struct which implements
  17. // the HashFunction interface
  18. HashFunctionSha256 HashSha256
  19. // HashFunctionPoseidon contains the HashPoseidon struct which implements
  20. // the HashFunction interface
  21. HashFunctionPoseidon HashPoseidon
  22. // HashFunctionBlake2b contains the HashBlake2b struct which implements
  23. // the HashFunction interface
  24. HashFunctionBlake2b HashBlake2b
  25. )
  26. // Once Generics are at Go, this will be updated (August 2021
  27. // https://blog.golang.org/generics-next-step)
  28. // HashFunction defines the interface that is expected for a hash function to be
  29. // used in a generic way in the Tree.
  30. type HashFunction interface {
  31. Type() []byte
  32. Len() int
  33. Hash(...[]byte) ([]byte, error)
  34. // CheckInput checks if the input is valid without computing the hash
  35. // CheckInput(...[]byte) error
  36. }
  37. // HashSha256 implements the HashFunction interface for the Sha256 hash
  38. type HashSha256 struct{}
  39. // Type returns the type of HashFunction for the HashSha256
  40. func (f HashSha256) Type() []byte {
  41. return TypeHashSha256
  42. }
  43. // Len returns the length of the Hash output
  44. func (f HashSha256) Len() int {
  45. return 32 //nolint:gomnd
  46. }
  47. // Hash implements the hash method for the HashFunction HashSha256
  48. func (f HashSha256) Hash(b ...[]byte) ([]byte, error) {
  49. var toHash []byte
  50. for i := 0; i < len(b); i++ {
  51. toHash = append(toHash, b[i]...)
  52. }
  53. h := sha256.Sum256(toHash)
  54. return h[:], nil
  55. }
  56. // HashPoseidon implements the HashFunction interface for the Poseidon hash
  57. type HashPoseidon struct{}
  58. // Type returns the type of HashFunction for the HashPoseidon
  59. func (f HashPoseidon) Type() []byte {
  60. return TypeHashPoseidon
  61. }
  62. // Len returns the length of the Hash output
  63. func (f HashPoseidon) Len() int {
  64. return 32 //nolint:gomnd
  65. }
  66. // Hash implements the hash method for the HashFunction HashPoseidon. It
  67. // expects the byte arrays to be little-endian representations of big.Int
  68. // values.
  69. func (f HashPoseidon) Hash(b ...[]byte) ([]byte, error) {
  70. var toHash []*big.Int
  71. for i := 0; i < len(b); i++ {
  72. bi := BytesToBigInt(b[i])
  73. toHash = append(toHash, bi)
  74. }
  75. h, err := poseidon.Hash(toHash)
  76. if err != nil {
  77. return nil, err
  78. }
  79. hB := BigIntToBytes(f.Len(), h)
  80. return hB, nil
  81. }
  82. // HashBlake2b implements the HashFunction interface for the Blake2b hash
  83. type HashBlake2b struct{}
  84. // Type returns the type of HashFunction for the HashBlake2b
  85. func (f HashBlake2b) Type() []byte {
  86. return TypeHashBlake2b
  87. }
  88. // Len returns the length of the Hash output
  89. func (f HashBlake2b) Len() int {
  90. return 32 //nolint:gomnd
  91. }
  92. // Hash implements the hash method for the HashFunction HashBlake2b
  93. func (f HashBlake2b) Hash(b ...[]byte) ([]byte, error) {
  94. hasher, err := blake2b.New256(nil)
  95. if err != nil {
  96. return nil, err
  97. }
  98. for i := 0; i < len(b); i++ {
  99. if _, err = hasher.Write(b[i]); err != nil {
  100. return nil, err
  101. }
  102. }
  103. return hasher.Sum(nil), nil
  104. }