1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

clippy libsnark, fix wasm test in circle config

This commit is contained in:
schaeff 2022-05-13 14:51:58 +02:00
parent 46e41687b5
commit 25f48a0386
4 changed files with 51 additions and 67 deletions

View file

@ -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:

View file

@ -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");

View file

@ -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();

View file

@ -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!(),
}