Skip to content

Instantly share code, notes, and snippets.

@marcoonroad
Forked from rndme/hashcrypt.js
Created November 1, 2018 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcoonroad/5499c4981378274314c0c023753f75bf to your computer and use it in GitHub Desktop.
Save marcoonroad/5499c4981378274314c0c023753f75bf to your computer and use it in GitHub Desktop.
Symmetric encryption using hash function and key derivation
function hashCrypt(key, plain, hasher, workFactor=1) { // hasher is any sync string-output hash function
var len=plain.length, keyLen = key.length, keyOrig = key,
// calculate derivation count based on deterministic factors from the inputs:
mx = hasher(key).split("").map((a, b)=> a.charCodeAt(0) + b).reduce((a, b)=> a + b, 0) * workFactor;
// derive firstly for some hardness using cpu and ram hungry calculations:
for(let i = 0; i < mx; i++) key = hasher(key.repeat( ((i+len) % ((workFactor || 1) * 4))+1 ));
// expand key to needed length by appending re-hashing (with counters):
for(let i = 0, mx = (len / 32) - 1; i < mx; i++) key += hasher( key + i + keyLen + keyOrig );
// turn key into array of numbers to perform the XOR in the next step:
key = key.match(/\w{2}/g).map(a=>parseInt(a, 16));
// encrypt the message using derived key of the same length:
return plain.split("").map((c, i)=> String.fromCharCode(c.charCodeAt(0) ^ key[i])).join("");
} // end encrypt()
////////////////////////////
// simple demo using sha3 implementation from https://github.com/emn178/js-sha3
var txt = "Hello World!"; // the plain text message to encrypt
var key = "123456789"; // not really a good key, but works for the demo...
var hash = sha3_512; // customize as needed with any good hash function
var enc = hashCrypt(key, txt, hash, 2); // encrypt txt with key using sha3-512 and a work factor of 2
var dec = hashCrypt(key, enc, hash, 2); // decrypt enc with key using sha3-512 and a work factor of 2
// alert(hashCrypt(key, enc, hash, 2) === txt ); // quick proof of success
prompt(dec, enc); // show decoded and encoded versions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment