spend.pism 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. constant G_VCV FixedGenerator
  2. constant G_VCR FixedGenerator
  3. constant G_SPEND FixedGenerator
  4. constant PRF_NF BlakePersonalization
  5. constant CRH_IVK BlakePersonalization
  6. constant NOTE_COMMIT PedersenPersonalization
  7. contract spend_contract
  8. # Value commitment
  9. param value U64
  10. param randomness_value Fr
  11. param serial Fr
  12. param randomness_coin Fr
  13. param secret Fr
  14. {% for i in range(4) %}
  15. param branch_{{ i }} Scalar
  16. param is_right_{{ i }} Bool
  17. {% endfor %}
  18. start
  19. # Witness input values
  20. u64_as_binary_le value param:value
  21. fr_as_binary_le randomness_value param:randomness_value
  22. # Make value commitment
  23. # V = v * G_VCV + r * G_VCR
  24. ec_mul_const vcv value G_VCV
  25. ec_mul_const rcv randomness_value G_VCR
  26. ec_add cv vcv rcv
  27. # emit cv
  28. emit_ec cv
  29. # Make the nullifier
  30. # N = Hash(secret, serial)
  31. fr_as_binary_le serial param:serial
  32. fr_as_binary_le secret param:secret
  33. alloc_binary nf_preimage
  34. # Fr values are 252 bits so we need to pad it with extra 0s
  35. # to match the Rust values which are 256 bits
  36. {% macro binary_put_fr(binary, var) -%}
  37. binary_extend {{ binary }} {{ var }}
  38. {% for n in range(4) %}
  39. alloc_const_bit zero_bit false
  40. binary_push {{ binary }} zero_bit
  41. {% endfor %}
  42. {%- endmacro %}
  43. # secret
  44. binary_clone secret2 secret
  45. {{ binary_put_fr("nf_preimage", "secret2") }}
  46. # serial
  47. binary_clone serial2 serial
  48. {{ binary_put_fr("nf_preimage", "serial2") }}
  49. # Secret: Fr = 252 + 4 bits padding
  50. # Serial: Fr = 252 + 4 bits padding
  51. # TOTAL: 512 bits for preimage
  52. static_assert_binary_size nf_preimage 512
  53. blake2s nf nf_preimage PRF_NF
  54. emit_binary nf
  55. # Derive the public key
  56. # P = secret * G
  57. ec_mul_const public secret G_SPEND
  58. # Make the coin (same as mint contract)
  59. # C = Hash(public_key, value, serial, randomness_coin)
  60. fr_as_binary_le randomness_coin param:randomness_coin
  61. # Build the preimage to hash
  62. alloc_binary preimage
  63. # public_key
  64. ec_repr repr_public public
  65. binary_extend preimage repr_public
  66. # value
  67. binary_extend preimage value
  68. # serial
  69. {{ binary_put_fr("preimage", "serial") }}
  70. # randomness_coin
  71. {{ binary_put_fr("preimage", "randomness_coin") }}
  72. # Public key: SubgroupPoint = 256 bits
  73. # Value: u64 = 64 bits
  74. # Serial: Fr = 252 + 4 bits padding
  75. # Randomness coin Fr = 252 + 4 bits padding
  76. # TOTAL: 832 bits for preimage
  77. static_assert_binary_size preimage 832
  78. blake2s coin preimage CRH_IVK
  79. binary_clone coin2 coin
  80. emit_binary coin2
  81. # coin_commit = PedersenHash(coin)
  82. pedersen_hash cm coin NOTE_COMMIT
  83. # left = coin_commit.u
  84. ec_get_u left cm
  85. emit_scalar left
  86. # Our merkle tree has a height of 4
  87. {% for i in range(4) %}
  88. # right = branch[{{ i }}]
  89. # is_right = is_right[{{ i }}]
  90. # if is_right:
  91. # left, right = right, left
  92. # coin_commit = PedersenHash(left || right)
  93. # left = coin_commit.u
  94. {% endfor %}
  95. # Reveal the merkle root
  96. end