update key signing to use new SecureRandom
...and throw an error if you try to use the old, non-secure random number generator.
This commit is contained in:
parent
66b8b6d0ba
commit
c7b33eca9a
|
@ -7,7 +7,7 @@ Bitcoin.ECKey = (function () {
|
||||||
if (!input) {
|
if (!input) {
|
||||||
// Generate new key
|
// Generate new key
|
||||||
var n = ecparams.getN();
|
var n = ecparams.getN();
|
||||||
this.priv = ECDSA.getBigRandom(n);
|
//this.priv = ECDSA.getBigRandom(n);
|
||||||
} else if (input instanceof BigInteger) {
|
} else if (input instanceof BigInteger) {
|
||||||
// Input is a private key value
|
// Input is a private key value
|
||||||
this.priv = input;
|
this.priv = input;
|
||||||
|
|
|
@ -65,4 +65,6 @@ function rng_get_bytes(ba) {
|
||||||
|
|
||||||
function SecureRandom() {}
|
function SecureRandom() {}
|
||||||
|
|
||||||
SecureRandom.prototype.nextBytes = rng_get_bytes;
|
SecureRandom.prototype.nextBytes = function() {
|
||||||
|
throw new Error('Should not use old RNG');
|
||||||
|
};
|
||||||
|
|
|
@ -90,6 +90,62 @@ Key.prototype.regenerateSync = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Key.prototype.signSync = function(hash) {
|
Key.prototype.signSync = function(hash) {
|
||||||
|
var getSECCurveByName = require('../../browser/vendor-bundle.js').getSECCurveByName;
|
||||||
|
var BigInteger = require('../../browser/vendor-bundle.js').BigInteger;
|
||||||
|
var rng = new SecureRandom();
|
||||||
|
var ecparams = getSECCurveByName('secp256k1');
|
||||||
|
|
||||||
|
var rng = {};
|
||||||
|
rng.nextBytes = function(array) {
|
||||||
|
var buf = SecureRandom.getRandomBuffer(array.length);
|
||||||
|
var a = bufferToArray(SecureRandom.getRandomBuffer(array.length));
|
||||||
|
for (var i in array) {
|
||||||
|
array[i] = a[i];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var getBigRandom = function (limit) {
|
||||||
|
return new BigInteger(limit.bitLength(), rng)
|
||||||
|
.mod(limit.subtract(BigInteger.ONE))
|
||||||
|
.add(BigInteger.ONE);
|
||||||
|
};
|
||||||
|
|
||||||
|
var sign = function (hash, priv) {
|
||||||
|
var d = priv;
|
||||||
|
var n = ecparams.getN();
|
||||||
|
var e = BigInteger.fromByteArrayUnsigned(hash);
|
||||||
|
|
||||||
|
do {
|
||||||
|
var k = getBigRandom(n);
|
||||||
|
var G = ecparams.getG();
|
||||||
|
var Q = G.multiply(k);
|
||||||
|
var r = Q.getX().toBigInteger().mod(n);
|
||||||
|
} while (r.compareTo(BigInteger.ZERO) <= 0);
|
||||||
|
|
||||||
|
var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
|
||||||
|
|
||||||
|
return serializeSig(r, s);
|
||||||
|
};
|
||||||
|
|
||||||
|
var serializeSig = function (r, s) {
|
||||||
|
var rBa = r.toByteArraySigned();
|
||||||
|
var sBa = s.toByteArraySigned();
|
||||||
|
|
||||||
|
var sequence = [];
|
||||||
|
sequence.push(0x02); // INTEGER
|
||||||
|
sequence.push(rBa.length);
|
||||||
|
sequence = sequence.concat(rBa);
|
||||||
|
|
||||||
|
sequence.push(0x02); // INTEGER
|
||||||
|
sequence.push(sBa.length);
|
||||||
|
sequence = sequence.concat(sBa);
|
||||||
|
|
||||||
|
sequence.unshift(sequence.length);
|
||||||
|
sequence.unshift(0x30); // SEQUENCE
|
||||||
|
|
||||||
|
return sequence;
|
||||||
|
};
|
||||||
|
|
||||||
if (!this.private) {
|
if (!this.private) {
|
||||||
throw new Error('Key does not have a private key set');
|
throw new Error('Key does not have a private key set');
|
||||||
}
|
}
|
||||||
|
@ -97,10 +153,10 @@ Key.prototype.signSync = function(hash) {
|
||||||
if (!Buffer.isBuffer(hash) || hash.length !== 32) {
|
if (!Buffer.isBuffer(hash) || hash.length !== 32) {
|
||||||
throw new Error('Arg should be a 32 bytes hash buffer');
|
throw new Error('Arg should be a 32 bytes hash buffer');
|
||||||
}
|
}
|
||||||
var eck = new ECKey(this.private.toString('hex'));
|
var privhex = this.private.toString('hex');
|
||||||
eck.setCompressed(this._compressed);
|
var privnum = new BigInteger(privhex, 16);
|
||||||
var signature = eck.sign(bufferToArray(hash));
|
var signature = sign(bufferToArray(hash), privnum);
|
||||||
// return it as a buffer to keep c++ compatibility
|
|
||||||
return new Buffer(signature);
|
return new Buffer(signature);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ var imports = require('soop').imports();
|
||||||
var Key = imports.Key || require('./Key');
|
var Key = imports.Key || require('./Key');
|
||||||
var bignum = imports.bignum || require('bignum');
|
var bignum = imports.bignum || require('bignum');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var ECKey = require('../../browser/vendor-bundle.js').ECKey;
|
|
||||||
var ECPointFp = require('../../browser/vendor-bundle.js').ECPointFp;
|
var ECPointFp = require('../../browser/vendor-bundle.js').ECPointFp;
|
||||||
var ECFieldElementFp = require('../../browser/vendor-bundle.js').ECFieldElementFp;
|
var ECFieldElementFp = require('../../browser/vendor-bundle.js').ECFieldElementFp;
|
||||||
var getSECCurveByName = require('../../browser/vendor-bundle.js').getSECCurveByName;
|
var getSECCurveByName = require('../../browser/vendor-bundle.js').getSECCurveByName;
|
||||||
|
|
Loading…
Reference in New Issue