GithubHelp home page GithubHelp logo

jedisct1 / libsodium.js Goto Github PK

View Code? Open in Web Editor NEW
965.0 32.0 138.0 135.82 MB

libsodium compiled to Webassembly and pure JavaScript, with convenient wrappers.

License: Other

Makefile 1.47% JavaScript 22.23% Shell 0.11% HTML 76.18%
libsodium javascript cryptography crypto webassembly

libsodium.js's Introduction

libsodium.js

Overview

The sodium crypto library compiled to WebAssembly and pure JavaScript using Emscripten, with automatically generated wrappers to make it easy to use in web applications.

The complete library weighs 188 KB (minified, gzipped, includes pure JS + WebAssembly versions) and can run in a web browser as well as server-side.

Compatibility

Supported browsers/JS engines:

  • Chrome >= 16
  • Edge >= 0.11
  • Firefox >= 21
  • Mobile Safari on iOS >= 8.0 (older versions produce incorrect results)
  • NodeJS
  • Bun
  • Opera >= 15
  • Safari >= 6 (older versions produce incorrect results)

This is comparable to the WebCrypto API, which is compatible with a similar number of browsers.

Signatures and other Edwards25519-based operations are compatible with WasmCrypto.

Installation

The dist directory contains pre-built scripts. Copy the files from one of its subdirectories to your application:

  • browsers includes a single-file script that can be included in web pages. It contains code for commonly used functions.
  • browsers-sumo is a superset of the previous script, that contains all functions, including rarely used ones and undocumented ones.
  • modules includes commonly used functions, and is designed to be loaded as a module. libsodium-wrappers is the module your application should load, which will in turn automatically load libsodium as a dependency.
  • modules-sumo contains sumo variants of the previous modules.

The modules are also available on npm:

Usage (as a module)

Load the libsodium-wrappers module. The returned object contains a .ready property: a promise that must be resolve before the sodium functions can be used.

Example:

import _sodium from 'libsodium-wrappers';
await (async() => {
  await _sodium.ready;
  const sodium = _sodium;

  let key = sodium.crypto_secretstream_xchacha20poly1305_keygen();

  let res = sodium.crypto_secretstream_xchacha20poly1305_init_push(key);
  let [state_out, header] = [res.state, res.header];
  let c1 = sodium.crypto_secretstream_xchacha20poly1305_push(state_out,
    sodium.from_string('message 1'), null,
    sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE);
  let c2 = sodium.crypto_secretstream_xchacha20poly1305_push(state_out,
    sodium.from_string('message 2'), null,
    sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL);

  let state_in = sodium.crypto_secretstream_xchacha20poly1305_init_pull(header, key);
  let r1 = sodium.crypto_secretstream_xchacha20poly1305_pull(state_in, c1);
  let [m1, tag1] = [sodium.to_string(r1.message), r1.tag];
  let r2 = sodium.crypto_secretstream_xchacha20poly1305_pull(state_in, c2);
  let [m2, tag2] = [sodium.to_string(r2.message), r2.tag];

  console.log(m1);
  console.log(m2);
})();

Usage (in a web browser, via a callback)

The sodium.js file includes both the core libsodium functions, as well as the higher-level JavaScript wrappers. It can be loaded asynchronusly.

A sodium object should be defined in the global namespace, with the following property:

  • onload: the function to call after the wrapper is initialized.

Example:

<script>
    window.sodium = {
        onload: function (sodium) {
            let h = sodium.crypto_generichash(64, sodium.from_string('test'));
            console.log(sodium.to_hex(h));
        }
    };
</script>
<script src="sodium.js" async></script>

Additional helpers

  • from_base64(), to_base64() with an optional second parameter whose value is one of: base64_variants.ORIGINAL, base64_variants.ORIGINAL_NO_PADDING, base64_variants.URLSAFE or base64_variants.URLSAFE_NO_PADDING. Default is base64_variants.URLSAFE_NO_PADDING.
  • from_hex(), to_hex()
  • from_string(), to_string()
  • pad(<buffer>, <block size>), unpad(<buffer>, <block size>)
  • memcmp() (constant-time check for equality, returns true or false)
  • compare() (constant-time comparison. Values must have the same size. Returns -1, 0 or 1)
  • memzero() (applies to Uint8Array objects)
  • increment() (increments an arbitrary-long number stored as a little-endian Uint8Array - typically to increment nonces)
  • add() (adds two arbitrary-long numbers stored as little-endian Uint8Array vectors)
  • is_zero() (constant-time, checks Uint8Array objects for all zeros)

API

The API exposed by the wrappers is identical to the one of the C library, except that buffer lengths never need to be explicitly given.

Binary input buffers should be Uint8Array objects. However, if a string is given instead, the wrappers will automatically convert the string to an array containing a UTF-8 representation of the string.

Example:

var key = sodium.randombytes_buf(sodium.crypto_shorthash_KEYBYTES),
    hash1 = sodium.crypto_shorthash(new Uint8Array([1, 2, 3, 4]), key),
    hash2 = sodium.crypto_shorthash('test', key);

If the output is a unique binary buffer, it is returned as a Uint8Array object.

Example (secretbox):

let key = sodium.from_hex('724b092810ec86d7e35c9d067702b31ef90bc43a7b598626749914d6a3e033ed');

function encrypt_and_prepend_nonce(message) {
    let nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
    return nonce.concat(sodium.crypto_secretbox_easy(message, nonce, key));
}

function decrypt_after_extracting_nonce(nonce_and_ciphertext) {
    if (nonce_and_ciphertext.length < sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES) {
        throw "Short message";
    }
    let nonce = nonce_and_ciphertext.slice(0, sodium.crypto_secretbox_NONCEBYTES),
        ciphertext = nonce_and_ciphertext.slice(sodium.crypto_secretbox_NONCEBYTES);
    return sodium.crypto_secretbox_open_easy(ciphertext, nonce, key);
}

In addition, the from_hex, to_hex, from_string, and to_string functions are available to explicitly convert hexadecimal, and arbitrary string representations from/to Uint8Array objects.

Functions returning more than one output buffer are returning them as an object. For example, the sodium.crypto_box_keypair() function returns the following object:

{ keyType: 'curve25519', privateKey: (Uint8Array), publicKey: (Uint8Array) }

Standard vs Sumo version

The standard version (in the dist/browsers and dist/modules directories) contains the high-level functions, and is the recommended one for most projects.

Alternatively, the "sumo" version, available in the dist/browsers-sumo and dist/modules-sumo directories contains all the symbols from the original library. This includes undocumented, untested, deprecated, low-level and easy to misuse functions.

The crypto_pwhash_* function set is only included in the sumo version.

The sumo version is slightly larger than the standard version, reserves more memory, and should be used only if you really need the extra symbols it provides.

Compilation

If you want to compile the files yourself, the following dependencies need to be installed on your system:

  • Emscripten
  • binaryen
  • git
  • NodeJS
  • make

Running make will install the dev dependencies, clone libsodium, build it, test it, build the wrapper, and create the modules and minified distribution files.

Related projects

Authors

Built by Ahmad Ben Mrad, Frank Denis and Ryan Lester.

License

This wrapper is distributed under the ISC License.

libsodium.js's People

Contributors

abenmrad avatar bas-d avatar bennycode avatar bezi avatar brave44 avatar buu700 avatar cherrydt avatar danielecaggiari avatar dependabot-preview[bot] avatar dependabot[bot] avatar ffflorian avatar filosottile avatar fvgs avatar gaubee avatar hce avatar ionspin avatar jedisct1 avatar kevinburke avatar michaelkim20 avatar norbloc-vitalii avatar oconnor663-zoom avatar p-b-- avatar paragonie-security avatar sh-dv avatar svvac avatar toolness avatar webmaster128 avatar zachasme avatar zaenk avatar

Stargazers

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

Watchers

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

libsodium.js's Issues

Compile Error

I am getting AssertionError: Emscripten failed to generate .js: make: *** [libsodium/test/js.done] Error 1 even when I compile without modifying any files. I have already intalled all the dependencies mentioned on your readme.

PS: http://pastebin.com/g0XVgmaf

libsodium-wrappers-sumo npm package 0.4.6 contains no code

npm / yarn install of latest

yarn add libsodium-wrappers-sumo --save
yarn add v0.15.1
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 📃  Building fresh packages...
success Saved lockfile.
success Saved 2 new dependencies.
├─ [email protected]
└─ [email protected]
✨  Done in 2.45s.

But requiring the module:

sodium = require('libsodium-wrappers-sumo')

produces the following:

Error: Cannot find module 'libsodium-wrappers-sumo'
  at Function.Module._resolveFilename (module.js:455:15)
  at Function.Module._load (module.js:403:25)
  at Module.require (module.js:483:17)
  at require (internal/module.js:20:19)

Looking at the node_modules directory, there appears to be no code included

ls node_modules/libsodium-wrappers-sumo/
LICENSE README.md package.json

The package.json references a dist directory which doesn't exist.

Everything works nicely if installed manually direct from repo.

Default memory limit too low for `sodium.crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE`

Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value 50331648, (2) compile with -s ALLOW_MEMORY_GROWTH=1 which adjusts the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program runs, or if you want malloc to return NULL (0) instead of this abort, compile with -s ABORTING_MALLOC=0

That's an awful lot less than the 1073741824 bytes MEMLIMIT_SENSITIVE needs. Same for Argon, it seems.

Requiring libsodium eats exception stack traces in Node 6

With the following test.js

var libsodium = require('libsodium');
console.log('Hello');
throw Error('error');

Run in Node 6

$ nvm use 6
Now using node v6.2.0 (npm v3.8.9)
$ node test.js
/Users/jpo/Lucify/code/jep/node_modules/libsodium/dist/modules/libsodium.js:14
var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;if(Module["ENVIRONMENT"]){if(Module["ENVIRONMENT"]==="WEB"){ENVIRONMENT_IS_WEB=true}else if(Module["ENVIRONMENT"]==="WORKER"){ENVIRONMENT_IS_WORKER=true}else if(Module["ENVIRONMENT"]==="NODE"){ENVIRONMENT_IS_NODE=true}else if(Module["ENVIRONMENT"]==="SHELL"){ENVIRONMENT_IS_SHELL=true}else{throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.")}}else{ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENV

There is no exception stack trace for the thrown error, and some unrelated sodium code instead.

With node 5 it is a bit better:

$ nvm use 5
Now using node v5.11.1 (npm v3.8.6)
$ node test.js
Hello
/Users/jpo/Lucify/code/jep/node_modules/libsodium/dist/modules/libsodium.js:14
var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;if(Module["ENVIRONMENT"]){if(Module["ENVIRONMENT"]==="WEB"){ENVIRONMENT_IS_WEB=true}else if(Module["ENVIRONMENT"]==="WORKER"){ENVIRONMENT_IS_WORKER=true}else if(Module["ENVIRONMENT"]==="NODE"){ENVIRONMENT_IS_NODE=true}else if(Module["ENVIRONMENT"]==="SHELL"){ENVIRONMENT_IS_SHELL=true}else{throw new Error("The provided Module['ENVIRONMENT'] value is not valid. It must be one of: WEB|WORKER|NODE|SHELL.")}}else{ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENV

Error: error
    at Error (native)
    at Object.<anonymous> (/Users/jpo/Lucify/code/jep/test.js:4:7)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at Module.load (module.js:357:32)
    at Function.Module._load (module.js:314:12)
    at Function.Module.runMain (module.js:447:10)
    at startup (node.js:148:18)
    at node.js:405:3

Now at least the exception stack trace is there. There is however also the weird code snippet from libsodium. Same for Node 4.

So somehow just requiring sodium takes over some of the exception handling in node.

The same thing happens with both libsodium versions 3.0.0 and 0.2.11. I did the test with a fresh project created with npm init.

Uncaught EvalError: Refused to evaluate a string as JavaScript

Thanks for the wrappers. However when I'm using the library on ElectronJS for my app, I got this error:

Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self'

on this line

var d;d||(d=eval("(function() { try { return Module || {} } catch(e) { return {} } })()"));var g={},q;for(q in d)d.hasOwnProperty(q)&&(g[q]=d[q]);var aa="object"===typeof window,ba="object"===typeof process&&"function"===typeof require&&!aa,ca="function"===typeof importScripts,da=!aa&&!ba&&!ca;
. I think Chromium prevents execution from eval or Function. Do you know how to fix this error or any way to work around this issue so that I can use the lib for my app? Thank you!

sodium.min.js has broken asm code

I get the following error on Firefox:

sodiumasmerror

Not sure what the best way to fix it is, but this worked for me for now:

line=$(($(grep -n 'return Module;' sodium.js | sed 's/:.*//g')+1))
head -n $line sodium.js > sodium.min.js
tail -n +$(($line+1)) sodium.js | uglifyjs --stats --mangle --compress sequences=true,dead_code=true,conditionals=true,booleans=true,unused=true,if_return=true,join_vars=true,drop_console=true >> sodium.min.js # uglifyjs args copied from Makefile

sodium.crypto_aead_chacha20poly1305_encrypt is not a function

i want to use this lib's aead function, but the aead family cannot use.
may be dont export then?

I use it in browser with

<script src="sodium.js" async defer></script>

and test it use this:

temp = sodium.to_base64(
    sodium.crypto_generichash(
        64,
        TextIn
    )
);

it work.

but when i test aead with:

temp = sodium.crypto_aead_chacha20poly1305_encrypt(
    TextIn,
    "124",
    undefined,
    "public_nonce",
    "key",
    "base64"
);

it not work and tell me sodium.crypto_aead_chacha20poly1305_encrypt is not a function

Add node-zopfli and uglify-js as devDependencies

This is just a suggestion, but it may make sense to add the two above-mentioned npm dependencies as devDependencies in package.json rather than requiring the contributor to install them globally. Installing dependencies locally is generally good practice.

The accompanying executables would be installed to node_modules/.bin, the path to which can be acquired using npm bin.

I actually spent far too much time trying to implement this myself prior to submitting my earlier PRs. I thought it might be the contributor's responsibility to update the dist/ files, so I figured I'd make this change prior to building the project. Though I soon found out the build process takes an excruciatingly long time on my laptop, and I ran into errors when make tried to run Uglify.

But this should be a trivial improvement to make for someone better versed in Makefiles and better able to test the build than I.

`sodium_init()`. What's its role in JS?

Hey,

I noticed that you called "commented in" the libsodium_raw._sodium_init() line in wrap-template.js. I was wondering if it is a necessary call in JS, since it's role in C is to open /dev/urandom on Unix-like systems and to keep it open.

Cannot install 0.4.0

When I try to install the 0.4.0 release, I get the following error:

npm WARN install:[email protected] ENOENT: no such file or directory, open 'C:...\node_modules.staging\libsodium-822cf139\package.json'
npm ERR! Windows_NT 10.0.10586
npm ERR! argv "C:\Program Files\nodejs\node.exe" "C:...\AppData\Roaming\npm\node_modules\npm\bin\npm-cli.js" "install"
npm ERR! node v6.5.0
npm ERR! npm v3.10.7
npm ERR! path C:...\node_modules.staging\libsodium-wrappers-d8637cfb\package.json
npm ERR! code ENOENT
npm ERR! errno -4058
npm ERR! syscall open

npm ERR! enoent ENOENT: no such file or directory, open 'C:...\node_modules.staging\libsodium-wrappers-d8637cfb\package.json'
npm ERR! enoent ENOENT: no such file or directory, open 'C:...\node_modules.staging\libsodium-wrappers-d8637cfb\package.json'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! Please include the following file with any support request:
npm ERR! C:...\npm-debug.log

0.3.1 works fine, I suspect it has to do with the changes in 6050d93 and fb50aca.

crypto_secretbox_open_easy add characters at the end of the decryption result.

As we can see in the following code the output is: Song is canción in Spanish!A and not Song is canción in Spanish!

var text = 'Song is canción in Spanish!'
var key = '6de550be1ea85eec994e64a381a44582740967bf9c83e7105f9611923d99bb86';
var nonce = '474c38dacca0e0f41b8a247e0fb1b610a5f8b4fee213adb3';


var cipherText = sodium.crypto_secretbox_easy(text, sodium.from_hex(nonce), sodium.from_hex(key), 'hex');

 var result =  sodium.crypto_secretbox_open_easy(sodium.from_hex(cipherText), sodium.from_hex(options.nonce), sodium.from_hex(key), 'text'); 

console.log(result);

I've bypassed this Issue returning hex in fact of text in crypto_secretbox_open_easy and then parsing the result to text.

var text = 'Song is canción in Spanish!'
var key = '6de550be1ea85eec994e64a381a44582740967bf9c83e7105f9611923d99bb86';
var nonce = '474c38dacca0e0f41b8a247e0fb1b610a5f8b4fee213adb3';


var cipherText = sodium.crypto_secretbox_easy(text, sodium.from_hex(nonce), sodium.from_hex(key), 'hex');

 var result = sodium.crypto_secretbox_open_easy(sodium.from_hex(cipherText), sodium.from_hex(options.nonce), sodium.from_hex(key), 'hex');

console.log(sodium.to_string(sodium.from_hex(result)));

crypto_aead_chacha20poly1305_decrypt not implemented in libsodium.js

The libsodium_wrappers.js contains the function crypto_aead_chacha20poly1305_decrypt, but when you call this, an error is produced as this is not implemented in libsodium.js. I can that this has been added to the master branch, but is not available in an actual tagged release, which is all I can choose in npm.

Would it be possible to publish an update based on master to npm.

Uncaught ReferenceError: Module is not defined

I tried to use libsodium.js as discriped in your readme section Usage with global definitions, for web browsers, but loading of the js file failed with the error:

Uncaught ReferenceError: Module is not defined

the error is happening in line 13 of libsodium-wrappers.js because neither root.libsodium nor Module is defined. Is there a bug or am i missing something, maybe an undocumented dependency?

crypto_box_easy invalid output on some platforms

Isolated test case: http://codepen.io/anon/pen/PqgQyy

I can't say exactly what conditions cause this issue (our production error emails indicate a variety of devices and browsers, including Firefox and Chrome), but I've been able to reliably reproduce it in iOS 7 on BrowserStack (though, oddly, not in iOS 7 on my local iOS simulator).

My first suspicion was endianness, but this pen indicates that that isn't the case (both my machine and BS iOS 7 are little-endian).


Expected: bba64986e249af9642dd0067f6248857cb12cfb848

screen shot 2015-08-13 at 11 56 53 am

Actual: 78001e42c8b9a6e3ebe953dbd73681fc4edce12e92

screen shot 2015-08-13 at 11 54 55 am

sodium.crypto_pwhash missing?

Apologies if being dim, but sodium.crypto_pwhash is undefined in the .min.js and .js browser downloads. The libsodium._crypto_pwhash is undefined also. Other functions (e.g. generic_hash etc.) are fine.

Am I missing a step or something equally obvious?

TIA

Edit: In the libsodium.js module, there is no reference to "..._crypto_pwhash..." either, but the libsodium-wrappers.js seems to expect them there? Apologies again if I'm way off base here - it's been a while since I waded through Emscripten output...

[Bug fix] Support for to_string calls with big Uint8Arrays

It seems that, despite not being defined the ECMAScript spec, JavaScript runtimes tend to impose a limit on how many arguments a function can receive. And since the current to_string implementation in the libsodium wrapper uses a Function.call paradigm, you tend to hit that wall at some point.

Here is a fix (among other possible ones) :

/*
The main idea is to split the buffer into a smaller buffers,
call to_string on each one of them, and concatenate the results
*/
var toStringChunkSize = 32767;

function to_string(bytes) {
        if (typeof TextDecoder === "function") {
            return new TextDecoder("utf-8", {fatal: true}).decode(bytes);
        }

    var numChunks = Math.ceil(bytes.length / toStringChunkSize);
    if (numChunks > 1){
        var totalString = '';
        for (var i = 0; i < numChunks; i++){
            totalString += to_string(Array.prototype.slice.call(bytes, i * toStringChunkSize, (i + 1) * toStringChunkSize));
        }
        return totalString;
    }

    try {
        return decodeURIComponent(escape(String.fromCharCode.apply(null, bytes)));
    }
    catch (_) {
        throw new TypeError("The encoded data was not valid.");
    }
}

PS: Sorry for not submitting this as a PR.

Cannot read property '_sodium_init' of undefined - Using libsodiumjs with requirejs

When I use libsodiumjs with requirejs i get the following error:

      "Uncaught TypeError: Cannot read property '_sodium_init' of undefined(anonymous function) @ libsodium-wrappers.js:20context.execCb @ require.js:1665Module.check @ require.js:874(anonymous function) @ require.js:1121(anonymous function) @ require.js:132(anonymous function) @ require.js:1171each @ require.js:57Module.emit @ require.js:1170Module.check @ require.js:925Module.enable @ require.js:1158Module.init @ require.js:782callGetModule @ require.js:1185context.completeLoad @ require.js:1579context.onScriptLoad @ require.js:1686"

the way that i am using it is:
requiretest-html

main-js

test-js

When i run it i get the error thar i mention:

error

Feature request: explicit error message for crypto_sign_open

Name Version
libsodium-wrappers 0.3.1
Node.js v4.4.6

If for any reason crypto_sign_open fails with an error, there is absolutely no way to find out if the open procedure failed because the data didn't match (if it's the case, why a non-zero value wasn't returned) or if something internal caused the error. In the latter case, I would suggest to throw an error with an explicit message (which is not happening here).

increment() is not exported

libsodium-wrappers doesn't expose the increment() helper function

I think it's as simple as applying the patch below, but I haven't been able to create a working build environment to test it.

diff --git a/wrapper/wrap-template.js b/wrapper/wrap-template.js
index f72ec5a..25222e2 100644
--- a/wrapper/wrap-template.js
+++ b/wrapper/wrap-template.js
@@ -290,6 +290,7 @@
        exports.from_base64 = from_base64;
        exports.from_hex = from_hex;
        exports.from_string = from_string;
+       exports.increment = increment;
        exports.libsodium = libsodium;
        exports.memcmp = memcmp;
        exports.memzero = memzero;

Getting Error with Browserify

I created an empty main.js file with this in it:

var sodium = require('libsodium-wrappers');

I then browserified it:

browserify main.js -o bundle.js

After loading bundle.js into my html and loading that page I received this error in the console:

Uncaught TypeError: Cannot read property 'write' of undefined

It's coming from this call:

process.stderr.write(a+\n")

Though, it works fine with bower.

Can't minify a project that uses libsodium.js: Uncaught ReferenceError: window is not defined

I'm trying to minify my project (that is a library) that uses libsodium.js, and I get the following error when i load it:

result

Heare there is an example:

As we can see i'm using GruntJS and the grunt-contrib-requirejs module and almond to minify it.

g1
g2

Then i wrap it to have a module (based on https://github.com/jrburke/almond).

end-frag
start-frag

heare is my sample code that uses libsodium:

src
tf2

The test that fails

tf1

And the result of the execution of: grunt mochaTest:functional

result

side-channel attacks

When reading the papers about NaCl there are some strong statements about preventing timing attacks by not branching based on input data, doing constant time comparisons etc. [1]. There are some concerns about the inability to guarantee time safety in high-level languages like JavaScript [2][3] so I wonder how can libsodium.js guarantee to be safe from these side-channel attacks like the original NaCl C/C++ versions? It looks like the original emscripten authors don't even know what side-channels are when asked about it [4].

[1] http://cr.yp.to/highspeed/coolnacl-20120725.pdf p8 "No data flow from secrets to load addresses", "No data flow from secrets to branch conditions"
[2] https://news.ycombinator.com/item?id=704689
[3] signalapp/Signal-Desktop#41 (comment)
[4] https://twitter.com/kripken/status/490335241471422466

crypto_box_seal aborts with "Cannot enlarge memory arrays."

Hello,

I am using libsodium.js to encrypt answers from a secure backend server.

I am reading a binary file from disk (as base64), try to encrypt it with crypto_box_seal and send it back to the user (again as base64).

When the file is 5337kb everything works fine, as soon as the file is 5800kb libsodium.js will trigger this abort:

If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.
Cannot enlarge memory arrays. Either (1) compile with  -s TOTAL_MEMORY=X  with X higher than the current value 16777216, (2) compile with  -s ALLOW_ME
MORY_GROWTH=1  which adjusts the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher value before the program run
s, or if you want malloc to return NULL (0) instead of this abort, compile with  -s ABORTING_MALLOC=0
Unhandled rejection abort("Cannot enlarge memory arrays. Either (1) compile with  -s TOTAL_MEMORY=X  with X higher than the current value 16777216, (2
) compile with  -s ALLOW_MEMORY_GROWTH=1  which adjusts the size at runtime but prevents some optimizations, (3) set Module.TOTAL_MEMORY to a higher v
alue before the program runs, or if you want malloc to return NULL (0) instead of this abort, compile with  -s ABORTING_MALLOC=0 ") at Error
  at jsStackTrace (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:13:15866)
  at stackTrace (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:13:16037)
  at abort (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:26:15122)
  at abortOnCannotGrowMemory (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:13:16918)
  at enlargeMemory (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:13:17363)
  at Function.Runtime.dynamicAlloc [as alloc] (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:13:7173)
  at _sbrk (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:13:197184)
  at Object.bc [as _malloc] (/var/www/hello.world/node_modules/libsodium/dist/modules/libsodium.js:18:168615)
  at _malloc (/var/www/hello.world/node_modules/libsodium-wrappers/dist/modules/libsodium-wrappers.js:356:32)
  at _to_allocated_buf_address (/var/www/hello.world/node_modules/libsodium-wrappers/dist/modules/libsodium-wrappers.js:350:23)
  at Object.crypto_box_seal (/var/www/hello.world/node_modules/libsodium-wrappers/dist/modules/libsodium-wrappers.js:1631:25)
  at Socket.module.exports.Socket.encrypt (/var/www/hello.world/crypto.coffee:23:21)
  at Socket.encrypt (/var/www/hello.world/crypto.coffee:1:1)
  at /var/www/hello.world/handler.coffee:108:22
  at tryCatcher (/var/www/hello.world/node_modules/bluebird/js/release/util.js:16:23)
  at Promise._settlePromiseFromHandler (/var/www/hello.world/node_modules/bluebird/js/release/promise.js:504:31)
  at Promise._settlePromise (/var/www/hello.world/node

I can see the memory consumption spike up to roughly 300mb then the script crashes. The server has plenty (2GB) of ram, most of it is unused.

Is this a wanted behaviour?

Btw, have you tested version 0.4.0 of libsodium from npm? I am no longer able to install the newest version using npm:

$ npm i libsodium-wrappers@latest
npm WARN install:[email protected] ENOENT: no such file or directory, open '/var/www/hello.world/node_modules/.staging/libsodium-c18b7999/package.json'
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
npm ERR! Linux 4.4.0-36-generic
npm ERR! argv "/usr/local/bin/node" "/home/hans/.npm-packages/bin/npm" "i" "libsodium-wrappers@latest"
npm ERR! node v6.4.0
npm ERR! npm  v3.10.6
npm ERR! path /var/www/hello.world/node_modules/.staging/libsodium-wrappers-26114998/package.json
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! syscall open

npm ERR! enoent ENOENT: no such file or directory, open '/var/www/hello.world/node_modules/.staging/libsodium-wrappers-26114998/package.json'
npm ERR! enoent ENOENT: no such file or directory, open '/var/www/hello.world/node_modules/.staging/libsodium-wrappers-26114998/package.json'
npm ERR! enoent This is most likely not a problem with npm itself
npm ERR! enoent and is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! Please include the following file with any support request:
npm ERR!     /var/www/hello.world/npm-debug.log

Greetings

[Question] Using ChaCha in Javascript

Wondering if someone can help? I found the following example usage for the AEAD ChaCha20poly1305 function, and it looks like this:

crypto_aead_chacha20poly1305_encrypt(
  (unsigned char *) &ciphertext.front(),
  &ciphertext_length,
  (const unsigned char *) &plaintext.front(),
  plaintext.size(),
  additional_data.empty() ? nullptr : (const unsigned char *) &additional_data.front(),
  additional_data.size(), NULL,
  ks.getNonce(), ks.getKey());

but I can't figure out how to port it to javascript. I have this so far:

let ciphertext = new Buffer();
let ciphertext_len = ciphertext.length;
let MESSAGE = data;
let MESSAGE_LEN = data.length;
let ADDITIONAL_DATA = new Buffer();
let ADDITIONAL_DATA_LEN = ADDITIONAL_DATA.length;
sodium._crypto_aead_chacha20poly1305_encrypt(
  ciphertext,
  ciphertext_len,
  MESSAGE,
  MESSAGE_LEN,
  ADDITIONAL_DATA,
  ADDITIONAL_DATA_LEN,
  null,
  nonce,
  key);

But that does not seem to be on the right track to getting this to work in Javascript. I wonder if someone can point me in the right direction? In additon, is it possible to set something up like this?

const encryptedData = sodium._crypto_aead_chacha20poly1305_encrypt(
  DATA,
  NONCE,
  KEY);

Thanks!

Recommended strategy to protect secret keys in JavaScript?

I'm new to libsodium and am wondering about how to use libsodium.js correctly on the client side. How is it possible to use functions that require a secret key parameter without exposing the secret key to the client? Or do I need to consider a different strategy altogether so secret keys are never needed on the client side?

Base64 output adding "\r\n" after 76 characters

This might be intentional for compliance with base64 encoding, but parsing those characters out is required in order to not break the encryption.

Consider letting the user parse their base64 output into their own chunks or adding this information to documentation.

Update builds for node Version 5

Module version mismatch. Expected 46, got 47.
App threw an error when running [Error: Module version mismatch. Expected 46, got 47.]
/home/null/code/patchwork/node_modules/libsodium/dist/modules/libsodium.js:14
var Module;if(!Module)Module=(typeof Module!=="undefined"?Module:null)||{};var moduleOverrides={};for(var key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var ENVIRONMENT_IS_WEB=typeof window==="object";var ENVIRONMENT_IS_WORKER=typeof importScripts==="function";var ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof require==="function"&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;var ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;if(ENVIRONMENT_IS_NODE){if(!Module["print"])Module["print"]=function print(x){process["stdout"].write(x+"\n")};if(!Module["printErr"])Module["printErr"]=function printErr(x){process["stderr"].write(x+"\n")};var nodeFS=require("fs");var nodePath=require("path");Module["read"]=function read(filename,binary){filename=nodePath["normalize"](filename);var ret=nodeFS["readFileSync"](filename);if(!ret&&filename!=nodePath["resolve"](filenam

Error: Module version mismatch. Expected 46, got 47.
    at Error (native)
    at Object.module.(anonymous function) (ATOM_SHELL_ASAR.js:137:20)
    at Object.module.(anonymous function) [as .node] (ATOM_SHELL_ASAR.js:137:20)
    at Module.load (module.js:355:32)
    at Function.Module._load (module.js:310:12)
    at Module.require (module.js:365:17)
    at require (module.js:384:17)
    at bindings (/home/null/code/patchwork/node_modules/bindings/bindings.js:76:44)
    at Object.<anonymous> (/home/null/code/patchwork/node_modules/leveldown/leveldown.js:4:46)
    at Module._compile (module.js:434:26)

Scrypt can't put values bigger than 8589934592

On the wrapprer there are a validation that says

    if (!(typeof memLimit === "number" && (memLimit | 0) === memLimit) && (memLimit | 0) > 0) {
        _free_and_throw_type_error(address_pool, "memLimit must be an unsigned integer");
    }

I can't inform a memLimit value like 8589934593 or bigger.

and the problem is that (8589934593 | 0) is -1
(8589934592 | 0) is 0

but as I understand it makeas a kind of negative countdown.

Bump for bower verseion

Thanks for working on such an awesome project!

It looks like you recently updated to include 1.0.3 support (I'm looking to use the seal/unseal operations, so this is much appreciated). I think the bower files need a version bump from 0.2.5 to 0.2.6 to reflect the change. I'll use the raw js files for now, but it would be nice to have bower grab the new version.

"sodium.crypto_sign_keypair" is slow

I have a fairly new computer (Intel Core i7-6500U, 16 GB RAM, SSD) running Windows 10 (64-bit). But when I execute sodium.crypto_sign_keypair in my browser (Chrome 47) then it takes 2-3 seconds to get the key pair.

Do you experience the same performance issues with this call? If yes, is there anything which can be done to make it faster? Or do you know what specific calls inside crypto_sign_keypair slows it down? Maybe it's related to the entropy?

libsodium-wrappers-sumo npm package references unreleased version of libsodium

Trying to use crypto_pwhash on the server-side, which requires the use of libsodium-wrappers-sumo.

Installing via npm produces the following error:

npm install libsodium-wrappers-sumo --save
npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install" "libsodium-wrappers-sumo" "--save"
npm ERR! node v6.6.0
npm ERR! npm  v3.10.3

npm ERR! No compatible version found: [email protected]
npm ERR! Valid install targets:
npm ERR! 0.4.1, 0.4.0, 0.3.1, 0.3.0, 0.2.12, 0.2.11, 0.2.10, 0.2.9, 0.2.8, 0.2.7, 0.2.6, 0.2.5, 0.2.4, 0.2.2
npm ERR!
npm ERR!
npm ERR! If you need help, you may report this error at:
npm ERR!     <https://github.com/npm/npm/issues>

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/jmathews/work/dilysu/npm-debug.log

Looks like libsodium-wrappers-sumo was published 3 weeks ago at 0.4.5, but libsodium has not been updated on npm, which is still at 0.4.1, published 4 weeks ago.

Can this be updated?

Thanks.

Error 137 when using crypto_box_beforenm and crypto_box_easy

I'm trying to use crypto_box_beforenm and crypto_box_easy like this in Tonic, but always end up with error 137:

require('libsodium');
var sodium = require('libsodium-wrappers');

// Preliminary key setup
var keyAlice = sodium.crypto_box_keypair(); 
var keyBob = sodium.crypto_box_keypair();

// this throws error 137 in Tonic
var sharedKey = sodium.crypto_box_beforenm(keyBob.publicKey, keyAlice.privateKey); 

var json = '{ "superSecretMessage":"test" }';
var nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
// This also throws 137 in Tonic - suggest that the beforeNM function has a memory leak or similar?
var encrypted = sodium.crypto_box_easy(json, nonce, keyBob.publicKey, keyAlice.privateKey);

Any ideas how to fix this?

ES6 default import with Babel fails

When using the following ES6 default import:

import sodium from 'sodium-wrappers';

along with Babel to transpile, sodium receives the value undefined. It should, however, be receiving the exported module object.

I traced the issue to the presence of the following line:

Object.defineProperty(exports, '__esModule', { value: true });

When Babel sees this property, it assumes the module is ES6-conformant. Therefore, it does not make the adjustments that would otherwise be necessary in order for the module to play nicely in an ES6 environment. In particular, Babel ends up not creating the default property on the object, which is the property that is accessed when making a default import. Thus, this results in the accessed value being undefined.

Removal of this line allowed me to perform a default import and I have not encountered any issues as a result of doing so. Though, I just started using libsodium, so I have not performed any real, factorable testing of this.

As far as I understand, this line should not be necessary in this package. Therefore, unless there is a reason why it needs to be included, removing it is likely safe.

Re-adding test vectors

I suggest that we bring back the test vectors that have been written at the beginning of the project. It allows everyone to ensure that the js library works as well as the original C version, especially because the used test vectors were harvested from the original lib.

Buffer/adress_pool leak when using crypto_pwhash and crypto_aead_chacha20poly1305_ietf_decrypt with output format text with special characters

var sodium = require('libsodium-wrappers')
const mpw = 'this is my serious super secret hyper password'
const seed = sodium.crypto_generichash(32, mpw)
const userEmail = '[email protected]'
const userSalt = sodium.crypto_generichash(16, userEmail)
const userSaltNpub = sodium.crypto_generichash(12, userEmail)
const cryptKey = sodium.crypto_pwhash(32, seed, userSalt, 6, 10240, 1)
const msg = Buffer.from('account-type: login, username:[email protected], password:1239rijfsdl@#!z™£Ωå, url: github.com', 'utf8')
const adata = Buffer(userEmail)
const nsk = Buffer('')
const npub = Buffer(userSaltNpub)
const kek = Buffer(seed)
const ciphertext = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(msg, adata, nsk, npub, kek)
const de_msg = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(nsk, ciphertext, adata, npub, kek, 'text') 
console.log('decrypted msg:', de_msg)
> node -v
v6.2.1
> node leak.js
decrypted msg: account-type: login, username:[email protected], password:1239rijfsdl@#!z™£Ωå, url: github.com"兩�񠼧.ﲴ�򹪋0ff㯪9��煮�𓭿𓔰-け%���益�0��󲻖ǖ��ܭék����B󦸂g􍺝ﳇ�AԵ񅺽ُ陋�󉺇��@m͐C򦣷A𶩤�O蛒��ܕ=ȑb+f0䮚`諛{�~館�署�󽬒Bۄ,漯M曬흥ﳏ�r����Z吝�I��cy��Aʑ�ﵜ�42Ȭ,p��'y窔l參�⎑OߡН��ʷϳ��:贊

But when I comment cryptKey, output is correct

> node leak.js
decrypted msg: account-type: login, username:[email protected], password:1239rijfsdl@#!z™£Ωå, url: github.com

When I remove ™£Ωå symbols from password, output is also fine.
Should I use some secure memory function or any hints?

EDIT: Looks like using outputformat 'text' in sodium.crypto_aead_chacha20poly1305_ietf_decrypt is doing all the fun

[Question]Sumo version of npm

Hi,

How to get the sumo version of libsodium via npm? Through bower I can get several file distribution and I can just pick the sumo version, while in npm I only get one file distribution and it's the standard version.

Thanks

`crypto_hash_sha256()` not exported?

Our project need a browser version of SHA-256. I would like to use libsodium.js for that.
To my surprise, I find this function is deliberately not exported.

I see crypto_hash() (which is supposed to be a SHA-512-256) is exported.
Is there any reason not to export it?

Thanks.

Changelog for recent changes

Hi there,

I think it would be very cool to have a changelog to see what changed from version to version and if an update is needed (maybe some security related changes?) or if it's just cosmetic (like the missing dist items from the last update). Every "unneeded" update hurts me because I modified the emscripten-part of the lib in order to get it closure compiled in advanced mode more efficiently and I have to re-do this step everytime I need to update (guess i need some sort auf automation there).

Last but not least: Thanks for the great work!

[Question] Huge memory consumption

Hi,

I notice that this library consume quite huge memory portion in a browser (around 30MB in chrome - 3 times my core apps), I've tried to dereference any variable that refer to libsodium but still the memory won't goes down (it's like not being cleaned up by the garbage collector), is it a normal? Is there any way or workaround to free the memory after the the object not used? Will the web worker (#46) style help this issue??

Error at _free_and_throw_error

Hi,
I'm testing libsodium.js on node with mocha, when I try to decript some cripted data there's obviously something going wrong(otherwise I wouldn't see an error in _free_and_throw_error I guess), but I don't get any useful error message because _free_and_throw_error throws an error (line 278 of dist/modules/libsodium-wrappers.js).

Here are my crypt and decript functions:

this.nonce = sodium.randombytes_buf(sodium.crypto_secretbox_NONCEBYTES);
this.key = sodium.randombytes_buf(sodium.crypto_secretbox_KEYBYTES);
exports.cript = function (data) {
    this.sanitizeCrypt(data);
    data = new Buffer(data);
    return sodium.crypto_secretbox_easy(data, this.nonce, this.key, 'hex');
};
exports.decript = function (data) {
    this.sanitizeDecript(data);
    return sodium.crypto_secretbox_open_easy(data, this.nonce, this.key);
};

Surely I'm doing something wrong, but it looks like something's wrong in error handling.

Chrome: "Uncaught RangeError: Maximum call stack size exceeded" when running in a Web Worker

See test at http://aykevl.nl/test/sodium-webworker.html.
The page is empty, but in the console an error is logged:

Uncaught RangeError: Maximum call stack size exceeded

The issue is logged here: https://code.google.com/p/chromium/issues/detail?id=252492
A possible workaround is described here: https://code.google.com/p/crypto-js/issues/detail?id=68

I am using Chrome 41.0.2272.118 (64-bit) on Debian Linux.

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.