|
|
@ -9,9 +9,10 @@ var ZERO = new Buffer([0]) |
|
|
|
var ONE = new Buffer([1]) |
|
|
|
|
|
|
|
// https://tools.ietf.org/html/rfc6979#section-3.2
|
|
|
|
function deterministicGenerateK(curve, hash, d) { |
|
|
|
function deterministicGenerateK(curve, hash, d, checkSig) { |
|
|
|
typeForce('Buffer', hash) |
|
|
|
typeForce('BigInteger', d) |
|
|
|
typeForce('Function', checkSig) |
|
|
|
|
|
|
|
// sanity check
|
|
|
|
assert.equal(hash.length, 32, 'Hash must be 256 bit') |
|
|
@ -55,8 +56,8 @@ function deterministicGenerateK(curve, hash, d) { |
|
|
|
|
|
|
|
var T = BigInteger.fromBuffer(v) |
|
|
|
|
|
|
|
// Step H3, repeat until T is within the interval [1, n - 1]
|
|
|
|
while ((T.signum() <= 0) || (T.compareTo(curve.n) >= 0)) { |
|
|
|
// Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA
|
|
|
|
while ((T.signum() <= 0) || (T.compareTo(curve.n) >= 0) || !checkSig(T)) { |
|
|
|
k = crypto.createHmac('sha256', k) |
|
|
|
.update(v) |
|
|
|
.update(ZERO) |
|
|
@ -64,6 +65,9 @@ function deterministicGenerateK(curve, hash, d) { |
|
|
|
|
|
|
|
v = crypto.createHmac('sha256', k).update(v).digest() |
|
|
|
|
|
|
|
// Step H1/H2a, again, ignored as tlen === qlen (256 bit)
|
|
|
|
// Step H2b again
|
|
|
|
v = crypto.createHmac('sha256', k).update(v).digest() |
|
|
|
T = BigInteger.fromBuffer(v) |
|
|
|
} |
|
|
|
|
|
|
@ -71,18 +75,28 @@ function deterministicGenerateK(curve, hash, d) { |
|
|
|
} |
|
|
|
|
|
|
|
function sign(curve, hash, d) { |
|
|
|
var k = deterministicGenerateK(curve, hash, d) |
|
|
|
var r, s |
|
|
|
|
|
|
|
var e = BigInteger.fromBuffer(hash) |
|
|
|
var n = curve.n |
|
|
|
var G = curve.G |
|
|
|
var Q = G.multiply(k) |
|
|
|
var e = BigInteger.fromBuffer(hash) |
|
|
|
|
|
|
|
var r = Q.affineX.mod(n) |
|
|
|
assert.notEqual(r.signum(), 0, 'Invalid R value') |
|
|
|
deterministicGenerateK(curve, hash, d, function(k) { |
|
|
|
var Q = G.multiply(k) |
|
|
|
|
|
|
|
if (curve.isInfinity(Q)) |
|
|
|
return false |
|
|
|
|
|
|
|
r = Q.affineX.mod(n) |
|
|
|
if (r.signum() === 0) |
|
|
|
return false |
|
|
|
|
|
|
|
s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n) |
|
|
|
if (s.signum() === 0) |
|
|
|
return false |
|
|
|
|
|
|
|
var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n) |
|
|
|
assert.notEqual(s.signum(), 0, 'Invalid S value') |
|
|
|
return true |
|
|
|
}) |
|
|
|
|
|
|
|
var N_OVER_TWO = n.shiftRight(1) |
|
|
|
|
|
|
|