spend_contract.rs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. #![allow(unused_imports)]
  2. #![allow(unused_mut)]
  3. use bellman::{
  4. gadgets::{
  5. blake2s, boolean,
  6. boolean::{AllocatedBit, Boolean},
  7. multipack, num, Assignment,
  8. },
  9. groth16, Circuit, ConstraintSystem, SynthesisError,
  10. };
  11. use bls12_381::Bls12;
  12. use ff::{Field, PrimeField};
  13. use group::Curve;
  14. use zcash_proofs::circuit::{ecc, pedersen_hash};
  15. use crate::crypto::merkle_node::SAPLING_COMMITMENT_TREE_DEPTH;
  16. pub struct SpendContract {
  17. pub value: Option<u64>,
  18. pub token_id: Option<jubjub::Fr>,
  19. pub randomness_value: Option<jubjub::Fr>,
  20. pub randomness_token: Option<jubjub::Fr>,
  21. pub serial: Option<jubjub::Fr>,
  22. pub randomness_coin: Option<jubjub::Fr>,
  23. pub secret: Option<jubjub::Fr>,
  24. pub branch: [Option<bls12_381::Scalar>; SAPLING_COMMITMENT_TREE_DEPTH],
  25. pub is_right: [Option<bool>; SAPLING_COMMITMENT_TREE_DEPTH],
  26. pub signature_secret: Option<jubjub::Fr>,
  27. }
  28. impl Circuit<bls12_381::Scalar> for SpendContract {
  29. fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
  30. self,
  31. cs: &mut CS,
  32. ) -> Result<(), SynthesisError> {
  33. // Line 40: u64_as_binary_le value param:value
  34. let value = boolean::u64_into_boolean_vec_le(
  35. cs.namespace(|| "Line 40: u64_as_binary_le value param:value"),
  36. self.value,
  37. )?;
  38. // Line 41: u64_as_binary_le token_id param:token_id
  39. let token_id = boolean::field_into_boolean_vec_le(
  40. cs.namespace(|| "Line 41: u64_as_binary_le value param:value"),
  41. self.token_id,
  42. )?;
  43. // Line 41: fr_as_binary_le randomness_value param:randomness_value
  44. let randomness_value = boolean::field_into_boolean_vec_le(
  45. cs.namespace(|| "Line 41: fr_as_binary_le randomness_value param:randomness_value"),
  46. self.randomness_value,
  47. )?;
  48. // Line 41: fr_as_binary_le randomness_token param:randomness_token
  49. let randomness_token = boolean::field_into_boolean_vec_le(
  50. cs.namespace(|| "Line 41: fr_as_binary_le randomness_token param:randomness_token"),
  51. self.randomness_token,
  52. )?;
  53. // Line 46: ec_mul_const vcv value G_VCV
  54. let vcv = ecc::fixed_base_multiplication(
  55. cs.namespace(|| "Line 46: ec_mul_const vcv value G_VCV"),
  56. &zcash_proofs::constants::VALUE_COMMITMENT_VALUE_GENERATOR,
  57. &value,
  58. )?;
  59. // Line 47: ec_mul_const rcv randomness_value G_VCR
  60. let rcv = ecc::fixed_base_multiplication(
  61. cs.namespace(|| "Line 47: ec_mul_const rcv randomness_value G_VCR"),
  62. &zcash_proofs::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR,
  63. &randomness_value,
  64. )?;
  65. // Line 48: ec_add cv vcv rcv
  66. let cv = vcv.add(cs.namespace(|| "Line 48: ec_add cv vcv rcv"), &rcv)?;
  67. // Line 50: emit_ec cv
  68. cv.inputize(cs.namespace(|| "Line 50: emit_ec cv"))?;
  69. // Line 46: ec_mul_const vca token_id G_VCV
  70. let vca = ecc::fixed_base_multiplication(
  71. cs.namespace(|| "Line 46: ec_mul_const vca token_id G_VCV"),
  72. &zcash_proofs::constants::VALUE_COMMITMENT_VALUE_GENERATOR,
  73. &token_id,
  74. )?;
  75. // Line 47: ec_mul_const rca randomness_token G_VCR
  76. let rca = ecc::fixed_base_multiplication(
  77. cs.namespace(|| "Line 47: ec_mul_const rca randomness_token G_VCR"),
  78. &zcash_proofs::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR,
  79. &randomness_token,
  80. )?;
  81. // Line 48: ec_add ca vca rca
  82. let ca = vca.add(cs.namespace(|| "Line 48: ec_add ca vca rca"), &rca)?;
  83. // Line 50: emit_ec ca
  84. ca.inputize(cs.namespace(|| "Line 50: emit_ec ca"))?;
  85. // Line 54: fr_as_binary_le serial param:serial
  86. let serial = boolean::field_into_boolean_vec_le(
  87. cs.namespace(|| "Line 54: fr_as_binary_le serial param:serial"),
  88. self.serial,
  89. )?;
  90. // Line 55: fr_as_binary_le secret param:secret
  91. let secret = boolean::field_into_boolean_vec_le(
  92. cs.namespace(|| "Line 55: fr_as_binary_le secret param:secret"),
  93. self.secret,
  94. )?;
  95. // Line 57: alloc_binary nf_preimage
  96. let mut nf_preimage = vec![];
  97. // Line 64: binary_clone secret2 secret
  98. let mut secret2: Vec<_> = secret.to_vec();
  99. // Line 65: binary_extend nf_preimage secret2
  100. nf_preimage.extend(secret2);
  101. // Line 67: alloc_const_bit zero_bit false
  102. let zero_bit = Boolean::constant(false);
  103. // Line 68: binary_push nf_preimage zero_bit
  104. nf_preimage.push(zero_bit);
  105. // Line 70: alloc_const_bit zero_bit false
  106. let zero_bit = Boolean::constant(false);
  107. // Line 71: binary_push nf_preimage zero_bit
  108. nf_preimage.push(zero_bit);
  109. // Line 73: alloc_const_bit zero_bit false
  110. let zero_bit = Boolean::constant(false);
  111. // Line 74: binary_push nf_preimage zero_bit
  112. nf_preimage.push(zero_bit);
  113. // Line 76: alloc_const_bit zero_bit false
  114. let zero_bit = Boolean::constant(false);
  115. // Line 77: binary_push nf_preimage zero_bit
  116. nf_preimage.push(zero_bit);
  117. // Line 81: binary_clone serial2 serial
  118. let mut serial2: Vec<_> = serial.to_vec();
  119. // Line 82: binary_extend nf_preimage serial2
  120. nf_preimage.extend(serial2);
  121. // Line 84: alloc_const_bit zero_bit false
  122. let zero_bit = Boolean::constant(false);
  123. // Line 85: binary_push nf_preimage zero_bit
  124. nf_preimage.push(zero_bit);
  125. // Line 87: alloc_const_bit zero_bit false
  126. let zero_bit = Boolean::constant(false);
  127. // Line 88: binary_push nf_preimage zero_bit
  128. nf_preimage.push(zero_bit);
  129. // Line 90: alloc_const_bit zero_bit false
  130. let zero_bit = Boolean::constant(false);
  131. // Line 91: binary_push nf_preimage zero_bit
  132. nf_preimage.push(zero_bit);
  133. // Line 93: alloc_const_bit zero_bit false
  134. let zero_bit = Boolean::constant(false);
  135. // Line 94: binary_push nf_preimage zero_bit
  136. nf_preimage.push(zero_bit);
  137. // Line 100: static_assert_binary_size nf_preimage 512
  138. assert_eq!(nf_preimage.len(), 512);
  139. // Line 101: blake2s nf nf_preimage PRF_NF
  140. let mut nf = blake2s::blake2s(
  141. cs.namespace(|| "Line 101: blake2s nf nf_preimage PRF_NF"),
  142. &nf_preimage,
  143. zcash_primitives::constants::PRF_NF_PERSONALIZATION,
  144. )?;
  145. // Line 102: emit_binary nf
  146. multipack::pack_into_inputs(cs.namespace(|| "Line 102: emit_binary nf"), &nf)?;
  147. // Line 106: ec_mul_const public secret G_SPEND
  148. let public = ecc::fixed_base_multiplication(
  149. cs.namespace(|| "Line 106: ec_mul_const public secret G_SPEND"),
  150. &zcash_proofs::constants::SPENDING_KEY_GENERATOR,
  151. &secret,
  152. )?;
  153. // Line 110: fr_as_binary_le randomness_coin param:randomness_coin
  154. let randomness_coin = boolean::field_into_boolean_vec_le(
  155. cs.namespace(|| "Line 110: fr_as_binary_le randomness_coin param:randomness_coin"),
  156. self.randomness_coin,
  157. )?;
  158. // Line 113: alloc_binary preimage
  159. let mut preimage = vec![];
  160. // Line 116: ec_repr repr_public public
  161. let repr_public = public.repr(cs.namespace(|| "Line 116: ec_repr repr_public public"))?;
  162. // Line 117: binary_extend preimage repr_public
  163. preimage.extend(repr_public);
  164. // Line 120: binary_extend preimage value
  165. preimage.extend(value);
  166. // Line 109: binary_extend preimage token_id
  167. preimage.extend(token_id);
  168. // add 4 zero bits
  169. for _ in 0..4 {
  170. // Line 71: alloc_const_bit zero_bit false
  171. let zero_bit = Boolean::constant(false);
  172. // Line 72: binary_push preimage zero_bit
  173. preimage.push(zero_bit);
  174. }
  175. // Line 123: binary_extend preimage serial
  176. preimage.extend(serial);
  177. // add 4 zero bits
  178. for _ in 0..4 {
  179. // Line 71: alloc_const_bit zero_bit false
  180. let zero_bit = Boolean::constant(false);
  181. // Line 72: binary_push preimage zero_bit
  182. preimage.push(zero_bit);
  183. }
  184. // Line 139: binary_extend preimage randomness_coin
  185. preimage.extend(randomness_coin);
  186. // add 4 zero bits
  187. for _ in 0..4 {
  188. // Line 71: alloc_const_bit zero_bit false
  189. let zero_bit = Boolean::constant(false);
  190. // Line 72: binary_push preimage zero_bit
  191. preimage.push(zero_bit);
  192. }
  193. // Line 159: static_assert_binary_size preimage 1088
  194. assert_eq!(preimage.len(), 1088);
  195. // Line 160: blake2s coin preimage CRH_IVK
  196. let mut coin = blake2s::blake2s(
  197. cs.namespace(|| "Line 160: blake2s coin preimage CRH_IVK"),
  198. &preimage,
  199. zcash_primitives::constants::CRH_IVK_PERSONALIZATION,
  200. )?;
  201. // Line 166: pedersen_hash cm coin NOTE_COMMIT
  202. let mut cm = pedersen_hash::pedersen_hash(
  203. cs.namespace(|| "Line 166: pedersen_hash cm coin NOTE_COMMIT"),
  204. pedersen_hash::Personalization::NoteCommitment,
  205. &coin,
  206. )?;
  207. // Line 168: ec_get_u current cm
  208. let mut current = cm.get_u().clone();
  209. for i in 0..SAPLING_COMMITMENT_TREE_DEPTH {
  210. // Line 174: alloc_scalar branch param:branch_0
  211. let branch = num::AllocatedNum::alloc(
  212. cs.namespace(|| "Line 174: alloc_scalar branch param:branch_0"),
  213. || Ok(*self.branch[i].get()?),
  214. )?;
  215. // Line 177: alloc_bit is_right param:is_right_0
  216. let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc(
  217. cs.namespace(|| "Line 177: alloc_bit is_right param:is_right_0"),
  218. self.is_right[i],
  219. )?);
  220. // Line 180: conditionally_reverse left right current branch is_right
  221. let (left, right) = num::AllocatedNum::conditionally_reverse(
  222. cs.namespace(|| {
  223. "Line 180: conditionally_reverse left right current branch is_right"
  224. }),
  225. &current,
  226. &branch,
  227. &is_right,
  228. )?;
  229. // Line 183: scalar_as_binary left left
  230. let left = left.to_bits_le(cs.namespace(|| "Line 183: scalar_as_binary left left"))?;
  231. // Line 184: scalar_as_binary right right
  232. let right =
  233. right.to_bits_le(cs.namespace(|| "Line 184: scalar_as_binary right right"))?;
  234. // Line 185: alloc_binary preimage
  235. let mut preimage = vec![];
  236. // Line 186: binary_extend preimage left
  237. preimage.extend(left);
  238. // Line 187: binary_extend preimage right
  239. preimage.extend(right);
  240. // Line 188: pedersen_hash cm preimage MERKLE_0
  241. let mut cm = pedersen_hash::pedersen_hash(
  242. cs.namespace(|| "Line 188: pedersen_hash cm preimage MERKLE_0"),
  243. pedersen_hash::Personalization::MerkleTree(i),
  244. &preimage,
  245. )?;
  246. // Line 190: ec_get_u current cm
  247. current = cm.get_u().clone();
  248. }
  249. /*
  250. // Line 174: alloc_scalar branch param:branch_0
  251. let branch = num::AllocatedNum::alloc(
  252. cs.namespace(|| "Line 174: alloc_scalar branch param:branch_0"),
  253. || Ok(*self.branch_0.get()?),
  254. )?;
  255. // Line 177: alloc_bit is_right param:is_right_0
  256. let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc(
  257. cs.namespace(|| "Line 177: alloc_bit is_right param:is_right_0"),
  258. self.is_right_0,
  259. )?);
  260. // Line 180: conditionally_reverse left right current branch is_right
  261. let (left, right) = num::AllocatedNum::conditionally_reverse(
  262. cs.namespace(|| "Line 180: conditionally_reverse left right current branch is_right"),
  263. &current,
  264. &branch,
  265. &is_right,
  266. )?;
  267. // Line 183: scalar_as_binary left left
  268. let left = left.to_bits_le(cs.namespace(|| "Line 183: scalar_as_binary left left"))?;
  269. // Line 184: scalar_as_binary right right
  270. let right = right.to_bits_le(cs.namespace(|| "Line 184: scalar_as_binary right right"))?;
  271. // Line 185: alloc_binary preimage
  272. let mut preimage = vec![];
  273. // Line 186: binary_extend preimage left
  274. preimage.extend(left);
  275. // Line 187: binary_extend preimage right
  276. preimage.extend(right);
  277. // Line 188: pedersen_hash cm preimage MERKLE_0
  278. let mut cm = pedersen_hash::pedersen_hash(
  279. cs.namespace(|| "Line 188: pedersen_hash cm preimage MERKLE_0"),
  280. pedersen_hash::Personalization::MerkleTree(0),
  281. &preimage,
  282. )?;
  283. // Line 190: ec_get_u current cm
  284. let mut current = cm.get_u().clone();
  285. // Line 194: alloc_scalar branch param:branch_1
  286. let branch = num::AllocatedNum::alloc(
  287. cs.namespace(|| "Line 194: alloc_scalar branch param:branch_1"),
  288. || Ok(*self.branch_1.get()?),
  289. )?;
  290. // Line 197: alloc_bit is_right param:is_right_1
  291. let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc(
  292. cs.namespace(|| "Line 197: alloc_bit is_right param:is_right_1"),
  293. self.is_right_1,
  294. )?);
  295. // Line 200: conditionally_reverse left right current branch is_right
  296. let (left, right) = num::AllocatedNum::conditionally_reverse(
  297. cs.namespace(|| "Line 200: conditionally_reverse left right current branch is_right"),
  298. &current,
  299. &branch,
  300. &is_right,
  301. )?;
  302. // Line 203: scalar_as_binary left left
  303. let left = left.to_bits_le(cs.namespace(|| "Line 203: scalar_as_binary left left"))?;
  304. // Line 204: scalar_as_binary right right
  305. let right = right.to_bits_le(cs.namespace(|| "Line 204: scalar_as_binary right right"))?;
  306. // Line 205: alloc_binary preimage
  307. let mut preimage = vec![];
  308. // Line 206: binary_extend preimage left
  309. preimage.extend(left);
  310. // Line 207: binary_extend preimage right
  311. preimage.extend(right);
  312. // Line 208: pedersen_hash cm preimage MERKLE_1
  313. let mut cm = pedersen_hash::pedersen_hash(
  314. cs.namespace(|| "Line 208: pedersen_hash cm preimage MERKLE_1"),
  315. pedersen_hash::Personalization::MerkleTree(1),
  316. &preimage,
  317. )?;
  318. // Line 210: ec_get_u current cm
  319. let mut current = cm.get_u().clone();
  320. // Line 214: alloc_scalar branch param:branch_2
  321. let branch = num::AllocatedNum::alloc(
  322. cs.namespace(|| "Line 214: alloc_scalar branch param:branch_2"),
  323. || Ok(*self.branch_2.get()?),
  324. )?;
  325. // Line 217: alloc_bit is_right param:is_right_2
  326. let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc(
  327. cs.namespace(|| "Line 217: alloc_bit is_right param:is_right_2"),
  328. self.is_right_2,
  329. )?);
  330. // Line 220: conditionally_reverse left right current branch is_right
  331. let (left, right) = num::AllocatedNum::conditionally_reverse(
  332. cs.namespace(|| "Line 220: conditionally_reverse left right current branch is_right"),
  333. &current,
  334. &branch,
  335. &is_right,
  336. )?;
  337. // Line 223: scalar_as_binary left left
  338. let left = left.to_bits_le(cs.namespace(|| "Line 223: scalar_as_binary left left"))?;
  339. // Line 224: scalar_as_binary right right
  340. let right = right.to_bits_le(cs.namespace(|| "Line 224: scalar_as_binary right right"))?;
  341. // Line 225: alloc_binary preimage
  342. let mut preimage = vec![];
  343. // Line 226: binary_extend preimage left
  344. preimage.extend(left);
  345. // Line 227: binary_extend preimage right
  346. preimage.extend(right);
  347. // Line 228: pedersen_hash cm preimage MERKLE_2
  348. let mut cm = pedersen_hash::pedersen_hash(
  349. cs.namespace(|| "Line 228: pedersen_hash cm preimage MERKLE_2"),
  350. pedersen_hash::Personalization::MerkleTree(2),
  351. &preimage,
  352. )?;
  353. // Line 230: ec_get_u current cm
  354. let mut current = cm.get_u().clone();
  355. // Line 234: alloc_scalar branch param:branch_3
  356. let branch = num::AllocatedNum::alloc(
  357. cs.namespace(|| "Line 234: alloc_scalar branch param:branch_3"),
  358. || Ok(*self.branch_3.get()?),
  359. )?;
  360. // Line 237: alloc_bit is_right param:is_right_3
  361. let is_right = boolean::Boolean::from(boolean::AllocatedBit::alloc(
  362. cs.namespace(|| "Line 237: alloc_bit is_right param:is_right_3"),
  363. self.is_right_3,
  364. )?);
  365. // Line 240: conditionally_reverse left right current branch is_right
  366. let (left, right) = num::AllocatedNum::conditionally_reverse(
  367. cs.namespace(|| "Line 240: conditionally_reverse left right current branch is_right"),
  368. &current,
  369. &branch,
  370. &is_right,
  371. )?;
  372. // Line 243: scalar_as_binary left left
  373. let left = left.to_bits_le(cs.namespace(|| "Line 243: scalar_as_binary left left"))?;
  374. // Line 244: scalar_as_binary right right
  375. let right = right.to_bits_le(cs.namespace(|| "Line 244: scalar_as_binary right right"))?;
  376. // Line 245: alloc_binary preimage
  377. let mut preimage = vec![];
  378. // Line 246: binary_extend preimage left
  379. preimage.extend(left);
  380. // Line 247: binary_extend preimage right
  381. preimage.extend(right);
  382. // Line 248: pedersen_hash cm preimage MERKLE_3
  383. let mut cm = pedersen_hash::pedersen_hash(
  384. cs.namespace(|| "Line 248: pedersen_hash cm preimage MERKLE_3"),
  385. pedersen_hash::Personalization::MerkleTree(3),
  386. &preimage,
  387. )?;
  388. // Line 250: ec_get_u current cm
  389. let mut current = cm.get_u().clone();
  390. */
  391. // Line 253: emit_scalar current
  392. current.inputize(cs.namespace(|| "Line 253: emit_scalar current"))?;
  393. let signature_secret = boolean::field_into_boolean_vec_le(
  394. cs.namespace(|| "Signature secret"),
  395. self.signature_secret,
  396. )?;
  397. let signature_public = ecc::fixed_base_multiplication(
  398. cs.namespace(|| "Signature public"),
  399. &zcash_proofs::constants::SPENDING_KEY_GENERATOR,
  400. &signature_secret,
  401. )?;
  402. signature_public.inputize(cs.namespace(|| "Signature public inputize"))?;
  403. Ok(())
  404. }
  405. }