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.

86 lines
2.1 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. func (t *Tree) fillMissingEmptySiblings(s [][]byte) [][]byte {
  43. for i := len(s); i < t.maxLevels; i++ {
  44. s = append(s, emptyValue)
  45. }
  46. return s
  47. }
  48. // GenerateCircomVerifierProof generates a CircomVerifierProof for a given key
  49. // in the Tree
  50. func (t *Tree) GenerateCircomVerifierProof(k []byte) (*CircomVerifierProof, error) {
  51. kAux, v, siblings, existence, err := t.GenProof(k)
  52. if err != nil && err != ErrKeyNotFound {
  53. return nil, err
  54. }
  55. var cp CircomVerifierProof
  56. cp.Root = t.Root()
  57. s, err := UnpackSiblings(t.hashFunction, siblings)
  58. if err != nil {
  59. return nil, err
  60. }
  61. cp.Siblings = t.fillMissingEmptySiblings(s)
  62. if !existence {
  63. cp.OldKey = kAux
  64. cp.OldValue = v
  65. } else {
  66. cp.OldKey = emptyValue
  67. cp.OldValue = emptyValue
  68. }
  69. cp.Key = k
  70. cp.Value = v
  71. if existence {
  72. cp.Fnc = 0 // inclusion
  73. } else {
  74. cp.Fnc = 1 // non inclusion
  75. }
  76. return &cp, nil
  77. }