1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00

Move wasm plugin generation to a different repo

This commit is contained in:
Guillaume Ballet 2019-01-14 13:45:54 +01:00
parent de1a9d6292
commit 1bc3947e5e
9 changed files with 38 additions and 436 deletions

View file

@ -4,8 +4,4 @@ members = [
"zokrates_core",
"zokrates_cli",
"zokrates_fs_resolver",
]
exclude = [
"plugins"
]

View file

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

View file

@ -1,152 +0,0 @@
[[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 = "conditioneq_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 = "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 = "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

@ -1,10 +0,0 @@
[package]
name = "conditioneq_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

@ -1,33 +0,0 @@
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

@ -60,222 +60,4 @@ fn main() {
println!("cargo:rustc-link-lib=static=ff");
}
}
// #[cfg(feature = "wasm")]
{
extern crate parity_wasm;
use std::env;
use std::io::prelude::*;
use std::path::Path;
use std::process::Command;
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
))
}
}
/* Turn the output binary into a source file for zokrates_core */
fn wasm2rs(fname: &str, modname: &str) {
match validate(fname) {
Ok(module) => {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join(format!("{}.rs", modname));
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!(
"
#[allow(dead_code)]
pub const {} : &'static [u8] = &{:?};
",
modname.to_uppercase(),
buf
)
.as_bytes(),
)
.unwrap();
}
Err(e) => panic!(format!("Module validation error: {}", e.to_string())),
}
}
/* 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/conditioneq_wasm")
.args(&["build", "--target", "wasm32-unknown-unknown", "--release"])
.status()
.unwrap();
if !status.success() {
panic!("Error building WASM helpers");
}
/* Scan the plugins directory and compile them */
if let Ok(entries) = std::fs::read_dir("../plugins") {
for entry in entries {
if let Ok(entry) = entry {
if let Ok(ftype) = entry.file_type() {
if ftype.is_dir() {
let fname = format!(
"{}/target/wasm32-unknown-unknown/release/{}.wasm",
entry.path().display(),
entry.file_name().to_str().unwrap()
);
wasm2rs(&fname, entry.file_name().to_str().unwrap());
}
}
}
}
}
}
}

View file

@ -169,7 +169,7 @@ impl Flattener {
// add a directive to get the bits
statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new(
lhs_bits.clone(),
Helper::Rust(RustHelper::Bits),
Helper::bits(),
vec![lhs_id],
)));
@ -216,7 +216,7 @@ impl Flattener {
// add a directive to get the bits
statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new(
rhs_bits.clone(),
Helper::Rust(RustHelper::Bits),
Helper::bits(),
vec![rhs_id],
)));
@ -273,7 +273,7 @@ impl Flattener {
// add a directive to get the bits
statements_flattened.push(FlatStatement::Directive(DirectiveStatement::new(
sub_bits.clone(),
Helper::Rust(RustHelper::Bits),
Helper::bits(),
vec![subtraction_result_id],
)));

View file

@ -1,17 +1,17 @@
#[cfg(feature = "libsnark")]
mod libsnark_gadget;
mod rust;
// #[cfg(feature = "wasm")]
#[cfg(feature = "wasm")]
mod wasm;
#[cfg(feature = "libsnark")]
pub use self::libsnark_gadget::LibsnarkGadgetHelper;
pub use self::rust::RustHelper;
#[cfg(feature = "wasm")]
pub use self::wasm::WasmHelper;
use flat_absy::{FlatExpression, FlatVariable};
use std::fmt;
use zokrates_field::field::Field;
include!(concat!(env!("OUT_DIR"), "/conditioneq_wasm.rs"));
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct DirectiveStatement<T: Field> {
@ -62,16 +62,39 @@ pub enum Helper {
#[cfg(feature = "libsnark")]
LibsnarkGadget(LibsnarkGadgetHelper),
Rust(RustHelper),
// #[cfg(feature = "wasm")]
#[cfg(feature = "wasm")]
Wasm(WasmHelper),
}
#[cfg(feature = "wasm")]
impl Helper {
pub fn identity() -> Self {
Helper::Wasm(WasmHelper::from_hex(WasmHelper::IDENTITY_WASM))
}
pub fn bits() -> Self {
Helper::Wasm(WasmHelper::from(WasmHelper::BITS_WASM))
}
}
#[cfg(not(feature = "wasm"))]
impl Helper {
pub fn identity() -> Self {
Helper::Rust(RustHelper::Identity)
}
pub fn bits() -> Self {
Helper::Rust(RustHelper::Bits)
}
}
impl fmt::Display for Helper {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
#[cfg(feature = "libsnark")]
Helper::LibsnarkGadget(ref h) => write!(f, "LibsnarkGadget::{}", h),
Helper::Rust(ref h) => write!(f, "Rust::{}", h),
#[cfg(feature = "wasm")]
Helper::Wasm(ref h) => write!(f, "Wasm::{}", h),
}
}
@ -94,6 +117,7 @@ impl<T: Field> Executable<T> for Helper {
#[cfg(feature = "libsnark")]
Helper::LibsnarkGadget(helper) => helper.execute(inputs),
Helper::Rust(helper) => helper.execute(inputs),
#[cfg(feature = "wasm")]
Helper::Wasm(helper) => helper.execute(inputs),
};
@ -115,6 +139,7 @@ impl Signed for Helper {
#[cfg(feature = "libsnark")]
Helper::LibsnarkGadget(helper) => helper.get_signature(),
Helper::Rust(helper) => helper.get_signature(),
#[cfg(feature = "wasm")]
Helper::Wasm(helper) => helper.get_signature(),
}
}

View file

@ -2,7 +2,7 @@ use bimap::BiMap;
use flat_absy::flat_parameter::FlatParameter;
use flat_absy::flat_variable::FlatVariable;
use flat_absy::*;
use helpers::{DirectiveStatement, Helper, RustHelper, WasmHelper};
use helpers::{DirectiveStatement, Helper};
use reduce::Reduce;
use types::constraints::Constraint;
use types::signature::Signature;
@ -85,7 +85,7 @@ pub fn unpack<T: Field>(nbits: usize) -> FlatProg<T> {
.map(|index| use_variable(&mut bijection, format!("o{}", index), &mut counter))
.collect();
let helper = Helper::Rust(RustHelper::Bits);
let helper = Helper::bits();
let signature = Signature {
inputs: vec![Type::FieldElement],
@ -253,12 +253,8 @@ pub fn cast<T: Field>(from: &Type, to: &Type) -> FlatFunction<T> {
.collect();
let helper = match (from, to) {
(Type::Boolean, Type::FieldElement) => {
Helper::Wasm(WasmHelper::from_hex(WasmHelper::IDENTITY_WASM))
}
(Type::FieldElement, Type::Boolean) => {
Helper::Wasm(WasmHelper::from_hex(WasmHelper::IDENTITY_WASM))
}
(Type::Boolean, Type::FieldElement) => Helper::identity(),
(Type::FieldElement, Type::Boolean) => Helper::identity(),
_ => panic!(format!("can't cast {} to {}", from, to)),
};
@ -317,7 +313,7 @@ mod tests {
f2b.statements[0],
FlatStatement::Directive(DirectiveStatement::new(
vec![FlatVariable::new(1)],
Helper::Wasm(WasmHelper::from_hex(WasmHelper::IDENTITY_WASM)),
Helper::identity(),
vec![FlatVariable::new(0)]
))
);
@ -343,7 +339,7 @@ mod tests {
b2f.statements[0],
FlatStatement::Directive(DirectiveStatement::new(
vec![FlatVariable::new(1)],
Helper::Wasm(WasmHelper::from_hex(WasmHelper::IDENTITY_WASM)),
Helper::identity(),
vec![FlatVariable::new(0)]
))
);
@ -380,7 +376,7 @@ mod tests {
(0..FieldPrime::get_required_bits())
.map(|i| FlatVariable::new(i + 1))
.collect(),
Helper::Rust(RustHelper::Bits),
Helper::bits(),
vec![FlatVariable::new(0)]
))
);