first commit

This commit is contained in:
didier amyot committed 2016-03-25 17:54:34 -04:00
commit 5a8274a7ef
10 files changed
+651

No files matched your search

+274
View File
@@ -0,0 +1,274 @@
;(function() {
var util = {};
util.low = function(byte) {
return byte & 0xf;
};
util.high = function(byte) {
return byte >>> 4 & 0xf;
};
util.madd = function(a, b) { // TODO: rename to madd256
return (a + b) % N;
// return (a + b) & 0xff; // when N = 256, 0xff = N - 1
};
util.msub = function(a, b) {// TODO: rename to msub256
return util.madd(N, a - b);
};
util.swap = function(lst, p1, p2) {
var tmp = lst[p1];
lst[p1] = lst[p2];
lst[p2] = tmp;
};
util.gcd = function(a, b){
var t;
while (b !== 0) {
t = b;
b = a % b;
a = t;
}
return a;
};
var N = 256;
var N_OVER_TWO_FLOOR = Math.floor(N / 2);
var TWO_N = 2 * N;
var spritz = {};
spritz._util = util;
spritz._initializeState = function _initializeState() {
var state = {};
state.i = 0;
state.j = 0;
state.k = 0;
state.z = 0;
state.a = 0;
state.w = 1;
state.S = [];
for (var i = 0; i < N; i++) {
state.S[i] = i;
}
return state;
};
spritz._absorb = function _absorb(I, state){
var v;
/*
basic validation of I
consider bounds-checking and deep-checking of each N-value such that they are in the valid range (0 <= x < N)
*/
if(!(Array.isArray(I) && I.length > 0)){
return false;
}
for(v = 0; v < I.length; v++){
spritz._absorbByte(I[v], state);
}
return true;
};
spritz._absorbByte = function _absorbByte(b, state) {
spritz._absorbNibble(util.low(b), state);
spritz._absorbNibble(util.high(b), state);
};
spritz._absorbNibble = function _absorbNibble(x, state) {
if (state.a === N_OVER_TWO_FLOOR){
spritz.shuffle(state);
}
util.swap(state.S, state.a, util.madd(N_OVER_TWO_FLOOR, x));
state.a = util.madd(state.a, 1);
};
spritz._absorbStop = function _absorbStop(state){
if(state.a === N_OVER_TWO_FLOOR){
spritz._shuffle(state);
}
state.a = util.madd(state.a, 1);
};
spritz._shuffle = function _shuffle(state){
spritz._whip(TWO_N, state);
spritz._crush(state);
spritz._whip(TWO_N, state);
spritz._crush(state);
spritz._whip(TWO_N, state);
state.a = 0;
};
spritz._whip = function _whip(r, state) {
for (var i = 0; i < r; i++) {
spritz._update(state);
}
do {
state.w = util.madd(state.w, 1);
} while (util.gcd(state.w, N) !== 1);
// NB. a simple-case assumption is that if N is a power of 2 then one could instead use:
// w = madd(w, 2);
};
spritz._crush = function _crush(state) {
var index;
for (var i = 0; i < N_OVER_TWO_FLOOR; i++) {
index = N - i - 1;
if (state.S[i] > state.S[index]) {
util.swap(state.S, i, index);
}
}
};
spritz._update = function _update(state) { //done
state.i = util.madd(state.i, state.w);
state.j = util.madd(state.k, state.S[util.madd(state.j, state.S[state.i])]);
state.k = util.madd(state.i + state.k, state.S[state.j]);
util.swap(state.S, state.i, state.j);
};
spritz._squeeze = function _squeeze(r, state) {
if (state.a > 0) {
spritz._shuffle(state);
}
var P = [];
for (var i = 0; i < r; i++) {
P[i] = spritz._drip(state);
}
return P;
};
spritz._drip = function _drip(state){
if (state.a > 0) {
spritz._shuffle(state);
}
spritz._update(state);
return spritz._output(state);
};
spritz._output = function _output(state) {
var idx = util.madd(state.z, state.k);
idx = util.madd(state.i, state.S[idx]);
idx = util.madd(state.j, state.S[idx]);
state.z = state.S[idx];
return state.z;
};
spritz._keySetup = function _keySetup(K) {
var state = spritz._initializeState();
spritz._absorb(K, state);
return state;
};
spritz.stringToUtf8ByteArray = function stringToUtf8ByteArray(utf8Array){
var utf8 = unescape(encodeURIComponent(utf8Array));
var arr = [];
for (var i = 0; i < utf8.length; i++) {
arr.push(utf8.charCodeAt(i));
}
return arr;
};
spritz.utf8ByteArrayToString = function utf8ByteArrayToString(utf8Array){
var ret = "";
for(var i = 0; i < utf8Array.length; i++){
ret += String.fromCharCode(utf8Array[i]);
}
return decodeURIComponent(escape(ret));
};
spritz.hash = function hash(M, r){
if(typeof M == 'string'){
return spritz.hash(spritz.stringToUtf8ByteArray(M), r);
}
var state = spritz._initializeState();
spritz._absorb(M, state);
spritz._absorbStop(state);
spritz._absorb([r & 0xff], state); // NB. restricted(!) to 255-byte hashes
return spritz._squeeze(r, state);
};
spritz.encrypt = function encrypt(K, M) {
var C = [], stream , i;
var state = spritz._keySetup(K);
stream = spritz._squeeze(M.length, state);
for (i = 0; i < M.length; i++) {
C[i] = util.madd(M[i], stream[i]);
}
return C;
};
spritz.decrypt = function decrypt(K, C) {
var M = [] , stream , i;
var state = spritz._keySetup(K);
stream = spritz._squeeze(C.length, state);
for (i = 0; i < C.length; i++) {
M[i] = util.msub(C[i], stream[i]);
}
return M;
};
// Export spritz as lodash 4.5.0.
var objectTypes = {
'function': true,
'object': true
};
function checkGlobal(value) {
return (value && value.Object === Object) ? value : null;
}
var freeWindow = checkGlobal(objectTypes[typeof window] && window);
var freeSelf = checkGlobal(objectTypes[typeof self] && self);
var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
var freeModule = (objectTypes[typeof module] && module && !module.nodeType) ? module : undefined;
var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType) ? exports : undefined;
var moduleExports = (freeModule && freeModule.exports === freeExports) ? freeExports: undefined;
var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
var root = freeGlobal || ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) || freeSelf || thisGlobal || Function('return this')();
// Expose lodash on the free variable `window` or `self` when available. This
// prevents errors in cases where lodash is loaded by a script tag in the presence
// of an AMD loader. See http://requirejs.org/docs/errors.html#mismatch for more details.
(freeWindow || freeSelf || {}).spritz = spritz;
// Some AMD build optimizers like r.js check for condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// Define as an anonymous module so, through path mapping, it can be
// referenced as the "underscore" module.
define(function() {
return spritz;
});
}
// Check for `exports` after `define` in case a build optimizer adds an `exports` object.
else if (freeExports && freeModule) {
// Export for Node.js.
if (moduleExports) {
freeModule.exports = spritz;
}
// Export for CommonJS support.
freeExports.spritz = spritz;
}
else {
// Export to the global object.
root.spritz = spritz;
}
}.call(this)); // close the prefix