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.

77 lines
1.6 KiB

  1. package poseidon
  2. import (
  3. "math/big"
  4. "github.com/iden3/go-iden3-crypto/ffg"
  5. )
  6. func zero() *ffg.Element {
  7. return ffg.NewElement()
  8. }
  9. // exp7 performs x^7 mod p
  10. func exp7(a *ffg.Element) {
  11. a.Exp(*a, big.NewInt(7)) //nolint:gomnd
  12. }
  13. // exp7state perform exp7 for whole state
  14. func exp7state(state []*ffg.Element) {
  15. for i := 0; i < len(state); i++ {
  16. exp7(state[i])
  17. }
  18. }
  19. // ark computes Add-Round Key, from the paper https://eprint.iacr.org/2019/458.pdf
  20. func ark(state []*ffg.Element, it int) {
  21. for i := 0; i < len(state); i++ {
  22. state[i].Add(state[i], C[it+i])
  23. }
  24. }
  25. // mix returns [[matrix]] * [vector]
  26. func mix(state []*ffg.Element) []*ffg.Element {
  27. mul := zero()
  28. newState := make([]*ffg.Element, mLen)
  29. for i := 0; i < mLen; i++ {
  30. newState[i] = zero()
  31. }
  32. for i := 0; i < mLen; i++ {
  33. newState[i].SetUint64(0)
  34. for j := 0; j < mLen; j++ {
  35. mul.Mul(M[i][j], state[j])
  36. newState[i].Add(newState[i], mul)
  37. }
  38. }
  39. return newState
  40. }
  41. // Hash computes the Poseidon hash for the given inputs
  42. func Hash(inpBI [NROUNDSF]uint64, capBI [CAPLEN]uint64) ([CAPLEN]uint64, error) {
  43. state := make([]*ffg.Element, mLen)
  44. for i := 0; i < NROUNDSF; i++ {
  45. state[i] = ffg.NewElement().SetUint64(inpBI[i])
  46. }
  47. for i := 0; i < CAPLEN; i++ {
  48. state[i+NROUNDSF] = ffg.NewElement().SetUint64(capBI[i])
  49. }
  50. for r := 0; r < NROUNDSF+NROUNDSP; r++ {
  51. ark(state, r*mLen)
  52. if r < NROUNDSF/2 || r >= NROUNDSF/2+NROUNDSP {
  53. exp7state(state)
  54. } else {
  55. exp7(state[0])
  56. }
  57. state = mix(state)
  58. }
  59. return [CAPLEN]uint64{
  60. state[0].ToUint64Regular(),
  61. state[1].ToUint64Regular(),
  62. state[2].ToUint64Regular(),
  63. state[3].ToUint64Regular(),
  64. }, nil
  65. }