Skip to content

Instantly share code, notes, and snippets.

@timargra
Forked from bminer/variableHash.js
Last active March 20, 2023 13:47
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timargra/016f247dd83dbc97ea1d8f71dea38c3f to your computer and use it in GitHub Desktop.
Save timargra/016f247dd83dbc97ea1d8f71dea38c3f to your computer and use it in GitHub Desktop.
Generate a variable-length hash of `data` in Node.js
var crypto = require("crypto");
/* variableHash - Generate a variable-length hash of `data`.
Adapted node version 8.x
------------------------
Similar to the answer here: http://crypto.stackexchange.com/a/3559/4829
If you want a b-bit hash of the message m, then use the first b bits of AES-CTR(SHA256(m)).
Rather than using the suggested algorithm in the stackexchange answer above, I developed
my own.
I decided to derive AES256 initialization vector and key from the output of SHA256(data).
Then, the cipher is fed a zero-filled buffer as plaintext, which is encrypted using this key.
The result should be a pseudorandom number generator seeded with a 256-bit hash of `data`.
In other words, compute SHA256(m) and treat the resulting 256-bit string as a 256-bit AES key.
Next, use AES in counter mode (with this key) to generate an unending stream of pseudorandom bits.
Take the first b bits from this stream, and call it your hash.
*/
const IV = new Buffer('068f7bb47896981d6c8b3f9a186591ae', 'hex');
export function variableHash(data, size = 5, encoding = 'hex') {
// Create zero-filled output buffer with specified byte size
let output = Buffer.alloc(size);
// Generate 256-bit hash of data
let hash = crypto.createHash('sha256');
hash.update(data);
// Encrypt buffer using the SHA-256 hash as the AES-256 key
let cipher = crypto.createCipheriv('aes256', hash.digest(), IV);
let offset = output.write(cipher.update(output).toString('binary'));
output.write(cipher.final().toString('binary'), offset);
return output.toString(encoding);
}
@timargra
Copy link
Author

timargra commented Feb 26, 2018

I adapted the algorithm to work with node version 8.x.

Due to several breaking changes since the original code has been published, some non-trivial adaptions were necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment