Removed run_libsnark and shortcut cli operation. Some output cleanup.
This commit is contained in:
parent
954b5ddeee
commit
0925def13a
5 changed files with 9 additions and 270 deletions
|
@ -90,7 +90,7 @@ r1cs_ppzksnark_constraint_system<alt_bn128_pp> createConstraintSystem(const uint
|
|||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(A+row*variables*32 + idx*32);
|
||||
// cout << "C entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "A(" << idx << ", " << value << ")" << endl;
|
||||
// cout << "A(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_A.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ r1cs_ppzksnark_constraint_system<alt_bn128_pp> createConstraintSystem(const uint
|
|||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(B+row*variables*32 + idx*32);
|
||||
// cout << "B entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "B(" << idx << ", " << value << ")" << endl;
|
||||
// cout << "B(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_B.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ r1cs_ppzksnark_constraint_system<alt_bn128_pp> createConstraintSystem(const uint
|
|||
libsnark::bigint<libsnark::alt_bn128_r_limbs> value = libsnarkBigintFromBytes(C+row*variables*32 + idx*32);
|
||||
// cout << "C entry " << idx << " in row " << row << ": " << value << endl;
|
||||
if (!value.is_zero()) {
|
||||
cout << "C(" << idx << ", " << value << ")" << endl;
|
||||
// cout << "C(" << idx << ", " << value << ")" << endl;
|
||||
lin_comb_C.add_term(idx, value);
|
||||
}
|
||||
}
|
||||
|
@ -300,72 +300,3 @@ bool _generate_proof(const char* pk_path, const uint8_t* public_inputs, int publ
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool _run_libsnark(const uint8_t* A, const uint8_t* B, const uint8_t* C, const uint8_t* witness, int constraints, int variables, int inputs)
|
||||
{
|
||||
|
||||
libsnark::inhibit_profiling_info = true;
|
||||
libsnark::inhibit_profiling_counters = true;
|
||||
|
||||
//initialize curve parameters
|
||||
alt_bn128_pp::init_public_params();
|
||||
|
||||
// for testing of serialization only. remove later.
|
||||
// string decString = "123456789123456789123456789";
|
||||
// string hexString = "0x661efdf2e3b19f7c045f15";
|
||||
// libsnark::bigint<libsnark::alt_bn128_r_limbs> value = bigint<libsnark::alt_bn128_r_limbs>(decString.c_str());
|
||||
//
|
||||
// cout << "expected: " << hexString << endl;
|
||||
// cout << "computed: " << "0x"+HexStringFromLibsnarkBigint(value) <<endl;
|
||||
// assert("0x"+HexStringFromLibsnarkBigint(value) == hexString);
|
||||
|
||||
// Setup:
|
||||
// create constraint system
|
||||
r1cs_constraint_system<Fr<alt_bn128_pp>> cs;
|
||||
cs = createConstraintSystem(A, B ,C , constraints, variables, inputs);
|
||||
|
||||
// assign variables based on witness values, excludes ~one
|
||||
r1cs_variable_assignment<Fr<alt_bn128_pp> > full_variable_assignment;
|
||||
for (int i = 1; i < variables; i++) {
|
||||
// for debugging
|
||||
cout << "witness_hex ["<< i << "]: " << HexStringFromLibsnarkBigint(libsnarkBigintFromBytes(witness + i*32)) << endl;
|
||||
cout << "fieldElement ["<< i << "]: " << HexStringFromLibsnarkBigint((Fr<alt_bn128_pp>(libsnarkBigintFromBytes(witness + i*32))).as_bigint()) << endl;
|
||||
full_variable_assignment.push_back(Fr<alt_bn128_pp>(libsnarkBigintFromBytes(witness + i*32)));
|
||||
}
|
||||
|
||||
// split up variables into primary and auxiliary inputs. Does *NOT* include the constant 1 */
|
||||
// Output variables belong to primary input, helper variables are auxiliary input.
|
||||
r1cs_primary_input<Fr<alt_bn128_pp>> primary_input(full_variable_assignment.begin(), full_variable_assignment.begin() + inputs-1);
|
||||
r1cs_primary_input<Fr<alt_bn128_pp>> auxiliary_input(full_variable_assignment.begin() + inputs-1, full_variable_assignment.end());
|
||||
|
||||
// for debugging
|
||||
cout << "full variable assignment :"<< endl << full_variable_assignment;
|
||||
|
||||
// sanity checks
|
||||
assert(cs.num_variables() == full_variable_assignment.size());
|
||||
assert(cs.num_variables() >= inputs);
|
||||
assert(cs.num_inputs() == inputs);
|
||||
assert(cs.num_constraints() == constraints);
|
||||
assert(cs.is_satisfied(primary_input, auxiliary_input));
|
||||
|
||||
// create keypair
|
||||
r1cs_ppzksnark_keypair<alt_bn128_pp> keypair = r1cs_ppzksnark_generator<alt_bn128_pp>(cs);
|
||||
|
||||
// Print VerificationKey in Solidity compatible format
|
||||
exportVerificationKey(keypair);
|
||||
|
||||
// print primary input
|
||||
exportInput(primary_input);
|
||||
|
||||
// Proof Generation
|
||||
r1cs_ppzksnark_proof<alt_bn128_pp> proof = r1cs_ppzksnark_prover<alt_bn128_pp>(keypair.pk, primary_input, auxiliary_input);
|
||||
|
||||
// print proof
|
||||
printProof(proof);
|
||||
|
||||
// Verification
|
||||
bool result = r1cs_ppzksnark_verifier_strong_IC<alt_bn128_pp>(keypair.vk, primary_input, proof);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -29,15 +29,6 @@ bool _generate_proof(const char* pk_path,
|
|||
int private_inputs_length
|
||||
);
|
||||
|
||||
// entrypoint, wraps the whole process, probably should be removed later
|
||||
bool _run_libsnark(const uint8_t* A,
|
||||
const uint8_t* B,
|
||||
const uint8_t* C,
|
||||
const uint8_t* witness,
|
||||
int constraints,
|
||||
int variables,
|
||||
int inputs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
@ -443,8 +443,6 @@ impl Flattener {
|
|||
}
|
||||
}
|
||||
}
|
||||
println!("Param Expressions Flattened: {:?}", params_flattened);
|
||||
|
||||
|
||||
for funct in functions_flattened {
|
||||
if funct.id == *id && funct.arguments.len() == (*param_expressions).len() {
|
||||
|
@ -457,10 +455,6 @@ impl Flattener {
|
|||
// and the substitution needs to be added to replacement map.
|
||||
let mut replacement_map: HashMap<String, String> = HashMap::new();
|
||||
|
||||
println!("used variables: {:?}", used_vars);
|
||||
|
||||
println!("Called Function's Arguments: {:?}", funct.arguments);
|
||||
println!("Calling Function's Arguments: {:?}", params_flattened);
|
||||
for (i, _) in params_flattened.iter().enumerate() {
|
||||
let identifier_call: String =
|
||||
params_flattened.get(i).unwrap().id.clone();
|
||||
|
@ -470,8 +464,6 @@ impl Flattener {
|
|||
replacement_map.insert(identifier_called, identifier_call);
|
||||
}
|
||||
}
|
||||
println!("Param substitutions: {:?}", replacement_map);
|
||||
|
||||
|
||||
// add all flattened statements, adapt return statement
|
||||
for stat in funct.statements.clone() {
|
||||
|
@ -562,7 +554,6 @@ impl Flattener {
|
|||
if !(var == var_to_replace) && self.variables.contains(&var_to_replace) && !self.substitution.contains_key(&var_to_replace){
|
||||
self.substitution.insert(var_to_replace.clone().to_string(),var.clone());
|
||||
}
|
||||
println!("substitution: {:?}",self.substitution);
|
||||
statements_flattened.push(Statement::Definition(var, rhs));
|
||||
}
|
||||
Statement::Condition(ref expr1, ref expr2) => {
|
||||
|
|
|
@ -37,17 +37,6 @@ extern "C" {
|
|||
private_inputs: *const uint8_t,
|
||||
private_inputs_length: c_int,
|
||||
) -> bool;
|
||||
|
||||
fn _run_libsnark(
|
||||
A: *const uint8_t,
|
||||
B: *const uint8_t,
|
||||
C: *const uint8_t,
|
||||
witness: *const uint8_t,
|
||||
constraints: c_int,
|
||||
variables: c_int,
|
||||
inputs: c_int,
|
||||
) -> bool;
|
||||
|
||||
}
|
||||
|
||||
pub fn setup<T: Field> (
|
||||
|
@ -132,62 +121,6 @@ pub fn generate_proof<T: Field>(
|
|||
}
|
||||
}
|
||||
|
||||
// assumes that field elements can be represented with 32 bytes
|
||||
pub fn run_libsnark<T: Field>(
|
||||
variables: Vec<String>,
|
||||
a: Vec<Vec<(usize, T)>>,
|
||||
b: Vec<Vec<(usize, T)>>,
|
||||
c: Vec<Vec<(usize, T)>>,
|
||||
witness: Vec<T>,
|
||||
num_inputs: usize,
|
||||
) -> bool {
|
||||
|
||||
let num_constraints = a.len();
|
||||
let num_variables = variables.len();
|
||||
|
||||
//initialize matrix entries with 0s.
|
||||
let mut a_arr: Vec<[u8; 32]> = vec![[0u8; 32]; num_constraints * num_variables];
|
||||
let mut b_arr: Vec<[u8; 32]> = vec![[0u8; 32]; num_constraints * num_variables];
|
||||
let mut c_arr: Vec<[u8; 32]> = vec![[0u8; 32]; num_constraints * num_variables];
|
||||
let mut w_arr: Vec<[u8; 32]> = vec![[0u8; 32]; num_variables];
|
||||
|
||||
for row in 0..num_constraints {
|
||||
for &(idx, ref val) in &a[row] {
|
||||
a_arr[row * num_variables + idx] = vec_as_u8_32_array(&val.into_byte_vector());
|
||||
}
|
||||
for &(idx, ref val) in &b[row] {
|
||||
b_arr[row * num_variables + idx] = vec_as_u8_32_array(&val.into_byte_vector());
|
||||
}
|
||||
for &(idx, ref val) in &c[row] {
|
||||
c_arr[row * num_variables + idx] = vec_as_u8_32_array(&val.into_byte_vector());
|
||||
}
|
||||
}
|
||||
|
||||
//convert witness
|
||||
for (index, value) in witness.into_iter().enumerate() {
|
||||
w_arr[index] = vec_as_u8_32_array(&value.into_byte_vector());
|
||||
}
|
||||
|
||||
//debugging output
|
||||
//println!("debugging output:");
|
||||
//println!("a_arr {:?}", a_arr);
|
||||
//println!("b_arr {:?}", b_arr);
|
||||
//println!("c_arr {:?}", c_arr);
|
||||
//println!("w_arr {:?}", w_arr);
|
||||
|
||||
unsafe {
|
||||
_run_libsnark(
|
||||
a_arr[0].as_ptr(),
|
||||
b_arr[0].as_ptr(),
|
||||
c_arr[0].as_ptr(),
|
||||
w_arr[0].as_ptr(),
|
||||
num_constraints as i32,
|
||||
num_variables as i32,
|
||||
num_inputs as i32,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// utility function. Converts a Fields vector-based byte representation to fixed size array.
|
||||
fn vec_as_u8_32_array(vec: &Vec<u8>) -> [u8; 32] {
|
||||
assert!(vec.len() <= 32);
|
||||
|
|
119
src/main.rs
119
src/main.rs
|
@ -37,7 +37,7 @@ use flatten::Flattener;
|
|||
use r1cs::r1cs_program;
|
||||
use clap::{App, AppSettings, Arg, SubCommand};
|
||||
#[cfg(not(feature = "nolibsnark"))]
|
||||
use libsnark::{run_libsnark, setup, generate_proof};
|
||||
use libsnark::{setup, generate_proof};
|
||||
use bincode::{serialize_into, deserialize_from , Infinite};
|
||||
use regex::Regex;
|
||||
|
||||
|
@ -189,41 +189,6 @@ fn main() {
|
|||
.default_value(VARIABLES_INFORMATION_KEY_DEFAULT_PATH)
|
||||
)
|
||||
)
|
||||
.subcommand(SubCommand::with_name("shortcut")
|
||||
.about("Executes witness generation, setup and proof-generation in succession")
|
||||
.arg(Arg::with_name("input")
|
||||
.short("i")
|
||||
.long("input")
|
||||
.help("path of comiled code.")
|
||||
.value_name("FILE")
|
||||
.takes_value(true)
|
||||
.required(false)
|
||||
.default_value(FLATTENED_CODE_DEFAULT_PATH)
|
||||
).arg(Arg::with_name("arguments")
|
||||
.short("a")
|
||||
.long("arguments")
|
||||
.help("Arguments for the program's main method. Space separated list.")
|
||||
.takes_value(true)
|
||||
.multiple(true) // allows multiple values
|
||||
.required(false)
|
||||
)
|
||||
)
|
||||
// .subcommand(SubCommand::with_name("deploy-verifier")
|
||||
// .about("Deploys a given verification contract to the Ethereum network the current web3 provider is connected to.")
|
||||
// .arg(Arg::with_name("input")
|
||||
// .short("i")
|
||||
// .long("input")
|
||||
// .help("Solidity contract code.")
|
||||
// .value_name("FILE")
|
||||
// .takes_value(true)
|
||||
// .required(true)
|
||||
// ).arg(Arg::with_name("account")
|
||||
// .short("a)
|
||||
// .long("account")
|
||||
// .help("Address of the account triggering the Ethereum Transaction.")
|
||||
// .takes_value(true)
|
||||
// )
|
||||
// )
|
||||
.get_matches();
|
||||
|
||||
match matches.subcommand() {
|
||||
|
@ -270,10 +235,12 @@ fn main() {
|
|||
hrofb.flush().expect("Unable to flush buffer.");
|
||||
|
||||
// debugging output
|
||||
println!("Compiled program:\n{}", program_flattened);
|
||||
//println!("Compiled program:\n{}", program_flattened);
|
||||
|
||||
println!(
|
||||
"Compiled code written to {}",
|
||||
sub_matches.value_of("output").unwrap()
|
||||
"Compiled code written to '{}', \nHuman readable code to '{}'",
|
||||
bin_output_path.display(),
|
||||
hr_output_path.display(),
|
||||
);
|
||||
}
|
||||
("compute-witness", Some(sub_matches)) => {
|
||||
|
@ -346,7 +313,6 @@ fn main() {
|
|||
write!(&mut bw, "{} {}\n", var, val.to_dec_string()).expect("Unable to write data to file.");
|
||||
}
|
||||
bw.flush().expect("Unable to flush buffer.");
|
||||
|
||||
}
|
||||
("setup", Some(sub_matches)) => {
|
||||
println!("Performing setup...");
|
||||
|
@ -410,75 +376,6 @@ fn main() {
|
|||
let num_inputs = main_flattened.arguments.len() + 1; //currently exactly one output variable
|
||||
println!("setup successful: {:?}", setup(variables, a, b, c, num_inputs, pk_path, vk_path));
|
||||
}
|
||||
|
||||
}
|
||||
("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) {
|
||||
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.
|
||||
// TODO: is_flattened should be provided as method of Prog in absy.
|
||||
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);
|
||||
|
||||
// validate #arguments
|
||||
let mut args: Vec<FieldPrime> = Vec::new();
|
||||
match sub_matches.values_of("arguments"){
|
||||
Some(p) => {
|
||||
let arg_strings: Vec<&str> = p.collect();
|
||||
args = arg_strings.into_iter().map(|x| FieldPrime::from(x)).collect();
|
||||
},
|
||||
None => {
|
||||
}
|
||||
}
|
||||
|
||||
if main_flattened.arguments.len() != args.len() {
|
||||
println!("Wrong number of arguments. Given: {}, Required: {}.", args.len(), main_flattened.arguments.len());
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let witness_map = main_flattened.get_witness(args);
|
||||
println!("Witness: {:?}", witness_map);
|
||||
match witness_map.get("~out") {
|
||||
Some(out) => println!("Returned (~out): {}", out),
|
||||
None => println!("~out not found, no value returned")
|
||||
}
|
||||
|
||||
let (variables, _, a, b, c) = r1cs_program(&program_ast);
|
||||
|
||||
let witness: Vec<_> = variables.iter().map(|x| witness_map[x].clone()).collect();
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
("export-verifier", Some(sub_matches)) => {
|
||||
println!("Exporting verifier...");
|
||||
|
@ -620,10 +517,6 @@ fn main() {
|
|||
}
|
||||
|
||||
}
|
||||
// ("deploy-verifier", Some(_)) => {
|
||||
// println!("Deploying verifier...");
|
||||
// // Stays in feature branch until migrated to newer rust version.
|
||||
// }
|
||||
_ => unimplemented!(), // Either no subcommand or one not tested for...
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue