sapling.pseudocode 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # :set syntax=sapvi
  2. # :source ../scripts/sapvi.vim
  3. const:
  4. G_VCV: SubgroupPoint
  5. G_VCR: SubgroupPoint
  6. G_SPEND: SubgroupPoint
  7. G_PROOF: SubgroupPoint
  8. G_NOTE_COMMIT_R: SubgroupPoint
  9. G_NULL: SubgroupPoint
  10. CRH_IVK: Blake2sPersonalization
  11. NOTE_COMMIT: PedersenPersonalization
  12. MERKLE: list<PedersenPersonalization>
  13. PRF_NF: Blake2sPersonalization
  14. contract input_spend(
  15. value: BinaryNumber
  16. randomness: BinaryNumber
  17. ak: Point
  18. ar: BinaryNumber
  19. nsk: BinaryNumber
  20. g_d: Point
  21. commitment_randomness: BinaryNumber
  22. auth_path: [(Scalar, Bool)]
  23. anchor: Scalar
  24. ) -> (Point, Point, Scalar, BinaryNumber):
  25. let rk: Point = ak + ar * G_SPEND
  26. emit rk
  27. let nk: Point = nsk * G_PROOF
  28. let mut ivk_preimage: BinaryNumber = []
  29. ivk_preimage.put(ak)
  30. let mut nf_preimage: BinaryNumber = []
  31. ivk_preimage.put(nk)
  32. nf_preimage.put(nk)
  33. assert ivk_preimage.len() == 512
  34. assert nf_preimage.len() == 256
  35. let mut ivk = blake2s(ivk_preimage, CRH_IVK)
  36. ivk.truncate(Fr.CAPACITY)
  37. # This will error if ivk.len() != 256
  38. #let ivk: Fr = ivk as Fr
  39. let pk_d: Point = ivk * g_d
  40. let cv: Point = value * G_VCV + rcv * G_VCR
  41. emit cv
  42. let mut note_contents: BinaryNumber = []
  43. note_contents.put(value)
  44. note_contents.put(g_d)
  45. note_contents.put(p_k)
  46. assert note_contents.len() == 64 + 256 + 256
  47. let mut cm = pedersen_hash(note_contents, NOTE_COMMIT)
  48. cm += commitment_randomness * G_NOTE_COMMIT_R
  49. let mut position = []
  50. let mut cur: Scalar = cm.u
  51. for i in range(auth_path.size()):
  52. let (node: Scalar, is_right: Bool) = auth_path[i]
  53. position.push(is_right)
  54. # Scalar -> AllocatedNum
  55. let (left: Scalar, right: Scalar) = swap_if(is_right, cur, node)
  56. let mut preimage: BinaryNumber = []
  57. preimage.put(left)
  58. preimage.put(right)
  59. cur = pedersen_hash(MERKLE_TREE[i], preimage).u
  60. enforce cur == rt
  61. emit rt
  62. let rho: Point = rho + position * G_NULL
  63. nf_preimage.put(rho)
  64. assert nf_preimage.len() == 512
  65. let nf: BinaryNumber = blake2s(nf_preimage, PRF_NF)
  66. emit nf
  67. contract output_mint(
  68. value: BinaryNumber,
  69. randomness: BinaryNumber,
  70. g_d: Point,
  71. esk: BinaryNumber,
  72. pk_d: Point,
  73. commitment_randomness: Scalar
  74. ) -> (Point, Point, Scalar):
  75. let cv: Point = value * G_VCV + rcv * G_VCR
  76. emit cv
  77. let mut note_contents: Binary = []
  78. note_contents.put(value)
  79. let epk: Point = esk * g_d
  80. emit epk
  81. let v_contents: Scalar = pk_d.v
  82. let sign_bit: Bool = pk_d.u.is_odd()
  83. note_contents.put(v_contents)
  84. note_contents.put(sign_bit)
  85. assert len(note_contents) == 64 + 256 + 256
  86. let mut cm: Point = pedersen_hash(note_contents, NOTE_COMMIT)
  87. let rcm: Point = commitment_randomness * G_NOTE_COMMIT_R
  88. cm += rcm
  89. let cmu: Scalar = cm.u
  90. emit cmu