solana icon indicating copy to clipboard operation
solana copied to clipboard

web3.js: Investigate replacement for `tweetnacl`

Open steveluscher opened this issue 1 year ago • 3 comments

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

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 a Promise
image

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

steveluscher avatar Aug 04 '22 23:08 steveluscher

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.

paulmillr avatar Aug 05 '22 01:08 paulmillr

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.

steveluscher avatar Aug 05 '22 05:08 steveluscher

So if it's "shimmed", sha512 could also be shimmed. In node.js noble-ed25519 uses the same crypto module which provides csprng.

paulmillr avatar Aug 07 '22 18:08 paulmillr

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);

paulmillr avatar Aug 25 '22 21:08 paulmillr