mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
add tutorial example, corresponds to zk-explainer document
This commit is contained in:
52
proofs/tutorial.psm
Normal file
52
proofs/tutorial.psm
Normal 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
87
src/bin/tutorial.rs
Normal 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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user