UNPKG

js-nacl

Version:

Emscripten-compiled Javascript version of NaCl, the Networking and Cryptography library.

444 lines (382 loc) 17.7 kB
var nacl = (function () { 'use strict'; var exports = {}; //--------------------------------------------------------------------------- // Horrifying UTF-8 and hex codecs function encode_utf8(s) { return encode_latin1(unescape(encodeURIComponent(s))); } function encode_latin1(s) { var result = new Uint8Array(s.length); for (var i = 0; i < s.length; i++) { var c = s.charCodeAt(i); if ((c & 0xff) !== c) throw {message: "Cannot encode string in Latin1", str: s}; result[i] = (c & 0xff); } return result; } function decode_utf8(bs) { return decodeURIComponent(escape(decode_latin1(bs))); } function decode_latin1(bs) { var encoded = []; for (var i = 0; i < bs.length; i++) { encoded.push(String.fromCharCode(bs[i])); } return encoded.join(''); } function to_hex(bs) { var encoded = []; for (var i = 0; i < bs.length; i++) { encoded.push("0123456789abcdef"[(bs[i] >> 4) & 15]); encoded.push("0123456789abcdef"[bs[i] & 15]); } return encoded.join(''); } //--------------------------------------------------------------------------- function injectBytes(bs, leftPadding) { var p = leftPadding || 0; var address = nacl_raw._malloc(bs.length + p); nacl_raw.HEAPU8.set(bs, address + p); for (var i = address; i < address + p; i++) { nacl_raw.HEAPU8[i] = 0; } return address; } function check_injectBytes(function_name, what, thing, expected_length, leftPadding) { check_length(function_name, what, thing, expected_length); return injectBytes(thing, leftPadding); } function extractBytes(address, length) { var result = new Uint8Array(length); result.set(nacl_raw.HEAPU8.subarray(address, address + length)); return result; } //--------------------------------------------------------------------------- function check(function_name, result) { if (result !== 0) { throw {message: "nacl_raw." + function_name + " signalled an error"}; } } function check_length(function_name, what, thing, expected_length) { if (thing.length !== expected_length) { throw {message: "nacl." + function_name + " expected " + expected_length + "-byte " + what + " but got length " + thing.length}; } } function Target(length) { this.length = length; this.address = nacl_raw._malloc(length); } Target.prototype.extractBytes = function (offset) { var result = extractBytes(this.address + (offset || 0), this.length - (offset || 0)); nacl_raw._free(this.address); this.address = null; return result; }; function free_all(addresses) { for (var i = 0; i < addresses.length; i++) { nacl_raw._free(addresses[i]); } } //--------------------------------------------------------------------------- // Boxing function crypto_box_keypair() { var pk = new Target(nacl_raw._crypto_box_PUBLICKEYBYTES); var sk = new Target(nacl_raw._crypto_box_SECRETKEYBYTES); check("_crypto_box_keypair", nacl_raw._crypto_box_keypair(pk.address, sk.address)); return {boxPk: pk.extractBytes(), boxSk: sk.extractBytes()}; } function crypto_box_random_nonce() { return nacl_raw.RandomBytes.crypto.randomBytes(nacl_raw._crypto_box_NONCEBYTES); } function crypto_box(msg, nonce, pk, sk) { var m = injectBytes(msg, nacl_raw._crypto_box_ZEROBYTES); var na = check_injectBytes("crypto_box", "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); var pka = check_injectBytes("crypto_box", "pk", pk, nacl_raw._crypto_box_PUBLICKEYBYTES); var ska = check_injectBytes("crypto_box", "sk", sk, nacl_raw._crypto_box_SECRETKEYBYTES); var c = new Target(msg.length + nacl_raw._crypto_box_ZEROBYTES); check("_crypto_box", nacl_raw._crypto_box(c.address, m, c.length, 0, na, pka, ska)); free_all([m, na, pka, ska]); return c.extractBytes(nacl_raw._crypto_box_BOXZEROBYTES); } function crypto_box_open(ciphertext, nonce, pk, sk) { var c = injectBytes(ciphertext, nacl_raw._crypto_box_BOXZEROBYTES); var na = check_injectBytes("crypto_box_open", "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); var pka = check_injectBytes("crypto_box_open", "pk", pk, nacl_raw._crypto_box_PUBLICKEYBYTES); var ska = check_injectBytes("crypto_box_open", "sk", sk, nacl_raw._crypto_box_SECRETKEYBYTES); var m = new Target(ciphertext.length + nacl_raw._crypto_box_BOXZEROBYTES); check("_crypto_box_open", nacl_raw._crypto_box_open(m.address, c, m.length, 0, na, pka, ska)); free_all([c, na, pka, ska]); return m.extractBytes(nacl_raw._crypto_box_ZEROBYTES); } function crypto_box_precompute(pk, sk) { var pka = check_injectBytes("crypto_box_precompute", "pk", pk, nacl_raw._crypto_box_PUBLICKEYBYTES); var ska = check_injectBytes("crypto_box_precompute", "sk", sk, nacl_raw._crypto_box_SECRETKEYBYTES); var k = new Target(nacl_raw._crypto_box_BEFORENMBYTES); check("_crypto_box_beforenm", nacl_raw._crypto_box_beforenm(k.address, pka, ska)); free_all([pka, ska]); return {boxK: k.extractBytes()}; } function crypto_box_precomputed(msg, nonce, state) { var m = injectBytes(msg, nacl_raw._crypto_box_ZEROBYTES); var na = check_injectBytes("crypto_box_precomputed", "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); var ka = check_injectBytes("crypto_box_precomputed", "boxK", state.boxK, nacl_raw._crypto_box_BEFORENMBYTES); var c = new Target(msg.length + nacl_raw._crypto_box_ZEROBYTES); check("_crypto_box_afternm", nacl_raw._crypto_box_afternm(c.address, m, c.length, 0, na, ka)); free_all([m, na, ka]); return c.extractBytes(nacl_raw._crypto_box_BOXZEROBYTES); } function crypto_box_open_precomputed(ciphertext, nonce, state) { var c = injectBytes(ciphertext, nacl_raw._crypto_box_BOXZEROBYTES); var na = check_injectBytes("crypto_box_open_precomputed", "nonce", nonce, nacl_raw._crypto_box_NONCEBYTES); var ka = check_injectBytes("crypto_box_open_precomputed", "boxK", state.boxK, nacl_raw._crypto_box_BEFORENMBYTES); var m = new Target(ciphertext.length + nacl_raw._crypto_box_BOXZEROBYTES); check("_crypto_box_open_afternm", nacl_raw._crypto_box_open_afternm(m.address, c, m.length, 0, na, ka)); free_all([c, na, ka]); return m.extractBytes(nacl_raw._crypto_box_ZEROBYTES); } //--------------------------------------------------------------------------- // Hashing function crypto_hash(bs) { var address = injectBytes(bs); var hash = new Target(nacl_raw._crypto_hash_BYTES); check("_crypto_hash", nacl_raw._crypto_hash(hash.address, address, bs.length, 0)); nacl_raw._free(address); return hash.extractBytes(); } function crypto_hash_sha256(bs) { var address = injectBytes(bs); var hash = new Target(nacl_raw._crypto_hash_sha256_BYTES); check("_crypto_hash_sha256", nacl_raw._crypto_hash_sha256(hash.address, address, bs.length, 0)); nacl_raw._free(address); return hash.extractBytes(); } function crypto_hash_string(s) { return crypto_hash(encode_utf8(s)); } //--------------------------------------------------------------------------- // Symmetric-key encryption function crypto_stream_random_nonce() { return nacl_raw.RandomBytes.crypto.randomBytes(nacl_raw._crypto_stream_NONCEBYTES); } function crypto_stream(len, nonce, key) { var na = check_injectBytes("crypto_stream", "nonce", nonce, nacl_raw._crypto_stream_NONCEBYTES); var ka = check_injectBytes("crypto_stream", "key", key, nacl_raw._crypto_stream_KEYBYTES); var out = new Target(len); check("_crypto_stream", nacl_raw._crypto_stream(out.address, len, 0, na, ka)); free_all([na, ka]); return out.extractBytes(); } function crypto_stream_xor(msg, nonce, key) { var na = check_injectBytes("crypto_stream_xor", "nonce", nonce, nacl_raw._crypto_stream_NONCEBYTES); var ka = check_injectBytes("crypto_stream_xor", "key", key, nacl_raw._crypto_stream_KEYBYTES); var ma = injectBytes(msg); var out = new Target(msg.length); check("_crypto_stream_xor", nacl_raw._crypto_stream_xor(out.address, ma, msg.length, 0, na, ka)); free_all([na, ka, ma]); return out.extractBytes(); } //--------------------------------------------------------------------------- // One-time authentication function crypto_onetimeauth(msg, key) { var ka = check_injectBytes("crypto_onetimeauth", "key", key, nacl_raw._crypto_onetimeauth_KEYBYTES); var ma = injectBytes(msg); var authenticator = new Target(nacl_raw._crypto_onetimeauth_BYTES); check("_crypto_onetimeauth", nacl_raw._crypto_onetimeauth(authenticator.address, ma, msg.length, 0, ka)); free_all([ka, ma]); return authenticator.extractBytes(); } function crypto_onetimeauth_verify(authenticator, msg, key) { if (authenticator.length != nacl_raw._crypto_onetimeauth_BYTES) return false; var ka = check_injectBytes("crypto_onetimeauth_verify", "key", key, nacl_raw._crypto_onetimeauth_KEYBYTES); var ma = injectBytes(msg); var aa = injectBytes(authenticator); var result = nacl_raw._crypto_onetimeauth_verify(aa, ma, msg.length, 0, ka); free_all([ka, ma, aa]); return (result == 0); } //--------------------------------------------------------------------------- // Authentication function crypto_auth(msg, key) { var ka = check_injectBytes("crypto_auth", "key", key, nacl_raw._crypto_auth_KEYBYTES); var ma = injectBytes(msg); var authenticator = new Target(nacl_raw._crypto_auth_BYTES); check("_crypto_auth", nacl_raw._crypto_auth(authenticator.address, ma, msg.length, 0, ka)); free_all([ka, ma]); return authenticator.extractBytes(); } function crypto_auth_verify(authenticator, msg, key) { if (authenticator.length != nacl_raw._crypto_auth_BYTES) return false; var ka = check_injectBytes("crypto_auth_verify", "key", key, nacl_raw._crypto_auth_KEYBYTES); var ma = injectBytes(msg); var aa = injectBytes(authenticator); var result = nacl_raw._crypto_auth_verify(aa, ma, msg.length, 0, ka); free_all([ka, ma, aa]); return (result == 0); } //--------------------------------------------------------------------------- // Authenticated symmetric-key encryption function crypto_secretbox_random_nonce() { return nacl_raw.RandomBytes.crypto.randomBytes(nacl_raw._crypto_secretbox_NONCEBYTES); } function crypto_secretbox(msg, nonce, key) { var m = injectBytes(msg, nacl_raw._crypto_secretbox_ZEROBYTES); var na = check_injectBytes("crypto_secretbox", "nonce", nonce, nacl_raw._crypto_secretbox_NONCEBYTES); var ka = check_injectBytes("crypto_secretbox", "key", key, nacl_raw._crypto_secretbox_KEYBYTES); var c = new Target(msg.length + nacl_raw._crypto_secretbox_ZEROBYTES); check("_crypto_secretbox", nacl_raw._crypto_secretbox(c.address, m, c.length, 0, na, ka)); free_all([m, na, ka]); return c.extractBytes(nacl_raw._crypto_secretbox_BOXZEROBYTES); } function crypto_secretbox_open(ciphertext, nonce, key) { var c = injectBytes(ciphertext, nacl_raw._crypto_secretbox_BOXZEROBYTES); var na = check_injectBytes("crypto_secretbox_open", "nonce", nonce, nacl_raw._crypto_secretbox_NONCEBYTES); var ka = check_injectBytes("crypto_secretbox_open", "key", key, nacl_raw._crypto_secretbox_KEYBYTES); var m = new Target(ciphertext.length + nacl_raw._crypto_secretbox_BOXZEROBYTES); check("_crypto_secretbox_open", nacl_raw._crypto_secretbox_open(m.address, c, m.length, 0, na, ka)); free_all([c, na, ka]); return m.extractBytes(nacl_raw._crypto_secretbox_ZEROBYTES); } //--------------------------------------------------------------------------- // Signing function crypto_sign_keypair() { var pk = new Target(nacl_raw._crypto_sign_PUBLICKEYBYTES); var sk = new Target(nacl_raw._crypto_sign_SECRETKEYBYTES); check("_crypto_sign_keypair", nacl_raw._crypto_sign_keypair(pk.address, sk.address)); return {signPk: pk.extractBytes(), signSk: sk.extractBytes()}; } function crypto_sign(msg, sk) { var ma = injectBytes(msg); var ska = check_injectBytes("crypto_sign", "sk", sk, nacl_raw._crypto_sign_SECRETKEYBYTES); var sm = new Target(msg.length + nacl_raw._crypto_sign_BYTES); var smlen = new Target(8); check("_crypto_sign", nacl_raw._crypto_sign(sm.address, smlen.address, ma, msg.length, 0, ska)); free_all([ma, ska]); sm.length = nacl_raw.HEAPU32[smlen.address >> 2]; nacl_raw._free(smlen.address); return sm.extractBytes(); } function crypto_sign_open(sm, pk) { var sma = injectBytes(sm); var pka = check_injectBytes("crypto_sign_open", "pk", pk, nacl_raw._crypto_sign_PUBLICKEYBYTES); var m = new Target(sm.length); var mlen = new Target(8); if (nacl_raw._crypto_sign_open(m.address, mlen.address, sma, sm.length, 0, pka) === 0) { free_all([sma, pka]); m.length = nacl_raw.HEAPU32[mlen.address >> 2]; nacl_raw._free(mlen.address); return m.extractBytes(); } else { free_all([sma, pka, m.address, mlen.address]); return null; } } //--------------------------------------------------------------------------- // Keys function crypto_sign_keypair_from_seed(bs) { var seeda = check_injectBytes("crypto_sign_keypair_from_seed", "seed", bs, nacl_raw._crypto_sign_SECRETKEYBYTES / 2); var pk = new Target(nacl_raw._crypto_sign_PUBLICKEYBYTES); var sk = new Target(nacl_raw._crypto_sign_SECRETKEYBYTES); check("_crypto_sign_keypair_from_raw_sk", nacl_raw._crypto_sign_keypair_from_raw_sk(pk.address, sk.address, seeda)); nacl_raw._free(seeda); return {signPk: pk.extractBytes(), signSk: sk.extractBytes()}; } function crypto_box_keypair_from_seed(bs) { var hash = new Uint8Array(crypto_hash(bs)); var ska = injectBytes(hash.subarray(0, nacl_raw._crypto_box_SECRETKEYBYTES)); var pk = new Target(nacl_raw._crypto_box_PUBLICKEYBYTES); check("_crypto_scalarmult_curve25519_base", nacl_raw._crypto_scalarmult_curve25519_base(pk.address, ska)); var sk = extractBytes(ska, nacl_raw._crypto_box_SECRETKEYBYTES); nacl_raw._free(ska); return {boxPk: pk.extractBytes(), boxSk: sk}; } //--------------------------------------------------------------------------- exports.crypto_auth_BYTES = nacl_raw._crypto_auth_BYTES; exports.crypto_auth_KEYBYTES = nacl_raw._crypto_auth_KEYBYTES; exports.crypto_box_BEFORENMBYTES = nacl_raw._crypto_box_BEFORENMBYTES; exports.crypto_box_BOXZEROBYTES = nacl_raw._crypto_box_BOXZEROBYTES; exports.crypto_box_NONCEBYTES = nacl_raw._crypto_box_NONCEBYTES; exports.crypto_box_PUBLICKEYBYTES = nacl_raw._crypto_box_PUBLICKEYBYTES; exports.crypto_box_SECRETKEYBYTES = nacl_raw._crypto_box_SECRETKEYBYTES; exports.crypto_box_ZEROBYTES = nacl_raw._crypto_box_ZEROBYTES; exports.crypto_hash_BYTES = nacl_raw._crypto_hash_BYTES; exports.crypto_hash_sha256_BYTES = nacl_raw._crypto_hash_sha256_BYTES; exports.crypto_hashblocks_BLOCKBYTES = nacl_raw._crypto_hashblocks_BLOCKBYTES; exports.crypto_hashblocks_STATEBYTES = nacl_raw._crypto_hashblocks_STATEBYTES; exports.crypto_onetimeauth_BYTES = nacl_raw._crypto_onetimeauth_BYTES; exports.crypto_onetimeauth_KEYBYTES = nacl_raw._crypto_onetimeauth_KEYBYTES; exports.crypto_secretbox_BOXZEROBYTES = nacl_raw._crypto_secretbox_BOXZEROBYTES; exports.crypto_secretbox_KEYBYTES = nacl_raw._crypto_secretbox_KEYBYTES; exports.crypto_secretbox_NONCEBYTES = nacl_raw._crypto_secretbox_NONCEBYTES; exports.crypto_secretbox_ZEROBYTES = nacl_raw._crypto_secretbox_ZEROBYTES; exports.crypto_sign_BYTES = nacl_raw._crypto_sign_BYTES; exports.crypto_sign_PUBLICKEYBYTES = nacl_raw._crypto_sign_PUBLICKEYBYTES; exports.crypto_sign_SECRETKEYBYTES = nacl_raw._crypto_sign_SECRETKEYBYTES; exports.crypto_stream_BEFORENMBYTES = nacl_raw._crypto_stream_BEFORENMBYTES; exports.crypto_stream_KEYBYTES = nacl_raw._crypto_stream_KEYBYTES; exports.crypto_stream_NONCEBYTES = nacl_raw._crypto_stream_NONCEBYTES; exports.encode_utf8 = encode_utf8; exports.encode_latin1 = encode_latin1; exports.decode_utf8 = decode_utf8; exports.decode_latin1 = decode_latin1; exports.to_hex = to_hex; exports.crypto_box_keypair = crypto_box_keypair; exports.crypto_box_random_nonce = crypto_box_random_nonce; exports.crypto_box = crypto_box; exports.crypto_box_open = crypto_box_open; exports.crypto_box_precompute = crypto_box_precompute; exports.crypto_box_precomputed = crypto_box_precomputed; exports.crypto_box_open_precomputed = crypto_box_open_precomputed; exports.crypto_stream_random_nonce = crypto_stream_random_nonce; exports.crypto_stream = crypto_stream; exports.crypto_stream_xor = crypto_stream_xor; exports.crypto_onetimeauth = crypto_onetimeauth; exports.crypto_onetimeauth_verify = crypto_onetimeauth_verify; exports.crypto_auth = crypto_auth; exports.crypto_auth_verify = crypto_auth_verify; exports.crypto_secretbox_random_nonce = crypto_secretbox_random_nonce; exports.crypto_secretbox = crypto_secretbox; exports.crypto_secretbox_open = crypto_secretbox_open; exports.crypto_sign_keypair = crypto_sign_keypair; exports.crypto_sign = crypto_sign; exports.crypto_sign_open = crypto_sign_open; exports.crypto_hash = crypto_hash; exports.crypto_hash_sha256 = crypto_hash_sha256; exports.crypto_hash_string = crypto_hash_string; exports.crypto_sign_keypair_from_seed = crypto_sign_keypair_from_seed; exports.crypto_box_keypair_from_seed = crypto_box_keypair_from_seed; return exports; })();