Witness serialization and deserialization completed.
This commit is contained in:
parent
97e567431e
commit
8fc4d5609f
3 changed files with 120 additions and 14 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1,5 +1,5 @@
|
|||
[root]
|
||||
name = "ZoKrates"
|
||||
name = "zokrates"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
45
src/field.rs
45
src/field.rs
|
@ -1,10 +1,11 @@
|
|||
//
|
||||
// @file field.rs
|
||||
// @author Dennis Kuhnert <dennis.kuhnert@campus.tu-berlin.de>
|
||||
// @author Jacob Eberhardt <jacob.eberhardt@tu-berlin.de>
|
||||
// @date 2017
|
||||
|
||||
use num::{Integer, One, Zero};
|
||||
use num::bigint::{BigInt, BigUint, ToBigInt};
|
||||
use num::{Num, Integer, One, Zero};
|
||||
use num::bigint::{BigInt, BigUint, Sign, ToBigInt};
|
||||
use std::convert::From;
|
||||
use std::ops::{Add, Div, Mul, Sub};
|
||||
use std::fmt;
|
||||
|
@ -46,6 +47,12 @@ pub trait Field
|
|||
+ for<'a> Pow<&'a Self, Output = Self> {
|
||||
/// Returns this `Field`'s contents as little-endian byte vector
|
||||
fn into_byte_vector(&self) -> Vec<u8>;
|
||||
/// Returns an element of this `Field` from a little-endian byte vector
|
||||
fn from_byte_vector(Vec<u8>) -> Self;
|
||||
/// Returns this `Field`'s contents as decimal string
|
||||
fn to_dec_string(&self) -> String;
|
||||
/// Returns an element of this `Field` from a decimal string
|
||||
fn from_dec_string(val: String) -> Self;
|
||||
/// Returns the multiplicative inverse, i.e.: self * self.inverse_mul() = Self::one()
|
||||
fn inverse_mul(&self) -> Self;
|
||||
/// Returns the smallest value that can be represented by this field type.
|
||||
|
@ -63,17 +70,25 @@ pub struct FieldPrime {
|
|||
|
||||
impl Field for FieldPrime {
|
||||
fn into_byte_vector(&self) -> Vec<u8> {
|
||||
////for debugging
|
||||
//println!("uint dec: {}\n",self.value.to_biguint().unwrap().to_str_radix(10));
|
||||
//println!("uint bin: {}\n",self.value.to_biguint().unwrap().to_str_radix(2));
|
||||
//println!("uint bin length: {}\n",self.value.to_biguint().unwrap().to_str_radix(2).len());
|
||||
|
||||
match self.value.to_biguint() {
|
||||
Option::Some(val) => val.to_bytes_le(),
|
||||
Option::None => panic!("Should never happen."),
|
||||
}
|
||||
}
|
||||
|
||||
fn from_byte_vector(bytes: Vec<u8>) -> Self {
|
||||
let uval = BigUint::from_bytes_le(bytes.as_slice());
|
||||
FieldPrime{value: BigInt::from_biguint(Sign::Plus, uval)}
|
||||
}
|
||||
|
||||
fn to_dec_string(&self) -> String {
|
||||
self.value.to_str_radix(10)
|
||||
}
|
||||
|
||||
fn from_dec_string(val: String) -> Self {
|
||||
FieldPrime{value: BigInt::from_str_radix(val.as_str(), 10).unwrap()}
|
||||
}
|
||||
|
||||
fn inverse_mul(&self) -> FieldPrime {
|
||||
let (b, s, _) = extended_euclid(&self.value, &*P);
|
||||
assert_eq!(b, BigInt::one());
|
||||
|
@ -593,11 +608,25 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn ser_deser() {
|
||||
fn serde_ser_deser() {
|
||||
let serialized = &serialize(&FieldPrime::from("11"), Infinite).unwrap();
|
||||
let deserialized = deserialize(serialized).unwrap();
|
||||
assert_eq!(FieldPrime::from("11"), deserialized);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn bytes_ser_deser() {
|
||||
let fp = FieldPrime::from("101");
|
||||
let bv = fp.into_byte_vector();
|
||||
assert_eq!(fp, FieldPrime::from_byte_vector(bv));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn dec_string_ser_deser() {
|
||||
let fp = FieldPrime::from("101");
|
||||
let bv = fp.to_dec_string();
|
||||
assert_eq!(fp, FieldPrime::from_dec_string(bv));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
87
src/main.rs
87
src/main.rs
|
@ -25,7 +25,8 @@ mod libsnark;
|
|||
|
||||
use std::fs::File;
|
||||
use std::path::Path;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::io::{BufWriter, Write, BufReader, BufRead};
|
||||
use std::collections::HashMap;
|
||||
use field::{Field, FieldPrime};
|
||||
use absy::Prog;
|
||||
use parser::parse_program;
|
||||
|
@ -287,6 +288,7 @@ fn main() {
|
|||
}
|
||||
|
||||
let witness_map = main_flattened.get_witness(args);
|
||||
// let witness_map: HashMap<String, FieldPrime> = main_flattened.get_witness(args);
|
||||
println!("Witness: {:?}", witness_map);
|
||||
match witness_map.get("~out") {
|
||||
Some(out) => println!("Returned (~out): {}", out),
|
||||
|
@ -300,12 +302,63 @@ fn main() {
|
|||
Err(why) => panic!("couldn't create {}: {}", output_path.display(), why),
|
||||
};
|
||||
let mut bw = BufWriter::new(output_file);
|
||||
write!(&mut bw, "{:?}\n", witness_map).expect("Unable to write data to file.");
|
||||
for (var, val) in &witness_map {
|
||||
// TODO: Serialize PrimeField Elements
|
||||
println!("{}:{:?}",var, val.to_dec_string());
|
||||
write!(&mut bw, "{} {}\n", var, val.to_dec_string()).expect("Unable to write data to file.");
|
||||
//write!(&mut bw, "{} {}\n", var, String::from_utf8(val.into_byte_vector()).unwrap()).expect("Unable to write data to file.");
|
||||
}
|
||||
|
||||
bw.flush().expect("Unable to flush buffer.");
|
||||
|
||||
}
|
||||
("shortcut", Some(sub_matches)) => {
|
||||
("setup", Some(sub_matches)) => {
|
||||
println!("Performing setup...");
|
||||
|
||||
let path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let mut file = match File::open(&path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", path.display(), why),
|
||||
};
|
||||
|
||||
let program_ast: Prog<FieldPrime> = match deserialize_from(&mut file, Infinite) {
|
||||
Ok(x) => x,
|
||||
Err(why) => {
|
||||
println!("{:?}", why);
|
||||
std::process::exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
// make sure the input program is actually flattened.
|
||||
let main_flattened = program_ast
|
||||
.functions
|
||||
.iter()
|
||||
.find(|x| x.id == "main")
|
||||
.unwrap();
|
||||
for stat in main_flattened.statements.clone() {
|
||||
assert!(
|
||||
stat.is_flattened(),
|
||||
format!("Input conditions not flattened: {}", &stat)
|
||||
);
|
||||
}
|
||||
|
||||
// print deserialized flattened program
|
||||
println!("{}", main_flattened);
|
||||
|
||||
let (variables, a, b, c) = r1cs_program(&program_ast);
|
||||
|
||||
// TODO: Setup Operation
|
||||
|
||||
// run libsnark
|
||||
// #[cfg(not(feature="nolibsnark"))]{
|
||||
// // number of inputs in the zkSNARK sense, i.e., input variables + output variables
|
||||
// let num_inputs = main_flattened.arguments.len() + 1; //currently exactly one output variable
|
||||
// println!("run_libsnark = {:?}", run_libsnark(variables, a, b, c, witness, num_inputs));
|
||||
// }
|
||||
|
||||
}
|
||||
("shortcut", Some(sub_matches)) => {
|
||||
println!("Performing Setup, Witness Generation and Export...");
|
||||
// read compiled program
|
||||
let path = Path::new(sub_matches.value_of("input").unwrap());
|
||||
let mut file = match File::open(&path) {
|
||||
|
@ -376,9 +429,33 @@ fn main() {
|
|||
println!("Exporting verifier...");
|
||||
//TODO
|
||||
}
|
||||
("generate-proof", Some(_)) => {
|
||||
("generate-proof", Some(sub_matches)) => {
|
||||
println!("Generating proof...");
|
||||
//TODO
|
||||
|
||||
// deserialize witness
|
||||
let witness_path = Path::new(sub_matches.value_of("witness").unwrap());
|
||||
let mut witness_file = match File::open(&witness_path) {
|
||||
Ok(file) => file,
|
||||
Err(why) => panic!("couldn't open {}: {}", witness_path.display(), why),
|
||||
};
|
||||
|
||||
let reader = BufReader::new(witness_file);
|
||||
let mut lines = reader.lines();
|
||||
let mut witness_map = HashMap::new();
|
||||
|
||||
loop {
|
||||
match lines.next() {
|
||||
Some(Ok(ref x)) => {
|
||||
let pairs: Vec<&str> = x.split_whitespace().collect();
|
||||
witness_map.insert(pairs[0].to_string(),FieldPrime::from_dec_string(pairs[1].to_string()));
|
||||
},
|
||||
None => break,
|
||||
Some(Err(err)) => panic!("Error reading witness: {}", err),
|
||||
}
|
||||
}
|
||||
|
||||
println!("Witness: {:?}", witness_map);
|
||||
|
||||
}
|
||||
("deploy-verifier", Some(_)) => {
|
||||
println!("Deploying verifier...");
|
||||
|
|
Loading…
Reference in a new issue