Merge tag 'v0.1.15'

Conflicts:
	package.json
This commit is contained in:
Ryan X. Charles 2014-04-25 15:16:41 -03:00
commit 0cdb8941d7
7 changed files with 114 additions and 12 deletions

View File

@ -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;

View File

@ -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');
};

View File

@ -187,6 +187,30 @@ Script.prototype.finishedMultiSig = function() {
return missing === 0;
};
Script.prototype.getMultiSigInfo = function() {
if (!this.isMultiSig()) {
throw new Error("Script.getMultiSigInfo(): Not a multiSig script.");
}
var nsigs = this.chunks[0] - 80; //see OP_2-OP_16;
var npubkeys = this.chunks[this.chunks.length - 2] - 80; //see OP_2-OP_16;
var pubkeys = [];
for (var i = 1; i < this.chunks.length - 2; i++) {
pubkeys.push(this.chunks[i]);
}
if (pubkeys.length != npubkeys) {
throw new Error("Script.getMultiSigInfo(): Amount of PKs does not match what the script specifies.");
}
return {
nsigs : nsigs,
npubkeys : npubkeys,
pubkeys : pubkeys
}
};
Script.prototype.prependOp0 = function() {
var chunks = [0];
for (i in this.chunks) {

View File

@ -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);
};

View File

@ -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;

View File

@ -1,7 +1,7 @@
{
"name": "bitcore",
"description": "Bitcoin Library",
"version": "0.1.14",
"version": "0.1.15",
"author": {
"name": "Stephen Pair",
"email": "stephen@bitpay.com"

View File

@ -34,6 +34,7 @@ describe('Script', function() {
var script = Script.createPubKeyHashOut(addr.payload());
script.isP2SH().should.be.false;
});
describe('#finishedMultiSig', function() {
it('should report that this scriptSig has finished being signed', function() {
var scriptHex = '00493046022100954d2aa7af9a2de34b04e4151842933df81acc379580cd0c057883cfb0994a8b022100de1530692eda9cdb567c94e05fc856cfbc26fcf3482148bde85f143032f4902501483045022100d164d174118497d93e0062b573be78d4b9417aee09889cd242a966af73367917022054f095be0bce9edee556a2216239fcad45a7a64d8fb318dc5375c9159724689a014c695221033e4cc6b6ee8d8ce3335fed6d4917b2bbbac0f5743b2ced101ba036f95c51e59421023147410ce15e0a31c2bb970cdf01517266dc2c9182f5938636ed363cfd4cc3ae210342a3c8a4b20c7a122a011a07063df04e4c5ad520a1302a2a66e174fd9b0d4ea453ae';
@ -53,6 +54,26 @@ describe('Script', function() {
});
});
describe('#getMultiSigInfo', function() {
it('should report the expected pubkeys', function() {
// using same test case as used in #createMultisig
// 3 of 5 multisig, unsorted
// test case generated with: bitcoind createmultisig 3 '["02c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae0", "02b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758", "0266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea","02ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e70", "02c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af793"]'
var scriptHex = '532102c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae02102b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758210266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea2102ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e702102c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af79355ae';
var scriptBuf = new Buffer(scriptHex, 'hex');
var script = new Script(scriptBuf);
var info = script.getMultiSigInfo();
info.nsigs.should.equal(3);
info.npubkeys.should.equal(5);
info.pubkeys.length.should.equal(info.npubkeys);
info.pubkeys.map(function(pubkey) {
testPubKeysHex.indexOf(pubkey.toString('hex')).should.not.equal(-1);
});
});
});
describe('prependOp0', function() {
it('should prepend the script with OP_0', function() {
var scriptHex = '483045022002da7fae9b98615115b7e9a4f1d9efd581463b670f91ec6404a14cb6fc9c4531022100ff449d72ba4e72deb4317267e2d38cec9fd2f58a9afa39c9f5e35f5678694ff50100004c695221033e4cc6b6ee8d8ce3335fed6d4917b2bbbac0f5743b2ced101ba036f95c51e59421023147410ce15e0a31c2bb970cdf01517266dc2c9182f5938636ed363cfd4cc3ae210342a3c8a4b20c7a122a011a07063df04e4c5ad520a1302a2a66e174fd9b0d4ea453ae';
@ -116,14 +137,14 @@ describe('Script', function() {
var pubs = testPubKeysHex.map( function(hex) {
return new Buffer(hex,'hex');
});
var s1 = Script.createMultisig(3,pubs, {noSorting: true});
// 3 of 5 multisig, unsorted
// test case generated with: bitcoind createmultisig 3 '["02c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae0", "02b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758", "0266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea","02ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e70", "02c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af793"]'
var s1 = Script.createMultisig(3,pubs, {noSorting: true});
s1.getBuffer().toString('hex').should.equal('532102c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae02102b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758210266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea2102ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e702102c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af79355ae');
var s2 = Script.createMultisig(3,pubs);
// 3 of 5 multisig, sorted
// test case generated with: bitcoind createmultisig 3 '["0266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea", "02b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f0758", "02c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae0", "02c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af793", "02ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e70"]'
var s2 = Script.createMultisig(3,pubs);
s2.getBuffer().toString('hex').should.equal('53210266dd7664e65958f3cc67bf92ad6243bc495df5ab56691719263977104b635bea2102b937d54b550a3afdc2819772822d25869495f9e588b56a0205617d80514f07582102c525d65d18be8fb36ab50a21bee02ac9fdc2c176fa18791ac664ea4b95572ae02102c8f63ad4822ef360b5c300f08488fa0fa24af2b2bebb6d6b602ca938ee5af7932102ee91377073b04d1d9d19597b81a7be3db6554bd7d16151cb5599a6107a589e7055ae');
});