1
0
Fork 0
mirror of synced 2025-09-23 12:18:44 +00:00

Add a repo to support the WASM version of partial_eq

This commit is contained in:
Guillaume Ballet 2019-01-03 15:30:08 +01:00
parent 0ce5406fc8
commit cc21fd21be
8 changed files with 428 additions and 1 deletions

2
plugins/partialeq_wasm/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/target
**/*.rs.bk

152
plugins/partialeq_wasm/Cargo.lock generated Normal file
View file

@ -0,0 +1,152 @@
[[package]]
name = "bincode"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byteorder"
version = "1.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-bigint"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-integer"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-iter"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "partialeq_wasm"
version = "0.1.0"
dependencies = [
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"zokrates_field 0.3.0",
]
[[package]]
name = "proc-macro2"
version = "0.4.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "zokrates_field"
version = "0.3.0"
dependencies = [
"bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
"checksum byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "94f88df23a25417badc922ab0f5716cc1330e87f71ddd9203b3a3ccd9cedf75d"
"checksum lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "cf186d1a8aa5f5bee5fd662bc9c1b949e0259e1bcc379d1f006847b0080c7417"
"checksum num 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e"
"checksum num-bigint 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
"checksum serde 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)" = "6fa52f19aee12441d5ad11c9a00459122bd8f98707cadf9778c540674f1935b6"
"checksum serde_derive 1.0.82 (registry+https://github.com/rust-lang/crates.io-index)" = "96a7f9496ac65a2db5929afa087b54f8fc5008dcfbe48a8874ed20049b0d6154"
"checksum syn 0.15.23 (registry+https://github.com/rust-lang/crates.io-index)" = "9545a6a093a3f0bd59adb472700acc08cad3776f860f16a897dfce8c88721cbc"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"

View file

@ -0,0 +1,10 @@
[package]
name = "partialeq_wasm"
version = "0.1.0"
authors = ["Guillaume Ballet <gballet@gmail.com>"]
edition = "2018"
[dependencies]
num = {version = "0.1.36", default-features = false}
lazy_static = "0.1.*"
zokrates_field = {version = "0.3", path = "../../zokrates_field" }

View file

@ -0,0 +1,33 @@
extern crate zokrates_field;
extern crate num;
use zokrates_field::field::{Field, FieldPrime};
use num::{Zero, One};
static INPUT_BUFFER : [u8;32] = [0u8;32];
static mut OUTPUT_BUFFER : [u8;64] = [0u8;64];
#[no_mangle]
pub extern "C" fn get_inputs_off() -> *const u8 {
return &INPUT_BUFFER as *const u8;
}
#[no_mangle]
pub unsafe extern "C" fn solve() -> *const u8 {
// Transform the input bytes into output
let input = FieldPrime::from_byte_vector(Vec::from(&INPUT_BUFFER[..]));
let (output0, output1) = if input.is_zero() {
(FieldPrime::zero(), FieldPrime::one())
} else {
(FieldPrime::one(), FieldPrime::one() / input)
};
// Transform outputs back into bytes
&OUTPUT_BUFFER[..32].copy_from_slice(&output0.into_byte_vector()[..]);
&OUTPUT_BUFFER[32..].copy_from_slice(&output1.into_byte_vector()[..]);
return &OUTPUT_BUFFER as *const u8;
}
fn main() {
}

View file

@ -36,3 +36,4 @@ assert_cli = "0.5"
[build-dependencies]
cc = { version = "1.0", features = ["parallel"] }
cmake = "0.1.31"
parity-wasm = "0.35.3"

View file

@ -60,4 +60,233 @@ fn main() {
println!("cargo:rustc-link-lib=static=ff");
}
}
// #[cfg(feature = "wasm")]
{
extern crate parity_wasm;
use std::env;
use std::path::Path;
use std::process::Command;
use std::io::prelude::*;
fn has_symbol(symbol : &str,
exports : &[parity_wasm::elements::ExportEntry], funcs: &[parity_wasm::elements::Func], types: &[parity_wasm::elements::Type]) -> Result<(), String> {
match exports.iter().find(|ref export| export.field() == symbol) {
Some(export) => {
match export.internal() {
&parity_wasm::elements::Internal::Function(fidx) => {
let tidx = funcs[fidx as usize].type_ref();
let parity_wasm::elements::Type::Function(t) = &types[tidx as usize];
match t.return_type() {
Some(parity_wasm::elements::ValueType::I32) => {}
_ => return Err(format!("Invalid return type for `{}", symbol))
}
let params = t.params();
if params.len() != 0 {
Err(format!("Invalid number of parameters for `{}`", symbol))
} else {
Ok(())
}
}
_ => return Err(format!("Module has a `{}` export that is not a function", symbol))
}
}
None => Err(format!("Module is missing a `{}` export", symbol))
}
}
fn validate<U : Into<String>>(input : U) -> Result<parity_wasm::elements::Module, String> {
let fname = input.into();
let module = parity_wasm::deserialize_file(fname.clone())
.map_err(|e| e.to_string())?;
let functions = module.function_section()
.ok_or("Module has no function section")?
.entries();
let types = module.type_section()
.ok_or("Module has no function section")?
.types();
let exports = module.export_section()
.ok_or("Module has no export section")?
.entries();
/* Look for `get_input_offs` */
has_symbol("get_inputs_off", exports, functions, types)?;
/* Look for `solve` */
has_symbol("solve", exports, functions, types)?;
Ok(module.clone())
}
fn add_global(symbol : &str, module : &parity_wasm::elements::Module, value : i32) -> Result<parity_wasm::elements::Module, String> {
let nglobals = module
.global_section()
.unwrap()
.entries()
.len();
println!("Adding global at index {}", nglobals);
let nm = parity_wasm::builder::from_module(module.clone())
.global()
.value_type().i32()
.init_expr(parity_wasm::elements::Instruction::I32Const(value))
.build()
.export()
.field(symbol)
.internal()
.global(nglobals as u32)
.build()
.build();
Ok(nm)
}
fn add_global_if_missing(symbol : &str, module : &parity_wasm::elements::Module, expected_type : parity_wasm::elements::ValueType, value : i32, _force : bool) -> Result<parity_wasm::elements::Module, String> {
let global_section = module.global_section()
.ok_or("Could not get globals section")?
.entries()
.clone();
let exports = module
.export_section()
.ok_or("Could not get exports section")?
.entries();
let mut found = false;
if let Some(export) = exports.iter().find(|ref export| export.field() == symbol) {
found = true;
// Export already exists, check its type and return it if said
// type is correct.
if let &parity_wasm::elements::Internal::Global(gidx) = export.internal() {
let global_type = global_section[gidx as usize]
.global_type();
if !global_type.is_mutable() && expected_type == global_type.content_type() {
return Ok(module.clone());
}
}
}
/* overwrite only if asked with the -f switch */
if !found {
add_global(symbol, module, value)
} else {
Err(format!("Symbol {} is already present with a different type in module", symbol))
}
}
/* Regenerate if files have changed */
println!("cargo:rerun-if-changed=./plugins");
/* Build the WASM helpers and turn them into files */
let status = Command::new("cargo")
.current_dir("../plugins/partialeq_wasm")
.args(&["build", "--target", "wasm32-unknown-unknown", "--release"])
.status()
.unwrap();
if !status.success() {
panic!("Error building WASM helpers");
}
/* Turn the output binary into a source file for zokrates_core */
let fname =
"../plugins/partialeq_wasm/target/wasm32-unknown-unknown/release/partialeq_wasm.wasm";
match validate(fname) {
Ok(module) => {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("partialeq_wasm.rs");
let m0 = module.clone();
let m1 = add_global_if_missing(
"min_inputs",
&m0,
parity_wasm::elements::ValueType::I32,
1,
false,
)
.unwrap();
let m2 = add_global_if_missing(
"min_outputs",
&m1,
parity_wasm::elements::ValueType::I32,
2,
false,
)
.unwrap();
let m3 = add_global_if_missing(
"field_size",
&m2,
parity_wasm::elements::ValueType::I32,
32,
false,
)
.unwrap();
let buf = parity_wasm::serialize(m3).unwrap();
std::fs::File::create(dest_path)
.unwrap()
.write_all(
format!(
"
pub const PARTIALEQ_WASM : &'static [u8] = &{:?};
",
buf
)
.as_bytes(),
)
.unwrap();
}
Err(e) => panic!(format!("Module validation error: {}", e.to_string())),
}
}
} }
/* Turn the output binary into a source file for zokrates_core */
let fname =
"../plugins/partialeq_wasm/target/wasm32-unknown-unknown/release/partialeq_wasm.wasm";
match validate(fname) {
Ok(module) => {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("partialeq_wasm.rs");
let m0 = module.clone();
let m1 = add_global_if_missing(
"min_inputs",
&m0,
parity_wasm::elements::ValueType::I32,
1,
false,
)
.unwrap();
let m2 = add_global_if_missing(
"min_outputs",
&m1,
parity_wasm::elements::ValueType::I32,
2,
false,
)
.unwrap();
let m3 = add_global_if_missing(
"field_size",
&m2,
parity_wasm::elements::ValueType::I32,
32,
false,
)
.unwrap();
let buf = parity_wasm::serialize(m3).unwrap();
std::fs::File::create(dest_path)
.unwrap()
.write_all(
format!(
"
pub const PARTIALEQ_WASM : &'static [u8] = &{:?};
",
buf
)
.as_bytes(),
)
.unwrap();
}
Err(e) => panic!(format!("Module validation error: {}", e.to_string())),
}
}
}

View file

@ -11,6 +11,7 @@ pub use self::wasm::WasmHelper;
use flat_absy::{FlatExpression, FlatVariable};
use std::fmt;
use zokrates_field::field::Field;
include!(concat!(env!("OUT_DIR"), "/partialeq_wasm.rs"));
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct DirectiveStatement<T: Field> {

View file

@ -5,7 +5,6 @@ authors = ["Guillaume Ballet <gballet@gmail.com>"]
edition = "2018"
[dependencies]
serde = "1.0"
serde_derive = "1.0"
lazy_static = "0.1.*"