diff --git a/contrib/js/contrib/chacha20.js b/contrib/js/nntpchan/chacha20.js similarity index 90% rename from contrib/js/contrib/chacha20.js rename to contrib/js/nntpchan/chacha20.js index e9247bd..8f3c382 100644 --- a/contrib/js/contrib/chacha20.js +++ b/contrib/js/nntpchan/chacha20.js @@ -6,6 +6,7 @@ // See for details: http://cr.yp.to/chacha/chacha-20080128.pdf function U8TO32_LE(x, i) { + if(x === undefined) return; return x[i] | (x[i+1]<<8) | (x[i+2]<<16) | (x[i+3]<<24); } @@ -20,7 +21,7 @@ function ROTATE(v, c) { return (v << c) | (v >>> (32 - c)); } -var Chacha20 = function(key, nonce, counter) { +function Chacha20(key, nonce, counter) { this.input = new Uint32Array(16); // https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-01#section-2.3 @@ -103,14 +104,17 @@ Chacha20.prototype.keystream = function(dst, len) { this.encrypt(dst, dst, len); }; -// additions to make it easier and export it as a module +var Cipher = Chacha20; -exports.Cipher = Chacha20; +var chacha_encrypt; +var chacha_decrypt; -exports.encrypt = exports.decrypt = function(key, nonce, data) +chacha_decrypt = function(key, nonce, data) { - var cipher = new Chacha20(key, nonce); - var ret = new Buffer(data.length); + var cipher = new Chacha20(key, nonce, 0); + var ret = new Uint8Array(data.length); cipher.encrypt(ret, data, data.length); return ret; -} \ No newline at end of file +}; + +chacha_encrypt = chacha_decrypt; diff --git a/contrib/js/nntpchan/crypto.js b/contrib/js/nntpchan/crypto.js new file mode 100644 index 0000000..b5158e6 --- /dev/null +++ b/contrib/js/nntpchan/crypto.js @@ -0,0 +1,68 @@ + +var nntpchan_ToBase64 = function (u8) { + return btoa(String.fromCharCode.apply(null, u8)); +}; + +var nntpchan_FromBase64 = function (str) { + return atob(str).split('').map(function (c) { return c.charCodeAt(0); }); +}; + + +function nntpchan_keygen() { + var crypto = window.crypto || window.msCrypto; + if(!crypto) { + throw "no crypto"; + } + var key = new Uint8Array(32); + crypto.getRandomValues(key); + var nonce = new Uint8Array(12); + crypto.getRandomValues(nonce); + return nntpchan_ToBase64(key) + ":" + nntpchan_ToBase64(nonce); +} + +function nntpchan_chacha_nonce(blob) { + var parts = blob.split(":"); + return nntpchan_FromBase64(parts[1]); +} + +function nntpchan_chacha_key(blob) { + var parts = blob.split(":"); + return nntpchan_FromBase64(parts[0]); +} + +// encrypt text from an element using symettric key and nonce +// output to element.innerHTML as base64 +function nntpchan_encrypt_element(inelem, outelem, key, nonce) { + var plaintext = inelem.innerHTML; + console.log(plaintext); + var ciphertext = chacha_encrypt(key, nonce, plaintext); + outelem.innerHTML = nntpchan_ToBase64(ciphertext); +} + +// encrypt text from an element using symettric key and nonce +// output to element.innerHTML as base64 +function nntpchan_decrypt_element(inelem, outelem, key, nonce) { + var ciphertext = nntpchan_FromBase64(inelem.innerHTML); + console.log(ciphertext); + var plaintext = chacha_decrypt(key, nonce, ciphertext); + console.log(plaintext); + while(outelem.children.length > 0) { + outelem.children[0].remove(); + } + outelem.appendChild(document.createTextNode(plaintext)); +} + + + +function nntpchan_crypto_test() { + console.log("begin crypto test"); + var genelem = $("#test_keygen"); + genelem[0].innerHTML = nntpchan_keygen(); + var inelem = $("#encrypt_in")[0]; + var outelem = $("#encrypt_out")[0]; + var decryptelem = $("#decrypt_out")[0]; + var key = nntpchan_chacha_key(genelem[0].innerHTML); + var nonce = nntpchan_chacha_nonce(genelem[0].innerHTML); + nntpchan_encrypt_element(inelem, outelem, key, nonce); + nntpchan_decrypt_element(outelem, decryptelem, key, nonce); +} diff --git a/contrib/static/test.html b/contrib/static/test.html new file mode 100644 index 0000000..8a1c0e4 --- /dev/null +++ b/contrib/static/test.html @@ -0,0 +1,22 @@ + +
+