initial chacha20 code;
This commit is contained in:
parent
21008c857a
commit
94632b37c9
@ -6,6 +6,7 @@
|
|||||||
// See for details: http://cr.yp.to/chacha/chacha-20080128.pdf
|
// See for details: http://cr.yp.to/chacha/chacha-20080128.pdf
|
||||||
|
|
||||||
function U8TO32_LE(x, i) {
|
function U8TO32_LE(x, i) {
|
||||||
|
if(x === undefined) return;
|
||||||
return x[i] | (x[i+1]<<8) | (x[i+2]<<16) | (x[i+3]<<24);
|
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));
|
return (v << c) | (v >>> (32 - c));
|
||||||
}
|
}
|
||||||
|
|
||||||
var Chacha20 = function(key, nonce, counter) {
|
function Chacha20(key, nonce, counter) {
|
||||||
this.input = new Uint32Array(16);
|
this.input = new Uint32Array(16);
|
||||||
|
|
||||||
// https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-01#section-2.3
|
// 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);
|
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 cipher = new Chacha20(key, nonce, 0);
|
||||||
var ret = new Buffer(data.length);
|
var ret = new Uint8Array(data.length);
|
||||||
cipher.encrypt(ret, data, data.length);
|
cipher.encrypt(ret, data, data.length);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
chacha_encrypt = chacha_decrypt;
|
68
contrib/js/nntpchan/crypto.js
Normal file
68
contrib/js/nntpchan/crypto.js
Normal file
@ -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);
|
||||||
|
}
|
22
contrib/static/test.html
Normal file
22
contrib/static/test.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title> crypto test page </title>
|
||||||
|
<script src="nntpchan.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="test_keygen">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div id="encrypt_in">
|
||||||
|
test encrypt
|
||||||
|
</div>
|
||||||
|
<div id="encrypt_out">
|
||||||
|
</div>
|
||||||
|
<div id="decrypt_out">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
nntpchan_crypto_test();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Reference in New Issue
Block a user