You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I developed the environment to call wasm functions in the following manner.
First, I made an implementation in Rust calling exported wasm functions and getting a memory hosted in wasm.
This is a code of Wasmer version.
Second, I exported the rust functions with neon (https://github.com/neon-bindings/neon) so that they are called from js. Moreover, I added the functions that get/set uint8 or uint32 values from/to the memory.
use neon::prelude::*;
use crate::{WasmInstance};
use lazy_static::lazy_static;
use wasmer_runtime::{
WasmPtr,
Instance,
Module,
types::{
MemoryDescriptor
},
units::*,
memory::{
Memory
},
Ctx,
instantiate,
DynFunc,
Value,
Func,
imports,
func,
error,
};
lazy_static! {
static ref INSTANCE: WasmInstance = {
let bytes = include_bytes!("../test_circom/mul_bn128.wasm");
WasmInstance::new(bytes)
};
}
register_module!(mut cx, {
cx.export_function("init", init);
cx.export_function("getSignalOffset32", get_signal_offset32);
cx.export_function("getMultiSignal", get_multi_signal);
cx.export_function("setSignal", set_signal);
cx.export_function("getPWitness", get_p_witness);
cx.export_function("getWitnessBuffer", get_witness_buffer);
cx.export_function("getFrLen", get_fr_len);
cx.export_function("getPRawPrime", get_p_raw_prime);
cx.export_function("getNVars", get_n_vars);
cx.export_function("setU32Memory", set_u32_memory);
cx.export_function("getU8Memory", get_u8_memory);
cx.export_function("getU32Memory", get_u32_memory)
});
pub fn init(mut cx: FunctionContext) -> JsResult<JsUndefined> {
const INPUT_SIZE:usize = 1;
let mut inputs:[i32;INPUT_SIZE] = [0;INPUT_SIZE];
for i in 0..INPUT_SIZE {
inputs[i] = cx.argument::<JsNumber>(i as i32)?.value() as i32;
}
INSTANCE.init(inputs);
Ok(cx.undefined())
}
pub fn get_signal_offset32(mut cx: FunctionContext) -> JsResult<JsUndefined> {
const INPUT_SIZE:usize = 4;
let mut inputs:[i32;INPUT_SIZE] = [0;INPUT_SIZE];
for i in 0..INPUT_SIZE {
inputs[i] = cx.argument::<JsNumber>(i as i32)?.value() as i32;
}
INSTANCE.get_signal_offset32(inputs);
Ok(cx.undefined())
}
pub fn get_multi_signal(mut cx: FunctionContext) -> JsResult<JsUndefined> {
const INPUT_SIZE:usize = 5;
let mut inputs:[i32;INPUT_SIZE] = [0;INPUT_SIZE];
for i in 0..INPUT_SIZE {
inputs[i] = cx.argument::<JsNumber>(i as i32)?.value() as i32;
}
INSTANCE.get_multi_signal(inputs);
Ok(cx.undefined())
}
pub fn set_signal(mut cx: FunctionContext) -> JsResult<JsUndefined> {
const INPUT_SIZE:usize =4;
let mut inputs:[i32;INPUT_SIZE] = [0;INPUT_SIZE];
for i in 0..INPUT_SIZE {
inputs[i] = cx.argument::<JsNumber>(i as i32)?.value() as i32;
}
INSTANCE.set_signal(inputs);
Ok(cx.undefined())
}
pub fn get_p_witness(mut cx: FunctionContext) -> JsResult<JsNumber> {
const INPUT_SIZE:usize = 1;
let mut inputs:[i32;INPUT_SIZE] = [0;INPUT_SIZE];
for i in 0..INPUT_SIZE {
inputs[i] = cx.argument::<JsNumber>(i as i32)?.value() as i32;
}
let result = INSTANCE.get_p_witness(inputs);
Ok(cx.number(result))
}
pub fn get_witness_buffer(mut cx: FunctionContext) -> JsResult<JsNumber> {
let result = INSTANCE.get_witness_buffer();
Ok(cx.number(result))
}
pub fn get_fr_len(mut cx: FunctionContext) -> JsResult<JsNumber> {
let result = INSTANCE.get_fr_len();
Ok(cx.number(result))
}
pub fn get_p_raw_prime(mut cx: FunctionContext) -> JsResult<JsNumber> {
let result = INSTANCE.get_p_raw_prime();
Ok(cx.number(result))
}
pub fn get_n_vars(mut cx: FunctionContext) -> JsResult<JsNumber> {
let result = INSTANCE.get_n_vars();
Ok(cx.number(result))
}
pub fn set_u32_memory(mut cx: FunctionContext) -> JsResult<JsUndefined> {
let offset = cx.argument::<JsNumber>(0)?.value() as u32;
let value = cx.argument::<JsNumber>(1)?.value() as u32;
let v_bytes = value.to_le_bytes();
let memory = INSTANCE.get_memory();
for i in 0..4{
let ptr = WasmPtr::<u8>::new(4*offset+i as u32);
let derefed_ptr = ptr.deref(memory).unwrap();
derefed_ptr.set(v_bytes[i as usize] as u8);
}
Ok(cx.undefined())
}
pub fn get_u8_memory(mut cx: FunctionContext) -> JsResult<JsNumber> {
let offset = cx.argument::<JsNumber>(0)?.value() as u32;
let value = _get_u8_memory(offset);
Ok(cx.number(f64::from(value)))
}
pub fn get_u32_memory(mut cx: FunctionContext) -> JsResult<JsNumber> {
let offset = cx.argument::<JsNumber>(0)?.value() as u32;
let mut bytes4:[u8;4] = [0;4];
for i in 0..4 {
let value = _get_u8_memory(4*offset+i as u32);
bytes4[i] = value;
}
let value:u32 = u32::from_le_bytes(bytes4);
Ok(cx.number(f64::from(value)))
}
fn _get_u8_memory(offset:u32) -> u8 {
let memory = INSTANCE.get_memory();
let ptr = WasmPtr::<u8>::new(offset);
//println!("u8 ptr is {:?}", ptr);
let derefed_ptr = ptr.deref(memory).unwrap();
let value:u8 = derefed_ptr.get();
value
}
When executing the wasm file generated from the following circom file, it returned an error at "getSignalOffset32" function.
Its error message from the wasm was "code:3, pstr:104, a:0, b:0, c:0, d:0", which represented that the hashes of input names were not found in the memory. (https://github.com/iden3/circom/blob/master/ports/wasm/errs.js)
template Mul() {
signal input in[2];
signal output out;
signal dbl <== in[1] * in[1];
out <== in[0] * dbl;
}
component main = Mul();
Before calling the "getSignalOffset32" function, I compared the values of the wasm memory in the Rust environment with those of WebAssembly.Memory in js, and all values were identical. In other words, although both environments had the same inputs and values of the memory, only Rust one returned the error. I would appreciate it if you could give me the advice to solve this error.
Abstruct
I tried to execute wasm files generated by circom in the Rust environment, that is, Wasmi (https://github.com/paritytech/wasmi) and Wasmer (https://github.com/wasmerio/wasmer).
It, however, returned an error at "getSignalOffset32" function.
My attempt
I developed the environment to call wasm functions in the following manner.
First, I made an implementation in Rust calling exported wasm functions and getting a memory hosted in wasm.
This is a code of Wasmer version.
Second, I exported the rust functions with neon (https://github.com/neon-bindings/neon) so that they are called from js. Moreover, I added the functions that get/set uint8 or uint32 values from/to the memory.
Third, I modified the witness_calculator.js in https://github.com/iden3/circom_runtime/blob/master/js/witness_calculator.js to call the functions exported with neon. It also executed a wasm with the WebAssembly object in js.
Result
When executing the wasm file generated from the following circom file, it returned an error at "getSignalOffset32" function.
Its error message from the wasm was "code:3, pstr:104, a:0, b:0, c:0, d:0", which represented that the hashes of input names were not found in the memory. (https://github.com/iden3/circom/blob/master/ports/wasm/errs.js)
Before calling the "getSignalOffset32" function, I compared the values of the wasm memory in the Rust environment with those of WebAssembly.Memory in js, and all values were identical. In other words, although both environments had the same inputs and values of the memory, only Rust one returned the error. I would appreciate it if you could give me the advice to solve this error.
Environment
OS: macOS v10.13.4
node: v14.8.0
snarkjs: v0.3.44
circom: v0.5.35
rustc: v1.49.0-nightly
wasmer-runtime: v0.17.1
neon: v0.5.1
The text was updated successfully, but these errors were encountered: