Sleds/K2Proxy/hash.js

137 lines
3.4 KiB
JavaScript

/*
Modifications copyright (c) 2014 IOnU Security Inc. All rights reserved
Added to IonU source repository in April 2014 by Kendrick Webster,
based on public-domain code by Kendrick Webster.
-----------------------------------------------------------------------------
Simple chaos-based hash/PRNG and stream cypher 1991 - 2014
Written by Ken Webster <ken@kenwebster.org>
[ other contributers can add their names here ]
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
See the CC0 Public Domain Dedication for details:
<http://creativecommons.org/publicdomain/zero/1.0/>
-----------------------------------------------------------------------------
This is a small-footprint hasher and PRNG that incrementally hashes input
bytes into an evolving chaotic state pool from which pseudo random output
bytes are extracted. The output passes all dieharder tests.
---------------------------------------------------------------------------*/
"use strict";
/* how often to seed the RNG entroy pool with a high-res timer sample */
var RNG_SEED_INTERVAL_MS = 50;
function ror16(w) {
return (w >>> 1) | ((w & 1) ? 0x8000 : 0);
}
function rol32(w) {
return (w << 1) | ((w & 0x80000000) ? 1 : 0);
}
var HASH_WORDS = 64;
function Hash() {
var j;
this.a = new Array(HASH_WORDS);
this.b = 0;
this.i = 0;
for (j = 0; j < HASH_WORDS; j++) {
this.a[j] = 0;
}
}
var rng_hash = new Hash();
function hashbyte(h, byte) {
var w;
h.b += byte;
w = h.a[h.i];
w ^= h.b & 0xFFFF;
w = ror16(w);
w = (w + 0x5ca3) & 0xFFFF;
h.a[h.i] = w;
h.b += w;
h.b = rol32(h.b);
h.i = (h.i + 1) % HASH_WORDS;
return w & 0xFF;
}
function hashbuf(h, buf, len) {
var i;
len = len || buf.length;
for (i = 0; i < len; i++) {
hashbyte(h, buf[i]);
}
}
function hashstr(h, str) {
var i;
for (i = 0; i < str.length; i++) {
hashbyte(h, str.charCodeAt(i));
}
}
function mix(h, n) {
while (n--) {
hashbyte(h, 0);
}
}
function getbuf(h, buf, len) {
var i;
len = len || buf.length;
for (i = 0; i < len; i++) {
buf[i] = hashbyte(h, 0);
}
}
function encrypt(h, buf) {
var c, d, i;
d = hashbyte(h, 0);
for (i = 0; i < buf.length; i++) {
c = hashbyte(h, buf[i]);
buf[i] ^= d;
d = c;
}
}
function decrypt(h, buf) {
var d, i;
d = hashbyte(h, 0);
for (i = 0; i < buf.length; i++) {
buf[i] ^= d;
d = hashbyte(h, buf[i]);
}
}
function get_random_uint32() {
var r = hashbyte(rng_hash, 0);
r <<= 8;
r |= hashbyte(rng_hash, 0);
r <<= 8;
r |= hashbyte(rng_hash, 0);
r <<= 8;
r |= hashbyte(rng_hash, 0);
return r >>> 0;
}
setInterval(function () {
var t = process.hrtime(); /* t[0] is seconds, t[1] is nanoseconds */
hashbyte(rng_hash, t[1] & 0xFF);
hashbyte(rng_hash, (t[1] >>> 8) & 0xFF);
hashbyte(rng_hash, (t[1] >>> 16) & 0xFF);
}, RNG_SEED_INTERVAL_MS);
exports.Hash = Hash;
exports.rng_hash = rng_hash;
exports.hashbyte = hashbyte;
exports.hashbuf = hashbuf;
exports.hashstr = hashstr;
exports.mix = mix;
exports.getbuf = getbuf;
exports.encrypt = encrypt;
exports.decrypt = decrypt;
exports.get_random_uint32 = get_random_uint32;