ソースを参照

add tutorial example, corresponds to zk-explainer document

narodnik 5 年 前
コミット
83199007e1
2 ファイル変更139 行追加0 行削除
  1. 52 0
      proofs/tutorial.psm
  2. 87 0
      src/bin/tutorial.rs

+ 52 - 0
proofs/tutorial.psm

@@ -0,0 +1,52 @@
+constant one 0x0000000000000000000000000000000000000000000000000000000000000001
+
+contract tutorial_contract
+    param w
+    param a
+    param b
+
+    private m
+    set m a
+    mul m b
+
+    # ab = m
+    lc0_add a
+    lc1_add b
+    lc2_add m
+    enforce
+
+    # v = wab ...
+    public v
+    set v w
+    mul v a
+    mul v b
+
+    # v = wab + a + b ...
+    add v a
+    add v b
+
+    # v = wab + a + b - v'
+    # v' = w(a + b)
+    local vprime
+    set vprime a
+    add vprime b
+    mul vprime w
+    sub v vprime
+
+    # w(m - a - b) = v - a - b
+    lc0_add w
+    lc1_add m
+    lc1_sub a
+    lc1_sub b
+    lc2_add v
+    lc2_sub a
+    lc2_sub b
+    enforce
+
+    # Binary check that w^2 = w
+    lc0_add w
+    lc1_add w
+    lc2_add w
+    enforce
+end
+

+ 87 - 0
src/bin/tutorial.rs

@@ -0,0 +1,87 @@
+// This tutorial example corresponds to the VM proof in proofs/tutorial.psm
+// It encodes the same function as the one in zk-explainer document.
+use bls12_381::Scalar;
+use drk::{BlsStringConversion, Decodable, Encodable, ZKContract, ZKProof};
+use std::fs::File;
+use std::time::Instant;
+
+type Result<T> = std::result::Result<T, failure::Error>;
+
+fn main() -> Result<()> {
+    {
+        // Load the contract from file
+
+        let start = Instant::now();
+        let file = File::open("tutorial.zcd")?;
+        let mut contract = ZKContract::decode(file)?;
+        println!(
+            "Loaded contract '{}': [{:?}]",
+            contract.name,
+            start.elapsed()
+        );
+
+        println!("Stats:");
+        println!("    Constants: {}", contract.vm.constants.len());
+        println!("    Alloc: {}", contract.vm.alloc.len());
+        println!("    Operations: {}", contract.vm.ops.len());
+        println!(
+            "    Constraint Instructions: {}",
+            contract.vm.constraints.len()
+        );
+
+        // Do the trusted setup
+
+        contract.setup("tutorial.zts")?;
+    }
+
+    // Load the contract from file
+
+    let start = Instant::now();
+    let file = File::open("tutorial.zcd")?;
+    let mut contract = ZKContract::decode(file)?;
+    println!(
+        "Loaded contract '{}': [{:?}]",
+        contract.name,
+        start.elapsed()
+    );
+
+    contract.load_setup("tutorial.zts")?;
+
+    {
+        // Put in our input parameters
+
+        contract.set_param(
+            "w",
+            Scalar::from_string("0000000000000000000000000000000000000000000000000000000000000001"),
+        )?;
+        contract.set_param(
+            "a",
+            Scalar::from_string("0000000000000000000000000000000000000000000000000000000000000001"),
+        )?;
+        contract.set_param(
+            "b",
+            Scalar::from_string("0000000000000000000000000000000000000000000000000000000000000004"),
+        )?;
+
+        // Generate the ZK proof
+
+        let proof = contract.prove()?;
+
+        // Test and show our output values
+
+        assert_eq!(proof.public.len(), 1);
+        println!("v = {:?}", proof.public.get("v").unwrap());
+
+        let mut file = File::create("tutorial.prf")?;
+        proof.encode(&mut file)?;
+    }
+
+    // Verify the proof
+
+    let file = File::open("tutorial.prf")?;
+    let proof = ZKProof::decode(file)?;
+    assert!(contract.verify(&proof));
+
+    Ok(())
+}
+