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

Commit

Permalink
chore: use WASMValue for wasm arguments as well as return values (#157
Browse files Browse the repository at this point in the history
)

chore: use `WASMValue` for wasm args

Co-authored-by: Blaine Bublitz <blaine.bublitz@gmail.com>
  • Loading branch information
TomAFrench and phated authored May 5, 2023
1 parent ce2b9ed commit 4436b54
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 85 deletions.
3 changes: 1 addition & 2 deletions src/acvm_interop/smart_contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ impl SmartContract for Barretenberg {
impl SmartContract for Barretenberg {
fn eth_contract_from_vk(&self, verification_key: &[u8]) -> String {
use crate::wasm::POINTER_BYTES;
use wasmer::Value;

let g2 = G2::new();

Expand All @@ -50,7 +49,7 @@ impl SmartContract for Barretenberg {
let contract_size = self
.call_multiple(
"acir_proofs_get_solidity_verifier",
vec![&g2_ptr, &vk_ptr, &Value::I32(contract_ptr_ptr as i32)],
vec![&g2_ptr, &vk_ptr, &contract_ptr_ptr.into()],
)
.value();
let contract_size: usize = contract_size.unwrap_i32() as usize;
Expand Down
37 changes: 10 additions & 27 deletions src/composer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ impl Composer for Barretenberg {

let circuit_size = self
.call("acir_proofs_get_total_circuit_size", &cs_ptr)
.into_i32();
.i32();
let circuit_size =
u32::try_from(circuit_size).expect("circuit cannot have negative number of gates");

Expand All @@ -226,7 +226,7 @@ impl Composer for Barretenberg {

let circuit_size = self
.call("acir_proofs_get_exact_circuit_size", &cs_ptr)
.into_i32();
.i32();
let circuit_size =
u32::try_from(circuit_size).expect("circuit cannot have negative number of gates");

Expand All @@ -237,7 +237,6 @@ impl Composer for Barretenberg {

fn compute_proving_key(&self, constraint_system: &ConstraintSystem) -> Vec<u8> {
use super::wasm::POINTER_BYTES;
use wasmer::Value;

let cs_buf = constraint_system.to_bytes();
let cs_ptr = self.allocate(&cs_buf);
Expand All @@ -246,13 +245,11 @@ impl Composer for Barretenberg {
// `pk_ptr_ptr` is a pointer to a pointer which holds the proving key.
let pk_ptr_ptr: usize = 0;

let pk_size = self
.call_multiple(
"acir_proofs_init_proving_key",
vec![&cs_ptr, &Value::I32(pk_ptr_ptr as i32)],
)
.value();
let pk_size: usize = pk_size.unwrap_i32() as usize;
let pk_size = self.call_multiple(
"acir_proofs_init_proving_key",
vec![&cs_ptr, &pk_ptr_ptr.into()],
);
let pk_size: usize = pk_size.i32() as usize;

// We then need to read the pointer at `pk_ptr_ptr` to get the key's location
// and then slice memory again at `pk_ptr` to get the proving key.
Expand All @@ -269,7 +266,6 @@ impl Composer for Barretenberg {
proving_key: &[u8],
) -> Vec<u8> {
use super::wasm::POINTER_BYTES;
use wasmer::Value;

let circuit_size = self.get_circuit_size(constraint_system);
let CRS {
Expand All @@ -287,12 +283,7 @@ impl Composer for Barretenberg {
let vk_size = self
.call_multiple(
"acir_proofs_init_verification_key",
vec![
&pippenger_ptr,
&g2_ptr,
&pk_ptr,
&Value::I32(vk_ptr_ptr as i32),
],
vec![&pippenger_ptr, &g2_ptr, &pk_ptr, &vk_ptr_ptr.into()],
)
.value();
let vk_size: usize = vk_size.unwrap_i32() as usize;
Expand All @@ -313,7 +304,6 @@ impl Composer for Barretenberg {
proving_key: &[u8],
) -> Vec<u8> {
use super::wasm::POINTER_BYTES;
use wasmer::Value;

let circuit_size = self.get_circuit_size(constraint_system);
let CRS {
Expand Down Expand Up @@ -341,7 +331,7 @@ impl Composer for Barretenberg {
&pk_ptr,
&cs_ptr,
&witness_ptr,
&Value::I32(0),
&0.into(),
],
)
.value();
Expand Down Expand Up @@ -369,7 +359,6 @@ impl Composer for Barretenberg {
public_inputs: Assignments,
verification_key: &[u8],
) -> bool {
use wasmer::Value;
let g2_data = G2::new().data;

// Barretenberg expects public inputs to be prepended onto the proof
Expand All @@ -384,13 +373,7 @@ impl Composer for Barretenberg {
let verified = self
.call_multiple(
"acir_proofs_verify_proof",
vec![
&g2_ptr,
&vk_ptr,
&cs_ptr,
&proof_ptr,
&Value::I32(proof.len() as i32),
],
vec![&g2_ptr, &vk_ptr, &cs_ptr, &proof_ptr, &proof.len().into()],
)
.value();

Expand Down
52 changes: 40 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,46 @@ mod wasm {
memory: Memory,
}

/// A wrapper around the return value from a WASM call.
/// A wrapper around the arguments or return value from a WASM call.
/// Notice, `Option<Value>` is used because not every call returns a value,
/// some calls are simply made to free a pointer or manipulate the heap.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub(super) struct WASMValue(Option<Value>);

impl WASMValue {
pub(super) fn value(self) -> Value {
self.0.unwrap()
}
pub(super) fn into_i32(self) -> i32 {

pub(super) fn i32(self) -> i32 {
i32::try_from(self.0.unwrap()).expect("expected an i32 value")
}

pub(super) fn bool(self) -> bool {
match self.i32() {
0 => false,
1 => true,
_ => panic!("expected a boolean value"),
}
}
}

impl From<usize> for WASMValue {
fn from(value: usize) -> Self {
WASMValue(Some(Value::I32(value as i32)))
}
}

impl From<i32> for WASMValue {
fn from(value: i32) -> Self {
WASMValue(Some(Value::I32(value)))
}
}

impl From<Value> for WASMValue {
fn from(value: Value) -> Self {
WASMValue(Some(value))
}
}

impl Barretenberg {
Expand Down Expand Up @@ -156,38 +183,39 @@ mod wasm {
.collect();
}

pub(super) fn call(&self, name: &str, param: &Value) -> WASMValue {
pub(super) fn call(&self, name: &str, param: &WASMValue) -> WASMValue {
self.call_multiple(name, vec![param])
}

pub(super) fn call_multiple(&self, name: &str, params: Vec<&Value>) -> WASMValue {
pub(super) fn call_multiple(&self, name: &str, params: Vec<&WASMValue>) -> WASMValue {
// We take in a reference to values, since they do not implement Copy.
// We then clone them inside of this function, so that the API does not have a bunch of Clones everywhere

let params: Vec<_> = params.into_iter().cloned().collect();
let params: Vec<Value> = params
.into_iter()
.map(|param| param.clone().value())
.collect();
let func = self.instance.exports.get_function(name).unwrap();
let option_value = func.call(&params).unwrap().first().cloned();

WASMValue(option_value)
}

/// Creates a pointer and allocates the bytes that the pointer references to, to the heap
pub(super) fn allocate(&self, bytes: &[u8]) -> Value {
let ptr = self
.call("bbmalloc", &Value::I32(bytes.len() as i32))
.value();
pub(super) fn allocate(&self, bytes: &[u8]) -> WASMValue {
let ptr = self.call("bbmalloc", &bytes.len().into()).value();

let i32_bytes = ptr.unwrap_i32().to_be_bytes();
let u32_bytes = u32::from_be_bytes(i32_bytes);

self.transfer_to_heap(bytes, u32_bytes as usize);
ptr
ptr.into()
}

/// Frees a pointer.
/// Notice we consume the Value, if you clone the value before passing it to free
/// It most likely is a bug
pub(super) fn free(&self, pointer: Value) {
pub(super) fn free(&self, pointer: WASMValue) {
self.call("bbfree", &pointer);
}
}
Expand Down
13 changes: 3 additions & 10 deletions src/pedersen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ impl Pedersen for Barretenberg {
impl Pedersen for Barretenberg {
fn compress_native(&self, left: &FieldElement, right: &FieldElement) -> FieldElement {
use super::FIELD_BYTES;
use wasmer::Value;

let lhs_ptr: usize = 0;
let rhs_ptr: usize = lhs_ptr + FIELD_BYTES;
Expand All @@ -63,11 +62,7 @@ impl Pedersen for Barretenberg {

self.call_multiple(
"pedersen_plookup_compress_fields",
vec![
&Value::I32(lhs_ptr as i32),
&Value::I32(rhs_ptr as i32),
&Value::I32(result_ptr as i32),
],
vec![&lhs_ptr.into(), &rhs_ptr.into(), &result_ptr.into()],
);

let result_bytes = self.slice_memory(result_ptr, FIELD_BYTES);
Expand All @@ -78,15 +73,14 @@ impl Pedersen for Barretenberg {
fn compress_many(&self, inputs: Vec<FieldElement>) -> FieldElement {
use super::FIELD_BYTES;
use crate::barretenberg_structures::Assignments;
use wasmer::Value;

let input_buf = Assignments::from(inputs).to_bytes();
let input_ptr = self.allocate(&input_buf);
let result_ptr: usize = 0;

self.call_multiple(
"pedersen_plookup_compress",
vec![&input_ptr, &Value::I32(result_ptr as i32)],
vec![&input_ptr, &result_ptr.into()],
);

let result_bytes = self.slice_memory(result_ptr, FIELD_BYTES);
Expand All @@ -96,15 +90,14 @@ impl Pedersen for Barretenberg {
fn encrypt(&self, inputs: Vec<FieldElement>) -> (FieldElement, FieldElement) {
use super::FIELD_BYTES;
use crate::barretenberg_structures::Assignments;
use wasmer::Value;

let input_buf = Assignments::from(inputs).to_bytes();
let input_ptr = self.allocate(&input_buf);
let result_ptr: usize = 0;

self.call_multiple(
"pedersen_plookup_commit",
vec![&input_ptr, &Value::I32(result_ptr as i32)],
vec![&input_ptr, &result_ptr.into()],
);

let result_bytes = self.slice_memory(result_ptr, 2 * FIELD_BYTES);
Expand Down
12 changes: 3 additions & 9 deletions src/pippenger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub(crate) struct Pippenger {
#[cfg(feature = "native")]
pippenger_ptr: *mut std::os::raw::c_void,
#[cfg(not(feature = "native"))]
pippenger_ptr: wasmer::Value,
pippenger_ptr: crate::wasm::WASMValue,
}

#[cfg(feature = "native")]
Expand All @@ -16,7 +16,7 @@ impl Pippenger {

#[cfg(not(feature = "native"))]
impl Pippenger {
pub(crate) fn pointer(&self) -> wasmer::Value {
pub(crate) fn pointer(&self) -> crate::wasm::WASMValue {
self.pippenger_ptr.clone()
}
}
Expand All @@ -34,18 +34,12 @@ impl Barretenberg {
impl Barretenberg {
pub(crate) fn get_pippenger(&self, crs_data: &[u8]) -> Pippenger {
use super::FIELD_BYTES;
use wasmer::Value;

let num_points = crs_data.len() / (2 * FIELD_BYTES);

let crs_ptr = self.allocate(crs_data);

let pippenger_ptr = self
.call_multiple(
"new_pippenger",
vec![&crs_ptr, &Value::I32(num_points as i32)],
)
.value();
let pippenger_ptr = self.call_multiple("new_pippenger", vec![&crs_ptr, &num_points.into()]);

self.free(crs_ptr);

Expand Down
4 changes: 1 addition & 3 deletions src/scalar_mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ impl ScalarMul for Barretenberg {
#[cfg(not(feature = "native"))]
impl ScalarMul for Barretenberg {
fn fixed_base(&self, input: &FieldElement) -> (FieldElement, FieldElement) {
use wasmer::Value;

let lhs_ptr: usize = 0;
let result_ptr: usize = lhs_ptr + FIELD_BYTES;
self.transfer_to_heap(&input.to_be_bytes(), lhs_ptr);

self.call_multiple(
"compute_public_key",
vec![&Value::I32(lhs_ptr as i32), &Value::I32(result_ptr as i32)],
vec![&lhs_ptr.into(), &result_ptr.into()],
);

let result_bytes = self.slice_memory(result_ptr, 2 * FIELD_BYTES);
Expand Down
Loading

0 comments on commit 4436b54

Please sign in to comment.