1TweetNaCl.js 2============ 3 4Port of [TweetNaCl](http://tweetnacl.cr.yp.to) / [NaCl](http://nacl.cr.yp.to/) 5to JavaScript for modern browsers and Node.js. Public domain. 6 7[![Build Status](https://travis-ci.org/dchest/tweetnacl-js.svg?branch=master) 8](https://travis-ci.org/dchest/tweetnacl-js) 9 10Demo: <https://tweetnacl.js.org> 11 12**:warning: The library is stable and API is frozen, however it has not been 13independently reviewed. If you can help reviewing it, please [contact 14me](mailto:dmitry@codingrobots.com).** 15 16Documentation 17============= 18 19* [Overview](#overview) 20* [Installation](#installation) 21* [Usage](#usage) 22 * [Public-key authenticated encryption (box)](#public-key-authenticated-encryption-box) 23 * [Secret-key authenticated encryption (secretbox)](#secret-key-authenticated-encryption-secretbox) 24 * [Scalar multiplication](#scalar-multiplication) 25 * [Signatures](#signatures) 26 * [Hashing](#hashing) 27 * [Random bytes generation](#random-bytes-generation) 28 * [Constant-time comparison](#constant-time-comparison) 29* [System requirements](#system-requirements) 30* [Development and testing](#development-and-testing) 31* [Benchmarks](#benchmarks) 32* [Contributors](#contributors) 33* [Who uses it](#who-uses-it) 34 35 36Overview 37-------- 38 39The primary goal of this project is to produce a translation of TweetNaCl to 40JavaScript which is as close as possible to the original C implementation, plus 41a thin layer of idiomatic high-level API on top of it. 42 43There are two versions, you can use either of them: 44 45* `nacl.js` is the port of TweetNaCl with minimum differences from the 46 original + high-level API. 47 48* `nacl-fast.js` is like `nacl.js`, but with some functions replaced with 49 faster versions. 50 51 52Installation 53------------ 54 55You can install TweetNaCl.js via a package manager: 56 57[Bower](http://bower.io): 58 59 $ bower install tweetnacl 60 61[NPM](https://www.npmjs.org/): 62 63 $ npm install tweetnacl 64 65or [download source code](https://github.com/dchest/tweetnacl-js/releases). 66 67 68Usage 69----- 70 71All API functions accept and return bytes as `Uint8Array`s. If you need to 72encode or decode strings, use functions from 73<https://github.com/dchest/tweetnacl-util-js> or one of the more robust codec 74packages. 75 76In Node.js v4 and later `Buffer` objects are backed by `Uint8Array`s, so you 77can freely pass them to TweetNaCl.js functions as arguments. The returned 78objects are still `Uint8Array`s, so if you need `Buffer`s, you'll have to 79convert them manually; make sure to convert using copying: `new Buffer(array)`, 80instead of sharing: `new Buffer(array.buffer)`, because some functions return 81subarrays of their buffers. 82 83 84### Public-key authenticated encryption (box) 85 86Implements *curve25519-xsalsa20-poly1305*. 87 88#### nacl.box.keyPair() 89 90Generates a new random key pair for box and returns it as an object with 91`publicKey` and `secretKey` members: 92 93 { 94 publicKey: ..., // Uint8Array with 32-byte public key 95 secretKey: ... // Uint8Array with 32-byte secret key 96 } 97 98 99#### nacl.box.keyPair.fromSecretKey(secretKey) 100 101Returns a key pair for box with public key corresponding to the given secret 102key. 103 104#### nacl.box(message, nonce, theirPublicKey, mySecretKey) 105 106Encrypt and authenticates message using peer's public key, our secret key, and 107the given nonce, which must be unique for each distinct message for a key pair. 108 109Returns an encrypted and authenticated message, which is 110`nacl.box.overheadLength` longer than the original message. 111 112#### nacl.box.open(box, nonce, theirPublicKey, mySecretKey) 113 114Authenticates and decrypts the given box with peer's public key, our secret 115key, and the given nonce. 116 117Returns the original message, or `false` if authentication fails. 118 119#### nacl.box.before(theirPublicKey, mySecretKey) 120 121Returns a precomputed shared key which can be used in `nacl.box.after` and 122`nacl.box.open.after`. 123 124#### nacl.box.after(message, nonce, sharedKey) 125 126Same as `nacl.box`, but uses a shared key precomputed with `nacl.box.before`. 127 128#### nacl.box.open.after(box, nonce, sharedKey) 129 130Same as `nacl.box.open`, but uses a shared key precomputed with `nacl.box.before`. 131 132#### nacl.box.publicKeyLength = 32 133 134Length of public key in bytes. 135 136#### nacl.box.secretKeyLength = 32 137 138Length of secret key in bytes. 139 140#### nacl.box.sharedKeyLength = 32 141 142Length of precomputed shared key in bytes. 143 144#### nacl.box.nonceLength = 24 145 146Length of nonce in bytes. 147 148#### nacl.box.overheadLength = 16 149 150Length of overhead added to box compared to original message. 151 152 153### Secret-key authenticated encryption (secretbox) 154 155Implements *xsalsa20-poly1305*. 156 157#### nacl.secretbox(message, nonce, key) 158 159Encrypt and authenticates message using the key and the nonce. The nonce must 160be unique for each distinct message for this key. 161 162Returns an encrypted and authenticated message, which is 163`nacl.secretbox.overheadLength` longer than the original message. 164 165#### nacl.secretbox.open(box, nonce, key) 166 167Authenticates and decrypts the given secret box using the key and the nonce. 168 169Returns the original message, or `false` if authentication fails. 170 171#### nacl.secretbox.keyLength = 32 172 173Length of key in bytes. 174 175#### nacl.secretbox.nonceLength = 24 176 177Length of nonce in bytes. 178 179#### nacl.secretbox.overheadLength = 16 180 181Length of overhead added to secret box compared to original message. 182 183 184### Scalar multiplication 185 186Implements *curve25519*. 187 188#### nacl.scalarMult(n, p) 189 190Multiplies an integer `n` by a group element `p` and returns the resulting 191group element. 192 193#### nacl.scalarMult.base(n) 194 195Multiplies an integer `n` by a standard group element and returns the resulting 196group element. 197 198#### nacl.scalarMult.scalarLength = 32 199 200Length of scalar in bytes. 201 202#### nacl.scalarMult.groupElementLength = 32 203 204Length of group element in bytes. 205 206 207### Signatures 208 209Implements [ed25519](http://ed25519.cr.yp.to). 210 211#### nacl.sign.keyPair() 212 213Generates new random key pair for signing and returns it as an object with 214`publicKey` and `secretKey` members: 215 216 { 217 publicKey: ..., // Uint8Array with 32-byte public key 218 secretKey: ... // Uint8Array with 64-byte secret key 219 } 220 221#### nacl.sign.keyPair.fromSecretKey(secretKey) 222 223Returns a signing key pair with public key corresponding to the given 22464-byte secret key. The secret key must have been generated by 225`nacl.sign.keyPair` or `nacl.sign.keyPair.fromSeed`. 226 227#### nacl.sign.keyPair.fromSeed(seed) 228 229Returns a new signing key pair generated deterministically from a 32-byte seed. 230The seed must contain enough entropy to be secure. This method is not 231recommended for general use: instead, use `nacl.sign.keyPair` to generate a new 232key pair from a random seed. 233 234#### nacl.sign(message, secretKey) 235 236Signs the message using the secret key and returns a signed message. 237 238#### nacl.sign.open(signedMessage, publicKey) 239 240Verifies the signed message and returns the message without signature. 241 242Returns `null` if verification failed. 243 244#### nacl.sign.detached(message, secretKey) 245 246Signs the message using the secret key and returns a signature. 247 248#### nacl.sign.detached.verify(message, signature, publicKey) 249 250Verifies the signature for the message and returns `true` if verification 251succeeded or `false` if it failed. 252 253#### nacl.sign.publicKeyLength = 32 254 255Length of signing public key in bytes. 256 257#### nacl.sign.secretKeyLength = 64 258 259Length of signing secret key in bytes. 260 261#### nacl.sign.seedLength = 32 262 263Length of seed for `nacl.sign.keyPair.fromSeed` in bytes. 264 265#### nacl.sign.signatureLength = 64 266 267Length of signature in bytes. 268 269 270### Hashing 271 272Implements *SHA-512*. 273 274#### nacl.hash(message) 275 276Returns SHA-512 hash of the message. 277 278#### nacl.hash.hashLength = 64 279 280Length of hash in bytes. 281 282 283### Random bytes generation 284 285#### nacl.randomBytes(length) 286 287Returns a `Uint8Array` of the given length containing random bytes of 288cryptographic quality. 289 290**Implementation note** 291 292TweetNaCl.js uses the following methods to generate random bytes, 293depending on the platform it runs on: 294 295* `window.crypto.getRandomValues` (WebCrypto standard) 296* `window.msCrypto.getRandomValues` (Internet Explorer 11) 297* `crypto.randomBytes` (Node.js) 298 299If the platform doesn't provide a suitable PRNG, the following functions, 300which require random numbers, will throw exception: 301 302* `nacl.randomBytes` 303* `nacl.box.keyPair` 304* `nacl.sign.keyPair` 305 306Other functions are deterministic and will continue working. 307 308If a platform you are targeting doesn't implement secure random number 309generator, but you somehow have a cryptographically-strong source of entropy 310(not `Math.random`!), and you know what you are doing, you can plug it into 311TweetNaCl.js like this: 312 313 nacl.setPRNG(function(x, n) { 314 // ... copy n random bytes into x ... 315 }); 316 317Note that `nacl.setPRNG` *completely replaces* internal random byte generator 318with the one provided. 319 320 321### Constant-time comparison 322 323#### nacl.verify(x, y) 324 325Compares `x` and `y` in constant time and returns `true` if their lengths are 326non-zero and equal, and their contents are equal. 327 328Returns `false` if either of the arguments has zero length, or arguments have 329different lengths, or their contents differ. 330 331 332System requirements 333------------------- 334 335TweetNaCl.js supports modern browsers that have a cryptographically secure 336pseudorandom number generator and typed arrays, including the latest versions 337of: 338 339* Chrome 340* Firefox 341* Safari (Mac, iOS) 342* Internet Explorer 11 343 344Other systems: 345 346* Node.js 347 348 349Development and testing 350------------------------ 351 352Install NPM modules needed for development: 353 354 $ npm install 355 356To build minified versions: 357 358 $ npm run build 359 360Tests use minified version, so make sure to rebuild it every time you change 361`nacl.js` or `nacl-fast.js`. 362 363### Testing 364 365To run tests in Node.js: 366 367 $ npm run test-node 368 369By default all tests described here work on `nacl.min.js`. To test other 370versions, set environment variable `NACL_SRC` to the file name you want to test. 371For example, the following command will test fast minified version: 372 373 $ NACL_SRC=nacl-fast.min.js npm run test-node 374 375To run full suite of tests in Node.js, including comparing outputs of 376JavaScript port to outputs of the original C version: 377 378 $ npm run test-node-all 379 380To prepare tests for browsers: 381 382 $ npm run build-test-browser 383 384and then open `test/browser/test.html` (or `test/browser/test-fast.html`) to 385run them. 386 387To run headless browser tests with `tape-run` (powered by Electron): 388 389 $ npm run test-browser 390 391(If you get `Error: spawn ENOENT`, install *xvfb*: `sudo apt-get install xvfb`.) 392 393To run tests in both Node and Electron: 394 395 $ npm test 396 397### Benchmarking 398 399To run benchmarks in Node.js: 400 401 $ npm run bench 402 $ NACL_SRC=nacl-fast.min.js npm run bench 403 404To run benchmarks in a browser, open `test/benchmark/bench.html` (or 405`test/benchmark/bench-fast.html`). 406 407 408Benchmarks 409---------- 410 411For reference, here are benchmarks from MacBook Pro (Retina, 13-inch, Mid 2014) 412laptop with 2.6 GHz Intel Core i5 CPU (Intel) in Chrome 53/OS X and Xiaomi Redmi 413Note 3 smartphone with 1.8 GHz Qualcomm Snapdragon 650 64-bit CPU (ARM) in 414Chrome 52/Android: 415 416| | nacl.js Intel | nacl-fast.js Intel | nacl.js ARM | nacl-fast.js ARM | 417| ------------- |:-------------:|:-------------------:|:-------------:|:-----------------:| 418| salsa20 | 1.3 MB/s | 128 MB/s | 0.4 MB/s | 43 MB/s | 419| poly1305 | 13 MB/s | 171 MB/s | 4 MB/s | 52 MB/s | 420| hash | 4 MB/s | 34 MB/s | 0.9 MB/s | 12 MB/s | 421| secretbox 1K | 1113 op/s | 57583 op/s | 334 op/s | 14227 op/s | 422| box 1K | 145 op/s | 718 op/s | 37 op/s | 368 op/s | 423| scalarMult | 171 op/s | 733 op/s | 56 op/s | 380 op/s | 424| sign | 77 op/s | 200 op/s | 20 op/s | 61 op/s | 425| sign.open | 39 op/s | 102 op/s | 11 op/s | 31 op/s | 426 427(You can run benchmarks on your devices by clicking on the links at the bottom 428of the [home page](https://tweetnacl.js.org)). 429 430In short, with *nacl-fast.js* and 1024-byte messages you can expect to encrypt and 431authenticate more than 57000 messages per second on a typical laptop or more than 43214000 messages per second on a $170 smartphone, sign about 200 and verify 100 433messages per second on a laptop or 60 and 30 messages per second on a smartphone, 434per CPU core (with Web Workers you can do these operations in parallel), 435which is good enough for most applications. 436 437 438Contributors 439------------ 440 441See AUTHORS.md file. 442 443 444Third-party libraries based on TweetNaCl.js 445------------------------------------------- 446 447* [forward-secrecy](https://github.com/alax/forward-secrecy) — Axolotl ratchet implementation 448* [nacl-stream](https://github.com/dchest/nacl-stream-js) - streaming encryption 449* [tweetnacl-auth-js](https://github.com/dchest/tweetnacl-auth-js) — implementation of [`crypto_auth`](http://nacl.cr.yp.to/auth.html) 450* [chloride](https://github.com/dominictarr/chloride) - unified API for various NaCl modules 451 452 453Who uses it 454----------- 455 456Some notable users of TweetNaCl.js: 457 458* [miniLock](http://minilock.io/) 459* [Stellar](https://www.stellar.org/) 460