sapling3.prf 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. # You will need this repo:
  2. # https://github.com/zcash/librustzcash/
  3. # Then compare this code to the file:
  4. # librustzcash/zcash_proofs/src/circuit/sapling.rs
  5. # What is the LC stuff?
  6. # Difference between AllocatedNum and Num
  7. # Why BlsScalar vs JJScalar?
  8. const:
  9. G_VCV: SubgroupPoint
  10. G_VCR: SubgroupPoint
  11. G_SPEND: SubgroupPoint
  12. G_PROOF: SubgroupPoint
  13. G_NOTE_COMMIT_R: SubgroupPoint
  14. G_NULL: SubgroupPoint
  15. CRH_IVK: Blake2sPersonalization
  16. NOTE_COMMIT: PedersenPersonalization
  17. MERKLE: list<PedersenPersonalization>
  18. PRF_NF: Blake2sPersonalization
  19. def value_commit(value: U64, randomness: Scalar) -> Binary:
  20. let value_bits: Binary = value as Binary
  21. let value: SubgroupPoint = value * G_VCV
  22. let rcv: Binary = randomness as Binary
  23. let rcv: SubgroupPoint = rcv * G_VCR
  24. let cv: SubgroupPoint = value + rcv
  25. emit cv
  26. return value_bits
  27. # The parameters to this function are the same as in:
  28. # struct Spend
  29. contract input_burn(
  30. value: U64, # ValueCommitment.value
  31. randomness: Scalar, # ValueCommitment.randomness
  32. ak: SubgroupPoint, # from ProofGenerationKey
  33. ar: Scalar,
  34. nsk: Scalar, # from ProofGenerationKey
  35. g_d: SubgroupPoint, # Computed from payment_address
  36. commitment_randomness: Scalar,
  37. auth_path: list<(Scalar, Bool)>,
  38. anchor: Scalar
  39. ) -> (SubgroupPoint, SubgroupPoint, SubgroupPoint, Binary):
  40. let ak = witness(ak)
  41. ak.assert_not_small_order()
  42. let ar: Binary = ar as Binary
  43. let ar: SubgroupPoint = ar * G_SPEND
  44. let rk: SubgroupPoint = ak + ar
  45. let nsk: Binary = nsk as Binary
  46. let nk: SubgroupPoint = nsk * G_PROOF
  47. let mut ivk_preimage: Binary = []
  48. # Must be Binary as well
  49. ivk_preimage.extend(ak.repr())
  50. let mut nf_preimage: Binary = []
  51. let nk_repr: Binary = nk.repr()
  52. ivk_preimage.extend(nk_repr)
  53. nf_preimage.extend(nk_repr)
  54. assert len(ivk_preimage) == 512
  55. assert len(nf_preimage) == 256
  56. let mut ivk: Binary = blake2s(ivk_preimage, CRH_IVK)
  57. ivk.truncate(Scalar.CAPACITY)
  58. let g_d: SubgroupPoint = witness g_d
  59. g_d.assert_not_small_order()
  60. let pk_d: SubgroupPoint = ivk * g_d
  61. let mut note_contents: Binary = []
  62. let (cv: SubgroupPoint, value_bits: Binary) = value_commit(value, randomness)
  63. let mut value_num: Num = Num.zero()
  64. let mut coeff: Scalar = Scalar.one()
  65. for bit in value_bits:
  66. value_num = value_num.add_Bool_with_coeff(bit, coeff)
  67. coeff = coeff.double()
  68. # Is this equivalent?
  69. let value_num = value_bits as Num
  70. note_contents.extend(value_bits)
  71. note_contents.extend(g_d)
  72. note_contents.extend(pk_d)
  73. assert len(note_contents) == 64 + 256 + 256
  74. let mut cm: SubgroupPoint = pedersen_hash(NOTE_COMMIT, note_contents)
  75. let rcm: Binary = commitment_randomness as Binary
  76. let rcm: SubgroupPoint = rcm * G_NOTE_COMMIT_R
  77. cm += rcm
  78. let mut position_bits: Binary = []
  79. let mut cur: Scalar = cm.u
  80. for i in range(auth_path.size()):
  81. let (node: Scalar, is_right: Bool) = auth_path[i]
  82. position_bits.push(is_right)
  83. let node: EncryptedNum = EncryptedNum.from(node)
  84. print(node)
  85. let (left: Binary, right: Binary) = Num.swap_if(is_right, cur, node)
  86. let mut preimage: Binary = []
  87. preimage.extend(left)
  88. preimage.extend(right)
  89. cur = pedersen_hash(MERKLE_TREE[i], preimage).u
  90. let rt: SubgroupPoint = EncryptedNum.from(anchor)
  91. enforce (cur - rt) * value_num == 0
  92. let position: SubgroupPoint = position_bits * G_NULL
  93. let rho: SubgroupPoint = cm + position
  94. nf_preimage.extend(rho)
  95. assert len(nf_preimage) == 512
  96. let nf: Binary = blake2s(nf_preimage, PRF_NF)
  97. emit (rk, cv, rt, nf)
  98. contract output_mint(
  99. value: U64,
  100. randomness: Scalar,
  101. g_d: SubgroupPoint,
  102. esk: Scalar,
  103. pk_d: SubgroupPoint,
  104. commitment_randomness: Scalar
  105. ) -> (SubgroupPoint, SubgroupPoint, Scalar):
  106. let value_bits: Binary = value_commit(value, randomness)
  107. let mut note_contents: Binary = []
  108. note_contents.extend(value_bits)
  109. let g_d: EdwardsPoint = witness(g_d)
  110. g_d.assert_not_small_order()
  111. let esk: Binary = esk as Binary
  112. let epk: SubgroupPoint = esk * g_d
  113. let v_contents: Binary = pk_d.v as Binary
  114. let sign_bit: Bool = pk_d.u.is_odd() as Bool
  115. note_contents.extend(v_contents)
  116. note_contents.push(sign_bit)
  117. assert len(note_contents) == 64 + 256 + 256
  118. let mut cm: SubgroupPoint = pedersen_hash(NOTE_COMMIT, note_contents)
  119. let rcm: Binary = commitment_randomness as Binary
  120. let rcm: SubgroupPoint = rcm * G_NOTE_COMMIT_R
  121. cm += rcm
  122. let cmu: Scalar = cm.u
  123. emit (cv, epk, cmu)