spend_contract.rs 18 KB

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