diff --git a/src/js/crypto/nacl-crypto.js b/src/js/crypto/nacl-crypto.js index 27f0610..8b0f6f1 100644 --- a/src/js/crypto/nacl-crypto.js +++ b/src/js/crypto/nacl-crypto.js @@ -42,9 +42,85 @@ var NaclCrypto = function(nacl, util) { * @param nonce [String] The base64 encoded nonce * @param recipientPk [String] The receiver's base64 encoded public key * @param senderSk [String] The sender's base64 encoded private key - * @return [Object] The base64 encoded ciphertext and nonce + * @return [String] The base64 encoded ciphertext */ - this.asymEncrypt = function(plaintext, nonce, recipientPk, senderSk) { + this.asymEncrypt = function(plaintext, nonce, recipientPk, senderSk, callback) { + // convert to Uint8Array + var ptBuf = nacl.encode_utf8(plaintext); + var recipientPkBuf = nacl.encode_latin1(util.base642Str(recipientPk)); + var senderSkBuf = nacl.encode_latin1(util.base642Str(senderSk)); + var nonceBuf = nacl.encode_latin1(util.base642Str(nonce)); + + if (Worker) { + + var worker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js'); + worker.onmessage = function(e) { + // encode to base64 + callback(util.str2Base64(nacl.decode_latin1(e.data))); + }; + worker.postMessage({ + type: 'encrypt', + plaintext: ptBuf, + nonce: nonceBuf, + recipientPk: recipientPkBuf, + senderSk: senderSkBuf + }); + + } else { + // encrypt + var ct = nacl.crypto_box(ptBuf, nonceBuf, recipientPkBuf, senderSkBuf); + // encode to base64 + callback(util.str2Base64(nacl.decode_latin1(ct))); + } + }; + + /** + * Asymmetrically decrypt a String + * @param ciphertext [String] The base64 encoded ciphertext + * @param nonce [String] The base64 encoded nonce + * @param senderPk [String] The sender's base64 encoded public key + * @param recipientSk [String] The receiver's base64 encoded private key + * @return [String] The decrypted plaintext in UTF8 + */ + this.asymDecrypt = function(ciphertext, nonce, senderPk, recipientSk, callback) { + // convert to Uint8Array + var ctBuf = nacl.encode_latin1(util.base642Str(ciphertext)); + var nonceBuf = nacl.encode_latin1(util.base642Str(nonce)); + var senderPkBuf = nacl.encode_latin1(util.base642Str(senderPk)); + var recipientSkBuf = nacl.encode_latin1(util.base642Str(recipientSk)); + + if (Worker) { + + var worker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js'); + worker.onmessage = function(e) { + // decode to string + callback(nacl.decode_utf8(e.data)); + }; + worker.postMessage({ + type: 'decrypt', + ciphertext: ctBuf, + nonce: nonceBuf, + senderPk: senderPkBuf, + recipienSk: recipientSkBuf + }); + + } else { + // decrypt + var pt = nacl.crypto_box_open(ctBuf, nonceBuf, senderPkBuf, recipientSkBuf); + // decode to string + callback(nacl.decode_utf8(pt)); + } + }; + + /** + * Asymmetrically encrypt a String + * @param plaintext [String] The input string in UTF8 + * @param nonce [String] The base64 encoded nonce + * @param recipientPk [String] The receiver's base64 encoded public key + * @param senderSk [String] The sender's base64 encoded private key + * @return [String] The base64 encoded ciphertext + */ + this.asymEncryptSync = function(plaintext, nonce, recipientPk, senderSk) { // convert to Uint8Array var ptBuf = nacl.encode_utf8(plaintext); var recipientPkBuf = nacl.encode_latin1(util.base642Str(recipientPk)); @@ -66,7 +142,7 @@ var NaclCrypto = function(nacl, util) { * @param recipientSk [String] The receiver's base64 encoded private key * @return [String] The decrypted plaintext in UTF8 */ - this.asymDecrypt = function(ciphertext, nonce, senderPk, recipientSk) { + this.asymDecryptSync = function(ciphertext, nonce, senderPk, recipientSk) { // convert to Uint8Array var ctBuf = nacl.encode_latin1(util.base642Str(ciphertext)); var nonceBuf = nacl.encode_latin1(util.base642Str(nonce)); @@ -80,46 +156,6 @@ var NaclCrypto = function(nacl, util) { return ptStr; }; - /** - * Symmetrically encrypt a String - * @param plaintext [String] The input string in UTF8 - * @param nonce [String] The base64 encoded nonce - * @param secretKey [String] The receiver's base64 encoded public key - * @return [Object] The base64 encoded ciphertext and nonce - */ - this.symEncrypt = function(plaintext, nonce, secretKey) { - // convert to Uint8Array - var ptBuf = nacl.encode_utf8(plaintext); - var secretKeyBuf = nacl.encode_latin1(util.base642Str(secretKey)); - var nonceBuf = nacl.encode_latin1(util.base642Str(nonce)); - // encrypt - var ct = nacl.crypto_secretbox(ptBuf, nonceBuf, secretKeyBuf); - // encode to base64 - var ctBase64 = util.str2Base64(nacl.decode_latin1(ct)); - - return ctBase64; - }; - - /** - * Symmetrically decrypt a String - * @param ciphertext [String] The base64 encoded ciphertext - * @param nonce [String] The base64 encoded nonce - * @param secretKey [String] The sender's base64 encoded public key - * @return [String] The decrypted plaintext in UTF8 - */ - this.symDecrypt = function(ciphertext, nonce, secretKey) { - // convert to Uint8Array - var ctBuf = nacl.encode_latin1(util.base642Str(ciphertext)); - var nonceBuf = nacl.encode_latin1(util.base642Str(nonce)); - var secretKeyBuf = nacl.encode_latin1(util.base642Str(secretKey)); - // decrypt - var pt = nacl.crypto_secretbox_open(ctBuf, nonceBuf, secretKeyBuf); - // decode to string - var ptStr = nacl.decode_utf8(pt); - - return ptStr; - }; - }; if (typeof module !== 'undefined' && module.exports) { diff --git a/test/unit/nacl-crypto-test.js b/test/unit/nacl-crypto-test.js index 01b8426..d2d7aa5 100644 --- a/test/unit/nacl-crypto-test.js +++ b/test/unit/nacl-crypto-test.js @@ -32,77 +32,34 @@ test("Generate Keypair", 2, function() { nacl_test.recipientKeypair = recipientKeypair; }); -test("Asymmetric En/Decrypt", 3, function() { +test("Asymmetric En/Decrypt (Synchronous)", 3, function() { var plaintext = nacl_test.test_message; var nonce = nacl_test.crypto.generateNonce(); ok(nonce, 'Nonce: ' + nonce); // encrypt - var ct = nacl_test.crypto.asymEncrypt(plaintext, nonce, nacl_test.recipientKeypair.boxPk, nacl_test.senderKeypair.boxSk); + var ct = nacl_test.crypto.asymEncryptSync(plaintext, nonce, nacl_test.recipientKeypair.boxPk, nacl_test.senderKeypair.boxSk); ok(ct, 'Ciphertext length: ' + ct.length); // decrypt - var decrypted = nacl_test.crypto.asymDecrypt(ct, nonce, nacl_test.senderKeypair.boxPk, nacl_test.recipientKeypair.boxSk); + var decrypted = nacl_test.crypto.asymDecryptSync(ct, nonce, nacl_test.senderKeypair.boxPk, nacl_test.recipientKeypair.boxSk); equal(decrypted, plaintext, 'Decryption correct: ' + decrypted); }); -test("Symmetric En/Decrypt", 3, function() { +asyncTest("Asymmetric En/Decrypt (Async/Worker)", 3, function() { var plaintext = nacl_test.test_message; var nonce = nacl_test.crypto.generateNonce(); ok(nonce, 'Nonce: ' + nonce); // encrypt - var ct = nacl_test.crypto.symEncrypt(plaintext, nonce, nacl_test.senderKeypair.boxSk); - ok(ct, 'Ciphertext length: ' + ct.length); + nacl_test.crypto.asymEncrypt(plaintext, nonce, nacl_test.recipientKeypair.boxPk, nacl_test.senderKeypair.boxSk, function(ct) { + ok(ct, 'Ciphertext length: ' + ct.length); - // decrypt - var decrypted = nacl_test.crypto.symDecrypt(ct, nonce, nacl_test.senderKeypair.boxSk); - equal(decrypted, plaintext, 'Decryption correct: ' + decrypted); -}); + // decrypt + nacl_test.crypto.asymDecrypt(ct, nonce, nacl_test.senderKeypair.boxPk, nacl_test.recipientKeypair.boxSk, function(decrypted) { + equal(decrypted, plaintext, 'Decryption correct: ' + decrypted); -asyncTest("Asymmetric En/Decrypt (WebWorker)", 3, function() { - var plaintext = nacl.encode_utf8(nacl_test.test_message), - nonce = nacl.crypto_secretbox_random_nonce(), - utl = nacl_test.util, - recipientPk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.recipientKeypair.boxPk)), - senderSk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.senderKeypair.boxSk)), - recipienSk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.recipientKeypair.boxSk)), - senderPk = utl.binStr2Uint8Arr(utl.base642Str(nacl_test.senderKeypair.boxPk)); - - // encrypt - - function encrypt(pt) { - var encryptWorker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js'); - encryptWorker.onmessage = function(e) { - ok(e.data, 'Encryption'); - decrypt(e.data); - }; - encryptWorker.postMessage({ - type: 'encrypt', - plaintext: pt, - nonce: nonce, - recipientPk: recipientPk, - senderSk: senderSk - }); - } - - // decrypt - - function decrypt(ct) { - var decryptWorker = new Worker(app.config.workerPath + '/crypto/nacl-worker.js'); - decryptWorker.onmessage = function(e) { - ok(e.data, 'Decryption'); - deepEqual(e.data, plaintext, 'Decrypted = Plaintext'); start(); - }; - decryptWorker.postMessage({ - type: 'decrypt', - ciphertext: ct, - nonce: nonce, - senderPk: senderPk, - recipienSk: recipienSk }); - } - - encrypt(plaintext); + }); }); \ No newline at end of file