mirror of
https://github.com/danog/fast-srp.git
synced 2024-11-26 20:04:49 +01:00
Apply patch from Alex
This commit is contained in:
parent
0c812b0145
commit
077567779d
64
lib/srp.js
64
lib/srp.js
@ -41,33 +41,11 @@ function padToN(number, params) {
|
|||||||
return padTo(new Buffer(n, 'hex'), params.N_length_bits / 8);
|
return padTo(new Buffer(n, 'hex'), params.N_length_bits / 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
function padToH(number, params) {
|
|
||||||
assertIsBigInteger(number);
|
|
||||||
var hashlen_bits;
|
|
||||||
if (params.hash === "sha1")
|
|
||||||
hashlen_bits = 160;
|
|
||||||
else if (params.hash === "sha256")
|
|
||||||
hashlen_bits = 256;
|
|
||||||
else if (params.hash === "sha512")
|
|
||||||
hashlen_bits = 512;
|
|
||||||
else
|
|
||||||
throw Error("cannot determine length of hash '" +params.hash + "'");
|
|
||||||
|
|
||||||
return padTo(new Buffer(number, 'hex'), hashlen_bits / 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
function assertIsBuffer(arg, argname) {
|
function assertIsBuffer(arg, argname) {
|
||||||
argname = argname || "arg";
|
argname = argname || "arg";
|
||||||
assert_(Buffer.isBuffer(arg), "Type error: "+argname+" must be a buffer");
|
assert_(Buffer.isBuffer(arg), "Type error: "+argname+" must be a buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
function assertIsNBuffer(arg, params, argname) {
|
|
||||||
argname = argname || "arg";
|
|
||||||
assert_(Buffer.isBuffer(arg), "Type error: "+argname+" must be a buffer");
|
|
||||||
if (arg.length != params.N_length_bits/8)
|
|
||||||
assert_(false, argname+" was "+arg.length+", expected "+(params.N_length_bits/8));
|
|
||||||
}
|
|
||||||
|
|
||||||
function assertIsBigInteger(arg) {
|
function assertIsBigInteger(arg) {
|
||||||
assert_(arg.constructor.name === 'BigInteger', "Type error: " + arg.argname + " must be a BigInteger");
|
assert_(arg.constructor.name === 'BigInteger', "Type error: " + arg.argname + " must be a BigInteger");
|
||||||
}
|
}
|
||||||
@ -122,7 +100,7 @@ function computeVerifier(params, salt, I, P) {
|
|||||||
assertIsBuffer(I, "identity (I)");
|
assertIsBuffer(I, "identity (I)");
|
||||||
assertIsBuffer(P, "password (P)");
|
assertIsBuffer(P, "password (P)");
|
||||||
var v_num = params.g.modPow(getx(params, salt, I, P), params.N);
|
var v_num = params.g.modPow(getx(params, salt, I, P), params.N);
|
||||||
return padToN(v_num, params);
|
return v_num.toBuffer(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -187,7 +165,7 @@ function getB(params, k, v, b) {
|
|||||||
assertIsBigInteger(b);
|
assertIsBigInteger(b);
|
||||||
var N = params.N;
|
var N = params.N;
|
||||||
var r = k.multiply(v).add(params.g.modPow(b, N)).mod(N);
|
var r = k.multiply(v).add(params.g.modPow(b, N)).mod(N);
|
||||||
return padToN(r, params);
|
return r.toBuffer(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -208,7 +186,7 @@ function getA(params, a_num) {
|
|||||||
if (Math.ceil(a_num.toString(16).length / 2) < 32) {
|
if (Math.ceil(a_num.toString(16).length / 2) < 32) {
|
||||||
console.warn("getA: client key length", a_num.bitLength(), "is less than the recommended 256 bits");
|
console.warn("getA: client key length", a_num.bitLength(), "is less than the recommended 256 bits");
|
||||||
}
|
}
|
||||||
return padToN(params.g.modPow(a_num, params.N), params);
|
return params.g.modPow(a_num, params.N).toBuffer(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -226,10 +204,11 @@ function getA(params, a_num) {
|
|||||||
* returns: u (bignum) shared scrambling parameter
|
* returns: u (bignum) shared scrambling parameter
|
||||||
*/
|
*/
|
||||||
function getu(params, A, B) {
|
function getu(params, A, B) {
|
||||||
assertIsNBuffer(A, params, "A");
|
assertIsBuffer(A, params, "A");
|
||||||
assertIsNBuffer(B, params, "B");
|
assertIsBuffer(B, params, "B");
|
||||||
var u_buf = crypto.createHash(params.hash)
|
var u_buf = crypto.createHash(params.hash)
|
||||||
.update(A).update(B)
|
.update(padTo(A, params.N_length_bits / 8))
|
||||||
|
.update(padTo(B, params.N_length_bits / 8))
|
||||||
.digest();
|
.digest();
|
||||||
return(new BigInteger(u_buf));
|
return(new BigInteger(u_buf));
|
||||||
};
|
};
|
||||||
@ -257,8 +236,7 @@ function client_getS(params, k_num, x_num, a_num, B_num, u_num) {
|
|||||||
if((zero.compareTo(B_num) > 0) && (N.compareTo(B_num) < 0))
|
if((zero.compareTo(B_num) > 0) && (N.compareTo(B_num) < 0))
|
||||||
throw new Error("invalid server-supplied 'B', must be 1..N-1");
|
throw new Error("invalid server-supplied 'B', must be 1..N-1");
|
||||||
var S_num = B_num.subtract(k_num.multiply(params.g.modPow(x_num, params.N))).modPow(a_num.add(u_num.multiply(x_num)), params.N).mod(params.N);
|
var S_num = B_num.subtract(k_num.multiply(params.g.modPow(x_num, params.N))).modPow(a_num.add(u_num.multiply(x_num)), params.N).mod(params.N);
|
||||||
|
return S_num.toBuffer(true);
|
||||||
return padToN(S_num, params);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -278,11 +256,10 @@ function server_getS(params, v_num, A_num, b_num, u_num) {
|
|||||||
assertIsBigInteger(A_num);
|
assertIsBigInteger(A_num);
|
||||||
assertIsBigInteger(b_num);
|
assertIsBigInteger(b_num);
|
||||||
assertIsBigInteger(u_num);
|
assertIsBigInteger(u_num);
|
||||||
//! if (zero.greater(A_num) || N.lesser(A_num))
|
|
||||||
if((zero.compareTo(A_num) > 0) && (N.compareTo(A_num) < 0))
|
if((zero.compareTo(A_num) > 0) && (N.compareTo(A_num) < 0))
|
||||||
throw new Error("invalid client-supplied 'A', must be 1..N-1");
|
throw new Error("invalid client-supplied 'A', must be 1..N-1");
|
||||||
var S_num = A_num.multiply(v_num.modPow(u_num, params.N)).modPow(b_num, params.N).mod(params.N);
|
var S_num = A_num.multiply(v_num.modPow(u_num, params.N)).modPow(b_num, params.N).mod(params.N);
|
||||||
return padToN(S_num, params);
|
return S_num.toBuffer(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -295,17 +272,24 @@ function server_getS(params, v_num, A_num, b_num, u_num) {
|
|||||||
* returns: buffer
|
* returns: buffer
|
||||||
*/
|
*/
|
||||||
function getK(params, S_buf) {
|
function getK(params, S_buf) {
|
||||||
assertIsNBuffer(S_buf, params, "S");
|
assertIsBuffer(S_buf, params, "S");
|
||||||
return crypto.createHash(params.hash)
|
if (params.hash === "sha1") {
|
||||||
.update(S_buf)
|
// use t_mgf1 interleave for short sha1 hashes
|
||||||
.digest();
|
return Buffer.concat([
|
||||||
|
crypto.createHash(params.hash).update(S_buf).update(Buffer.from([0,0,0,0])).digest(),
|
||||||
|
crypto.createHash(params.hash).update(S_buf).update(Buffer.from([0,0,0,1])).digest()
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// use hash as-is otherwise
|
||||||
|
return crypto.createHash(params.hash).update(S_buf).digest();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function getM1(params, u_buf, s_buf, A_buf, B_buf, K_buf) {
|
function getM1(params, u_buf, s_buf, A_buf, B_buf, K_buf) {
|
||||||
assertIsBuffer(u_buf, params, "identity (I)");
|
assertIsBuffer(u_buf, params, "identity (I)");
|
||||||
assertIsBuffer(s_buf, params, "salt (s)")
|
assertIsBuffer(s_buf, params, "salt (s)")
|
||||||
assertIsNBuffer(A_buf, params, "A");
|
assertIsBuffer(A_buf, params, "A");
|
||||||
assertIsNBuffer(B_buf, params, "B");
|
assertIsBuffer(B_buf, params, "B");
|
||||||
assertIsBuffer(K_buf, params, "K");
|
assertIsBuffer(K_buf, params, "K");
|
||||||
|
|
||||||
var hN = crypto.createHash(params.hash).update(params.N.toBuffer(true)).digest();
|
var hN = crypto.createHash(params.hash).update(params.N.toBuffer(true)).digest();
|
||||||
@ -323,7 +307,7 @@ function getM1(params, u_buf, s_buf, A_buf, B_buf, K_buf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getM2(params, A_buf, M1_buf, K_buf) {
|
function getM2(params, A_buf, M1_buf, K_buf) {
|
||||||
assertIsNBuffer(A_buf, params, "A");
|
assertIsBuffer(A_buf, params, "A");
|
||||||
assertIsBuffer(M1_buf, params, "M1");
|
assertIsBuffer(M1_buf, params, "M1");
|
||||||
assertIsBuffer(K_buf, params, "K");
|
assertIsBuffer(K_buf, params, "K");
|
||||||
|
|
||||||
@ -365,8 +349,6 @@ Client.prototype = {
|
|||||||
var u_num = getu(p.params, p.A_buf, B_buf);
|
var u_num = getu(p.params, p.A_buf, B_buf);
|
||||||
var S_buf_x = client_getS(p.params, p.k_num, p.x_num, p.a_num, B_num, u_num);
|
var S_buf_x = client_getS(p.params, p.k_num, p.x_num, p.a_num, B_num, u_num);
|
||||||
p.K_buf = getK(p.params, S_buf_x);
|
p.K_buf = getK(p.params, S_buf_x);
|
||||||
p.M1_buf = getM1(p.params, p.A_buf, B_buf, S_buf_x);
|
|
||||||
p.M2_buf = getM2(p.params, p.A_buf, p.M1_buf, p.K_buf);
|
|
||||||
p.u_num = u_num; // only for tests
|
p.u_num = u_num; // only for tests
|
||||||
p.S_buf = S_buf_x; // only for tests
|
p.S_buf = S_buf_x; // only for tests
|
||||||
p.B_buf = B_buf;
|
p.B_buf = B_buf;
|
||||||
|
Loading…
Reference in New Issue
Block a user