triplesec
Version:
A CommonJS-compliant system for secure encryption of smallish secrets
274 lines (244 loc) • 9.22 kB
JavaScript
// Generated by IcedCoffeeScript 108.0.8
(function() {
var Global, Hasher, KECCAK, WordArray, X64Word, X64WordArray, glbl, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
_ref = require('./wordarray'), WordArray = _ref.WordArray, X64Word = _ref.X64Word, X64WordArray = _ref.X64WordArray;
Hasher = require('./algbase').Hasher;
Global = (function() {
function Global() {
this.RHO_OFFSETS = [];
this.PI_INDEXES = [];
this.ROUND_CONSTANTS = [];
this.T = [];
this.compute_rho_offsets();
this.compute_pi_indexes();
this.compute_round_constants();
this.make_reusables();
}
Global.prototype.compute_rho_offsets = function() {
var newX, newY, t, x, y, _i, _results;
x = 1;
y = 0;
_results = [];
for (t = _i = 0; _i < 24; t = ++_i) {
this.RHO_OFFSETS[x + 5 * y] = ((t + 1) * (t + 2) / 2) % 64;
newX = y % 5;
newY = (2 * x + 3 * y) % 5;
x = newX;
_results.push(y = newY);
}
return _results;
};
Global.prototype.compute_pi_indexes = function() {
var x, y, _i, _results;
_results = [];
for (x = _i = 0; _i < 5; x = ++_i) {
_results.push((function() {
var _j, _results1;
_results1 = [];
for (y = _j = 0; _j < 5; y = ++_j) {
_results1.push(this.PI_INDEXES[x + 5 * y] = y + ((2 * x + 3 * y) % 5) * 5);
}
return _results1;
}).call(this));
}
return _results;
};
Global.prototype.compute_round_constants = function() {
var LFSR, bitPosition, i, j, roundConstantLsw, roundConstantMsw, _i, _j, _results;
LFSR = 0x01;
_results = [];
for (i = _i = 0; _i < 24; i = ++_i) {
roundConstantMsw = 0;
roundConstantLsw = 0;
for (j = _j = 0; _j < 7; j = ++_j) {
if (LFSR & 0x01) {
bitPosition = (1 << j) - 1;
if (bitPosition < 32) {
roundConstantLsw ^= 1 << bitPosition;
} else {
roundConstantMsw ^= 1 << (bitPosition - 32);
}
}
if (LFSR & 0x80) {
LFSR = (LFSR << 1) ^ 0x71;
} else {
LFSR <<= 1;
}
}
_results.push(this.ROUND_CONSTANTS[i] = new X64Word(roundConstantMsw, roundConstantLsw));
}
return _results;
};
Global.prototype.make_reusables = function() {
var i;
return this.T = (function() {
var _i, _results;
_results = [];
for (i = _i = 0; _i < 25; i = ++_i) {
_results.push(new X64Word(0, 0));
}
return _results;
})();
};
return Global;
})();
glbl = new Global();
exports.KECCAK = KECCAK = (function(_super) {
__extends(KECCAK, _super);
function KECCAK() {
return KECCAK.__super__.constructor.apply(this, arguments);
}
KECCAK.outputLength = 512;
KECCAK.prototype.outputLength = KECCAK.outputLength;
KECCAK.blockSize = (1600 - 2 * KECCAK.outputLength) / 32;
KECCAK.prototype.blockSize = KECCAK.blockSize;
KECCAK.output_size = KECCAK.outputLength / 8;
KECCAK.prototype.output_size = KECCAK.output_size;
KECCAK.prototype.pad = 0x01;
KECCAK.prototype._doReset = function() {
var i;
return this._state = (function() {
var _i, _results;
_results = [];
for (i = _i = 0; _i < 25; i = ++_i) {
_results.push(new X64Word(0, 0));
}
return _results;
})();
};
KECCAK.prototype._doProcessBlock = function(M, offset) {
var G, M2i, M2i1, T0, TLane, TPiLane, Tx, Tx1, Tx1Lane, Tx1Lsw, Tx1Msw, Tx2Lane, Tx4, i, lane, laneIndex, laneLsw, laneMsw, nBlockSizeLanes, rhoOffset, round, roundConstant, state, state0, tLsw, tMsw, x, y, _i, _j, _k, _l, _m, _n, _o, _p, _q, _results;
G = glbl;
state = this._state;
nBlockSizeLanes = this.blockSize / 2;
for (i = _i = 0; 0 <= nBlockSizeLanes ? _i < nBlockSizeLanes : _i > nBlockSizeLanes; i = 0 <= nBlockSizeLanes ? ++_i : --_i) {
M2i = M[offset + 2 * i];
M2i1 = M[offset + 2 * i + 1];
M2i = (((M2i << 8) | (M2i >>> 24)) & 0x00ff00ff) | (((M2i << 24) | (M2i >>> 8)) & 0xff00ff00);
M2i1 = (((M2i1 << 8) | (M2i1 >>> 24)) & 0x00ff00ff) | (((M2i1 << 24) | (M2i1 >>> 8)) & 0xff00ff00);
lane = state[i];
lane.high ^= M2i1;
lane.low ^= M2i;
}
_results = [];
for (round = _j = 0; _j < 24; round = ++_j) {
for (x = _k = 0; _k < 5; x = ++_k) {
tMsw = tLsw = 0;
for (y = _l = 0; _l < 5; y = ++_l) {
lane = state[x + 5 * y];
tMsw ^= lane.high;
tLsw ^= lane.low;
}
Tx = G.T[x];
Tx.high = tMsw;
Tx.low = tLsw;
}
for (x = _m = 0; _m < 5; x = ++_m) {
Tx4 = G.T[(x + 4) % 5];
Tx1 = G.T[(x + 1) % 5];
Tx1Msw = Tx1.high;
Tx1Lsw = Tx1.low;
tMsw = Tx4.high ^ ((Tx1Msw << 1) | (Tx1Lsw >>> 31));
tLsw = Tx4.low ^ ((Tx1Lsw << 1) | (Tx1Msw >>> 31));
for (y = _n = 0; _n < 5; y = ++_n) {
lane = state[x + 5 * y];
lane.high ^= tMsw;
lane.low ^= tLsw;
}
}
for (laneIndex = _o = 1; _o < 25; laneIndex = ++_o) {
lane = state[laneIndex];
laneMsw = lane.high;
laneLsw = lane.low;
rhoOffset = G.RHO_OFFSETS[laneIndex];
if (rhoOffset < 32) {
tMsw = (laneMsw << rhoOffset) | (laneLsw >>> (32 - rhoOffset));
tLsw = (laneLsw << rhoOffset) | (laneMsw >>> (32 - rhoOffset));
} else {
tMsw = (laneLsw << (rhoOffset - 32)) | (laneMsw >>> (64 - rhoOffset));
tLsw = (laneMsw << (rhoOffset - 32)) | (laneLsw >>> (64 - rhoOffset));
}
TPiLane = G.T[G.PI_INDEXES[laneIndex]];
TPiLane.high = tMsw;
TPiLane.low = tLsw;
}
T0 = G.T[0];
state0 = state[0];
T0.high = state0.high;
T0.low = state0.low;
for (x = _p = 0; _p < 5; x = ++_p) {
for (y = _q = 0; _q < 5; y = ++_q) {
laneIndex = x + 5 * y;
lane = state[laneIndex];
TLane = G.T[laneIndex];
Tx1Lane = G.T[((x + 1) % 5) + 5 * y];
Tx2Lane = G.T[((x + 2) % 5) + 5 * y];
lane.high = TLane.high ^ (~Tx1Lane.high & Tx2Lane.high);
lane.low = TLane.low ^ (~Tx1Lane.low & Tx2Lane.low);
}
}
lane = state[0];
roundConstant = G.ROUND_CONSTANTS[round];
lane.high ^= roundConstant.high;
_results.push(lane.low ^= roundConstant.low);
}
return _results;
};
KECCAK.prototype._doFinalize = function() {
var blockSizeBits, data, dataWords, hashWords, i, lane, laneLsw, laneMsw, nBitsLeft, nBitsTotal, outputLengthBytes, outputLengthLanes, state, _i;
data = this._data;
dataWords = data.words;
nBitsTotal = this._nDataBytes * 8;
nBitsLeft = data.sigBytes * 8;
blockSizeBits = this.blockSize * 32;
dataWords[nBitsLeft >>> 5] |= this.pad << (24 - nBitsLeft % 32);
dataWords[((Math.ceil((nBitsLeft + 1) / blockSizeBits) * blockSizeBits) >>> 5) - 1] |= 0x80;
data.sigBytes = dataWords.length * 4;
this._process();
state = this._state;
outputLengthBytes = this.outputLength / 8;
outputLengthLanes = outputLengthBytes / 8;
hashWords = [];
for (i = _i = 0; 0 <= outputLengthLanes ? _i < outputLengthLanes : _i > outputLengthLanes; i = 0 <= outputLengthLanes ? ++_i : --_i) {
lane = state[i];
laneMsw = lane.high;
laneLsw = lane.low;
laneMsw = (((laneMsw << 8) | (laneMsw >>> 24)) & 0x00ff00ff) | (((laneMsw << 24) | (laneMsw >>> 8)) & 0xff00ff00);
laneLsw = (((laneLsw << 8) | (laneLsw >>> 24)) & 0x00ff00ff) | (((laneLsw << 24) | (laneLsw >>> 8)) & 0xff00ff00);
hashWords.push(laneLsw);
hashWords.push(laneMsw);
}
return new WordArray(hashWords, outputLengthBytes);
};
KECCAK.prototype.copy_to = function(obj) {
var s;
KECCAK.__super__.copy_to.call(this, obj);
return obj._state = (function() {
var _i, _len, _ref1, _results;
_ref1 = this._state;
_results = [];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
s = _ref1[_i];
_results.push(s.clone());
}
return _results;
}).call(this);
};
KECCAK.prototype.scrub = function() {};
KECCAK.prototype.clone = function() {
var out;
out = new KECCAK();
this.copy_to(out);
return out;
};
return KECCAK;
})(Hasher);
exports.transform = function(x) {
var out;
out = (new KECCAK).finalize(x);
x.scrub();
return out;
};
}).call(this);