Closed memcorrupt closed 4 months ago
What I initially stated in the linked issue still applies, I prefer not to use the Web Crypto API if it means breaking compatibility, since jsSHA, while not native, is a widely used SHA implementation that works well.
But there is room for improvement here, the first thing would be to study the feasibility of creating an alternative build that uses the Web Crypto API (although it would not be trivial as this build would have to expose a slightly different API since it would have to use asynchronous methods) and the second thing would be to have a build that does not bundle jsSHA to avoid it being included multiple times in case another dependency imports it.
Right now this is not a priority for me, but I leave this issue open to review it in the future, a PR would also be welcome.
@hectorm I had started some progress here, but I wasn't quite sure how to produce a WebCrypto build & a jsSHA build to maintain the browser compatbility required to upstream the changes.
If this is a good start, you could possibly finish it or provide the insight needed to continue.
After a benchmark with jsSHA, @noble/hashes and your SubtleCrypto fork, I noticed that the latter is much slower (possibly due to the overhead of the async function), so I don't think I will use the Web Crypto API for the time being.
Although thanks to this I'm thinking about switching to @noble/hashes as it would reduce the minified bundle size from 30 KB to 24 KB (without compression). The idea of providing a variant that doesn't bundle the HMAC library to avoid duplication still stands, but that's outside the scope of this issue, so I'll close this one and create another.
Task Name | ops/sec | Average Time (ns) | Margin | Samples |
---|---|---|---|---|
totpValidate | 55 | 18172903.26860257 | ±0.29% | 551 |
totpNobleValidate | 103 | 9625471.101058695 | ±1.04% | 1039 |
totpSubtleValidate | 23 | 42465075.48305099 | ±2.07% | 236 |
Task Name | ops/sec | Average Time (ns) | Margin | Samples |
---|---|---|---|---|
totpValidate | 74 | 13454301.075268818 | ±0.85% | 744 |
totpNobleValidate | 73 | 13608163.265306123 | ±1.55% | 735 |
totpSubtleValidate | 19 | 51517948.71794872 | ±0.81% | 195 |
Task Name | ops/sec | Average Time (ns) | Margin | Samples |
---|---|---|---|---|
totpValidate | 82 | 12078045.838318126 | ±0.57% | 829 |
totpNobleValidate | 71 | 14077918.424788447 | ±0.60% | 711 |
totpSubtleValidate | 8 | 122246341.46336012 | ±2.72% | 82 |
Task Name | ops/sec | Average Time (ns) | Margin | Samples |
---|---|---|---|---|
totpValidate | 62 | 16059390.048154093 | ±0.66% | 623 |
totpNobleValidate | 39 | 25173366.834170856 | ±0.92% | 398 |
totpSubtleValidate | 11 | 88796460.17699115 | ±7.37% | 113 |
See #296 for original issue.
This package uses jsSHA as a dependency, which adds 21.4 kB to the bundle size (ESM minified). This is ~77.4% of this module's bundle size.
The WebCrypto API (including SubtleCrypto) is widely supported in browsers (while using HTTPS), and provides native implementations of crypto functions. Additionally, it supports all the currently supported algorithms in
hmac-digest.js
except SHA-224; however, only SHA-1, SHA-256, and SHA-512 are actually specified in the TOTP RFC.Additionally, because the library's dependencies are currently bundled, jsSHA may be unnecessarily bundled in a final project multiple times if dependent projects contain files or dependencies that require jsSHA.
Since Web Crypto API is asynchronous only, this improvement could either be implemented as a breaking change, or with seperate asynchronous generate/validate methods that include the Web Crypto implementation.