Quellcode durchsuchen

proof: Add example for arithmetic operations.

parazyd vor 4 Jahren
Ursprung
Commit
b07bb4e2b0
4 geänderte Dateien mit 89 neuen und 1 gelöschten Zeilen
  1. 7 0
      Cargo.toml
  2. 2 1
      Makefile
  3. 66 0
      proof/arithmetic.rs
  4. 14 0
      proof/arithmetic.zk

+ 7 - 0
Cargo.toml

@@ -241,6 +241,13 @@ name = "tree"
 path = "example/tree.rs"
 required-features = ["crypto"]
 
+# ZK VM Proof examples
+
+[[example]]
+name = "arithmetic"
+path = "proof/arithmetic.rs"
+required-features = ["cli", "crypto", "zkas"]
+
 [[example]]
 name = "mint"
 path = "proof/mint.rs"

+ 2 - 1
Makefile

@@ -39,13 +39,14 @@ test: test-vm test-tx
 test-tx:
 	$(CARGO) run --release --features=node,zkas --example tx
 
-VM_SRC = proof/mint.zk proof/burn.zk
+VM_SRC = proof/arithmetic.zk proof/mint.zk proof/burn.zk
 VM_BIN = $(VM_SRC:=.bin)
 
 $(VM_BIN): zkas $(VM_SRC)
 	./zkas $(basename $@) -o $@
 
 test-vm: $(VM_BIN)
+	$(CARGO) run --release --features=cli,crypto,zkas --example arithmetic
 	$(CARGO) run --release --features=cli,crypto,zkas --example mint
 	$(CARGO) run --release --features=cli,crypto,zkas --example burn
 

+ 66 - 0
proof/arithmetic.rs

@@ -0,0 +1,66 @@
+use darkfi::{
+    crypto::{
+        proof::{ProvingKey, VerifyingKey},
+        Proof,
+    },
+    zk::vm::{Witness, ZkCircuit},
+    zkas::decoder::ZkBinary,
+    Result,
+};
+use log::info;
+use pasta_curves::pallas;
+use rand::rngs::OsRng;
+use simplelog::{ColorChoice::Auto, Config, LevelFilter, TermLogger, TerminalMode::Mixed};
+
+fn main() -> Result<()> {
+    let loglevel = match option_env!("RUST_LOG") {
+        Some("debug") => LevelFilter::Debug,
+        Some("trace") => LevelFilter::Trace,
+        Some(_) | None => LevelFilter::Info,
+    };
+    TermLogger::init(loglevel, Config::default(), Mixed, Auto)?;
+
+    /* ANCHOR: main */
+    let bincode = include_bytes!("arithmetic.zk.bin");
+    let zkbin = ZkBinary::decode(bincode)?;
+
+    // ======
+    // Prover
+    // ======
+
+    // Witness values
+    let a = pallas::Base::from(42);
+    let b = pallas::Base::from(69);
+
+    let prover_witnesses = vec![Witness::Base(Some(a)), Witness::Base(Some(b))];
+
+    // Create the public inputs
+    let sum = a + b;
+    let product = a * b;
+
+    let public_inputs = vec![sum, product];
+
+    // Create the circuit
+    let circuit = ZkCircuit::new(prover_witnesses, zkbin.clone());
+
+    info!(target: "PROVER", "Building proving key and creating the zero-knowledge proof");
+    let proving_key = ProvingKey::build(11, &circuit);
+    let proof = Proof::create(&proving_key, &[circuit], &public_inputs, &mut OsRng)?;
+
+    // ========
+    // Verifier
+    // ========
+
+    // Construct empty witnesses
+    let verifier_witnesses = vec![Witness::Base(None), Witness::Base(None)];
+
+    // Create the circuit
+    let circuit = ZkCircuit::new(verifier_witnesses, zkbin);
+
+    info!(target: "VERIFIER", "Building verifying key and verifying the zero-knowledge proof");
+    let verifying_key = VerifyingKey::build(11, &circuit);
+    proof.verify(&verifying_key, &public_inputs)?;
+    /* ANCHOR_END: main */
+
+    Ok(())
+}

+ 14 - 0
proof/arithmetic.zk

@@ -0,0 +1,14 @@
+constant "Arith" {}
+
+contract "Arith" {
+	Base a,
+	Base b,
+}
+
+circuit "Arith" {
+	sum = base_add(a, b);
+	constrain_instance(sum);
+
+	product = base_mul(a, b);
+	constrain_instance(product);
+}