clippy libsnark, fix wasm test in circle config
This commit is contained in:
parent
46e41687b5
commit
25f48a0386
4 changed files with 51 additions and 67 deletions
|
@ -68,8 +68,8 @@ jobs:
|
|||
- run:
|
||||
name: Test on firefox
|
||||
command: |
|
||||
cd zokrates_core
|
||||
wasm-pack test --firefox --headless -- --no-default-features --features "wasm ark"
|
||||
cd zokrates_test
|
||||
wasm-pack test --firefox --headless
|
||||
- save-sccache-cache
|
||||
integration_test:
|
||||
docker:
|
||||
|
|
|
@ -6,8 +6,8 @@ fn main() {
|
|||
use std::process::Command;
|
||||
|
||||
// fetch libsnark source
|
||||
const LIBSNARK_URL: &'static str = "https://github.com/scipr-lab/libsnark.git";
|
||||
const LIBSNARK_COMMIT: &'static str = "f7c87b88744ecfd008126d415494d9b34c4c1b20";
|
||||
const LIBSNARK_URL: &str = "https://github.com/scipr-lab/libsnark.git";
|
||||
const LIBSNARK_COMMIT: &str = "f7c87b88744ecfd008126d415494d9b34c4c1b20";
|
||||
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let libsnark_source_path = &out_path.join("libsnark");
|
||||
|
|
|
@ -20,7 +20,7 @@ extern "C" {
|
|||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn from_vec(v: &Vec<u8>) -> Buffer {
|
||||
pub fn from_vec(v: &[u8]) -> Buffer {
|
||||
let data = v.as_ptr();
|
||||
let len = v.len();
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ use zokrates_field::Field;
|
|||
pub struct Libsnark;
|
||||
|
||||
// utility function. Converts a Field's vector-based byte representation to fixed size array.
|
||||
fn vec_as_u8_32_array(vec: &Vec<u8>) -> [u8; 32] {
|
||||
fn vec_as_u8_32_array(vec: &[u8]) -> [u8; 32] {
|
||||
assert!(vec.len() <= 32);
|
||||
let mut array = [0u8; 32];
|
||||
for (index, byte) in vec.iter().enumerate() {
|
||||
|
@ -32,6 +32,7 @@ pub fn prepare_public_inputs<T: Field>(public_inputs: Vec<T>) -> (Vec<[u8; 32]>,
|
|||
}
|
||||
|
||||
// proof-system-independent preparation for the setup phase
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub fn prepare_setup<T: Field>(
|
||||
program: ir::Prog<T>,
|
||||
) -> (
|
||||
|
@ -46,33 +47,33 @@ pub fn prepare_setup<T: Field>(
|
|||
usize,
|
||||
) {
|
||||
// transform to R1CS
|
||||
let (variables, public_variables_count, a, b, c) = r1cs_program(program);
|
||||
let (variables, public_variables_count, constraints) = r1cs_program(program);
|
||||
|
||||
let num_inputs = public_variables_count - 1;
|
||||
let num_constraints = constraints.len();
|
||||
|
||||
let num_constraints = a.len();
|
||||
let num_variables = variables.len();
|
||||
|
||||
// Create single A,B,C vectors of tuples (constraint_number, variable_id, variable_value)
|
||||
let mut a_vec = vec![];
|
||||
let mut b_vec = vec![];
|
||||
let mut c_vec = vec![];
|
||||
for row in 0..num_constraints {
|
||||
for &(idx, ref val) in &a[row] {
|
||||
for (row, (a, b, c)) in constraints.iter().enumerate() {
|
||||
for &(idx, ref val) in a {
|
||||
a_vec.push((
|
||||
row as i32,
|
||||
idx as i32,
|
||||
vec_as_u8_32_array(&val.to_byte_vector()),
|
||||
));
|
||||
}
|
||||
for &(idx, ref val) in &b[row] {
|
||||
for &(idx, ref val) in b {
|
||||
b_vec.push((
|
||||
row as i32,
|
||||
idx as i32,
|
||||
vec_as_u8_32_array(&val.to_byte_vector()),
|
||||
));
|
||||
}
|
||||
for &(idx, ref val) in &c[row] {
|
||||
for &(idx, ref val) in c {
|
||||
c_vec.push((
|
||||
row as i32,
|
||||
idx as i32,
|
||||
|
@ -97,10 +98,9 @@ pub fn prepare_setup<T: Field>(
|
|||
let mut a_arr: Vec<u8> = vec![0u8; STRUCT_SIZE * a_vec.len()];
|
||||
let mut b_arr: Vec<u8> = vec![0u8; STRUCT_SIZE * b_vec.len()];
|
||||
let mut c_arr: Vec<u8> = vec![0u8; STRUCT_SIZE * c_vec.len()];
|
||||
use std::mem::transmute;
|
||||
for (id, (row, idx, val)) in a_vec.iter().enumerate() {
|
||||
let row_bytes: [u8; ROW_SIZE] = unsafe { transmute(row.to_le()) };
|
||||
let idx_bytes: [u8; IDX_SIZE] = unsafe { transmute(idx.to_le()) };
|
||||
let row_bytes: [u8; ROW_SIZE] = row.to_le().to_ne_bytes();
|
||||
let idx_bytes: [u8; IDX_SIZE] = idx.to_le().to_ne_bytes();
|
||||
|
||||
for x in 0..ROW_SIZE {
|
||||
a_arr[id * STRUCT_SIZE + x] = row_bytes[x];
|
||||
|
@ -113,8 +113,8 @@ pub fn prepare_setup<T: Field>(
|
|||
}
|
||||
}
|
||||
for (id, (row, idx, val)) in b_vec.iter().enumerate() {
|
||||
let row_bytes: [u8; ROW_SIZE] = unsafe { transmute(row.to_le()) };
|
||||
let idx_bytes: [u8; IDX_SIZE] = unsafe { transmute(idx.to_le()) };
|
||||
let row_bytes: [u8; ROW_SIZE] = row.to_le().to_ne_bytes();
|
||||
let idx_bytes: [u8; IDX_SIZE] = idx.to_le().to_ne_bytes();
|
||||
|
||||
for x in 0..ROW_SIZE {
|
||||
b_arr[id * STRUCT_SIZE + x] = row_bytes[x];
|
||||
|
@ -127,8 +127,8 @@ pub fn prepare_setup<T: Field>(
|
|||
}
|
||||
}
|
||||
for (id, (row, idx, val)) in c_vec.iter().enumerate() {
|
||||
let row_bytes: [u8; ROW_SIZE] = unsafe { transmute(row.to_le()) };
|
||||
let idx_bytes: [u8; IDX_SIZE] = unsafe { transmute(idx.to_le()) };
|
||||
let row_bytes: [u8; ROW_SIZE] = row.to_le().to_ne_bytes();
|
||||
let idx_bytes: [u8; IDX_SIZE] = idx.to_le().to_ne_bytes();
|
||||
|
||||
for x in 0..ROW_SIZE {
|
||||
c_arr[id * STRUCT_SIZE + x] = row_bytes[x];
|
||||
|
@ -160,12 +160,12 @@ pub fn prepare_generate_proof<T: Field>(
|
|||
witness: ir::Witness<T>,
|
||||
) -> (Vec<[u8; 32]>, usize, Vec<[u8; 32]>, usize) {
|
||||
// recover variable order from the program
|
||||
let (variables, public_variables_count, _, _, _) = r1cs_program(program);
|
||||
let (variables, public_variables_count, _) = r1cs_program(program);
|
||||
|
||||
let witness: Vec<_> = variables.iter().map(|x| witness.0[x].clone()).collect();
|
||||
|
||||
// split witness into public and private inputs at offset
|
||||
let mut public_inputs: Vec<_> = witness.clone();
|
||||
let mut public_inputs: Vec<_> = witness;
|
||||
let private_inputs: Vec<_> = public_inputs.split_off(public_variables_count);
|
||||
|
||||
let public_inputs_length = public_inputs.len();
|
||||
|
@ -202,6 +202,9 @@ pub fn provide_variable_idx(variables: &mut HashMap<Variable, usize>, var: &Vari
|
|||
*variables.entry(*var).or_insert(index)
|
||||
}
|
||||
|
||||
type LinComb<T> = Vec<(usize, T)>;
|
||||
type Constraint<T> = (LinComb<T>, LinComb<T>, LinComb<T>);
|
||||
|
||||
/// Calculates one R1CS row representation of a program and returns (V, A, B, C) so that:
|
||||
/// * `V` contains all used variables and the index in the vector represents the used number in `A`, `B`, `C`
|
||||
/// * `<A,x>*<B,x> = <C,x>` for a witness `x`
|
||||
|
@ -209,15 +212,7 @@ pub fn provide_variable_idx(variables: &mut HashMap<Variable, usize>, var: &Vari
|
|||
/// # Arguments
|
||||
///
|
||||
/// * `prog` - The program the representation is calculated for.
|
||||
pub fn r1cs_program<T: Field>(
|
||||
prog: ir::Prog<T>,
|
||||
) -> (
|
||||
Vec<Variable>,
|
||||
usize,
|
||||
Vec<Vec<(usize, T)>>,
|
||||
Vec<Vec<(usize, T)>>,
|
||||
Vec<Vec<(usize, T)>>,
|
||||
) {
|
||||
pub fn r1cs_program<T: Field>(prog: ir::Prog<T>) -> (Vec<Variable>, usize, Vec<Constraint<T>>) {
|
||||
let mut variables: HashMap<Variable, usize> = HashMap::new();
|
||||
provide_variable_idx(&mut variables, &Variable::one());
|
||||
|
||||
|
@ -242,45 +237,39 @@ pub fn r1cs_program<T: Field>(
|
|||
Statement::Directive(..) => None,
|
||||
}) {
|
||||
for (k, _) in &quad.left.0 {
|
||||
provide_variable_idx(&mut variables, &k);
|
||||
provide_variable_idx(&mut variables, k);
|
||||
}
|
||||
for (k, _) in &quad.right.0 {
|
||||
provide_variable_idx(&mut variables, &k);
|
||||
provide_variable_idx(&mut variables, k);
|
||||
}
|
||||
for (k, _) in &lin.0 {
|
||||
provide_variable_idx(&mut variables, &k);
|
||||
provide_variable_idx(&mut variables, k);
|
||||
}
|
||||
}
|
||||
|
||||
let mut a = vec![];
|
||||
let mut b = vec![];
|
||||
let mut c = vec![];
|
||||
let mut constraints = vec![];
|
||||
|
||||
// second pass to convert program to raw sparse vectors
|
||||
for (quad, lin) in prog.statements.into_iter().filter_map(|s| match s {
|
||||
Statement::Constraint(quad, lin, _) => Some((quad, lin)),
|
||||
Statement::Directive(..) => None,
|
||||
}) {
|
||||
a.push(
|
||||
constraints.push((
|
||||
quad.left
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|(k, v)| (variables.get(&k).unwrap().clone(), v))
|
||||
.map(|(k, v)| (*variables.get(&k).unwrap(), v))
|
||||
.collect(),
|
||||
);
|
||||
b.push(
|
||||
quad.right
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|(k, v)| (variables.get(&k).unwrap().clone(), v))
|
||||
.map(|(k, v)| (*variables.get(&k).unwrap(), v))
|
||||
.collect(),
|
||||
);
|
||||
c.push(
|
||||
lin.0
|
||||
.into_iter()
|
||||
.map(|(k, v)| (variables.get(&k).unwrap().clone(), v))
|
||||
.map(|(k, v)| (*variables.get(&k).unwrap(), v))
|
||||
.collect(),
|
||||
);
|
||||
));
|
||||
}
|
||||
|
||||
// Convert map back into list ordered by index
|
||||
|
@ -289,16 +278,17 @@ pub fn r1cs_program<T: Field>(
|
|||
assert_eq!(variables_list[v], Variable::new(0));
|
||||
variables_list[v] = k;
|
||||
}
|
||||
(variables_list, private_inputs_offset, a, b, c)
|
||||
(variables_list, private_inputs_offset, constraints)
|
||||
}
|
||||
|
||||
pub mod serialization {
|
||||
use std::io::Error;
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
use zokrates_proof_systems::{G1Affine, G2Affine, G2AffineFq2};
|
||||
|
||||
#[inline]
|
||||
fn decode_hex(value: &String) -> Vec<u8> {
|
||||
fn decode_hex(value: &str) -> Vec<u8> {
|
||||
hex::decode(value.strip_prefix("0x").unwrap()).unwrap()
|
||||
}
|
||||
|
||||
|
@ -307,44 +297,38 @@ pub mod serialization {
|
|||
format!("0x{}", hex::encode(data))
|
||||
}
|
||||
|
||||
pub fn read_g1<R: Read>(reader: &mut R) -> Result<G1Affine, ()> {
|
||||
pub fn read_g1<R: Read>(reader: &mut R) -> Result<G1Affine, Error> {
|
||||
let mut buffer = [0; 64];
|
||||
reader.read_exact(&mut buffer).map_err(|_| ())?;
|
||||
reader.read_exact(&mut buffer)?;
|
||||
|
||||
Ok(G1Affine(
|
||||
encode_hex(&buffer[0..32].to_vec()),
|
||||
encode_hex(&buffer[32..64].to_vec()),
|
||||
encode_hex(&buffer[0..32]),
|
||||
encode_hex(&buffer[32..64]),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn read_g2<R: Read>(reader: &mut R) -> Result<G2Affine, ()> {
|
||||
pub fn read_g2<R: Read>(reader: &mut R) -> Result<G2Affine, Error> {
|
||||
let mut buffer = [0; 128];
|
||||
reader.read_exact(&mut buffer).map_err(|_| ())?;
|
||||
reader.read_exact(&mut buffer)?;
|
||||
|
||||
Ok(G2Affine::Fq2(G2AffineFq2(
|
||||
(
|
||||
encode_hex(&buffer[0..32].to_vec()),
|
||||
encode_hex(&buffer[32..64].to_vec()),
|
||||
),
|
||||
(
|
||||
encode_hex(&buffer[64..96].to_vec()),
|
||||
encode_hex(&buffer[96..128].to_vec()),
|
||||
),
|
||||
(encode_hex(&buffer[0..32]), encode_hex(&buffer[32..64])),
|
||||
(encode_hex(&buffer[64..96]), encode_hex(&buffer[96..128])),
|
||||
)))
|
||||
}
|
||||
|
||||
pub fn write_g1<W: Write>(writer: &mut W, g1: &G1Affine) {
|
||||
writer.write(decode_hex(&g1.0).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&g1.1).as_ref()).unwrap();
|
||||
writer.write_all(decode_hex(&g1.0).as_ref()).unwrap();
|
||||
writer.write_all(decode_hex(&g1.1).as_ref()).unwrap();
|
||||
}
|
||||
|
||||
pub fn write_g2<W: Write>(writer: &mut W, g2: &G2Affine) {
|
||||
match g2 {
|
||||
G2Affine::Fq2(g2) => {
|
||||
writer.write(decode_hex(&(g2.0).0).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&(g2.0).1).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&(g2.1).0).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&(g2.1).1).as_ref()).unwrap();
|
||||
writer.write_all(decode_hex(&(g2.0).0).as_ref()).unwrap();
|
||||
writer.write_all(decode_hex(&(g2.0).1).as_ref()).unwrap();
|
||||
writer.write_all(decode_hex(&(g2.1).0).as_ref()).unwrap();
|
||||
writer.write_all(decode_hex(&(g2.1).1).as_ref()).unwrap();
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue