Skip to content

Commit

Permalink
Wasm Pack Fixes (#609)
Browse files Browse the repository at this point in the history
* update wasm with new verifier api

* fmt

* Re add wasm compile and test

* Add wasm commands to makefile

* Add wasm commands to makefile

* Fix wasm commands

* Fix wasm

* Fix wasm CI

* Fmt

* Fmt + fmt ci wasm

* Compatibility with main

* Fix

* Fmt

* Remove unnecesary clone

* Fix linters

* Raise security

* Re add dep

* Wasm

---------

Co-authored-by: Mauro Toscano <[email protected]>
Co-authored-by: MauroFab <[email protected]>
  • Loading branch information
3 people authored Nov 3, 2023
1 parent e54efbe commit ee1200b
Show file tree
Hide file tree
Showing 8 changed files with 1,328 additions and 1,977 deletions.
26 changes: 25 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,31 @@ jobs:
token: ${{ secrets.CODECOV_TOKEN }}
files: lcov.info
fail_ci_if_error: true


test_wasm_pack:
name: Test wasm-pack
runs-on: ubuntu-latest
env:
CARGO_TERM_COLOR: always
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
components: clippy

- name: Set up cargo cache
uses: Swatinem/rust-cache@v2

- name: Install wasm-pack tools for testing
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh

- name: Run wasm-pack tests in firefox
run: cd provers/cairo && wasm-pack test --release --firefox --headless -- --features wasm

- name: Run wasm-pack tests in chrome
run: cd provers/cairo && wasm-pack test --release --chrome --headless -- --features wasm

test_macos:
name: Test (macOS, Apple sillicon)
runs-on: [self-hosted, macOS]
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ test: $(COMPILED_CAIRO0_PROGRAMS)

clippy:
cargo clippy --workspace --all-targets -- -D warnings
cargo clippy --workspace --all-targets --features wasm -- -D warnings
cargo clippy --workspace --all-targets --features cli -- -D warnings
cargo clippy --tests

clippy-cuda:
Expand Down Expand Up @@ -89,3 +91,8 @@ run-cuda-fuzzer:
cd fuzz/cuda_fuzz
cargo hfuzz run $(CUDAFUZZER)

build_wasm:
cd provers/cairo && wasm-pack build --release --target=web -- --features wasm

test_wasm_with_firefox:
cd provers/cairo && wasm-pack test --release --firefox --headless -- --features wasm
6 changes: 6 additions & 0 deletions provers/cairo/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,9 @@ clean:
rm -f $(CAIRO0_PROGRAMS_DIR)/*.json
rm -f $(CAIRO0_PROGRAMS_DIR)/*.trace
rm -f $(CAIRO0_PROGRAMS_DIR)/*.memory

build_wasm:
wasm-pack build --target=web -- --features wasm

test_wasm:
wasm-pack test --node --release -- --features wasm
6 changes: 0 additions & 6 deletions provers/cairo/cairo-prover-lib/requirements.txt

This file was deleted.

1,942 changes: 0 additions & 1,942 deletions provers/cairo/cairo-prover-lib/tests/wasm.rs

This file was deleted.

29 changes: 21 additions & 8 deletions provers/cairo/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField;
use lambdaworks_math::traits::{Deserializable, Serializable};
use platinum_prover::air::{generate_cairo_proof, verify_cairo_proof, PublicInputs};
use platinum_prover::cairo_layout::CairoLayout;
use platinum_prover::runner::run::generate_prover_args;
Expand Down Expand Up @@ -167,18 +166,28 @@ fn write_proof(
proof_path: String,
) {
let mut bytes = vec![];

let proof_bytes: Vec<u8> =
bincode::serde::encode_to_vec(&proof, bincode::config::standard()).unwrap();
bincode::serde::encode_to_vec(proof, bincode::config::standard()).unwrap();

let pub_inputs_bytes: Vec<u8> =
bincode::serde::encode_to_vec(&pub_inputs, bincode::config::standard()).unwrap();

// This should be reworked
// Public inputs shouldn't be stored in the proof if the verifier wants to check them

// An u32 is enough for storing proofs up to 32 GiB
// They shouldn't exceed the order of kbs
// Reading an usize leads to problem in WASM (32 bit vs 64 bit architecture)

bytes.extend(proof_bytes.len().to_be_bytes());
bytes.extend((proof_bytes.len() as u32).to_le_bytes());
bytes.extend(proof_bytes);
bytes.extend(pub_inputs.serialize());
bytes.extend(pub_inputs_bytes);

let Ok(()) = std::fs::write(&proof_path, bytes) else {
eprintln!("Error writing proof to file: {}", &proof_path);
return;
};

println!("Proof written to {}", &proof_path);
}

Expand Down Expand Up @@ -220,8 +229,10 @@ fn main() {
return;
}

let proof_len = usize::from_be_bytes(bytes[0..8].try_into().unwrap());
bytes = &bytes[8..];
// Proof len was stored as an u32, 4u8 needs to be read
let proof_len = u32::from_le_bytes(bytes[0..4].try_into().unwrap()) as usize;

bytes = &bytes[4..];
if bytes.len() < proof_len {
eprintln!("Error reading proof from file: {}", args.proof_path);
return;
Expand All @@ -236,7 +247,9 @@ fn main() {
};
bytes = &bytes[proof_len..];

let Ok(pub_inputs) = PublicInputs::deserialize(bytes) else {
let Ok((pub_inputs, _)) =
bincode::serde::decode_from_slice(bytes, bincode::config::standard())
else {
println!("Error reading proof from file: {}", args.proof_path);
return;
};
Expand Down
53 changes: 33 additions & 20 deletions provers/cairo/src/wasm_wrappers.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use super::air::{CairoAIR, PublicInputs};
use crate::air::MemorySegment;
use super::air::CairoAIR;
use lambdaworks_math::field::element::FieldElement;
use lambdaworks_math::field::fields::fft_friendly::stark_252_prime_field::Stark252PrimeField;
use serde::{Deserialize, Serialize};
use stark_platinum_prover::proof::options::ProofOptions;
use stark_platinum_prover::proof::stark::StarkProof;
use stark_platinum_prover::verifier::verify;
use stark_platinum_prover::transcript::StoneProverTranscript;
use stark_platinum_prover::verifier::{IsStarkVerifier, Verifier};
use std::collections::HashMap;
use std::ops::Range;
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]
Expand All @@ -17,27 +16,41 @@ pub struct Stark252PrimeFieldProof(StarkProof<Stark252PrimeField>);
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Eq, PartialEq, Hash)]
pub struct FE(FieldElement<Stark252PrimeField>);

#[wasm_bindgen]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemorySegmentMap(HashMap<MemorySegment, Range<u64>>);

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MemoryMap(HashMap<FE, FE>);

#[wasm_bindgen]
pub fn verify_cairo_proof_wasm(
proof: &Stark252PrimeFieldProof,
pub_input_serialized: &[u8],
proof_options: &ProofOptions,
) -> bool {
let pub_input: PublicInputs = serde_cbor::from_slice(pub_input_serialized).unwrap();
verify::<Stark252PrimeField, CairoAIR>(&proof.0, &pub_input, proof_options)
}
pub fn verify_cairo_proof_wasm(proof_bytes: &[u8], proof_options: &ProofOptions) -> bool {
let bytes = proof_bytes;

#[wasm_bindgen]
pub fn deserialize_proof_wasm(proof: &[u8]) -> Stark252PrimeFieldProof {
let proof_inner: StarkProof<Stark252PrimeField> = serde_cbor::from_slice(proof).unwrap();
Stark252PrimeFieldProof(proof_inner)
// This logic is the same as main verify, with only error handling changing. In wasm, we simply return a false if the proof is invalid, instead of rising an error.

// Proof len was stored as an u32, 4u8 needs to be read
let proof_len = u32::from_le_bytes(bytes[0..4].try_into().unwrap()) as usize;

let bytes = &bytes[4..];
if bytes.len() < proof_len {
return false;
}

let Ok((proof, _)) =
bincode::serde::decode_from_slice(&bytes[0..proof_len], bincode::config::standard())
else {
return false;
};
let bytes = &bytes[proof_len..];

let Ok((pub_inputs, _)) = bincode::serde::decode_from_slice(bytes, bincode::config::standard())
else {
return false;
};

Verifier::verify::<CairoAIR>(
&proof,
&pub_inputs,
proof_options,
StoneProverTranscript::new(&[]),
)
}

#[wasm_bindgen]
Expand Down
Loading

0 comments on commit ee1200b

Please sign in to comment.