web3x
Version:
Typescript port of web3.js
254 lines (251 loc) • 24.4 kB
JavaScript
;
/*
This file is part of web3x.
web3x is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
web3x is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with web3x. If not, see <http://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const pbkdf2_1 = require("./pbkdf2");
const MAX_VALUE = 0x7fffffff;
// The following is an adaptation of scryptsy
// See: https://www.npmjs.com/package/scryptsy
function blockmix_salsa8(BY, Yi, r, x, _X) {
let i;
arraycopy(BY, (2 * r - 1) * 16, _X, 0, 16);
for (i = 0; i < 2 * r; i++) {
blockxor(BY, i * 16, _X, 16);
salsa20_8(_X, x);
arraycopy(_X, 0, BY, Yi + i * 16, 16);
}
for (i = 0; i < r; i++) {
arraycopy(BY, Yi + i * 2 * 16, BY, i * 16, 16);
}
for (i = 0; i < r; i++) {
arraycopy(BY, Yi + (i * 2 + 1) * 16, BY, (i + r) * 16, 16);
}
}
function R(a, b) {
return (a << b) | (a >>> (32 - b));
}
function salsa20_8(B, x) {
arraycopy(B, 0, x, 0, 16);
for (let i = 8; i > 0; i -= 2) {
x[4] ^= R(x[0] + x[12], 7);
x[8] ^= R(x[4] + x[0], 9);
x[12] ^= R(x[8] + x[4], 13);
x[0] ^= R(x[12] + x[8], 18);
x[9] ^= R(x[5] + x[1], 7);
x[13] ^= R(x[9] + x[5], 9);
x[1] ^= R(x[13] + x[9], 13);
x[5] ^= R(x[1] + x[13], 18);
x[14] ^= R(x[10] + x[6], 7);
x[2] ^= R(x[14] + x[10], 9);
x[6] ^= R(x[2] + x[14], 13);
x[10] ^= R(x[6] + x[2], 18);
x[3] ^= R(x[15] + x[11], 7);
x[7] ^= R(x[3] + x[15], 9);
x[11] ^= R(x[7] + x[3], 13);
x[15] ^= R(x[11] + x[7], 18);
x[1] ^= R(x[0] + x[3], 7);
x[2] ^= R(x[1] + x[0], 9);
x[3] ^= R(x[2] + x[1], 13);
x[0] ^= R(x[3] + x[2], 18);
x[6] ^= R(x[5] + x[4], 7);
x[7] ^= R(x[6] + x[5], 9);
x[4] ^= R(x[7] + x[6], 13);
x[5] ^= R(x[4] + x[7], 18);
x[11] ^= R(x[10] + x[9], 7);
x[8] ^= R(x[11] + x[10], 9);
x[9] ^= R(x[8] + x[11], 13);
x[10] ^= R(x[9] + x[8], 18);
x[12] ^= R(x[15] + x[14], 7);
x[13] ^= R(x[12] + x[15], 9);
x[14] ^= R(x[13] + x[12], 13);
x[15] ^= R(x[14] + x[13], 18);
}
for (let i = 0; i < 16; ++i) {
B[i] += x[i];
}
}
// naive approach... going back to loop unrolling may yield additional performance
function blockxor(S, Si, D, len) {
for (let i = 0; i < len; i++) {
D[i] ^= S[Si + i];
}
}
function arraycopy(src, srcPos, dest, destPos, length) {
while (length--) {
dest[destPos++] = src[srcPos++];
}
}
function ensureInteger(value, name) {
const intValue = parseInt(value, 10);
if (value !== intValue) {
throw new Error('invalid ' + name);
}
return intValue;
}
// N = Cpu cost, r = Memory cost, p = parallelization cost
// callback(error, progress, key)
function scrypt(password, salt, N, r, p, dkLen, callback) {
return new Promise(async (resolve, reject) => {
N = ensureInteger(N, 'N');
r = ensureInteger(r, 'r');
p = ensureInteger(p, 'p');
dkLen = ensureInteger(dkLen, 'dkLen');
if (N === 0 || (N & (N - 1)) !== 0) {
reject(new Error('N must be power of 2'));
}
if (N > MAX_VALUE / 128 / r) {
reject(new Error('N too large'));
}
if (r > MAX_VALUE / 128 / p) {
reject(new Error('r too large'));
}
let b = [...(await pbkdf2_1.pbkdf2(password, salt, 1, p * 128 * r))];
const B = new Uint32Array(p * 32 * r);
for (let i = 0; i < B.length; i++) {
const j = i * 4;
B[i] =
((b[j + 3] & 0xff) << 24) | ((b[j + 2] & 0xff) << 16) | ((b[j + 1] & 0xff) << 8) | ((b[j + 0] & 0xff) << 0);
}
const XY = new Uint32Array(64 * r);
const V = new Uint32Array(32 * r * N);
const Yi = 32 * r;
// scratch space
const x = new Uint32Array(16); // salsa20_8
const _X = new Uint32Array(16); // blockmix_salsa8
const totalOps = p * N * 2;
let currentOp = 0;
let lastPercent10 = null;
// Set this to true to abandon the scrypt on the next step
let stop = false;
// State information
let state = 0;
let i0 = 0;
let i1 = 0;
let Bi;
// How many blockmix_salsa8 can we do per step?
const limit = Math.trunc(1000 / r);
// Trick from scrypt-async; if there is a setImmediate shim in place, use it
const nextTick = typeof setImmediate !== 'undefined' ? setImmediate : setTimeout;
// This is really all I changed; making scryptsy a state machine so we occasionally
// stop and give other evnts on the evnt loop a chance to run. ~RicMoo
const incrementalSMix = async () => {
if (stop) {
if (callback) {
callback(currentOp / totalOps);
}
reject(new Error('cancelled'));
return;
}
switch (state) {
case 0:
// for (var i = 0; i < p; i++)...
Bi = i0 * 32 * r;
arraycopy(B, Bi, XY, 0, Yi); // ROMix - 1
state = 1; // Move to ROMix 2
i1 = 0;
// Fall through
case 1: {
// Run up to 1000 steps of the first inner smix loop
let steps = N - i1;
if (steps > limit) {
steps = limit;
}
for (let i = 0; i < steps; i++) {
// ROMix - 2
arraycopy(XY, 0, V, (i1 + i) * Yi, Yi); // ROMix - 3
blockmix_salsa8(XY, Yi, r, x, _X); // ROMix - 4
}
// for (var i = 0; i < N; i++)
i1 += steps;
currentOp += steps;
// Call the callback with the progress (optionally stopping us)
const percent10 = Math.trunc((1000 * currentOp) / totalOps);
if (percent10 !== lastPercent10) {
if (callback) {
stop = callback(currentOp / totalOps);
}
if (stop) {
break;
}
lastPercent10 = percent10;
}
if (i1 < N) {
break;
}
i1 = 0; // Move to ROMix 6
state = 2;
}
// Fall through
case 2: {
// Run up to 1000 steps of the second inner smix loop
let steps = N - i1;
if (steps > limit) {
steps = limit;
}
for (let i = 0; i < steps; i++) {
// ROMix - 6
const offset = (2 * r - 1) * 16; // ROMix - 7
const j = XY[offset] & (N - 1);
blockxor(V, j * Yi, XY, Yi); // ROMix - 8 (inner)
blockmix_salsa8(XY, Yi, r, x, _X); // ROMix - 9 (outer)
}
// for (var i = 0; i < N; i++)...
i1 += steps;
currentOp += steps;
// Call the callback with the progress (optionally stopping us)
const percent10 = Math.trunc((1000 * currentOp) / totalOps);
if (percent10 !== lastPercent10) {
if (callback) {
stop = callback(currentOp / totalOps);
}
if (stop) {
break;
}
lastPercent10 = percent10;
}
if (i1 < N) {
break;
}
arraycopy(XY, 0, B, Bi, Yi); // ROMix - 10
// for (var i = 0; i < p; i++)...
i0++;
if (i0 < p) {
state = 0;
break;
}
b = [];
for (const bb of B) {
b.push((bb >> 0) & 0xff);
b.push((bb >> 8) & 0xff);
b.push((bb >> 16) & 0xff);
b.push((bb >> 24) & 0xff);
}
const derivedKey = await pbkdf2_1.pbkdf2(password, Buffer.from(b), 1, dkLen);
// Done; don't break (which would reschedule)
if (callback) {
callback(1.0);
}
resolve(derivedKey);
return;
}
}
// Schedule the next steps
nextTick(incrementalSMix);
};
// Bootstrap the incremental smix
incrementalSMix();
});
}
exports.scrypt = scrypt;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyeXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3NjcnlwdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7OztFQWVFOztBQUVGLHFDQUFrQztBQUVsQyxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUM7QUFFN0IsNkNBQTZDO0FBQzdDLDhDQUE4QztBQUM5QyxTQUFTLGVBQWUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUN2QyxJQUFJLENBQUMsQ0FBQztJQUVOLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUMxQixRQUFRLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdCLFNBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakIsU0FBUyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0tBQ3ZDO0lBRUQsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUU7UUFDdEIsU0FBUyxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDaEQ7SUFFRCxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtRQUN0QixTQUFTLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDNUQ7QUFDSCxDQUFDO0FBRUQsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDYixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDckMsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3JCLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFFMUIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFO1FBQzdCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzNCLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzVCLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM1QixDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDN0Is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