zkvm.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #[macro_use]
  2. extern crate clap;
  3. use bls12_381::Scalar;
  4. use sapvi::{BlsStringConversion, Decodable, Encodable, ZKContract, ZKProof};
  5. use simplelog::*;
  6. use std::fs;
  7. use std::fs::File;
  8. use std::time::Instant;
  9. //use log::*;
  10. type Result<T> = std::result::Result<T, failure::Error>;
  11. // do the setup for mint.zcd, save the params in mint.setup
  12. fn trusted_setup(contract_data: String, setup_file: String) -> Result<()> {
  13. let start = Instant::now();
  14. let file = File::open("jubjub.zcd")?;
  15. let mut contract = ZKContract::decode(file)?;
  16. println!(
  17. "loaded contract '{}': [{:?}]",
  18. contract.name,
  19. start.elapsed()
  20. );
  21. println!("Stats:");
  22. println!(" Constants: {}", contract.vm.constants.len());
  23. println!(" Alloc: {}", contract.vm.alloc.len());
  24. println!(" Operations: {}", contract.vm.ops.len());
  25. println!(" Constraint Instructions: {}",
  26. contract.vm.constraints.len()
  27. );
  28. contract.setup("jubjub.zts")?;
  29. Ok(())
  30. }
  31. // make the proof
  32. fn create_proof(
  33. contract_data: String,
  34. setup_file: String,
  35. params: String,
  36. zk_proof: String,
  37. ) -> Result<()> {
  38. let start = Instant::now();
  39. let file = File::open("jubjub.zcd")?;
  40. let mut contract = ZKContract::decode(file)?;
  41. println!(
  42. "Loaded contract '{}': [{:?}]",
  43. contract.name,
  44. start.elapsed()
  45. );
  46. contract.load_setup("jubjub.zts")?;
  47. let param_content = fs::read_to_string(params).expect("something went wrong reading the file");
  48. let lines: Vec<&str> = param_content.lines().collect();
  49. for line in lines {
  50. let name = line.split_whitespace().next().unwrap_or("");
  51. let value = line.trim_start_matches(name).trim_left();
  52. contract.set_param(name, Scalar::from_string(value));
  53. }
  54. let proof = contract.prove()?;
  55. let mut file = File::create("jubjub.prf")?;
  56. proof.encode(&mut file)?;
  57. Ok(())
  58. }
  59. //verify the proof
  60. fn verify_proof(contract_data: String, setup_file: String, zk_proof: String) -> Result<()> {
  61. let start = Instant::now();
  62. let proof_file = File::open("jubjub.prf")?;
  63. let proof = ZKProof::decode(proof_file)?;
  64. let contract_file = File::open("jubjub.zcd")?;
  65. let mut contract = ZKContract::decode(contract_file)?;
  66. contract.load_setup("jubjub.zts")?;
  67. assert!(contract.verify(&proof));
  68. Ok(())
  69. }
  70. // show public values in proof
  71. fn show_public(zk_proof: String) -> Result<()> {
  72. let start = Instant::now();
  73. let file = File::open("jubjub.prf")?;
  74. let proof = ZKProof::decode(file)?;
  75. assert_eq!(proof.public.len(), 2);
  76. println!("Public values: {:?}", proof.public);
  77. Ok(())
  78. }
  79. fn main() -> Result<()> {
  80. let matches = clap_app!(zkvm =>
  81. (version: "0.1.0")
  82. (author: "Rose O'Leary <rrose@tuta.io>")
  83. (about: "Zero Knowledge Virtual Machine Command Line Interface")
  84. (@subcommand init =>
  85. (about: "Trusted setup phase")
  86. (@arg CONTRACT_DATA: +required "Input zero-knowledge contract data (.zcd)")
  87. (@arg SETUP_FILE: +required "Output setup parameters")
  88. )
  89. (@subcommand prove =>
  90. (about: "Create zero-knowledge proof")
  91. (@arg CONTRACT_DATA: +required "Input zero-knowledge contract data (.zcd)")
  92. (@arg SETUP_FILE: +required "Input setup parameters")
  93. (@arg PARAMS: +required "Input parameters json file")
  94. (@arg ZK_PROOF: +required "Output zero-knowledge proof")
  95. )
  96. (@subcommand verify =>
  97. (about: "Verify zero-knowledge proof")
  98. (@arg CONTRACT_DATA: +required "Input zero-knowledge contract data (.zcd)")
  99. (@arg SETUP_FILE: +required "Input setup parameters")
  100. (@arg ZK_PROOF: +required "Input zero-knowledge proof")
  101. )
  102. (@subcommand show =>
  103. (about: "Show public values in proof")
  104. (@arg ZK_PROOF: +required "Input zero-knowledge proof")
  105. )
  106. )
  107. .get_matches();
  108. CombinedLogger::init(vec![TermLogger::new(
  109. LevelFilter::Debug,
  110. Config::default(),
  111. TerminalMode::Mixed,
  112. )
  113. .unwrap()])
  114. .unwrap();
  115. match matches.subcommand() {
  116. Some(("init", matches)) => {
  117. let contract_data: String = matches.value_of("CONTRACT_DATA").unwrap().parse()?;
  118. let setup_file: String = matches.value_of("SETUP_FILE").unwrap().parse()?;
  119. trusted_setup(contract_data, setup_file);
  120. }
  121. Some(("prove", matches)) => {
  122. let contract_data: String = matches.value_of("CONTRACT_DATA").unwrap().parse()?;
  123. let setup_file: String = matches.value_of("SETUP_FILE").unwrap().parse()?;
  124. let params: String = matches.value_of("PARAMS").unwrap().parse()?;
  125. let zk_proof: String = matches.value_of("ZK_PROOF").unwrap().parse()?;
  126. create_proof(contract_data, setup_file, params, zk_proof);
  127. }
  128. Some(("verify", matches)) => {
  129. let contract_data: String = matches.value_of("CONTRACT_DATA").unwrap().parse()?;
  130. let setup_file: String = matches.value_of("SETUP_FILE").unwrap().parse()?;
  131. let zk_proof: String = matches.value_of("ZK_PROOF").unwrap().parse()?;
  132. verify_proof(contract_data, setup_file, zk_proof);
  133. }
  134. Some(("show", matches)) => {
  135. let zk_proof: String = matches.value_of("ZK_PROOF").unwrap().parse()?;
  136. show_public(zk_proof);
  137. }
  138. _ => {
  139. eprintln!("error: Invalid subcommand invoked");
  140. std::process::exit(-1);
  141. }
  142. }
  143. Ok(())
  144. }