mirror of
https://github.com/YunoHost-Apps/movim_ynh.git
synced 2024-09-03 19:46:19 +02:00
254 lines
No EOL
9.8 KiB
JavaScript
254 lines
No EOL
9.8 KiB
JavaScript
// Salsa20 implementation
|
|
// Contributed to Cryptocat by Dmitry Chestnykh
|
|
// 21-01-2013
|
|
|
|
;(function (root, factory) {
|
|
|
|
if (typeof define === 'function' && define.amd) {
|
|
define(factory)
|
|
} else if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = factory()
|
|
} else {
|
|
root.Salsa20 = factory()
|
|
}
|
|
|
|
}(this, function () {
|
|
|
|
function Salsa20(key, nonce) {
|
|
// Constants.
|
|
this.rounds = 20; // number of Salsa rounds
|
|
this.sigmaWords = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574];
|
|
|
|
// State.
|
|
this.keyWords = []; // key words
|
|
this.nonceWords = [0, 0]; // nonce words
|
|
this.counterWords = [0, 0]; // block counter words
|
|
|
|
// Output buffer.
|
|
this.block = []; // output block of 64 bytes
|
|
this.blockUsed = 64; // number of block bytes used
|
|
|
|
this.setKey(key);
|
|
this.setNonce(nonce);
|
|
}
|
|
|
|
// setKey sets the key to the given 32-byte array.
|
|
Salsa20.prototype.setKey = function(key) {
|
|
for (var i = 0, j = 0; i < 8; i++, j += 4) {
|
|
this.keyWords[i] = (key[j] & 0xff) |
|
|
((key[j+1] & 0xff)<<8) |
|
|
((key[j+2] & 0xff)<<16) |
|
|
((key[j+3] & 0xff)<<24);
|
|
}
|
|
this._reset();
|
|
};
|
|
|
|
// setNonce sets the nonce to the given 8-byte array.
|
|
Salsa20.prototype.setNonce = function(nonce) {
|
|
this.nonceWords[0] = (nonce[0] & 0xff) |
|
|
((nonce[1] & 0xff)<<8) |
|
|
((nonce[2] & 0xff)<<16) |
|
|
((nonce[3] & 0xff)<<24);
|
|
this.nonceWords[1] = (nonce[4] & 0xff) |
|
|
((nonce[5] & 0xff)<<8) |
|
|
((nonce[6] & 0xff)<<16) |
|
|
((nonce[7] & 0xff)<<24);
|
|
this._reset();
|
|
};
|
|
|
|
// getBytes returns the next numberOfBytes bytes of stream.
|
|
Salsa20.prototype.getBytes = function(numberOfBytes) {
|
|
var out = new Array(numberOfBytes);
|
|
for (var i = 0; i < numberOfBytes; i++) {
|
|
if (this.blockUsed == 64) {
|
|
this._generateBlock();
|
|
this._incrementCounter();
|
|
this.blockUsed = 0;
|
|
}
|
|
out[i] = this.block[this.blockUsed];
|
|
this.blockUsed++;
|
|
}
|
|
return out;
|
|
};
|
|
|
|
Salsa20.prototype.getHexString = function(numberOfBytes) {
|
|
var hex=['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'];
|
|
var out = [];
|
|
var bytes = this.getBytes(numberOfBytes);
|
|
for(var i = 0; i < bytes.length; i++) {
|
|
out.push(hex[(bytes[i] >> 4) & 15]);
|
|
out.push(hex[bytes[i] & 15]);
|
|
}
|
|
return out.join('');
|
|
};
|
|
|
|
// Private methods.
|
|
|
|
Salsa20.prototype._reset = function() {
|
|
this.counterWords[0] = 0;
|
|
this.counterWords[1] = 0;
|
|
this.blockUsed = 64;
|
|
};
|
|
|
|
// _incrementCounter increments block counter.
|
|
Salsa20.prototype._incrementCounter = function() {
|
|
// Note: maximum 2^64 blocks.
|
|
this.counterWords[0] = (this.counterWords[0] + 1) & 0xffffffff;
|
|
if (this.counterWords[0] == 0) {
|
|
this.counterWords[1] = (this.counterWords[1] + 1) & 0xffffffff;
|
|
}
|
|
};
|
|
|
|
// _generateBlock generates 64 bytes from key, nonce, and counter,
|
|
// and puts the result into this.block.
|
|
Salsa20.prototype._generateBlock = function() {
|
|
var j0 = this.sigmaWords[0],
|
|
j1 = this.keyWords[0],
|
|
j2 = this.keyWords[1],
|
|
j3 = this.keyWords[2],
|
|
j4 = this.keyWords[3],
|
|
j5 = this.sigmaWords[1],
|
|
j6 = this.nonceWords[0],
|
|
j7 = this.nonceWords[1],
|
|
j8 = this.counterWords[0],
|
|
j9 = this.counterWords[1],
|
|
j10 = this.sigmaWords[2],
|
|
j11 = this.keyWords[4],
|
|
j12 = this.keyWords[5],
|
|
j13 = this.keyWords[6],
|
|
j14 = this.keyWords[7],
|
|
j15 = this.sigmaWords[3];
|
|
|
|
var x0 = j0, x1 = j1, x2 = j2, x3 = j3, x4 = j4, x5 = j5, x6 = j6, x7 = j7,
|
|
x8 = j8, x9 = j9, x10 = j10, x11 = j11, x12 = j12, x13 = j13, x14 = j14, x15 = j15;
|
|
|
|
var u;
|
|
|
|
for (var i = 0; i < this.rounds; i += 2) {
|
|
u = x0 + x12;
|
|
x4 ^= (u<<7) | (u>>>(32-7));
|
|
u = x4 + x0;
|
|
x8 ^= (u<<9) | (u>>>(32-9));
|
|
u = x8 + x4;
|
|
x12 ^= (u<<13) | (u>>>(32-13));
|
|
u = x12 + x8;
|
|
x0 ^= (u<<18) | (u>>>(32-18));
|
|
|
|
u = x5 + x1;
|
|
x9 ^= (u<<7) | (u>>>(32-7));
|
|
u = x9 + x5;
|
|
x13 ^= (u<<9) | (u>>>(32-9));
|
|
u = x13 + x9;
|
|
x1 ^= (u<<13) | (u>>>(32-13));
|
|
u = x1 + x13;
|
|
x5 ^= (u<<18) | (u>>>(32-18));
|
|
|
|
u = x10 + x6;
|
|
x14 ^= (u<<7) | (u>>>(32-7));
|
|
u = x14 + x10;
|
|
x2 ^= (u<<9) | (u>>>(32-9));
|
|
u = x2 + x14;
|
|
x6 ^= (u<<13) | (u>>>(32-13));
|
|
u = x6 + x2;
|
|
x10 ^= (u<<18) | (u>>>(32-18));
|
|
|
|
u = x15 + x11;
|
|
x3 ^= (u<<7) | (u>>>(32-7));
|
|
u = x3 + x15;
|
|
x7 ^= (u<<9) | (u>>>(32-9));
|
|
u = x7 + x3;
|
|
x11 ^= (u<<13) | (u>>>(32-13));
|
|
u = x11 + x7;
|
|
x15 ^= (u<<18) | (u>>>(32-18));
|
|
|
|
u = x0 + x3;
|
|
x1 ^= (u<<7) | (u>>>(32-7));
|
|
u = x1 + x0;
|
|
x2 ^= (u<<9) | (u>>>(32-9));
|
|
u = x2 + x1;
|
|
x3 ^= (u<<13) | (u>>>(32-13));
|
|
u = x3 + x2;
|
|
x0 ^= (u<<18) | (u>>>(32-18));
|
|
|
|
u = x5 + x4;
|
|
x6 ^= (u<<7) | (u>>>(32-7));
|
|
u = x6 + x5;
|
|
x7 ^= (u<<9) | (u>>>(32-9));
|
|
u = x7 + x6;
|
|
x4 ^= (u<<13) | (u>>>(32-13));
|
|
u = x4 + x7;
|
|
x5 ^= (u<<18) | (u>>>(32-18));
|
|
|
|
u = x10 + x9;
|
|
x11 ^= (u<<7) | (u>>>(32-7));
|
|
u = x11 + x10;
|
|
x8 ^= (u<<9) | (u>>>(32-9));
|
|
u = x8 + x11;
|
|
x9 ^= (u<<13) | (u>>>(32-13));
|
|
u = x9 + x8;
|
|
x10 ^= (u<<18) | (u>>>(32-18));
|
|
|
|
u = x15 + x14;
|
|
x12 ^= (u<<7) | (u>>>(32-7));
|
|
u = x12 + x15;
|
|
x13 ^= (u<<9) | (u>>>(32-9));
|
|
u = x13 + x12;
|
|
x14 ^= (u<<13) | (u>>>(32-13));
|
|
u = x14 + x13;
|
|
x15 ^= (u<<18) | (u>>>(32-18));
|
|
}
|
|
|
|
x0 += j0;
|
|
x1 += j1;
|
|
x2 += j2;
|
|
x3 += j3;
|
|
x4 += j4;
|
|
x5 += j5;
|
|
x6 += j6;
|
|
x7 += j7;
|
|
x8 += j8;
|
|
x9 += j9;
|
|
x10 += j10;
|
|
x11 += j11;
|
|
x12 += j12;
|
|
x13 += j13;
|
|
x14 += j14;
|
|
x15 += j15;
|
|
|
|
this.block[ 0] = ( x0 >>> 0) & 0xff; this.block[ 1] = ( x0 >>> 8) & 0xff;
|
|
this.block[ 2] = ( x0 >>> 16) & 0xff; this.block[ 3] = ( x0 >>> 24) & 0xff;
|
|
this.block[ 4] = ( x1 >>> 0) & 0xff; this.block[ 5] = ( x1 >>> 8) & 0xff;
|
|
this.block[ 6] = ( x1 >>> 16) & 0xff; this.block[ 7] = ( x1 >>> 24) & 0xff;
|
|
this.block[ 8] = ( x2 >>> 0) & 0xff; this.block[ 9] = ( x2 >>> 8) & 0xff;
|
|
this.block[10] = ( x2 >>> 16) & 0xff; this.block[11] = ( x2 >>> 24) & 0xff;
|
|
this.block[12] = ( x3 >>> 0) & 0xff; this.block[13] = ( x3 >>> 8) & 0xff;
|
|
this.block[14] = ( x3 >>> 16) & 0xff; this.block[15] = ( x3 >>> 24) & 0xff;
|
|
this.block[16] = ( x4 >>> 0) & 0xff; this.block[17] = ( x4 >>> 8) & 0xff;
|
|
this.block[18] = ( x4 >>> 16) & 0xff; this.block[19] = ( x4 >>> 24) & 0xff;
|
|
this.block[20] = ( x5 >>> 0) & 0xff; this.block[21] = ( x5 >>> 8) & 0xff;
|
|
this.block[22] = ( x5 >>> 16) & 0xff; this.block[23] = ( x5 >>> 24) & 0xff;
|
|
this.block[24] = ( x6 >>> 0) & 0xff; this.block[25] = ( x6 >>> 8) & 0xff;
|
|
this.block[26] = ( x6 >>> 16) & 0xff; this.block[27] = ( x6 >>> 24) & 0xff;
|
|
this.block[28] = ( x7 >>> 0) & 0xff; this.block[29] = ( x7 >>> 8) & 0xff;
|
|
this.block[30] = ( x7 >>> 16) & 0xff; this.block[31] = ( x7 >>> 24) & 0xff;
|
|
this.block[32] = ( x8 >>> 0) & 0xff; this.block[33] = ( x8 >>> 8) & 0xff;
|
|
this.block[34] = ( x8 >>> 16) & 0xff; this.block[35] = ( x8 >>> 24) & 0xff;
|
|
this.block[36] = ( x9 >>> 0) & 0xff; this.block[37] = ( x9 >>> 8) & 0xff;
|
|
this.block[38] = ( x9 >>> 16) & 0xff; this.block[39] = ( x9 >>> 24) & 0xff;
|
|
this.block[40] = (x10 >>> 0) & 0xff; this.block[41] = (x10 >>> 8) & 0xff;
|
|
this.block[42] = (x10 >>> 16) & 0xff; this.block[43] = (x10 >>> 24) & 0xff;
|
|
this.block[44] = (x11 >>> 0) & 0xff; this.block[45] = (x11 >>> 8) & 0xff;
|
|
this.block[46] = (x11 >>> 16) & 0xff; this.block[47] = (x11 >>> 24) & 0xff;
|
|
this.block[48] = (x12 >>> 0) & 0xff; this.block[49] = (x12 >>> 8) & 0xff;
|
|
this.block[50] = (x12 >>> 16) & 0xff; this.block[51] = (x12 >>> 24) & 0xff;
|
|
this.block[52] = (x13 >>> 0) & 0xff; this.block[53] = (x13 >>> 8) & 0xff;
|
|
this.block[54] = (x13 >>> 16) & 0xff; this.block[55] = (x13 >>> 24) & 0xff;
|
|
this.block[56] = (x14 >>> 0) & 0xff; this.block[57] = (x14 >>> 8) & 0xff;
|
|
this.block[58] = (x14 >>> 16) & 0xff; this.block[59] = (x14 >>> 24) & 0xff;
|
|
this.block[60] = (x15 >>> 0) & 0xff; this.block[61] = (x15 >>> 8) & 0xff;
|
|
this.block[62] = (x15 >>> 16) & 0xff; this.block[63] = (x15 >>> 24) & 0xff;
|
|
};
|
|
|
|
return Salsa20
|
|
|
|
})) |