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 support? #141

Closed
NullVoxPopuli opened this issue May 7, 2018 · 8 comments
Closed

WASM support? #141

NullVoxPopuli opened this issue May 7, 2018 · 8 comments

Comments

@NullVoxPopuli
Copy link

It'd be great of this library could run in a web-assembly environment for boosted speed.

@dchest
Copy link
Owner

dchest commented May 7, 2018

I tried a prototype, but it turned out that currently it's not faster than the existing pure JS (nacl-fast) implementation.

https://twitter.com/dchest/status/935099198583779328

I expect that a different, fully 64-bit X/Ed25519 implementation will be faster, but it will also be larger and, to some extent, out of scope for tweetnacl.js (which is a port of tweetnacl.c, mostly). SHA-512 should also be faster, but it's now shipped with browsers in WebCrypto API (with async interface, so we can't directly plug it into the current library API, unfortunately).

So, I'm kinda torn between the choices:

  • Make a pure tweetnacl.c -> wasm port, which will not be faster than the nacl-fast.js version (except SHA512). I like this option, because the purpose of tweetnacl is to provide a small, auditable code base, and if we can use the original one, it's even better. It may also improve timing safety.
  • Create a new faster version, adopting different implementations of primitives. I'm not sure this option makes sense, because we already have libsodium, and it has a WASM target, so why make more libraries.

It would also make sense to switch the current API to be async like WebCrypto so whatever the choice, maybe it can be implemented as a separate project instead.

@NullVoxPopuli
Copy link
Author

I expect that a different, fully 64-bit X/Ed25519 implementation will be faster, but it will also be larger and, to some extent, out of scope for tweetnacl.js (which is a port of tweetnacl.c, mostly). SHA-512 should also be faster, but it's now shipped with browsers in WebCrypto API (with async interface, so we can't directly plug it into the current library API, unfortunately).

interesting. I'd be on board with 64bit implementations of everything. :-)
slightly bigger is fine :-)

It would also make sense to switch the current API to be async like WebCrypto so whatever the choice, maybe it can be implemented as a separate project instead.

I've been toying with libsodium.js's wasm and it's all async, because the wasm loader has to be async.
the apis for it are much less intuitive than tweetnacl, though.

so why make more libraries.

I'm with ya here. :-)
My post here about wasm was because of libsodium.js's less-intuitive apis.

@awwong1
Copy link

awwong1 commented May 18, 2018

I too would like to see wasm support.
I have converted the tweetnacl.c -> wasm in my project udia-software/wasmcrypt

The available methods are in tweetnacl.d.ts.

Still need to write up tests and verify all of the functionality. I am interested in making this work with the type definitions here.

@NullVoxPopuli
Copy link
Author

NullVoxPopuli commented May 26, 2019

Just did some benchmarks:
image

libsodium and js-nacl use WASM, but they're also huge. :-\

@sshelton76
Copy link

Have you tried the benchmarks in firefox? Firefox has been super speedy with most WebASM stuff.

@NullVoxPopuli
Copy link
Author

@sshelton76 I ran the benchmark in node, which supports WASM :-
idk how much difference there'd be between WASM implementations.

You're welcome to try though: benchmark code is here: https://github.com/NullVoxPopuli/emberclear/tree/master/packages/benchmarks/crypto

@mitschabaude
Copy link

Hi, I just ported the signing part (ed-25519) of tweetnacl-js to Wasm, available here: https://github.com/mitschabaude/watsign
I made it available as npm package for node, deno and the browser

Besides rewriting the whole thing in raw WebAssembly, I also jumped on the opportunity to use the Web Crypto API for SHA-512 for some additional speed gains.

It might interest you that the result is considerably faster than tweetnacl-js. Here are some benchmarks for signing / verifying:

  • watsign (my Wasm version)
First run after page load (varies between runs!):
sign (short msg):   3.40 ms
verify (short msg): 2.09 ms
sign (long msg):    1.71 ms
verify (long msg):  2.06 ms

Average of 50x after warm-up of 50x:
sign (short msg):   1.12 ± 0.14 ms
verify (short msg): 1.57 ± 0.23 ms
sign (long msg):    1.48 ± 0.13 ms
verify (long msg):  1.77 ± 0.13 ms
  • tweetnacl-js
First run after page load (varies between runs!):
sign (short msg):   29.58 ms
verify (short msg): 15.70 ms
sign (long msg):    91.31 ms
verify (long msg):  22.83 ms

Average of 50x after warm-up of 50x:
sign (short msg):   4.13 ± 0.37 ms
verify (short msg): 8.25 ± 0.42 ms
sign (long msg):    8.65 ± 0.42 ms
verify (long msg):  10.87 ± 0.48 ms

I also included benchmarks of running immediately after page load, because that is relevant on the web. As you see, fast startup is where Wasm really shines. But the warmed-up benchmarks are also quite good. Even the "short message" version, which doesn't really benefit from faster SHA-512, is more than 3x faster with Wasm.

These numbers were done on a medium-end laptop (Intel i7). The performance difference tends to be larger on higher-end machines.

Anyway, thanks @dchest for your super useful library which I'm using all the time ❤️

@dchest
Copy link
Owner

dchest commented Aug 27, 2023

I've decided that it wouldn't be wise to add WASM support to TweetNaCl, since proper C/Rust/Zig/etc libraries can be compiled and used instead of this one.

@dchest dchest closed this as completed Aug 27, 2023
@dchest dchest closed this as not planned Won't fix, can't repro, duplicate, stale Aug 27, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants