Skip to content

Instantly share code, notes, and snippets.

@msf
Last active December 16, 2022 19:02
Show Gist options
  • Save msf/5b5f8ea49a18ecfc4917a1aa4081bed3 to your computer and use it in GitHub Desktop.
Save msf/5b5f8ea49a18ecfc4917a1aa4081bed3 to your computer and use it in GitHub Desktop.
add back fromHex()
<!DOCTYPE html>
<html>
<body>
<h2>My Heading</h2>
<p>Play around with the code and click on the "Run" button to view the result.</p>
<p id="demo"></p>
<script>
/* chacha20 - 256 bits */
// Written in 2014 by Devi Mandiri. Public domain.
//
// Implementation derived from chacha-ref.c version 20080118
// See for details: http://cr.yp.to/chacha/chacha-20080128.pdf
function U8TO32_LE(x, i) {
return x[i] | (x[i+1]<<8) | (x[i+2]<<16) | (x[i+3]<<24);
}
function U32TO8_LE(x, i, u) {
x[i] = u; u >>>= 8;
x[i+1] = u; u >>>= 8;
x[i+2] = u; u >>>= 8;
x[i+3] = u;
}
function ROTATE(v, c) {
return (v << c) | (v >>> (32 - c));
}
var Chacha20 = function(key, nonce, counter) {
this.input = new Uint32Array(16);
// https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-01#section-2.3
this.input[0] = 1634760805;
this.input[1] = 857760878;
this.input[2] = 2036477234;
this.input[3] = 1797285236;
this.input[4] = U8TO32_LE(key, 0);
this.input[5] = U8TO32_LE(key, 4);
this.input[6] = U8TO32_LE(key, 8);
this.input[7] = U8TO32_LE(key, 12);
this.input[8] = U8TO32_LE(key, 16);
this.input[9] = U8TO32_LE(key, 20);
this.input[10] = U8TO32_LE(key, 24);
this.input[11] = U8TO32_LE(key, 28);
this.input[12] = counter;
this.input[13] = U8TO32_LE(nonce, 0);
this.input[14] = U8TO32_LE(nonce, 4);
this.input[15] = U8TO32_LE(nonce, 8);
};
Chacha20.prototype.quarterRound = function(x, a, b, c, d) {
x[a] += x[b]; x[d] = ROTATE(x[d] ^ x[a], 16);
x[c] += x[d]; x[b] = ROTATE(x[b] ^ x[c], 12);
x[a] += x[b]; x[d] = ROTATE(x[d] ^ x[a], 8);
x[c] += x[d]; x[b] = ROTATE(x[b] ^ x[c], 7);
};
Chacha20.prototype.encrypt = function(dst, src, len) {
var x = new Uint32Array(16);
var output = new Uint8Array(64);
var i, dpos = 0, spos = 0;
while (len > 0 ) {
for (i = 16; i--;) x[i] = this.input[i];
for (i = 20; i > 0; i -= 2) {
this.quarterRound(x, 0, 4, 8,12);
this.quarterRound(x, 1, 5, 9,13);
this.quarterRound(x, 2, 6,10,14);
this.quarterRound(x, 3, 7,11,15);
this.quarterRound(x, 0, 5,10,15);
this.quarterRound(x, 1, 6,11,12);
this.quarterRound(x, 2, 7, 8,13);
this.quarterRound(x, 3, 4, 9,14);
}
for (i = 16; i--;) x[i] += this.input[i];
for (i = 16; i--;) U32TO8_LE(output, 4*i, x[i]);
this.input[12] += 1;
if (!this.input[12]) {
this.input[13] += 1;
}
if (len <= 64) {
for (i = len; i--;) {
dst[i+dpos] = src[i+spos] ^ output[i];
}
return;
}
for (i = 64; i--;) {
dst[i+dpos] = src[i+spos] ^ output[i];
}
len -= 64;
spos += 64;
dpos += 64;
}
};
Chacha20.prototype.keystream = function(dst, len) {
for (var i = 0; i < len; ++i) dst[i] = 0;
this.encrypt(dst, dst, len);
};
function fromHex(h) {
h = h.replace(/([^0-9a-f])/g, '');
var out = [], len = h.length, w = '';
for (var i = 0; i < len; i += 2) {
w = h[i];
if (((i+1) >= len) || typeof h[i+1] === 'undefined') {
w += '0';
} else {
w += h[i+1];
}
out.push(parseInt(w, 16));
}
return out;
}
const textEncoder = new TextEncode
const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();
let text = "testing encryption!!";
const key =fromHex('1c 92 40 a5 eb 55 d3 f3 33 88 86 04 f6 b5 f0 47 39 17 c1 40 2b 80 09 9d ca 5c bc 20 70 75 c0');
const nonce = fromHex('00 00 00 00 01 02 03 04 05 06 07 08');
function msf_encrypt(key, nonce, text) {
var plaintext = textEncoder.encode(text);
var plen = plaintext.length,
buf = new Uint8Array(plen),
ciphertext = new Uint8Array(plen),
ctx = new Chacha20(key, nonce, 0);
ctx.keystream(buf, plen);
for (var i = 0; i < plen; i++) {
ciphertext[i] = buf[i] ^ plaintext[i];
}
return ciphertext;
}
function msf_decrypt(key, nonce, ciphertext) {
var plen = ciphertext.length,
buf = new Uint8Array(plen),
plaintext = new Uint8Array(plen),
ctx = new Chacha20(key, nonce, 0);
ctx.keystream(buf, plen);
for (var i = 0; i < plen; i++) {
plaintext[i] = buf[i] ^ ciphertext[i];
}
return textDecoder.decode(plaintext);
}
function roundtrip(text) {
var out = msf_encrypt(key, nonce, text);
var cleartext = msf_decrypt(key, nonce, out);
return cleartext;
}
let x = 5;
let y = 6;
let z = roundtrip(text);
let a = roundtrip("o");
document.getElementById("demo").innerHTML = text + " roundtrip: "+ roundtrip(text) + " The value of z is: " +a;
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment