Skip to content
This repository has been archived by the owner on Oct 31, 2023. It is now read-only.

Commit

Permalink
Preprocess wasm (#52)
Browse files Browse the repository at this point in the history
* bb_wasm update for new composer methods using pk and vk

* clippy fixes
  • Loading branch information
vezenovm authored Feb 9, 2023
1 parent 3a54eae commit bdb7ced
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 9 deletions.
2 changes: 1 addition & 1 deletion barretenberg_static_lib/src/acvm_interop/proof_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ impl ProofSystemCompiler for Plonk {
let constraint_system = serialise_circuit(&circuit);
let mut composer = StandardComposer::new(constraint_system);

composer.verify_with_keys(
composer.verify_with_vk(
proof,
Some(Assignments::from_vec(public_inputs)),
&verification_key,
Expand Down
4 changes: 2 additions & 2 deletions barretenberg_static_lib/src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ impl StandardComposer {
remove_public_inputs(self.constraint_system.public_inputs.len(), result.to_vec())
}

pub fn verify_with_keys(
pub fn verify_with_vk(
&mut self,
// XXX: Important: This assumes that the proof does not have the public inputs pre-pended to it
// This is not the case, if you take the proof directly from Barretenberg
Expand Down Expand Up @@ -699,7 +699,7 @@ mod test {

for test_case in test_cases.into_iter() {
let proof = sc.create_proof_with_pk(test_case.witness, &proving_key);
let verified = sc.verify_with_keys(&proof, test_case.public_inputs, &verification_key);
let verified = sc.verify_with_vk(&proof, test_case.public_inputs, &verification_key);
assert_eq!(verified, test_case.result);
}
}
Expand Down
41 changes: 35 additions & 6 deletions barretenberg_wasm/src/acvm_interop/proof_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,29 +77,58 @@ impl ProofSystemCompiler for Plonk {
}
}

#[allow(unused_variables)]
fn preprocess(&self, circuit: Circuit) -> (Vec<u8>, Vec<u8>) {
todo!()
let constraint_system = serialise_circuit(&circuit);
let mut composer = StandardComposer::new(constraint_system);

let proving_key = composer.compute_proving_key();
let verification_key = composer.compute_verification_key(&proving_key);

(proving_key, verification_key)
}

#[allow(unused_variables)]
fn prove_with_pk(
&self,
circuit: Circuit,
witness_values: BTreeMap<Witness, FieldElement>,
proving_key: Vec<u8>,
) -> Vec<u8> {
todo!()
let constraint_system = serialise_circuit(&circuit);

let mut composer = StandardComposer::new(constraint_system);

// Add witnesses in the correct order
// Note: The witnesses are sorted via their witness index
// witness_values may not have all the witness indexes, e.g for unused witness which are not solved by the solver
let mut sorted_witness = Assignments::new();
let num_witnesses = circuit.num_vars();
for i in 1..num_witnesses {
// Get the value if it exists. If i does not, then we fill it with the zero value
let value = match witness_values.get(&Witness(i)) {
Some(value) => *value,
None => FieldElement::zero(),
};

sorted_witness.push(value);
}

composer.create_proof_with_pk(sorted_witness, &proving_key)
}

#[allow(unused_variables)]
fn verify_with_vk(
&self,
proof: &[u8],
public_inputs: Vec<FieldElement>,
circuit: Circuit,
verification_key: Vec<u8>,
) -> bool {
todo!()
let constraint_system = serialise_circuit(&circuit);
let mut composer = StandardComposer::new(constraint_system);

composer.verify_with_vk(
proof,
Some(Assignments::from_vec(public_inputs)),
&verification_key,
)
}
}
Binary file modified barretenberg_wasm/src/barretenberg.wasm
100644 → 100755
Binary file not shown.
136 changes: 136 additions & 0 deletions barretenberg_wasm/src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,142 @@ impl StandardComposer {
_ => panic!("Expected a 1 or a zero for the verification result"),
}
}

pub fn compute_proving_key(&mut self) -> Vec<u8> {
let cs_buf = self.constraint_system.to_bytes();
let cs_ptr = self.barretenberg.allocate(&cs_buf);

let pk_size = self
.barretenberg
.call_multiple("c_init_proving_key", vec![&cs_ptr, &Value::I32(0)])
.value();

let pk_ptr = self.barretenberg.slice_memory(0, 4);
let pk_ptr = u32::from_le_bytes(pk_ptr[0..4].try_into().unwrap());

self.barretenberg.slice_memory(
pk_ptr as usize,
pk_ptr as usize + pk_size.unwrap_i32() as usize,
)
}

pub fn compute_verification_key(&mut self, proving_key: &[u8]) -> Vec<u8> {
let g2_ptr = self.barretenberg.allocate(&self.crs.g2_data);

let pk_ptr = self.barretenberg.allocate(proving_key);

let vk_size = self
.barretenberg
.call_multiple(
"c_init_verification_key",
vec![&self.pippenger.pointer(), &g2_ptr, &pk_ptr, &Value::I32(0)],
)
.value();

let vk_ptr = self.barretenberg.slice_memory(0, 4);
let vk_ptr = u32::from_le_bytes(vk_ptr[0..4].try_into().unwrap());

self.barretenberg.slice_memory(
vk_ptr as usize,
vk_ptr as usize + vk_size.unwrap_i32() as usize,
)
}

pub fn create_proof_with_pk(
&mut self,
witness: WitnessAssignments,
proving_key: &[u8],
) -> Vec<u8> {
let cs_buf = self.constraint_system.to_bytes();
let cs_ptr = self.barretenberg.allocate(&cs_buf);

let witness_buf = witness.to_bytes();
let witness_ptr = self.barretenberg.allocate(&witness_buf);

let g2_ptr = self.barretenberg.allocate(&self.crs.g2_data);

let pk_ptr = self.barretenberg.allocate(proving_key);

let proof_size = self
.barretenberg
.call_multiple(
"c_new_proof",
vec![
&self.pippenger.pointer(),
&g2_ptr,
&pk_ptr,
&cs_ptr,
&witness_ptr,
&Value::I32(0),
],
)
.value();

let proof_ptr = self.barretenberg.slice_memory(0, 4);
let proof_ptr = u32::from_le_bytes(proof_ptr[0..4].try_into().unwrap());

let proof = self.barretenberg.slice_memory(
proof_ptr as usize,
proof_ptr as usize + proof_size.unwrap_i32() as usize,
);
remove_public_inputs(self.constraint_system.public_inputs.len(), proof)
}

pub fn verify_with_vk(
&mut self,
// XXX: Important: This assumes that the proof does not have the public inputs pre-pended to it
// This is not the case, if you take the proof directly from Barretenberg
proof: &[u8],
public_inputs: Option<Assignments>,
verification_key: &[u8],
) -> bool {
// Prepend the public inputs to the proof.
// This is how Barretenberg expects it to be.
// This is non-standard however, so this Rust wrapper will strip the public inputs
// from proofs created by Barretenberg. Then in Verify we prepend them again.
//

let mut proof = proof.to_vec();
if let Some(pi) = &public_inputs {
let mut proof_with_pi = Vec::new();
for assignment in pi.0.iter() {
proof_with_pi.extend(&assignment.to_be_bytes());
}
proof_with_pi.extend(proof);
proof = proof_with_pi;
}

let cs_buf = self.constraint_system.to_bytes();
let cs_ptr = self.barretenberg.allocate(&cs_buf);

let proof_ptr = self.barretenberg.allocate(&proof);

let g2_ptr = self.barretenberg.allocate(&self.crs.g2_data);

let vk_ptr = self.barretenberg.allocate(verification_key);

let verified = self
.barretenberg
.call_multiple(
"c_verify_proof",
vec![
&g2_ptr,
&vk_ptr,
&cs_ptr,
&proof_ptr,
&Value::I32(proof.len() as i32),
],
)
.value();

self.barretenberg.free(proof_ptr);

match verified.unwrap_i32() {
0 => false,
1 => true,
_ => panic!("Expected a 1 or a zero for the verification result"),
}
}
}

pub(crate) fn remove_public_inputs(num_pub_inputs: usize, proof: Vec<u8>) -> Vec<u8> {
Expand Down

0 comments on commit bdb7ced

Please sign in to comment.