-
Notifications
You must be signed in to change notification settings - Fork 937
web3.js: replace dependencies to lower supply-chain risk, improve tree-shakeability, and reduce bundle size #1103
Comments
It also seems like tweetnacl has a security vulnerability, which is a separate issue. |
Paul! Thanks for this. This is great, worthwhile work that I'll start on now. I had started down this road in solana-labs/solana#25014 - particularly eliminating I'll start picking these off one by one. I have learned to expect significant challenges, such as:
I'll work through all these challenges as they come. |
The lockfile for Nevertheless, I'll update the deps for avoidance of doubt. |
Immediately, when trying to replace class Transaction {
sign(...signers: Array<Signer>): void;
} Then replace the signing implementation - const signature = nacl.sign.detached(signData, signer.secretKey);
+ const signature = await nobleEd25519.sign(signData, signer.secretKey); …without having to change the signature to this: class Transaction {
- sign(...signers: Array<Signer>): void;
+ sign(...signers: Array<Signer>): Promise<void>;
} You can always start with an async API and remove the genuinely async parts of it, but you can't go the other way without breaking the entire universe. Everyone who currently does this in function handleClick(): void {
const t = new Transaction().add(/* ... */).sign(signer);
/* ... */
} Would have to change to this: function handleClick(): void {
- const t = new Transaction().add(/* ... */).sign(signer);
+ const t = new Transaction().add(/* ... */);
+ await t.sign(signer);
/* ... */
} …which in turn would force the outer method to become async… - function handleClick(): void {
+ async function handleClick(): Promise<void> {
const t = new Transaction().add(/* ... */);
await t.sign(signer);
/* ... */
} …which in turn would cause folks to have to completely rethink the lifecycle of their event handlers (eg. what happens if the event handler is halfway done but then the UI it's handling an event for unmounts?). This is part of
|
It is the simplest and most reasonable way to implement no-dependency ed25519. Current consumers are fine with using it as-is. If you need synchronous api, see how noble-secp256k1 implemented both async and sync versions — it is still possible. What happens if you'll decide to sign sol TX with hardware wallet? The procedure cannot be sync — since that can take indefinite amount of time. |
As for
False: sha512 is not a bottleneck — scalar multiplication is. Native sha512 is 2x slower than noble-hashes implementation. Noble-hashes on Apple M1 can still do 463,606 sha512 hashings of 32-byte input per second — one hashing every 2 microseconds, or ~4000 hashings per 1 120fps frame. For comparison, noble-ed25519
False: sha512 takes about 350 tree-shaken lines of code in noble-hashes. |
100% agree!
You're right! It's possible to inject a sync implementation with a modification like that. But then, we have to go find a userspace implementation of sha512. But then we lose all the benefits that
This isn't something that |
You don't have to find anything. noble-hashes is audited and it is there. You will need it in any case, to replace
secp with
It is still
You will need noble-hashes in any case. Or you can bundle its implementation of sha512, which is about 350 lines of code. |
Want to reiterate: We have made the same thing in |
|
@steveluscher heads up, much smaller v2 of noble-secp, noble-ed is out. Many features have been removed, but should be fine for your case. The libraries are just 4kb gzipped now. Another option is to use noble-curves which have improved security, are larger; but tree shaking is supported so all is cool. |
Thanks, @paulmillr! |
Closed by 5a20ed0. |
Because there has been no activity on this issue for 7 days since it was closed, it has been automatically locked. Please open a new issue if it requires a follow up. |
You have quite a few dependencies in web3. All of those can be replaced by 4 deps:
I suggest switching to audited libraries that are faster, use less dependencies.
@noble/hashes
for sha2, sha3. It's faster than ethersproject/sha2, js-sha3, and was audited@noble/secp256k1
for secp256k1. It's faster than js implementations of secp, and was audited@noble/ed25519
for ed25519 — which is 7x faster than tweetnacl, and was audited@scure/base
could be used forbase58
— it was audited and has 0 depsbn.js
,bigint-buffer
,buffer
can be removed altogetherSupply chain attacks are very dangerous. Breaking any sub-dependency of your dependencies could leak user keys. So, the best option is to use projects that don't have sub-dependencies.
Individual tracking tasks
tweetnacl
solana#26933The text was updated successfully, but these errors were encountered: