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

chore: use WASMValue for wasm arguments as well as return values #157

Merged
merged 1 commit into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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