solana
solana copied to clipboard
web3.js: Investigate replacement for `tweetnacl`
Overview
This is the ed25519 library that we use to:
- generate keypairs
- sign and verify messages
Properties:
- No dependencies
- Audited
- 10.5K gzipped
- side effects in module factory
- not tree-shakeable
- compatible with React Native
![image](https://user-images.githubusercontent.com/13243/182971280-b68d9183-9479-4c5a-80cd-a81caeb9b4b1.png)
Alternatives (ruled out)
@noble/ed25519
Properties:
- No dependencies
- Audited
- 5.4kb gzipped
- side effects in module factory
- not tree-shakeable because of side effects in module factory
- not compatible with React Native because of dependency on
SubtleCrypto
- not compatible with current API because
sign()
returns aPromise
![image](https://user-images.githubusercontent.com/13243/182971438-c0e34a24-2b59-4fa7-b18e-a7a012b82b8c.png)
dazoe/ed25519
Does not run in browser.
supercop.js
Is >130KB
nazar-pc/supercop.wasm
Introduces asynchronicity because of WASM initialization step.
nkeys.js
Just a wrapper around tweetnacl
.
substack/ed25519-supercop
Does not run in browser.
xwi88/crypto
Just a wrapper around tweetnacl
.
BENMFeng/Ed25519_DS
Just a wrapper around tweetnacl
.
skorotkiewicz/ed25519-keys
Is >45KB
Even if you replace sha512
, SubtleCrypto
would still be a requirement, for CSPRNG. You can't use ed25519 without CSPRNG.
It's either subtle crypto, or node.js built-in, which is replaced by crypto-browserify
.
SubtleCrypto
is not actually a requirement for React Native. In React Native, we supply a shim to what’s called a Native Module, that in turn delegates to the native RNG on iOS or Android respectively.
So if it's "shimmed", sha512 could also be shimmed. In node.js noble-ed25519 uses the same crypto
module which provides csprng.
I've went ahead and decided to add sync support to ed25519. It took one commit https://github.com/paulmillr/noble-ed25519/commit/d6263e0df732fbcc102eeb55904580beba7c5afa, 50 lines of code and a few hours of work.
Usage is as following:
import { sha512 } from '@noble/hashes/sha512';
ed.utils.sha512Sync = (...m) => sha512(ed.utils.concatBytes(...m));
const { getPublicKey, sign, verify, getExtendedPublicKey } = ed.sync;
// Use it freely
getPublicKey(privKey);