Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

Commit

Permalink
chore: run browser tests on both Chromium and Webkit (#41)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Koby <[email protected]>
  • Loading branch information
TomAFrench and kobyhallx authored Jun 19, 2023
1 parent eb3d98a commit 2d43c0d
Show file tree
Hide file tree
Showing 9 changed files with 54 additions and 121 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ jobs:
uses: ./.github/actions/setup

- name: Install playwright deps
run: npx playwright install --with-deps webkit
run: |
npx playwright install
npx playwright install-deps
- name: Run browser tests
run: yarn test:browser
2 changes: 2 additions & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//
"blackbox",
"bindir",
"brillig",
"cout",
"jsdoc",
"keccak",
Expand All @@ -23,6 +24,7 @@
"ESUCCESS",
"fdstat",
"getrandom",
"jsvalue",
"logstr",
"plookup",
"wasi",
Expand Down
55 changes: 29 additions & 26 deletions src/barretenberg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ mod barretenberg_structures;
pub(crate) mod pedersen;
pub(crate) mod scalar_mul;
pub(crate) mod schnorr;

use barretenberg_structures::Assignments;

/// The number of bytes necessary to store a `FieldElement`.
Expand Down Expand Up @@ -54,27 +53,14 @@ pub(crate) struct Barretenberg {
instance: wasmer::Instance,
}

impl Default for Barretenberg {
fn default() -> Barretenberg {
Barretenberg::new()
}
}

#[test]
fn smoke() -> Result<(), Error> {
use pedersen::Pedersen;

let b = Barretenberg::new();
let (x, y) = b.encrypt(vec![acvm::FieldElement::zero(), acvm::FieldElement::one()])?;
dbg!(x.to_hex(), y.to_hex());
Ok(())
}

mod wasm {
use js_sys::WebAssembly::{self};
use log::debug;
use std::cell::RefCell;

use wasmer::{
imports, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, MemoryType, Module,
Store, Value, WasmPtr,
imports, AsJs, Function, FunctionEnv, FunctionEnvMut, Instance, Memory, MemoryType, Store,
Value, WasmPtr,
};

use super::{Barretenberg, Error, FeatureError};
Expand All @@ -98,8 +84,8 @@ mod wasm {
struct Wasm;

impl Barretenberg {
pub(crate) fn new() -> Barretenberg {
let (instance, memory, store) = instance_load();
pub(crate) async fn new() -> Barretenberg {
let (instance, memory, store) = instance_load().await;
Barretenberg { memory, instance, store: RefCell::new(store) }
}
}
Expand Down Expand Up @@ -251,16 +237,14 @@ mod wasm {
// }
}

fn instance_load() -> (Instance, Memory, Store) {
async fn instance_load() -> (Instance, Memory, Store) {
debug!("> Will Load black box functions vendor binary");
let mut store = Store::default();

let module = Module::new(&store, Wasm::get("barretenberg.wasm").unwrap().data).unwrap();

let mem_type = MemoryType::new(22, None, false);
let memory = Memory::new(&mut store, mem_type).unwrap();

let function_env = FunctionEnv::new(&mut store, memory.clone());

let custom_imports = imports! {
"env" => {
"logstr" => Function::new_typed_with_env(
Expand Down Expand Up @@ -292,7 +276,26 @@ mod wasm {
},
};

(Instance::new(&mut store, &module, &custom_imports).unwrap(), memory, store)
let wasm_binary = Wasm::get("barretenberg.wasm").unwrap().data;
let js_bytes: js_sys::Uint8Array;
unsafe {
js_bytes = js_sys::Uint8Array::view(&wasm_binary);
}
debug!("> Will compile black box functions vendor module");
let js_module_promise = WebAssembly::compile(&js_bytes);
let js_module: js_sys::WebAssembly::Module =
wasm_bindgen_futures::JsFuture::from(js_module_promise).await.unwrap().into();

debug!("> Will create black box functions vendor instance");
let js_instance_promise =
WebAssembly::instantiate_module(&js_module, &custom_imports.as_jsvalue(&store).into());
let js_instance = wasm_bindgen_futures::JsFuture::from(js_instance_promise).await.unwrap();
let module: wasmer::Module = (js_module, wasm_binary).into();
let instance: wasmer::Instance = Instance::from_jsvalue(&mut store, &module, &js_instance)
.map_err(|_| "Error while creating BlackBox Functions vendor instance")
.unwrap();

(instance, memory, store)
}

fn logstr(mut env: FunctionEnvMut<Memory>, ptr: i32) {
Expand Down
19 changes: 0 additions & 19 deletions src/barretenberg/pedersen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,22 +23,3 @@ impl Pedersen for Barretenberg {
Ok((point_x, point_y))
}
}

#[test]
fn pedersen_hash_to_point() -> Result<(), Error> {
let barretenberg = Barretenberg::new();
let (x, y) = barretenberg.encrypt(vec![FieldElement::zero(), FieldElement::one()])?;
let expected_x = FieldElement::from_hex(
"0x11831f49876c313f2a9ec6d8d521c7ce0b6311c852117e340bfe27fd1ac096ef",
)
.unwrap();
let expected_y = FieldElement::from_hex(
"0x0ecf9d98be4597a88c46a7e0fa8836b57a7dcb41ee30f8d8787b11cc259c83fa",
)
.unwrap();

assert_eq!(expected_x.to_hex(), x.to_hex());
assert_eq!(expected_y.to_hex(), y.to_hex());
Ok(())
}
// }
18 changes: 0 additions & 18 deletions src/barretenberg/scalar_mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,3 @@ impl ScalarMul for Barretenberg {
Ok((pubkey_x, pubkey_y))
}
}

#[cfg(test)]
mod test {
use super::*;
#[test]
fn smoke_test() -> Result<(), Error> {
let barretenberg = Barretenberg::new();
let input = FieldElement::one();

let res = barretenberg.fixed_base(&input)?;
let x = "0000000000000000000000000000000000000000000000000000000000000001";
let y = "0000000000000002cf135e7506a45d632d270d45f1181294833fc48d823f272c";

assert_eq!(x, res.0.to_hex());
assert_eq!(y, res.1.to_hex());
Ok(())
}
}
53 changes: 0 additions & 53 deletions src/barretenberg/schnorr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,56 +102,3 @@ impl SchnorrSig for Barretenberg {
Ok(verified.try_into()?)
}
}

#[test]
fn basic_interop() -> Result<(), Error> {
let barretenberg = Barretenberg::new();

// First case should pass, standard procedure for Schnorr
let private_key = [2; 32];
let message = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

let public_key = barretenberg.construct_public_key(private_key)?;
let (sig_s, sig_e) = barretenberg.construct_signature(&message, private_key)?;
let valid_signature = barretenberg.verify_signature(public_key, sig_s, sig_e, &message)?;
assert!(valid_signature);

// Should fail, since the messages are different
let private_key = [2; 32];
let message = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

let public_key = barretenberg.construct_public_key(private_key)?;
let (sig_s, sig_e) = barretenberg.construct_signature(&message, private_key)?;
let valid_signature = barretenberg.verify_signature(public_key, sig_s, sig_e, &[0, 2])?;
assert!(!valid_signature);

// Should fail, since the signature is not valid
let private_key = [2; 32];
let message = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let sig_s = [1; 32];
let sig_e = [1; 32];

let public_key = barretenberg.construct_public_key(private_key)?;
let valid_signature = barretenberg.verify_signature(public_key, sig_s, sig_e, &message)?;
assert!(!valid_signature);

// Should fail, since the public key does not match
let private_key_a = [1; 32];
let private_key_b = [2; 32];
let message = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

let public_key_b = barretenberg.construct_public_key(private_key_b)?;
let (sig_s, sig_e) = barretenberg.construct_signature(&message, private_key_a)?;
let valid_signature = barretenberg.verify_signature(public_key_b, sig_s, sig_e, &message)?;
assert!(!valid_signature);

// Test the first case again, to check if memory is being freed and overwritten properly
let private_key = [2; 32];
let message = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

let public_key = barretenberg.construct_public_key(private_key)?;
let (sig_s, sig_e) = barretenberg.construct_signature(&message, private_key)?;
let valid_signature = barretenberg.verify_signature(public_key, sig_s, sig_e, &message)?;
assert!(valid_signature);
Ok(())
}
10 changes: 8 additions & 2 deletions src/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ use crate::{
JsWitnessMap,
};

#[derive(Default)]
struct SimulatedBackend {
blackbox_vendor: Barretenberg,
}

impl SimulatedBackend {
async fn initialize() -> SimulatedBackend {
let blackbox_vendor = Barretenberg::new().await;
SimulatedBackend { blackbox_vendor }
}
}

impl PartialWitnessGenerator for SimulatedBackend {
fn schnorr_verify(
&self,
Expand Down Expand Up @@ -152,7 +158,7 @@ pub async fn execute_circuit(
let circuit: Circuit = Circuit::read(&*circuit).expect("Failed to deserialize circuit");
let mut witness_map = WitnessMap::from(initial_witness);

let backend = SimulatedBackend::default();
let backend = SimulatedBackend::initialize().await;
let mut blocks = Blocks::default();
let mut opcodes = circuit.opcodes;

Expand Down
6 changes: 5 additions & 1 deletion test/browser/execute_circuit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import initACVMSimulator, {
abiDecode,
executeCircuit,
WitnessMap,
init_log_level,
} from "../../result/";

beforeEach(async () => {
await initACVMSimulator();

init_log_level("INFO");
});

it("successfully executes circuit and extracts return value", async () => {
Expand Down Expand Up @@ -37,7 +40,8 @@ it("successfully executes circuit and extracts return value", async () => {
expect(decoded_inputs.return_value).to.equal(expectedResult);
});

it("successfully executes a Pedersen opcode", async () => {
it("successfully executes a Pedersen opcode", async function () {
this.timeout(10000);
const { abi, bytecode, inputs, expectedResult } = await import(
"../shared/pedersen"
);
Expand Down
8 changes: 7 additions & 1 deletion web-test-runner.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import { esbuildPlugin } from "@web/dev-server-esbuild";
import { playwrightLauncher } from "@web/test-runner-playwright";

export default {
browsers: [playwrightLauncher({ product: "webkit" })],
browsers: [
playwrightLauncher({ product: "chromium" }),
playwrightLauncher({ product: "webkit" }),
// Firefox requires 40s to perform a Pedersen hash so we recommend using either
// a Chromium- or Webkit-based browser
// playwrightLauncher({ product: "firefox" }),
],
plugins: [
esbuildPlugin({
ts: true,
Expand Down

0 comments on commit 2d43c0d

Please sign in to comment.