Skip to content

Commit a1f1b46

Browse files
vouillonrickyvetter
andcommitted
Wasm runtime: BLAKE2b implementation
Co-authored-by: Ricky Vetter <rickywvetter@gmail.com>
1 parent 559fbce commit a1f1b46

File tree

7 files changed

+138
-2
lines changed

7 files changed

+138
-2
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* Runtime: update constant imports to use `node:fs` module (#1850)
1111
* Runtime: make Obj.dup work with floats and boxed numbers (#1871)
1212
* Lib: make the Wasm version of Json.output work with native ints and JavaScript objects (#1872)
13+
* Runtime: implement BLAKE2b primitives for Wasm (#1873)
1314

1415
## Bug fixes
1516
* Runtime: fix path normalization (#1848)

compiler/tests-check-prim/main.5.3.output

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ caml_bigstring_blit_string_to_ba
2727
caml_bigstring_memcmp
2828
caml_hash_mix_bigstring
2929

30+
From +blake2.js:
31+
blake2_js_for_wasm_create
32+
blake2_js_for_wasm_final
33+
blake2_js_for_wasm_update
34+
3035
From +effect.js:
3136
jsoo_effect_not_supported
3237

compiler/tests-check-prim/unix-Unix.5.3.output

+5
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ caml_bigstring_blit_string_to_ba
103103
caml_bigstring_memcmp
104104
caml_hash_mix_bigstring
105105

106+
From +blake2.js:
107+
blake2_js_for_wasm_create
108+
blake2_js_for_wasm_final
109+
blake2_js_for_wasm_update
110+
106111
From +effect.js:
107112
jsoo_effect_not_supported
108113

compiler/tests-check-prim/unix-Win32.5.3.output

+5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ caml_bigstring_blit_string_to_ba
7676
caml_bigstring_memcmp
7777
caml_hash_mix_bigstring
7878

79+
From +blake2.js:
80+
blake2_js_for_wasm_create
81+
blake2_js_for_wasm_final
82+
blake2_js_for_wasm_update
83+
7984
From +effect.js:
8085
jsoo_effect_not_supported
8186

compiler/tests-ocaml/lib-digest/dune

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,4 @@
1010
(build_if
1111
(>= %{ocaml_version} 5.2))
1212
(modules digests)
13-
; blake2b not supported by wasm_of_ocaml yet
14-
(modes js))
13+
(modes js wasm))

runtime/js/blake2.js

+31
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,34 @@ function caml_blake2_bytes(hashlen, key, buf, ofs, len) {
379379
caml_blake2_update(ctx, buf, ofs, len);
380380
return caml_blake2_final(ctx, hashlen);
381381
}
382+
383+
//Provides: blake2_js_for_wasm_create
384+
//Requires: caml_blake2_create, caml_string_of_jsbytes
385+
//Version: >= 5.2
386+
function blake2_js_for_wasm_create(hashlen, key) {
387+
const key_jsoo_string = caml_string_of_jsbytes(key);
388+
return caml_blake2_create(hashlen, key_jsoo_string);
389+
}
390+
391+
//Provides: blake2_js_for_wasm_final
392+
//Requires: caml_blake2_final, caml_jsbytes_of_string
393+
//Version: >= 5.2
394+
function blake2_js_for_wasm_final(ctx, hashlen) {
395+
return caml_jsbytes_of_string(caml_blake2_final(ctx, hashlen));
396+
}
397+
398+
//Provides: blake2_js_for_wasm_update
399+
//Requires: caml_blake2_update, caml_bytes_of_jsbytes
400+
//Version: >= 5.2, < 5.3
401+
function blake2_js_for_wasm_update(ctx, buf, ofs, len) {
402+
const buf_jsoo_string = caml_string_of_jsbytes(buf);
403+
return caml_blake2_update(ctx, buf_jsoo_string, ofs, len);
404+
}
405+
406+
//Provides: blake2_js_for_wasm_update
407+
//Requires: caml_blake2_update, caml_bytes_of_jsbytes
408+
//Version: >= 5.3
409+
function blake2_js_for_wasm_update(ctx, buf, ofs, len) {
410+
const buf_jsoo_string = caml_bytes_of_jsbytes(buf);
411+
return caml_blake2_update(ctx, buf_jsoo_string, ofs, len);
412+
}

runtime/wasm/blake2.wat

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
(module
2+
(@if (>= ocaml_version (5 2 0))
3+
(@then
4+
(import "jslib" "wrap" (func $wrap (param anyref) (result (ref eq))))
5+
(import "jslib" "unwrap" (func $unwrap (param (ref eq)) (result anyref)))
6+
(import "jslib" "caml_string_of_jsbytes"
7+
(func $caml_string_of_jsbytes (param (ref eq)) (result (ref eq))))
8+
(import "jslib" "caml_jsbytes_of_string"
9+
(func $caml_jsbytes_of_string (param (ref eq)) (result (ref eq))))
10+
11+
(import "js" "blake2_js_for_wasm_create"
12+
(func $blake2_js_for_wasm_create (param (ref eq) anyref) (result anyref)))
13+
14+
(import "js" "blake2_js_for_wasm_update"
15+
(func $blake2_js_for_wasm_update (param anyref anyref i32 i32)))
16+
17+
(import "js" "blake2_js_for_wasm_string"
18+
(func $blake2_js_for_wasm_string
19+
(param (ref eq) anyref anyref i32 i32) (result anyref)))
20+
21+
(import "js" "blake2_js_for_wasm_final"
22+
(func $blake2_js_for_wasm_final (param anyref (ref eq)) (result anyref)))
23+
24+
(type $bytes (array (mut i8)))
25+
26+
(func (export "caml_blake2_create")
27+
(param $hashlen (ref eq)) (param $key (ref eq)) (result (ref eq))
28+
(return_call $wrap
29+
(call $blake2_js_for_wasm_create
30+
(local.get $hashlen)
31+
(call $unwrap (call $caml_jsbytes_of_string (local.get $key))))))
32+
33+
(func $jsbytes_of_substring
34+
(param $vbuf (ref eq)) (param $vofs (ref eq)) (param $vlen (ref eq))
35+
(result anyref i32 i32)
36+
(local $buf (ref $bytes)) (local $buf' (ref $bytes))
37+
(local $ofs i32) (local $len i32)
38+
(local.set $buf (ref.cast (ref $bytes) (local.get $vbuf)))
39+
(local.set $ofs (i31.get_u (ref.cast (ref i31) (local.get $vofs))))
40+
(local.set $len (i31.get_u (ref.cast (ref i31) (local.get $vlen))))
41+
;; We copy the relevant part of the buffer if we only use a small portion
42+
(if (i32.le_u (i32.shl (local.get $len) (i32.const 1))
43+
(array.len (local.get $buf)))
44+
(then
45+
(local.set $buf' (array.new $bytes (i32.const 0) (local.get $len)))
46+
(array.copy $bytes $bytes
47+
(local.get $buf') (i32.const 0)
48+
(local.get $buf) (local.get $ofs) (local.get $len))
49+
(local.set $buf (local.get $buf'))
50+
(local.set $ofs (i32.const 0))))
51+
(tuple.make 3
52+
(call $unwrap (call $caml_jsbytes_of_string (local.get $buf)))
53+
(local.get $ofs)
54+
(local.get $len)))
55+
56+
(func (export "caml_blake2_update")
57+
(param $ctx (ref eq)) (param $buf (ref eq)) (param $ofs (ref eq))
58+
(param $len (ref eq)) (result (ref eq))
59+
(call $blake2_js_for_wasm_update
60+
(call $unwrap (local.get $ctx))
61+
(call $jsbytes_of_substring
62+
(local.get $buf) (local.get $ofs) (local.get $len)))
63+
(ref.i31 (i32.const 0)))
64+
65+
(func (export "caml_blake2_final")
66+
(param $ctx (ref eq)) (param $hashlen (ref eq)) (result (ref eq))
67+
(return_call $caml_string_of_jsbytes
68+
(call $wrap
69+
(call $blake2_js_for_wasm_final
70+
(call $unwrap (local.get $ctx))
71+
(local.get $hashlen)))))
72+
73+
(func (export "caml_blake2_string") (export "caml_blake2_bytes")
74+
(param $hashlen (ref eq)) (param $key (ref eq)) (param $buf (ref eq))
75+
(param $ofs (ref eq)) (param $len (ref eq)) (result (ref eq))
76+
(local $ctx anyref)
77+
(local.set $ctx
78+
(call $blake2_js_for_wasm_create
79+
(local.get $hashlen)
80+
(call $unwrap (call $caml_jsbytes_of_string (local.get $key)))))
81+
(call $blake2_js_for_wasm_update
82+
(local.get $ctx)
83+
(call $jsbytes_of_substring
84+
(local.get $buf) (local.get $ofs) (local.get $len)))
85+
(return_call $caml_string_of_jsbytes
86+
(call $wrap
87+
(call $blake2_js_for_wasm_final
88+
(local.get $ctx) (local.get $hashlen)))))
89+
))
90+
)

0 commit comments

Comments
 (0)