gleam-lang / crypto

⛓️ Crypto functionality for Gleam applications
https://hexdocs.pm/gleam_crypto/
Apache License 2.0
36 stars 11 forks source link

what is the preferred method of adding browser and sha3 support? #8

Closed quixoten closed 4 months ago

quixoten commented 4 months ago

My first iteration added sha3 without relying on a node module. That approach works for erlang and nodejs, but fails for the other js runtimes. This approach uses the @noble/hashes library for pure js implementations of the hashing algorithms (except md5). This works on all js platforms, but I'm not sure this is valid either. I wasn't able to find other examples of gleam libraries that bundle up node module dependencies in the build, and I can understand why it would be preferable to avoid external dependencies (especially in a core library like this).

Let me know if there's a path forward here, but understand if this should just be left out for now, or handled in a separate package.

lpil commented 4 months ago

This package must not use any external JS dependencies, only the JS standard libraries may be used.

If functionality requires an npm library then it must be a different Gleam package.

quixoten commented 4 months ago

TL;DR: not sure this is the best solution, but currently gleam/crypto doesn't support the browser. using SubtleCrypto seems like the ideal way to add browser support (node, deno, and bun also support it), but since it's an async API is that even possible? this change adds support for browsers using noble-hashes (MIT Licensed) (but "statically linked") and adds the sha3 algorithms. happy to pursue other paths for browser support if this is still a no go, but not sure what to try next.


updated to avoid using an external dependency (kind of). this is still using noble-hashes (MIT Licensed) but with the single-file build copied into this repo. since it's a pure js implementation, it should provide the broadest reach in terms of support. for example, the hmac and hash functions in gleam/crypto do not currently work in any browser since they're based on node:crypto, but with this change they will work in most browsers.

i came to this solution after pursuing the use of custom apis for bun and deno (node supports sha3 in node:crypto), but that would still leave the browser in an unsupported state. i also discovered that deno removed their sha3 specific lib in favor of mirroring the SubtleCrypto web API with support for additional algorithms. Since that's an async API, I'm not sure that provides a viable way to add sha3 or browser support to gleam/crypto. I like the idea of defaulting to the native platform implementation through crypto.subtle and only using noble-hashes for algorithms the platform doesn't support, but I couldn't figure out a way to return anything other than a Promise when I attempted it.

scrot-1718741333

quixoten commented 4 months ago

Please remove the noble-hashes module. This library does not depend on any non-stdlib code, and vendoring makes it harder to maintain than using a package manager.

the noble-hashes module is what allows the hash and hmac functions to work in the browser. if browser support is a non-goal for this library, i would recommend closing this PR. although browser support may be possible using the SubtleCrypto API, it's an async API and I do not know how to work around the function coloring problem.

lpil commented 4 months ago

I understand, but as I said it is not appropriate for this library to have these dependencies.

If you would like to use these dependencies then you may want to create and maintain your own package which is responsible for them.