main.rs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2026 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{
  19. fs::{read_dir, File},
  20. io::{Read, Write},
  21. path::Path,
  22. };
  23. use darkfi::{
  24. zk::{empty_witnesses, Proof, ProvingKey, VerifyingKey, Witness, ZkCircuit},
  25. zkas::ZkBinary,
  26. };
  27. use darkfi_sdk::pasta::{pallas::Base, Eq, Fp};
  28. use darkfi_serial::serialize;
  29. use halo2_proofs::dev::CircuitCost;
  30. use rand::rngs::OsRng;
  31. /// Dao contract zk proofs witness and public input generator.
  32. mod dao;
  33. /// Money contract zk proofs witness and public input generator.
  34. mod money;
  35. /// Opcode zk proofs witness and public input generator.
  36. mod opcodes;
  37. fn main() {
  38. // Read all src/*/proof directories contents
  39. let mut zk_bin_files = vec![];
  40. for entry in read_dir("src").unwrap() {
  41. let path = entry.unwrap().path();
  42. if !path.is_dir() {
  43. continue;
  44. }
  45. let path = path.join("proof");
  46. if path.exists() && path.is_dir() {
  47. read_dir(path).unwrap().flatten().for_each(|e| {
  48. let zk_path = e.path();
  49. if zk_path.is_file() && zk_path.to_str().unwrap().ends_with(".zk.bin") {
  50. zk_bin_files.push(zk_path)
  51. }
  52. })
  53. }
  54. }
  55. // Read each compiled zk file bin
  56. for path in zk_bin_files {
  57. let base_dir = path.parent().unwrap().to_str().unwrap();
  58. let name = path.file_name().unwrap().to_str().unwrap().split(".").next().unwrap();
  59. let proof_file = format!("{base_dir}/{name}.proof.bin");
  60. let vk_file = format!("{base_dir}/{name}.vks.bin");
  61. let public_inputs_file = format!("{base_dir}/{name}.pi.bin");
  62. // Skip if already generated
  63. if Path::new(&proof_file).exists() &&
  64. Path::new(&vk_file).exists() &&
  65. Path::new(&public_inputs_file).exists()
  66. {
  67. println!("{name} is already generated");
  68. continue;
  69. }
  70. println!("Generating {name}....");
  71. // Open zk bin
  72. let mut file = File::open(&path).unwrap();
  73. let mut buf = vec![];
  74. file.read_to_end(&mut buf).unwrap();
  75. let zkbin = ZkBinary::decode(&buf, false).unwrap();
  76. // Get witnesses and public inputs for that particular zk file
  77. let (witnesses, public_inputs) = retrieve_proof_inputs(name);
  78. // Generate and save Proof
  79. let circuit = ZkCircuit::new(witnesses, &zkbin);
  80. let proving_key = ProvingKey::build(zkbin.k, &circuit);
  81. let proof = Proof::create(&proving_key, &[circuit], &public_inputs, &mut OsRng).unwrap();
  82. let proof_export = serialize(&proof);
  83. let mut f = File::create(&proof_file).unwrap();
  84. f.write_all(&proof_export).unwrap();
  85. // Generate and save Verifying Key
  86. let verifier_witnesses = empty_witnesses(&zkbin).unwrap();
  87. let circuit = ZkCircuit::new(verifier_witnesses, &zkbin);
  88. let verifying_key = VerifyingKey::build(zkbin.k, &circuit);
  89. let mut vk_export = vec![];
  90. verifying_key.write(&mut vk_export).unwrap();
  91. let mut f = File::create(&vk_file).unwrap();
  92. f.write_all(&vk_export).unwrap();
  93. // Save Public inputs
  94. let public_inputs_export = serialize(&public_inputs);
  95. let mut f = File::create(&public_inputs_file).unwrap();
  96. f.write_all(&public_inputs_export).unwrap();
  97. // Show circuit cost
  98. let circuit_cost = CircuitCost::<Eq, ZkCircuit>::measure(zkbin.k, &circuit);
  99. println!("{:#?}", circuit_cost);
  100. }
  101. }
  102. fn retrieve_proof_inputs(name: &str) -> (Vec<Witness>, Vec<Base>) {
  103. match name {
  104. "sparse_merkle_root" => opcodes::sparse_merkle_root(),
  105. "merkle_root" => opcodes::merkle_root(),
  106. "base_add" => opcodes::base_add(),
  107. "base_mul" => opcodes::base_mul(),
  108. "base_sub" => opcodes::base_sub(),
  109. "ec_add" => opcodes::ec_add(),
  110. "ec_mul" => opcodes::ec_mul(),
  111. "ec_mul_base" => opcodes::ec_mul_base(),
  112. "ec_mul_short" => opcodes::ec_mul_short(),
  113. "ec_mul_var_base" => opcodes::ec_mul_var_base(),
  114. "ec_get_x" => opcodes::ec_get_x(),
  115. "ec_get_y" => opcodes::ec_get_y(),
  116. "poseidon_hash" => opcodes::poseidon_hash_opcode(),
  117. "constrain_instance" => opcodes::constrain_instance(),
  118. "witness_base" => (vec![], vec![Fp::from(2)]),
  119. "constrain_equal_base" => opcodes::constrain_equal_base(),
  120. "constrain_equal_point" => opcodes::constrain_equal_point(),
  121. "less_than_strict" => opcodes::less_than_strict(),
  122. "less_than_loose" => opcodes::less_than_loose(),
  123. "bool_check" => opcodes::bool_check(),
  124. "cond_select" => opcodes::cond_select(),
  125. "zero_cond" => opcodes::zero_cond(),
  126. "range_check" => opcodes::range_check(),
  127. "debug" => opcodes::debug(),
  128. "money_mint_v1" => money::mint_v1(),
  129. "money_burn_v1" => money::burn_v1(),
  130. "money_fee_v1" => money::fee_v1(),
  131. "money_token_mint_v1" => money::token_mint_v1(),
  132. "money_auth_token_mint_v1" => money::auth_token_mint_v1(),
  133. "dao_mint" => dao::mint(),
  134. "dao_propose_input" => dao::propose_input(),
  135. "dao_propose_main" => dao::propose_main(),
  136. "dao_vote_input" => dao::vote_input(),
  137. "dao_vote_main" => dao::vote_main(),
  138. "dao_exec" => dao::exec(),
  139. "dao_early_exec" => dao::early_exec(),
  140. "dao_auth_money_transfer" => dao::auth_money_transfer(),
  141. "dao_auth_money_transfer_enc_coin" => dao::auth_money_transfer_enc_coin(),
  142. _ => panic!("unsupported Zk script"),
  143. }
  144. }