Skip to content

Slow crypto operations (WebCryptoAPI support) #554

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

Open
r-l-x opened this issue Dec 16, 2016 · 7 comments
Open

Slow crypto operations (WebCryptoAPI support) #554

r-l-x opened this issue Dec 16, 2016 · 7 comments

Comments

@r-l-x
Copy link
Contributor

r-l-x commented Dec 16, 2016

Crypto operations are really slow with gopherjs.
Here is a small benchmark, consisting of hashing a 10MB buffer through SHA-256: http://www.gopherjs.org/playground/#/X98vxh8Y97

  • native go: about 120ms
  • gopherjs: about 1400ms under Chrome, 1900ms under Firefox

Depending on the type of operation, the difference can be even bigger. Issue #526 mentions 300x slower operations for RSA signatures.

I think it would be really great if crypto operations were implemented by calling the WebCryptoAPI.
As an exemple, here is a simple POC, with the same operation implemented with WebCrypto: http://www.gopherjs.org/playground/#/-_Ed7QocdZ
The execution times are:

  • Chrome (you have to load it over HTTPS): about 50ms
  • Firefox: about 70ms

That's about 25x as fast as the current version, and even twice as fast as a native go program!

@r-l-x
Copy link
Contributor Author

r-l-x commented Dec 16, 2016

A lot of work has already been done by @kothar here: https://bitbucket.org/kevalin-p2p/subtlecrypto
But one of the problem is that the various features of WebCrypto are not supported in every browser (See https://diafygi.github.io/webcrypto-examples), and there are some specific restrictions like with Chrome: WebCryptoAPI support is only enabled for pages loaded over HTTPS, so it would be necessary to have a fallback using the current go implementation when the WebCryptoAPI is not available.
Currently with gopherjs, it's not easy to override a function of the standard library while being able to call the original function, as original overridden functions are renamed "_".
So we need to have a way to override functions, while being able to call the original function. I'm not sure what's the best way to do this.

@kothar
Copy link

kothar commented Dec 16, 2016

I had similar thoughts - my initial plan was to create an isomorphic library that could fall back to the stdlib implementation if it couldn't find a browser implementation (or was running natively), but that doesn't help any of the other standard library code which uses crypto. Specifically net/http2 for what I was working on, although I feel like that's a bizarre use case anyway.

@flimzy
Copy link
Member

flimzy commented Dec 16, 2016

A general method for fallbacks like that would probably be useful in many areas, not just crypto.

@r-l-x
Copy link
Contributor Author

r-l-x commented Dec 16, 2016

I guess one way to do it would be to rename the original overridden function e.g. by adding a suffix, allowing it to be called from the overriding function.

@dmitshur
Copy link
Member

I was considering that too. For example, by always adding a prefix such as _ or _GopherJS_ to the identifier being replaced.

My main concern about that was the following. Currently, replaced identifiers get replaced with blank identifiers _. How does that intersect with dead-code elimination?

If we change all _ into non _, does that mean some things that were previously DCEed would no longer be? If so, then we'd want to selectively add the prefix instead of globally. If not, a global prefix is probably fine.

@r-l-x
Copy link
Contributor Author

r-l-x commented Dec 21, 2016

Here is a first POC, only implementing jsSum256 for now: #558

@shurcooL I didn't notice any problem with dead code elimination (on my current project, the generated javascript code has slightly the same size), but I'm not sure if there are other points we can check ?

@ZenifiedFromI2P
Copy link

It'll be very useful for OFACrypto.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants