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.

91 lines
2.3 KiB

  1. package arbo
  2. import (
  3. "encoding/json"
  4. )
  5. // CircomVerifierProof contains the needed data to check a Circom Verifier Proof
  6. // inside a circom circuit. CircomVerifierProof allow to verify through a
  7. // zkSNARK proof the inclusion/exclusion of a leaf in a tree.
  8. type CircomVerifierProof struct {
  9. Root []byte `json:"root"`
  10. Siblings [][]byte `json:"siblings"`
  11. OldKey []byte `json:"oldKey"`
  12. OldValue []byte `json:"oldValue"`
  13. IsOld0 bool `json:"isOld0"`
  14. Key []byte `json:"key"`
  15. Value []byte `json:"value"`
  16. Fnc int `json:"fnc"` // 0: inclusion, 1: non inclusion
  17. }
  18. // MarshalJSON implements the JSON marshaler
  19. func (cvp CircomVerifierProof) MarshalJSON() ([]byte, error) {
  20. m := make(map[string]interface{})
  21. m["root"] = BytesToBigInt(cvp.Root).String()
  22. m["siblings"] = siblingsToStringArray(cvp.Siblings)
  23. m["oldKey"] = BytesToBigInt(cvp.OldKey).String()
  24. m["oldValue"] = BytesToBigInt(cvp.OldValue).String()
  25. if cvp.IsOld0 {
  26. m["isOld0"] = "1"
  27. } else {
  28. m["isOld0"] = "0"
  29. }
  30. m["key"] = BytesToBigInt(cvp.Key).String()
  31. m["value"] = BytesToBigInt(cvp.Value).String()
  32. m["fnc"] = cvp.Fnc
  33. return json.Marshal(m)
  34. }
  35. func siblingsToStringArray(s [][]byte) []string {
  36. var r []string
  37. for i := 0; i < len(s); i++ {
  38. r = append(r, BytesToBigInt(s[i]).String())
  39. }
  40. return r
  41. }
  42. // FillMissingEmptySiblings adds the empty values to the array of siblings for
  43. // the Tree number of max levels
  44. func (t *Tree) FillMissingEmptySiblings(s [][]byte) [][]byte {
  45. for i := len(s); i < t.maxLevels; i++ {
  46. s = append(s, emptyValue)
  47. }
  48. return s
  49. }
  50. // GenerateCircomVerifierProof generates a CircomVerifierProof for a given key
  51. // in the Tree
  52. func (t *Tree) GenerateCircomVerifierProof(k []byte) (*CircomVerifierProof, error) {
  53. kAux, v, siblings, existence, err := t.GenProof(k)
  54. if err != nil && err != ErrKeyNotFound {
  55. return nil, err
  56. }
  57. var cp CircomVerifierProof
  58. cp.Root, err = t.Root()
  59. if err != nil {
  60. return nil, err
  61. }
  62. s, err := UnpackSiblings(t.hashFunction, siblings)
  63. if err != nil {
  64. return nil, err
  65. }
  66. cp.Siblings = t.FillMissingEmptySiblings(s)
  67. if !existence {
  68. cp.OldKey = kAux
  69. cp.OldValue = v
  70. } else {
  71. cp.OldKey = emptyValue
  72. cp.OldValue = emptyValue
  73. }
  74. cp.Key = k
  75. cp.Value = v
  76. if existence {
  77. cp.Fnc = 0 // inclusion
  78. } else {
  79. cp.Fnc = 1 // non inclusion
  80. }
  81. return &cp, nil
  82. }