Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasm runtime: BLAKE2b implementation #1873

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* Runtime: update constant imports to use `node:fs` module (#1850)
* Runtime: make Obj.dup work with floats and boxed numbers (#1871)
* Lib: make the Wasm version of Json.output work with native ints and JavaScript objects (#1872)
* Runtime: implement BLAKE2b primitives for Wasm (#1873)

## Bug fixes
* Runtime: fix path normalization (#1848)
Expand Down
5 changes: 5 additions & 0 deletions compiler/tests-check-prim/main.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ caml_bigstring_blit_string_to_ba
caml_bigstring_memcmp
caml_hash_mix_bigstring

From +blake2.js:
blake2_js_for_wasm_create
blake2_js_for_wasm_final
blake2_js_for_wasm_update

From +effect.js:
jsoo_effect_not_supported

Expand Down
5 changes: 5 additions & 0 deletions compiler/tests-check-prim/unix-Unix.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ caml_bigstring_blit_string_to_ba
caml_bigstring_memcmp
caml_hash_mix_bigstring

From +blake2.js:
blake2_js_for_wasm_create
blake2_js_for_wasm_final
blake2_js_for_wasm_update

From +effect.js:
jsoo_effect_not_supported

Expand Down
5 changes: 5 additions & 0 deletions compiler/tests-check-prim/unix-Win32.5.3.output
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ caml_bigstring_blit_string_to_ba
caml_bigstring_memcmp
caml_hash_mix_bigstring

From +blake2.js:
blake2_js_for_wasm_create
blake2_js_for_wasm_final
blake2_js_for_wasm_update

From +effect.js:
jsoo_effect_not_supported

Expand Down
3 changes: 1 addition & 2 deletions compiler/tests-ocaml/lib-digest/dune
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@
(build_if
(>= %{ocaml_version} 5.2))
(modules digests)
; blake2b not supported by wasm_of_ocaml yet
(modes js))
(modes js wasm))
31 changes: 31 additions & 0 deletions runtime/js/blake2.js
Original file line number Diff line number Diff line change
Expand Up @@ -379,3 +379,34 @@ function caml_blake2_bytes(hashlen, key, buf, ofs, len) {
caml_blake2_update(ctx, buf, ofs, len);
return caml_blake2_final(ctx, hashlen);
}

//Provides: blake2_js_for_wasm_create
//Requires: caml_blake2_create, caml_string_of_jsbytes
//Version: >= 5.2
function blake2_js_for_wasm_create(hashlen, key) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should do something to make this available to wasm_of_ocaml only.
Are there other primitives used by wasmoo only ?

const key_jsoo_string = caml_string_of_jsbytes(key);
return caml_blake2_create(hashlen, key_jsoo_string);
}

//Provides: blake2_js_for_wasm_final
//Requires: caml_blake2_final, caml_jsbytes_of_string
//Version: >= 5.2
function blake2_js_for_wasm_final(ctx, hashlen) {
return caml_jsbytes_of_string(caml_blake2_final(ctx, hashlen));
}

//Provides: blake2_js_for_wasm_update
//Requires: caml_blake2_update, caml_bytes_of_jsbytes
//Version: >= 5.2, < 5.3
function blake2_js_for_wasm_update(ctx, buf, ofs, len) {
const buf_jsoo_string = caml_string_of_jsbytes(buf);
return caml_blake2_update(ctx, buf_jsoo_string, ofs, len);
}

//Provides: blake2_js_for_wasm_update
//Requires: caml_blake2_update, caml_bytes_of_jsbytes
//Version: >= 5.3
function blake2_js_for_wasm_update(ctx, buf, ofs, len) {
const buf_jsoo_string = caml_bytes_of_jsbytes(buf);
return caml_blake2_update(ctx, buf_jsoo_string, ofs, len);
}
90 changes: 90 additions & 0 deletions runtime/wasm/blake2.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
(module
(@if (>= ocaml_version (5 2 0))
(@then
(import "jslib" "wrap" (func $wrap (param anyref) (result (ref eq))))
(import "jslib" "unwrap" (func $unwrap (param (ref eq)) (result anyref)))
(import "jslib" "caml_string_of_jsbytes"
(func $caml_string_of_jsbytes (param (ref eq)) (result (ref eq))))
(import "jslib" "caml_jsbytes_of_string"
(func $caml_jsbytes_of_string (param (ref eq)) (result (ref eq))))

(import "js" "blake2_js_for_wasm_create"
(func $blake2_js_for_wasm_create (param (ref eq) anyref) (result anyref)))

(import "js" "blake2_js_for_wasm_update"
(func $blake2_js_for_wasm_update (param anyref anyref i32 i32)))

(import "js" "blake2_js_for_wasm_string"
(func $blake2_js_for_wasm_string
(param (ref eq) anyref anyref i32 i32) (result anyref)))

(import "js" "blake2_js_for_wasm_final"
(func $blake2_js_for_wasm_final (param anyref (ref eq)) (result anyref)))

(type $bytes (array (mut i8)))

(func (export "caml_blake2_create")
(param $hashlen (ref eq)) (param $key (ref eq)) (result (ref eq))
(return_call $wrap
(call $blake2_js_for_wasm_create
(local.get $hashlen)
(call $unwrap (call $caml_jsbytes_of_string (local.get $key))))))

(func $jsbytes_of_substring
(param $vbuf (ref eq)) (param $vofs (ref eq)) (param $vlen (ref eq))
(result anyref i32 i32)
(local $buf (ref $bytes)) (local $buf' (ref $bytes))
(local $ofs i32) (local $len i32)
(local.set $buf (ref.cast (ref $bytes) (local.get $vbuf)))
(local.set $ofs (i31.get_u (ref.cast (ref i31) (local.get $vofs))))
(local.set $len (i31.get_u (ref.cast (ref i31) (local.get $vlen))))
;; We copy the relevant part of the buffer if we only use a small portion
(if (i32.le_u (i32.shl (local.get $len) (i32.const 1))
(array.len (local.get $buf)))
(then
(local.set $buf' (array.new $bytes (i32.const 0) (local.get $len)))
(array.copy $bytes $bytes
(local.get $buf') (i32.const 0)
(local.get $buf) (local.get $ofs) (local.get $len))
(local.set $buf (local.get $buf'))
(local.set $ofs (i32.const 0))))
(tuple.make 3
(call $unwrap (call $caml_jsbytes_of_string (local.get $buf)))
(local.get $ofs)
(local.get $len)))

(func (export "caml_blake2_update")
(param $ctx (ref eq)) (param $buf (ref eq)) (param $ofs (ref eq))
(param $len (ref eq)) (result (ref eq))
(call $blake2_js_for_wasm_update
(call $unwrap (local.get $ctx))
(call $jsbytes_of_substring
(local.get $buf) (local.get $ofs) (local.get $len)))
(ref.i31 (i32.const 0)))

(func (export "caml_blake2_final")
(param $ctx (ref eq)) (param $hashlen (ref eq)) (result (ref eq))
(return_call $caml_string_of_jsbytes
(call $wrap
(call $blake2_js_for_wasm_final
(call $unwrap (local.get $ctx))
(local.get $hashlen)))))

(func (export "caml_blake2_string") (export "caml_blake2_bytes")
(param $hashlen (ref eq)) (param $key (ref eq)) (param $buf (ref eq))
(param $ofs (ref eq)) (param $len (ref eq)) (result (ref eq))
(local $ctx anyref)
(local.set $ctx
(call $blake2_js_for_wasm_create
(local.get $hashlen)
(call $unwrap (call $caml_jsbytes_of_string (local.get $key)))))
(call $blake2_js_for_wasm_update
(local.get $ctx)
(call $jsbytes_of_substring
(local.get $buf) (local.get $ofs) (local.get $len)))
(return_call $caml_string_of_jsbytes
(call $wrap
(call $blake2_js_for_wasm_final
(local.get $ctx) (local.get $hashlen)))))
))
)
Loading