1#[cfg(feature = "tinyjson")]
20use {
21 super::halo2::Value,
22 darkfi_sdk::crypto::{pasta_prelude::*, util::FieldElemAsStr, MerkleNode},
23 std::{
24 collections::HashMap,
25 fs::File,
26 io::{Read, Write},
27 path::Path,
28 },
29 tinyjson::JsonValue::{
30 self, Array as JsonArray, Number as JsonNum, Object as JsonObj, String as JsonStr,
31 },
32};
33
34use darkfi_sdk::pasta::pallas;
35use tracing::error;
36
37use super::{Witness, ZkCircuit};
38use crate::{zkas, Error, Result};
39
40#[cfg(feature = "tinyjson")]
41pub fn export_witness_json<P: AsRef<Path>>(
44 output_path: P,
45 prover_witnesses: &Vec<Witness>,
46 public_inputs: &Vec<pallas::Base>,
47) {
48 let mut witnesses = Vec::new();
49 for witness in prover_witnesses {
50 let mut value_json = HashMap::new();
51 match witness {
52 Witness::Base(value) => {
53 value.map(|w| {
54 value_json.insert("Base".to_string(), JsonStr(w.to_string()));
55 w
56 });
57 }
58 Witness::Scalar(value) => {
59 value.map(|w| {
60 value_json.insert("Scalar".to_string(), JsonStr(w.to_string()));
61 w
62 });
63 }
64 Witness::Uint32(value) => {
65 value.map(|w| {
66 value_json.insert("Uint32".to_string(), JsonNum(w.into()));
67 w
68 });
69 }
70 Witness::MerklePath(value) => {
71 let mut path = Vec::new();
72 value.map(|w| {
73 for node in w {
74 path.push(JsonStr(node.inner().to_string()));
75 }
76 w
77 });
78 value_json.insert("MerklePath".to_string(), JsonArray(path));
79 }
80 Witness::SparseMerklePath(value) => {
81 let mut path = Vec::new();
82 value.map(|w| {
83 for node in w {
84 path.push(JsonStr(node.to_string()));
85 }
86 w
87 });
88 value_json.insert("SparseMerklePath".to_string(), JsonArray(path));
89 }
90 Witness::EcNiPoint(value) => {
91 let (mut x, mut y) = (pallas::Base::ZERO, pallas::Base::ZERO);
92 value.map(|w| {
93 let coords = w.to_affine().coordinates().unwrap();
94 (x, y) = (*coords.x(), *coords.y());
95 w
96 });
97 let coords = vec![JsonStr(x.to_string()), JsonStr(y.to_string())];
98 value_json.insert("EcNiPoint".to_string(), JsonArray(coords));
99 }
100 _ => unimplemented!(),
101 }
102 witnesses.push(JsonObj(value_json));
103 }
104
105 let mut instances = Vec::new();
106 for instance in public_inputs {
107 instances.push(JsonStr(instance.to_string()));
108 }
109
110 let witnesses_json = JsonArray(witnesses);
111 let instances_json = JsonArray(instances);
112 let witness_json = JsonObj(HashMap::from([
113 ("witnesses".to_string(), witnesses_json),
114 ("instances".to_string(), instances_json),
115 ]));
116 let json = witness_json.format().expect("cannot create debug json");
118 let mut output = File::create(output_path).expect("cannot write file");
119 output.write_all(json.as_bytes()).expect("write failed");
120}
121
122#[cfg(feature = "tinyjson")]
123pub fn import_witness_json<P: AsRef<Path>>(input_path: P) -> (Vec<Witness>, Vec<pallas::Base>) {
126 let mut input = File::open(input_path).expect("could not open input file");
127 let mut json_str = String::new();
128 input.read_to_string(&mut json_str).expect("unable to read to string");
129 let json: JsonValue = json_str.parse().unwrap();
130 drop(input);
131 drop(json_str);
132
133 let root: &HashMap<_, _> = json.get().expect("root");
134 let json_witness: &Vec<_> = root["witnesses"].get().expect("witnesses");
135
136 let jval_as_fp = |j_val: &JsonValue| {
137 let valstr: &String = j_val.get().expect("value str");
138 pallas::Base::from_str(valstr).unwrap()
139 };
140
141 let jval_as_vecfp = |j_val: &JsonValue| {
142 j_val
143 .get::<Vec<_>>()
144 .expect("value str")
145 .iter()
146 .map(jval_as_fp)
147 .collect::<Vec<pallas::Base>>()
148 };
149
150 let mut witnesses = Vec::new();
151 for j_witness in json_witness {
152 let item: &HashMap<_, _> = j_witness.get().expect("root");
153 assert_eq!(item.len(), 1);
154 let (typename, j_val) = item.iter().next().expect("witness has single item");
155 match typename.as_str() {
156 "Base" => {
157 let fp = jval_as_fp(j_val);
158 witnesses.push(Witness::Base(Value::known(fp)));
159 }
160 "Scalar" => {
161 let valstr: &String = j_val.get().expect("value str");
162 let fq = pallas::Scalar::from_str(valstr).unwrap();
163 witnesses.push(Witness::Scalar(Value::known(fq)));
164 }
165 "Uint32" => {
166 let val: &f64 = j_val.get().expect("value str");
167 witnesses.push(Witness::Uint32(Value::known(*val as u32)));
168 }
169 "MerklePath" => {
170 let vals: Vec<_> = jval_as_vecfp(j_val).into_iter().map(MerkleNode::new).collect();
171 assert_eq!(vals.len(), 32);
172 let vals: [MerkleNode; 32] = vals.try_into().unwrap();
173 witnesses.push(Witness::MerklePath(Value::known(vals)));
174 }
175 "SparseMerklePath" => {
176 let vals = jval_as_vecfp(j_val);
177 assert_eq!(vals.len(), 255);
178 let vals: [pallas::Base; 255] = vals.try_into().unwrap();
179 witnesses.push(Witness::SparseMerklePath(Value::known(vals)));
180 }
181 "EcNiPoint" => {
182 let vals = jval_as_vecfp(j_val);
183 assert_eq!(vals.len(), 2);
184 let (x, y) = (vals[0], vals[1]);
185 let point: pallas::Point = pallas::Affine::from_xy(x, y).unwrap().to_curve();
186 witnesses.push(Witness::EcNiPoint(Value::known(point)));
187 }
188 _ => unimplemented!(),
189 }
190 }
191
192 let instances = jval_as_vecfp(&root["instances"]);
193
194 (witnesses, instances)
195}
196
197pub fn zkas_type_checks(
200 circuit: &ZkCircuit,
201 binary: &zkas::ZkBinary,
202 instances: &[pallas::Base],
203) -> Result<()> {
204 if circuit.witnesses.len() != binary.witnesses.len() {
205 error!(
206 "Wrong number of witnesses. Should be {}, but instead got {}.",
207 binary.witnesses.len(),
208 circuit.witnesses.len()
209 );
210 return Err(Error::WrongWitnessesCount)
211 }
212
213 for (i, (circuit_witness, binary_witness)) in
214 circuit.witnesses.iter().zip(binary.witnesses.iter()).enumerate()
215 {
216 let is_pass = match circuit_witness {
217 Witness::EcPoint(_) => *binary_witness == zkas::VarType::EcPoint,
218 Witness::EcNiPoint(_) => *binary_witness == zkas::VarType::EcNiPoint,
219 Witness::EcFixedPoint(_) => *binary_witness == zkas::VarType::EcFixedPoint,
220 Witness::Base(_) => *binary_witness == zkas::VarType::Base,
221 Witness::Scalar(_) => *binary_witness == zkas::VarType::Scalar,
222 Witness::MerklePath(_) => *binary_witness == zkas::VarType::MerklePath,
223 Witness::SparseMerklePath(_) => *binary_witness == zkas::VarType::SparseMerklePath,
224 Witness::Uint32(_) => *binary_witness == zkas::VarType::Uint32,
225 Witness::Uint64(_) => *binary_witness == zkas::VarType::Uint64,
226 };
227 if !is_pass {
228 error!(
229 "Wrong witness type at index {}. Expected '{}', but instead got '{}'.",
230 i,
231 binary_witness.name(),
232 circuit_witness.name()
233 );
234 return Err(Error::WrongWitnessType(i))
235 }
236 }
237
238 let mut instances_count = 0;
240 for opcode in &circuit.opcodes {
241 if let (zkas::Opcode::ConstrainInstance, _) = opcode {
242 instances_count += 1;
243 }
244 }
245 if instances.len() != instances_count {
246 error!(
247 "Wrong number of public inputs. Should be {}, but instead got {}.",
248 instances_count,
249 instances.len()
250 );
251 return Err(Error::WrongPublicInputsCount)
252 }
253 Ok(())
254}