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) {
|
||||
// Generate new key
|
||||
var n = ecparams.getN();
|
||||
this.priv = ECDSA.getBigRandom(n);
|
||||
//this.priv = ECDSA.getBigRandom(n);
|
||||
} else if (input instanceof BigInteger) {
|
||||
// Input is a private key value
|
||||
this.priv = input;
|
||||
|
|
|
@ -65,4 +65,6 @@ function rng_get_bytes(ba) {
|
|||
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
throw new Error('Arg should be a 32 bytes hash buffer');
|
||||
}
|
||||
var eck = new ECKey(this.private.toString('hex'));
|
||||
eck.setCompressed(this._compressed);
|
||||
var signature = eck.sign(bufferToArray(hash));
|
||||
// return it as a buffer to keep c++ compatibility
|
||||
var privhex = this.private.toString('hex');
|
||||
var privnum = new BigInteger(privhex, 16);
|
||||
var signature = sign(bufferToArray(hash), privnum);
|
||||
|
||||
return new Buffer(signature);
|
||||
};
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ var imports = require('soop').imports();
|
|||
var Key = imports.Key || require('./Key');
|
||||
var bignum = imports.bignum || require('bignum');
|
||||
var assert = require('assert');
|
||||
var ECKey = require('../../browser/vendor-bundle.js').ECKey;
|
||||
var ECPointFp = require('../../browser/vendor-bundle.js').ECPointFp;
|
||||
var ECFieldElementFp = require('../../browser/vendor-bundle.js').ECFieldElementFp;
|
||||
var getSECCurveByName = require('../../browser/vendor-bundle.js').getSECCurveByName;
|
||||
|
|
Loading…
Reference in New Issue