You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

459 lines
13 KiB

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