add tutorial example, corresponds to zk-explainer document

This commit is contained in:
narodnik
2021-07-04 12:38:41 +02:00
parent f28ec92099
commit 83199007e1
2 changed files with 139 additions and 0 deletions

52
proofs/tutorial.psm Normal file
View File

@@ -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
src/bin/tutorial.rs Normal file
View File

@@ -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(())
}