Giter VIP home page Giter VIP logo

watsign's Introduction

watsign

This library is a port of the signing part of tweetnacl to WebAssembly + JavaScript. It implements the ed25519 signature scheme. watsign works in all modern browsers as well as node and deno!

The code is based on and tested against tweetnacl-js. If you only need signing, we offer the following advantages:

  • About 5x faster than tweetnacl-js, see comparison below
  • Size impact is about 70% of tweetnacl-js: 7.4kB vs 10.6kB, minified + gzipped. (But tweetnacl-js contains much more than signing!)

watsign is even a bit faster than noble-ed25519, which uses built-in JS BigInt for field arithmetic. As opposed to BigInt, the algorithms here (from tweetnacl) are carefully designed to resist timing attacks and prevent memory access patterns depending on secret data.

The code is almost entirely written in raw WAT (Webassembly text format) and bundled to JS-friendly Wasm with watever, the WAT bundler written also by me. Fun fact: even the entry point of this lib is autogenerated from a WAT file (./src/sign.wat). There is no custom JS glue code.

npm i watsign

Usage

import {newKeyPair, sign, verify} from 'watsign';

let {publicKey, secretKey} = await newKeyPair();

let message = new TextEncoder().encode('Something I want to sign');
let signature = await sign(message, secretKey);

let ok = await verify(message, signature, publicKey);
console.log('everything ok?', ok);

In deno, you can import from github:

import {newKeyPair, sign, verify} from 'https://raw.githubusercontent.com/mitschabaude/watsign/main/mod.js';

API

The API is a streamlined version of nacl.sign from tweetnacl-js. The only differences are:

  • All exported functions are async (this is dictated by WebAssembly, and also enables us to use native browser crypto for SHA-512)
  • We only support detached signatures, so our sign is nacl.sign.detached
  • There is just a normal named export for each function, no nacl object with nested sub-objects
  • There is only the "high-level" API, not the redundant "low-level" API (crypto_sign etc.) and no constants (nacl.sign.signatureLength etc.)

Like in tweetnacl-js, all functions operate on Uint8Arrays.

The following is the full list of exported functions and their tweetnacl-js equivalents:

  • sign(message: Uint8Array, secretKey: Uint8Array): Promise<Uint8Array>
    Sign a message with your secret key. Returns a 64 byte signature. Async version of nacl.sign.detached.

  • verify(message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): Promise<boolean>
    Verifies the signature, returns true if and only if it is valid. Async version of nacl.sign.detached.verify.

  • newKeyPair(): Promise<{secretKey: Uint8Array, publicKey: Uint8Array}>
    Creates a new, random key pair. Async version of nacl.sign.keyPair.

  • keyPairFromSeed(seed: Uint8Array): Promise<{secretKey: Uint8Array, publicKey: Uint8Array}>
    Deterministically creates a key pair from a 32-byte seed. Async version of nacl.sign.keyPair.fromSeed.

  • keyPairFromSecretKey(secretKey: Uint8Array): Promise<{secretKey: Uint8Array, publicKey: Uint8Array}>
    Re-creates the full key pair from the 64-byte secret key (which, in fact, has the public key stored in its last 32 bytes). Async version of nacl.sign.keyPair.fromSecretKey.

Performance

Performance compared to tweetnacl-js and noble-ed25519 on my computer (Intel i7-10700) in Chromium 93 (via puppeteer).

We are 4-6x faster than tweetnacl-js in the warmed-up regime and up to 33x faster on cold start after page load. Compared to noble-ed25519, we are 1.2-3x faster (warmed up) and up to 17x on cold start.

  • watsign
First run after startup (varies between runs!):
sign (short msg):    2.99 ms
verify (short msg):  1.81 ms
sign (long msg):     1.32 ms
verify (long msg):   1.61 ms

Average of 50x after warm-up of 50x:
sign (short msg):    0.67 ± 0.06 ms
verify (short msg):  1.11 ± 0.03 ms
sign (long msg):     0.96 ± 0.06 ms
verify (long msg):   1.28 ± 0.02 ms
  • tweetnacl-js
First run after startup (varies between runs!):
sign (short msg):    15.85 ms
verify (short msg):  8.45 ms
sign (long msg):     43.88 ms
verify (long msg):   12.18 ms

Average of 50x after warm-up of 50x:
sign (short msg):    2.86 ± 0.19 ms
verify (short msg):  5.65 ± 0.22 ms
sign (long msg):     5.70 ± 0.22 ms
verify (long msg):   7.21 ± 0.23 ms
  • noble-ed25519
First run after startup (varies between runs!):
sign (short msg):    53.17 ms
verify (short msg):  3.72 ms
sign (long msg):     2.11 ms
verify (long msg):   3.97 ms

Average of 50x after warm-up of 50x:
sign (short msg):    1.00 ± 0.06 ms
verify (short msg):  3.09 ± 0.09 ms
sign (long msg):     1.27 ± 0.09 ms
verify (long msg):   3.24 ± 0.09 ms

Testing

# before you do anything else
npm install

# build wasm and separate entry-points for node / deno / browser
npm run build

# run performance comparison above
node test/performance.js

watsign's People

Contributors

doublemalt avatar mitschabaude avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

watsign's Issues

Publish on deno.land/x

There is package on npm, so it works fine with npm:watsign or https://esm.sh/watsign. However, it would be nice to also have the package available on deno.land/x so we can just import directly from there.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.