1 | # js-nacl: Pure-Javascript High-level API to Emscripten-compiled libsodium routines
|
2 |
|
3 | A high-level Javascript API wrapping an
|
4 | [Emscripten](https://github.com/kripken/emscripten)-compiled
|
5 | [libsodium](http://libsodium.org/), a cryptographic library based on
|
6 | [NaCl](http://nacl.cr.yp.to/). Includes both in-browser and node.js
|
7 | support.
|
8 |
|
9 | The paper "[The security impact of a new cryptographic
|
10 | library](http://cr.yp.to/highspeed/coolnacl-20120725.pdf)" is an
|
11 | excellent summary of the motivation behind the NaCl API and library
|
12 | design.
|
13 |
|
14 | Using this library in the browser requires support for the newish
|
15 | `window.crypto.getRandomValues` API.
|
16 |
|
17 | **WARNING**: This code will not run in Safari version 5.1.x; or, at
|
18 | least, will not run when Safari's Javascript debug mode is *disabled*.
|
19 | Symptoms include corruption during hash calculation, failures when
|
20 | unboxing, and failures when producing and verifying signatures. Safari
|
21 | 7.0 seems to be just fine, however. I don't know exactly at which
|
22 | version Safari started working: I don't have access to enough of a
|
23 | range of systems. The code has run fine on Chrome and Firefox across
|
24 | all the versions I've tried.
|
25 |
|
26 | ## Changes
|
27 |
|
28 | Version 1.3.0: Updated from libsodium 1.0.11 to stable-2018-11-19.
|
29 | Added `crypto_box_seal` and `crypto_box_seal_open`. Switched from
|
30 | using the Emscripten SDK to using a Dockerized Emscripten to produce
|
31 | the built version of the library. Because this enables WASM by
|
32 | default, the approach to handling of `requested_total_memory` is now
|
33 | different; see below.
|
34 |
|
35 | Version 1.2.2: Updated from libsodium 1.0.10 to 1.0.11.
|
36 |
|
37 | Version 1.2.1: Repaired a mistake where I had failed to export the new
|
38 | names `crypto_sign_seed_keypair` and `crypto_box_seed_keypair`.
|
39 |
|
40 | Version 1.2.0: js-nacl is now based around libsodium rather than the
|
41 | plain NaCl tarball. Functions `crypto_sign_keypair_from_seed` and
|
42 | `crypto_box_keypair_from_seed` have been renamed to their libsodium
|
43 | names, `crypto_sign_seed_keypair` and `crypto_box_seed_keypair`
|
44 | respectively; the old names are still available as aliases, though
|
45 | **deprecated**, to be removed in a future version.
|
46 |
|
47 | Version 1.1.0: **API change.** The `nacl_factory.instantiate` function
|
48 | now expects a callback as its first argument. It calls the callback
|
49 | with the `nacl` instance containing the API functions, and returns no
|
50 | useful value.
|
51 |
|
52 | Version 0.5.0: **API change.** Instead of being provided with a module
|
53 | `nacl`, with API functions available directly, library importers are
|
54 | given `nacl_factory` with a single function `instantiate`, which
|
55 | returns a `nacl` instance containing the API functions.
|
56 |
|
57 | ## NPM Package
|
58 |
|
59 | This library is [registered on
|
60 | npmjs.org](https://npmjs.org/package/js-nacl). To install it:
|
61 |
|
62 | npm install js-nacl
|
63 |
|
64 | ## Building the library
|
65 |
|
66 | The git checkout includes a pre-compiled version of the library, so
|
67 | you won't need Emscripten unless you want to change something about
|
68 | the underlying C-language library itself.
|
69 |
|
70 | Essentially, the source checkout contains everything you will need to
|
71 | use the library in both the browser and in node.js.
|
72 |
|
73 | If you do find yourself wanting to build the library, see the
|
74 | instructions in
|
75 | [BUILDING.md](https://github.com/tonyg/js-nacl/blob/master/BUILDING.md).
|
76 |
|
77 | ## Using the library
|
78 |
|
79 | In the browser, include the `lib/nacl_factory.js` script:
|
80 |
|
81 | <script src="lib/nacl_factory.js"></script>
|
82 | ...
|
83 | <script>
|
84 | nacl_factory.instantiate(function (nacl) {
|
85 | alert(nacl.to_hex(nacl.random_bytes(16)));
|
86 | });
|
87 | </script>
|
88 |
|
89 | In node.js, require the `lib/nacl_factory.js` module:
|
90 |
|
91 | var nacl_factory = require("./lib/nacl_factory.js");
|
92 | nacl_factory.instantiate(function (nacl) {
|
93 | ...
|
94 | console.log(nacl.to_hex(nacl.random_bytes(16)));
|
95 | });
|
96 |
|
97 | Or if you have installed the library via `npm`,
|
98 |
|
99 | var nacl_factory = require("js-nacl");
|
100 | nacl_factory.instantiate(function (nacl) {
|
101 | ...
|
102 | console.log(nacl.to_hex(nacl.random_bytes(16)));
|
103 | });
|
104 |
|
105 | In addition, since version 1.3.0, the `instantiate` function returns a
|
106 | `Promise` that yields the `nacl` object.
|
107 |
|
108 | ## Instantiating the NaCl module
|
109 |
|
110 | Pass `nacl_factory.instantiate` a callback function expecting a single
|
111 | argument, the `nacl` module instance.
|
112 |
|
113 | The `nacl_factory.instantiate` function expects also a second optional
|
114 | argument, a dictionary of optional configuration values.
|
115 |
|
116 | Each call to `nacl_factory.instantiate()` creates an entirely fresh
|
117 | module instance, complete with its own private heap area. **Since
|
118 | v1.3.0:** The heap should automatically grow as required, and should
|
119 | no longer require manual ahead-of-time configuration.
|
120 |
|
121 | It's fine to instantiate the module more than once in a single
|
122 | program, though beware of the large amount of memory potentially taken
|
123 | up by each instance. The memory assigned to each module instance will
|
124 | not be released until the instance is garbage collected.
|
125 |
|
126 | If you notice memory leaks across multiple uses of a *single* module
|
127 | instance, please report them, with a test case if at all possible.
|
128 |
|
129 | ## Strings vs. Binary Data
|
130 |
|
131 | The library enforces a strict distinction between strings and binary
|
132 | data. Binary data is represented using instances of
|
133 | [`Uint8Array`](https://developer.mozilla.org/en-US/docs/JavaScript/Typed_arrays/Uint8Array).
|
134 |
|
135 | ### nacl.to_hex(Uint8Array) → String
|
136 |
|
137 | Returns a lower-case hexadecimal representation of the given binary
|
138 | data.
|
139 |
|
140 | ### nacl.from_hex(String) → Uint8Array
|
141 |
|
142 | Converts a lower- or upper-case hexadecimal representation of binary
|
143 | data into the equivalent Uint8Array.
|
144 |
|
145 | ### nacl.encode_utf8(String) → Uint8Array
|
146 |
|
147 | Returns the binary equivalent of the argument, encoded using UTF-8.
|
148 |
|
149 | ### nacl.encode_latin1(String) → Uint8Array
|
150 |
|
151 | Returns the binary equivalent of the argument, encoded using Latin1
|
152 | (an 8-bit clean encoding). If any of the character codes in the
|
153 | argument string are greater than 255, an exception is thrown.
|
154 |
|
155 | ### nacl.decode_utf8(Uint8Array) → String
|
156 |
|
157 | Decodes the binary data in the argument using the UTF-8 encoding,
|
158 | producing the corresponding string.
|
159 |
|
160 | ### nacl.decode_latin1(Uint8Array) → String
|
161 |
|
162 | Decodes the binary data in the argument using the Latin1 8-bit clean
|
163 | encoding, producing the corresponding string.
|
164 |
|
165 | ## Hashing: crypto_hash
|
166 |
|
167 | Follows the [NaCl crypto_hash API](http://nacl.cr.yp.to/hash.html).
|
168 |
|
169 | ### nacl.crypto\_hash(Uint8Array) → Uint8Array
|
170 |
|
171 | Computes the SHA-512 hash of its argument.
|
172 |
|
173 | While SHA-512 is recommended, the SHA-256 function is also available,
|
174 | as `nacl.crypto\_hash\_sha256`.
|
175 |
|
176 | ### nacl.crypto\_hash\_string(String) → Uint8Array
|
177 |
|
178 | Encodes its argument using `nacl.encode_utf8`, and then calls
|
179 | `crypto_hash`.
|
180 |
|
181 | ## Public-key authenticated encryption: crypto_box
|
182 |
|
183 | Follows the [NaCl crypto_box API](http://nacl.cr.yp.to/box.html).
|
184 |
|
185 | You do not need to perform any padding of any arguments to these
|
186 | functions; the API given here is most similar to the "C++" API in the
|
187 | NaCl documentation.
|
188 |
|
189 | **Make sure to follow the instructions regarding nonce selection given
|
190 | in the "Security model" section of the NaCl API documentation!**
|
191 |
|
192 | senderKeypair = nacl.crypto_box_keypair();
|
193 | recipientKeypair = nacl.crypto_box_keypair();
|
194 | message = nacl.encode_utf8("Hello!");
|
195 |
|
196 | nonce = nacl.crypto_box_random_nonce();
|
197 | packet = nacl.crypto_box(message, nonce, recipientKeypair.boxPk, senderKeypair.boxSk);
|
198 |
|
199 | decoded = nacl.crypto_box_open(packet, nonce, senderKeypair.boxPk, recipientKeypair.boxSk);
|
200 |
|
201 | "Hello!" === nacl.decode_utf8(decoded); // always true
|
202 |
|
203 | ### nacl.crypto\_box\_keypair() → {"boxPk": Uint8Array, "boxSk": Uint8Array}
|
204 |
|
205 | Creates a fresh random keypair. `boxPk` is the public key and `boxSk`
|
206 | is the secret key.
|
207 |
|
208 | ### nacl.crypto\_box\_random\_nonce() → Uint8Array
|
209 |
|
210 | Returns a fresh randomly-chosen nonce suitable for use with
|
211 | `crypto_box`.
|
212 |
|
213 | ### nacl.crypto\_box(msgBin, nonceBin, recipientPublicKeyBin, senderSecretKeyBin) → Uint8Array
|
214 |
|
215 | Places `msg` in an authenticated, encrypted box that can only be
|
216 | verified and decrypted by the secret key corresponding to
|
217 | `recipientPublicKey`.
|
218 |
|
219 | ### nacl.crypto\_box\_open(ciphertextBin, nonceBin, senderPublicKeyBin, recipientSecretKeyBin) → Uint8Array
|
220 |
|
221 | Verifies and decrypts a box from `crypto_box`. Throws an exception if
|
222 | the verification fails or any of the inputs are invalid.
|
223 |
|
224 | ### nacl.crypto\_box\_precompute(publicKeyBin, secretKeyBin) → {"boxK": Uint8Array}
|
225 |
|
226 | Precomputes a shared secret between two parties. See the documentation
|
227 | for `crypto_box_beforenm` at the NaCl website.
|
228 |
|
229 | ### nacl.crypto\_box\_precomputed(msgBin, nonceBin, {"boxK": Uint8Array}) → Uint8Array<br>nacl.crypto\_box\_open\_precomputed(ciphertextBin, nonceBin, {"boxK": Uint8Array}) → Uint8Array
|
230 |
|
231 | Precomputed-secret variants of `crypto_box` and `crypto_box_open`.
|
232 |
|
233 | ## Secret-key authenticated encryption: crypto_secretbox
|
234 |
|
235 | Follows the [NaCl crypto_secretbox API](http://nacl.cr.yp.to/secretbox.html).
|
236 |
|
237 | You do not need to perform any padding of any arguments to these
|
238 | functions; the API given here is most similar to the "C++" API in the
|
239 | NaCl documentation.
|
240 |
|
241 | **Make sure to follow the instructions regarding nonce selection given
|
242 | in the "Security model" section of the NaCl API documentation!**
|
243 |
|
244 | k = ...;
|
245 | m = nacl.encode_utf8("message");
|
246 | n = nacl.crypto_secretbox_random_nonce();
|
247 | c = nacl.crypto_secretbox(m, n, k);
|
248 | m1 = nacl.crypto_secretbox_open(c, n, k);
|
249 | "message" === nacl.decode_utf8(m1); // always true
|
250 |
|
251 | ### nacl.crypto\_secretbox\_random\_nonce() → Uint8Array
|
252 |
|
253 | Returns a fresh randomly-chosen nonce suitable for use with
|
254 | `crypto_secretbox`.
|
255 |
|
256 | ### nacl.crypto\_secretbox(msgBin, nonceBin, keyBin) → Uint8Array
|
257 |
|
258 | Places `msg` in an authenticated, encrypted box that can only be
|
259 | verified and decrypted by someone who knows `keyBin`. The `keyBin`
|
260 | Uint8Array must be `nacl.crypto_secretbox_KEYBYTES` bytes long.
|
261 |
|
262 | ### nacl.crypto\_secretbox\_open(ciphertextBin, nonceBin, keyBin) → Uint8Array
|
263 |
|
264 | Verifies and decrypts a packet from `crypto_secretbox`. Throws an
|
265 | exception if the verification fails or any of the inputs are invalid.
|
266 |
|
267 | ## Anonymous authenticated encryption: crypto_box_seal
|
268 |
|
269 | Uses a freshly-created ephemeral box keypair to send an "anonymous"
|
270 | message to a specific recipient, who is identified by their public box
|
271 | key, and who may decrypt the message using the matching box keypair.
|
272 |
|
273 | ### nacl.crypto\_box\_seal(msgBin, recipientPublicKeyBin) → Uint8Array
|
274 |
|
275 | Places `msgBin` in an authenticated, encrypted box that can only be
|
276 | verified and decrypted by the secret key corresponding to
|
277 | `recipientPublicKeyBin`.
|
278 |
|
279 | ### nacl.crypto\_box\_seal\_open(ciphertextBin, recipientPublicKeyBin, recipientSecretKeyBin) → Uint8Array
|
280 |
|
281 | Verifies and decrypts a box from `crypto_box_seal`. Throws an
|
282 | exception if the verification fails or any of the inputs are invalid.
|
283 | Unlike `crypto_box_open`, no nonce is required, and the *recipient's*
|
284 | public key is supplied instead of the *sender's*. The sender remains
|
285 | anonymous.
|
286 |
|
287 | ## Secret-key encryption: crypto_stream
|
288 |
|
289 | Follows the [NaCl crypto_stream API](http://nacl.cr.yp.to/stream.html).
|
290 |
|
291 | **Make sure to follow the instructions regarding nonce selection given
|
292 | in the "Security model" section of the NaCl API documentation!**
|
293 |
|
294 | Since this style of secret-key encryption is symmetric,
|
295 | `nacl.crypto_stream_xor` is suitable for decryption as well as
|
296 | encryption:
|
297 |
|
298 | k = ...;
|
299 | m = nacl.encode_utf8("message");
|
300 | n = nacl.crypto_stream_random_nonce();
|
301 | c = nacl.crypto_stream_xor(m, n, k);
|
302 | m1 = nacl.crypto_stream_xor(c, n, k);
|
303 | "message" === nacl.decode_utf8(m1); // always true
|
304 |
|
305 | ### nacl.crypto\_stream\_random\_nonce() → Uint8Array
|
306 |
|
307 | Returns a fresh randomly-chosen nonce suitable for use with
|
308 | `crypto_stream`.
|
309 |
|
310 | ### nacl.crypto\_stream(lenInt, nonceBin, keyBin) → Uint8Array
|
311 |
|
312 | Returns a `lenInt`-byte length keystream based on the given nonce and
|
313 | key. The key must be `nacl.crypto_stream_KEYBYTES` bytes long.
|
314 |
|
315 | ### nacl.crypto\_stream\_xor(msgBin, nonceBin, keyBin) → Uint8Array
|
316 |
|
317 | Returns `msgBin.length` bytes of ciphertext (or plaintext, depending
|
318 | on the contents of `msgBin`) produced by XORing `msgBin` with the
|
319 | result of `nacl.crypto_stream(msgBin.length, nonceBin, keyBin)`.
|
320 |
|
321 | ## Secret-key single-message authentication: crypto_onetimeauth
|
322 |
|
323 | Follows the [NaCl crypto_onetimeauth API](http://nacl.cr.yp.to/onetimeauth.html).
|
324 |
|
325 | ## Secret-key message authentication: crypto_auth
|
326 |
|
327 | Follows the [NaCl crypto_auth API](http://nacl.cr.yp.to/auth.html).
|
328 |
|
329 | ## Signatures: crypto_sign
|
330 |
|
331 | Follows the [NaCl crypto_sign API](http://nacl.cr.yp.to/sign.html).
|
332 |
|
333 | Note that this uses the version of [Ed25519](http://ed25519.cr.yp.to/)
|
334 | from [SUPERCOP](http://bench.cr.yp.to/supercop.html), and *not* the
|
335 | old prototype implementation from the nacl 20110221 release.
|
336 |
|
337 | The SUPERCOP Ed25519 signature scheme used is compatible with
|
338 | libsodium and most other bindings and wrappers of libsodium and nacl.
|
339 |
|
340 | ### nacl.crypto\_sign\_keypair() → {"signPk": Uint8Array, "signSk": Uint8Array}
|
341 |
|
342 | Creates a fresh random keypair. `signPk` is the public key and
|
343 | `signSk` is the secret key.
|
344 |
|
345 | k = nacl.crypto_sign_keypair();
|
346 | m = nacl.encode_utf8("message");
|
347 | signed_m = nacl.crypto_sign(m, k.signSk);
|
348 | m1 = nacl.crypto_sign_open(signed_m, k.signPk);
|
349 | "message" === nacl.decode_utf8(m1); // always true
|
350 |
|
351 | ### nacl.crypto\_sign(msgBin, signerSecretKey) → Uint8Array
|
352 |
|
353 | Produces a signature-wrapped version of `msgBin`.
|
354 |
|
355 | ### nacl.crypto\_sign\_open(packetBin, signerPublicKey) → (Uint8Array || null)
|
356 |
|
357 | Verifies the signature on the given `packetBin`, and if it is valid,
|
358 | extracts the carried message and returns it. If the signature could
|
359 | not be verified, returns `null`.
|
360 |
|
361 | ### nacl.crypto\_sign\_detached(msgBin, signerSecretKey) → Uint8Array
|
362 |
|
363 | **WARNING: Experimental.** Produces a "detached" signature that,
|
364 | unlike `crypto_sign`, excludes the actual message body. The result can
|
365 | be used with `crypto_sign_verify_detached`.
|
366 |
|
367 | The returned detached signature will be `nacl.crypto_sign_BYTES` in
|
368 | length.
|
369 |
|
370 | ### nacl.crypto\_sign\_verify\_detached(detachedSignatureBin, msgBin, signerPublicKey) → (true || false)
|
371 |
|
372 | **WARNING: Experimental.** Given a "detached" signature from
|
373 | `crypto_sign_detached`, along with the original message and the
|
374 | signer's public signing key, returns `true` if the signature is valid,
|
375 | and `false` otherwise.
|
376 |
|
377 | ## Derived Keys
|
378 |
|
379 | **WARNING: Experimental**
|
380 |
|
381 | If you see yourself wanting to use these, you will need to know why
|
382 | [PBKDF2](http://en.wikipedia.org/wiki/PBKDF2) and
|
383 | [scrypt](http://www.tarsnap.com/scrypt.html) are of crucial
|
384 | importance.
|
385 |
|
386 | You might like to explore the use of these functions in tandem with
|
387 | `scrypt.crypto_scrypt` from
|
388 | [js-scrypt](https://github.com/tonyg/js-scrypt).
|
389 |
|
390 | It is not generally safe to supply (for example) a user's passphrase
|
391 | directly to these procedures without using PBKDF2, scrypt or something
|
392 | similar beforehand.
|
393 |
|
394 | ### nacl.crypto\_sign\_seed\_keypair(Uint8Array) → {"signPk": Uint8Array, "signSk": Uint8Array}
|
395 |
|
396 | Produces a *signing* keypair from its argument. A given binary input
|
397 | will always produce the same keypair as output.
|
398 |
|
399 | The input must be 32 bytes long. As
|
400 | [Brian Warner puts it](https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/),
|
401 | "Ed25519 keys start life as a 32-byte (256-bit) uniformly random
|
402 | binary seed" such as might be produced by sha256, or better yet,
|
403 | PBKDF2 or scrypt.
|
404 |
|
405 | Make sure to read and understand the warnings relating to passphrases,
|
406 | PBKDF2 and scrypt at the beginning of this section.
|
407 |
|
408 | Compatible with [PyNaCl](https://github.com/warner/pynacl)'s
|
409 | `crypto_sign_keypair_fromseed` and
|
410 | [racl](https://github.com/tonyg/racl)'s `bytes->crypto-sign-keypair`.
|
411 |
|
412 | (Prior to v1.2.0, known as `nacl.crypto_sign_keypair_from_seed`.)
|
413 |
|
414 | ### nacl.crypto\_box\_seed\_keypair(Uint8Array) → {"boxPk": Uint8Array, "boxSk": Uint8Array}
|
415 |
|
416 | Produces an *encrypted authenticated box* keypair from its argument. A
|
417 | given binary input will always produce the same keypair as output.
|
418 |
|
419 | The input may be of any length. The input is hashed once with sha512,
|
420 | and the first 32 bytes of the result are taken as the 32-byte secret
|
421 | key, which is then passed to `nacl.crypto_box_keypair_from_raw_sk`.
|
422 |
|
423 | Make sure to read and understand the warnings relating to passphrases,
|
424 | PBKDF2 and scrypt at the beginning of this section.
|
425 |
|
426 | Compatible with [racl](https://github.com/tonyg/racl)'s
|
427 | `bytes->crypto-box-keypair`.
|
428 |
|
429 | (Prior to v1.2.0, known as `nacl.crypto_box_keypair_from_seed`.)
|
430 |
|
431 | ### nacl.crypto\_box\_keypair\_from\_raw\_sk(Uint8Array) → {"boxPk": Uint8Array, "boxSk": Uint8Array}
|
432 |
|
433 | Produces an *encrypted authenticated box* keypair from its argument. A
|
434 | given binary input will always produce the same keypair as output.
|
435 |
|
436 | The input must be 32 bytes long, and could be a random 32-byte value,
|
437 | or the output of sha256, or better yet, the output of PBKDF2 or
|
438 | scrypt.
|
439 |
|
440 | Make sure to read and understand the warnings relating to passphrases,
|
441 | PBKDF2 and scrypt at the beginning of this section.
|
442 |
|
443 | Compatible with [racl](https://github.com/tonyg/racl)'s
|
444 | `crypto-box-sk->pk`.
|
445 |
|
446 | ## Low-level tools
|
447 |
|
448 | ### nacl.crypto\_scalarmult(Uint8Array, Uint8Array) → Uint8Array
|
449 |
|
450 | Expects two binaries, the first of length
|
451 | `nacl.crypto_scalarmult_SCALARBYTES` (representing an integer), and
|
452 | the second of length `nacl.crypto_scalarmult_BYTES` (representing a
|
453 | group element). The two are multiplied using the underlying NaCl
|
454 | `crypto_scalarmult` primitive, and the resulting
|
455 | `nacl.crypto_scalarmult_BYTES`-length group element binary is
|
456 | returned.
|
457 |
|
458 | ### nacl.crypto\_scalarmult\_base(Uint8Array) → Uint8Array
|
459 |
|
460 | As `nacl.crypto_scalarmult`, but multiplies the
|
461 | `nacl.crypto_scalarmult_SCALARBYTES`-length argument by a standard
|
462 | group element, returning the result.
|
463 |
|
464 | ## License
|
465 |
|
466 | js-nacl is written by Tony Garnock-Jones <tonygarnockjones@gmail.com>
|
467 | and is licensed under the [MIT
|
468 | license](http://opensource.org/licenses/MIT):
|
469 |
|
470 | > Copyright © 2013-2016 Tony Garnock-Jones.
|
471 | >
|
472 | > Permission is hereby granted, free of charge, to any person
|
473 | > obtaining a copy of this software and associated documentation files
|
474 | > (the "Software"), to deal in the Software without restriction,
|
475 | > including without limitation the rights to use, copy, modify, merge,
|
476 | > publish, distribute, sublicense, and/or sell copies of the Software,
|
477 | > and to permit persons to whom the Software is furnished to do so,
|
478 | > subject to the following conditions:
|
479 | >
|
480 | > The above copyright notice and this permission notice shall be
|
481 | > included in all copies or substantial portions of the Software.
|
482 | >
|
483 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
484 | > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
485 | > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
486 | > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
487 | > BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
488 | > ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
489 | > CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
490 | > SOFTWARE.
|
491 |
|
492 | js-nacl relies on libsodium, which is released under the
|
493 | [ISC license](https://en.wikipedia.org/wiki/ISC_license):
|
494 |
|
495 | > Copyright (c) 2013-2016
|
496 | > Frank Denis <j at pureftpd dot org>
|
497 | >
|
498 | > Permission to use, copy, modify, and/or distribute this software for any
|
499 | > purpose with or without fee is hereby granted, provided that the above
|
500 | > copyright notice and this permission notice appear in all copies.
|
501 | >
|
502 | > THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
503 | > WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
504 | > MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
505 | > ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
506 | > WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
507 | > ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
508 | > OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
509 |
|
510 | libsodium in turn relies on NaCl itself, which is public domain code
|
511 | by Daniel J. Bernstein and others.
|