Wednesday, July 19, 2023

TypeScript => WASM

 wasmati: You should write your WebAssembly in TypeScript - ZKSECURITY

wasmati (@GitHub), a TypeScript library to write Wasm at the instruction level. The wasmati API looks exactly like Webassembly text format (WAT).

import { i64, func, local } from "wasmati";

const myMultiply = func({ in: [i64, i64], out: [i64] }, ([x, y]) => {
  local.get(x); // put input x on the stack
  local.get(y); // put input y on the stack
  i64.mul(); // pop the two last values from the stack, multiply them, put the result on the stack
});

For reference, this would be an equivalent WAT code snippet:

(func $myMultiply (param $x i64) (param $y i64) (result i64)
  (local.get $x)
  (local.get $y)
  i64.mul
)


zksecurity/wasmati: Write low-level WebAssembly, from JavaScript @GitHub

  • Readability. Wasm code looks imperative - like writing WAT by hand, just with better DX:

const myFunction = func({ in: [i32, i32], out: [i32] }, ([x, y]) => {
  local.get(x);
  local.get(y);
  i32.add();
  i32.const(2);
  i32.shl();
  call(otherFunction);
});
  • Optional syntax sugar to reduce boilerplate assembly like local.get and i32.const

const myFunction = func({ in: [i32, i32], out: [i32] }, ([x, y]) => {
  i32.add(x, y); // local.get(x), local.get(y) are filled in
  i32.shl($, 2); // $ is the top of the stack; i32.const(2) is filled in
  call(otherFunction);
});

// or also

const myFunction = func({ in: [i32, i32], out: [i32] }, ([x, y]) => {
  let z = i32.add(x, y);
  call(otherFunction, [i32.shl(z, 2)]);
});


similar tools

different approaches taken by ZPrize participants:

  • The winning team, Yrrid led by Niall Emmart, wrote their code from scratch in C and compiled it to Wasm with clang. They auto-generated the C code for finite field arithmetic using Java.
  • My submission used mostly JS, plus raw Wasm generated using a hacked-together, badly-typed JS lib for dumping WAT syntax into a string.
  • The third-placing team used a fork of wasmcurves by Jordi Baylina, which generates Wasm using a JS package called wasmbuilder. This is similar in spirit to wasmati, without the API polish and types.
  • The 4th-placing team used Go (gnark) compiled to Wasm
  • The 5th-placing team used Rust (arkworks) compiled to Wasm
  • The 6th-placing team used C (MIRACL Core) compiled to Wasm

evanw/polywasm @GitHub
This is a polyfill for WebAssembly. It implements enough of the WebAssembly API to be able to run a .wasm file in a JavaScript environment that lacks a