forked from darkrenaissance/darkfi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
129 lines (112 loc) · 3.64 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use std::collections::{HashMap, HashSet};
use bellman::groth16;
use bls12_381::{Bls12, Scalar};
pub mod async_serial;
pub mod blockchain;
pub mod bls_extensions;
pub mod circuit;
pub mod cli;
pub mod client;
pub mod crypto;
pub mod endian;
pub mod error;
pub mod net;
pub mod rpc;
pub mod serial;
pub mod service;
pub mod state;
pub mod system;
pub mod tx;
pub mod util;
pub mod vm;
pub mod vm_serial;
pub mod wallet;
pub use crate::bls_extensions::BlsStringConversion;
pub use crate::error::{Error, Result};
pub use crate::net::p2p::P2p;
pub use crate::serial::{Decodable, Encodable};
pub use crate::vm::{
AllocType, ConstraintInstruction, CryptoOperation, VariableIndex, VariableRef,
ZkVirtualMachine, ZkVmCircuit,
};
pub type Bytes = Vec<u8>;
pub struct ZkContract {
pub name: String,
pub vm: ZkVirtualMachine,
params_map: HashMap<String, VariableIndex>,
pub params: HashMap<VariableIndex, Scalar>,
public_map: bimap::BiMap<String, VariableIndex>,
}
pub struct ZkProof {
pub public: HashMap<String, Scalar>,
pub proof: groth16::Proof<Bls12>,
}
impl ZkContract {
// Just have a load() and save()
// Load the contract, do the setup, save it...
pub fn setup(&mut self, filename: &str) -> Result<()> {
self.vm.setup()?;
let buffer = std::fs::File::create(filename)?;
self.vm.params.as_ref().unwrap().write(buffer)?;
Ok(())
}
pub fn load_setup(&mut self, filename: &str) -> Result<()> {
let buffer = std::fs::File::open(filename)?;
let setup = groth16::Parameters::<Bls12>::read(buffer, false)?;
let vk = groth16::prepare_verifying_key(&setup.vk);
self.vm.params = Some(setup);
self.vm.verifying_key = Some(vk);
Ok(())
}
pub fn param_names(&self) -> Vec<String> {
self.params_map.keys().cloned().collect()
}
pub fn set_param(&mut self, name: &str, value: Scalar) -> Result<()> {
match self.params_map.get(name) {
Some(index) => {
self.params.insert(*index, value);
Ok(())
}
None => Err(Error::InvalidParamName),
}
}
pub fn prove(&mut self) -> Result<ZkProof> {
// Error if params not all set
let user_params: HashSet<_> = self.params.keys().collect();
let req_params: HashSet<_> = self.params_map.values().collect();
if user_params != req_params {
return Err(Error::MissingParams);
}
// execute
let params = std::mem::take(&mut self.params);
self.vm.initialize(¶ms.into_iter().collect())?;
// prove
let proof = self.vm.prove();
let mut public = HashMap::new();
for (index, value) in self.vm.public() {
match self.public_map.get_by_right(&index) {
Some(name) => {
public.insert(name.clone(), value);
}
None => return Err(Error::BadContract),
}
}
// return proof and public values (Hashmap string -> scalars)
Ok(ZkProof { public, proof })
}
pub fn verify(&self, proof: &ZkProof) -> bool {
let mut public = vec![];
for (name, value) in &proof.public {
match self.public_map.get_by_left(name) {
Some(index) => {
public.push((index, *value));
}
None => return false,
}
}
public.sort_by(|a, b| a.0.partial_cmp(b.0).unwrap());
let (_, public): (Vec<VariableIndex>, Vec<Scalar>) = public.into_iter().unzip();
// Takes proof and public values
self.vm.verify(&proof.proof, &public)
}
}