Browse Source

Merge pull request #139 from dcousens/eckeystrict

Migrates ECKey to stricter API
hk-custom-address
Wei Lu 11 years ago
parent
commit
06cd6a698b
  1. 6
      README.md
  2. 222
      src/eckey.js
  3. 30
      src/hdwallet.js
  4. 7
      src/message.js
  5. 7
      src/script.js
  6. 10
      src/transaction.js
  7. 2
      test/ec.js
  8. 12
      test/ecdsa.js
  9. 87
      test/eckey.js
  10. 28
      test/hdwallet.js
  11. 17
      test/message.js
  12. 8
      test/transaction.js

6
README.md

@ -49,14 +49,14 @@ These examples assume you are running bitcoinjs-lib in the browser.
```javascript ```javascript
key = new Bitcoin.ECKey() key = Bitcoin.ECKey.makeRandom()
// Print your private key (a hex string) // Print your private key (a hex string)
console.log(key.toString()) console.log(key.toString())
// => 8c112cf628362ecf4d482f68af2dbb50c8a2cb90d226215de925417aa9336a48 // => 8c112cf628362ecf4d482f68af2dbb50c8a2cb90d226215de925417aa9336a48
// Print your public key (defaults to a Bitcoin address) // Print your public key (defaults to a Bitcoin address)
console.log(key.getPub().getAddress()) console.log(key.pub.getAddress())
// => 14bZ7YWde4KdRb5YN7GYkToz3EHVCvRxkF // => 14bZ7YWde4KdRb5YN7GYkToz3EHVCvRxkF
``` ```
@ -72,7 +72,7 @@ tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31",
tx.addOutput("1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK", 15000) tx.addOutput("1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK", 15000)
// Initialize a private key using hex // Initialize a private key using hex
key = new Bitcoin.ECKey("8c112cf628362ecf4d482f68af2dbb50c8a2cb90d226215de925417aa9336a48") key = Bitcoin.ECKey.fromHex("8c112cf628362ecf4d482f68af2dbb50c8a2cb90d226215de925417aa9336a48")
// Sign the first input with the new key // Sign the first input with the new key
tx.sign(0, key) tx.sign(0, key)

222
src/eckey.js

@ -1,191 +1,135 @@
var Address = require('./address')
var assert = require('assert') var assert = require('assert')
var base58check = require('./base58check') var base58check = require('./base58check')
var BigInteger = require('./jsbn/jsbn')
var convert = require('./convert')
var crypto = require('./crypto')
var ecdsa = require('./ecdsa') var ecdsa = require('./ecdsa')
var ECPointFp = require('./jsbn/ec').ECPointFp var network = require('./network')
var sec = require('./jsbn/sec') var secureRandom = require('secure-random')
var Network = require('./network')
var ecparams = sec("secp256k1")
// input can be nothing, array of bytes, hex string, or base58 string
var ECKey = function (input, compressed) {
if (!(this instanceof ECKey)) { return new ECKey(input, compressed) }
if (!input) {
// Generate new key
var n = ecparams.getN()
this.priv = ecdsa.getBigRandom(n)
this.compressed = compressed || false
}
else this.import(input,compressed)
}
ECKey.prototype.import = function (input, compressed) { var Address = require('./address')
function has(li, v) { return li.indexOf(v) >= 0 } var crypto = require('./crypto')
function fromBin(x) { return BigInteger.fromByteArrayUnsigned(x) }
this.priv = var sec = require('./jsbn/sec')
input instanceof ECKey ? input.priv var ecparams = sec('secp256k1')
: input instanceof BigInteger ? input.mod(ecparams.getN())
: Array.isArray(input) ? fromBin(input.slice(0, 32))
: Buffer.isBuffer(input) ? fromBin(input.slice(0, 32))
: typeof input != "string" ? null
: input.length == 44 ? fromBin(convert.base64ToBytes(input))
: input.length == 51 && input[0] == '5' ? fromBin(base58check.decode(input).payload)
: input.length == 51 && input[0] == '9' ? fromBin(base58check.decode(input).payload)
: input.length == 52 && has('LK', input[0]) ? fromBin(base58check.decode(input).payload.slice(0, 32))
: input.length == 52 && input[0] == 'c' ? fromBin(base58check.decode(input).payload.slice(0, 32))
: has([64,65],input.length) ? fromBin(convert.hexToBytes(input.slice(0, 64)))
: null
assert(this.priv !== null) var BigInteger = require('./jsbn/jsbn')
var ECPointFp = require('./jsbn/ec').ECPointFp
this.compressed = function ECKey(D, compressed) {
compressed !== undefined ? compressed assert(D.compareTo(BigInteger.ZERO) > 0, 'Private key must be greater than 0')
: input instanceof ECKey ? input.compressed assert(D.compareTo(ecparams.getN()) < 0, 'Private key must be less than the curve order')
: input instanceof BigInteger ? false
: Array.isArray(input) ? false
: typeof input != "string" ? null
: input.length == 44 ? false
: input.length == 51 && input[0] == '5' ? false
: input.length == 51 && input[0] == '9' ? false
: input.length == 52 && has('LK', input[0]) ? true
: input.length == 52 && input[0] == 'c' ? true
: input.length == 64 ? false
: input.length == 65 ? true
: null
assert(this.compressed !== null) var Q = ecparams.getG().multiply(D)
}
ECKey.prototype.getPub = function(compressed) { this.D = D
if (compressed === undefined) compressed = this.compressed this.pub = new ECPubKey(Q, compressed)
return ECPubKey(ecparams.getG().multiply(this.priv), compressed)
} }
ECKey.prototype.toBin = function() { // Static constructors
return convert.bytesToString(this.toBytes()) ECKey.fromBuffer = function(buffer, compressed) {
} assert(Buffer.isBuffer(buffer), 'First argument must be a Buffer')
assert.strictEqual(buffer.length, 32, 'Invalid buffer length')
ECKey.version_bytes = { var D = BigInteger.fromByteArrayUnsigned(buffer)
0: 128, return new ECKey(D, compressed)
111: 239
} }
ECKey.fromHex = function(hex, compressed) {
ECKey.prototype.toWif = function(version) { return ECKey.fromBuffer(new Buffer(hex, 'hex'), compressed)
version = version || Network.bitcoin.pubKeyHash
return base58check.encode(this.toBytes(), ECKey.version_bytes[version])
} }
ECKey.prototype.toHex = function() { ECKey.fromWIF = function(string) {
return convert.bytesToHex(this.toBytes()) var decode = base58check.decode(string)
}
ECKey.prototype.toBytes = function() { var payload = decode.payload
var bytes = this.priv.toByteArrayUnsigned() if (payload.length === 33) {
assert.strictEqual(payload[32], 0x01, 'Invalid WIF string')
// ensure 32 bytes return ECKey.fromBuffer(payload.slice(0, 32), true)
while (bytes.length < 32) bytes.unshift(0) }
if (this.compressed) bytes.push(1) return ECKey.fromBuffer(payload, false)
return bytes
} }
ECKey.prototype.toBase64 = function() { ECKey.makeRandom = function(compressed, rng) {
return convert.bytesToBase64(this.toBytes()) rng = rng || secureRandom
}
ECKey.prototype.toString = ECKey.prototype.toHex var buffer = new Buffer(rng(32))
var D = BigInteger.fromByteArrayUnsigned(buffer)
D = D.mod(ecparams.getN())
ECKey.prototype.getAddress = function(version) { return new ECKey(D, compressed)
return this.getPub().getAddress(version)
} }
ECKey.prototype.add = function(key) { // Operations
return ECKey(this.priv.add(ECKey(key).priv), this.compressed) ECKey.prototype.sign = function(hash) {
return ecdsa.sign(hash, this.D)
} }
ECKey.prototype.multiply = function(key) { // Export functions
return ECKey(this.priv.multiply(ECKey(key).priv), this.compressed) ECKey.prototype.toBuffer = function() {
} var buffer = new Buffer(this.D.toByteArrayUnsigned())
ECKey.prototype.sign = function(hash) { // pad out to atleast 32 bytes
return ecdsa.sign(hash, this.priv) var padded = new Buffer(32 - buffer.length)
} padded.fill(0)
ECKey.prototype.verify = function(hash, sig) { return Buffer.concat([padded, buffer])
return this.getPub().verify(hash, sig)
} }
ECKey.prototype.toHex = function() {
return this.toBuffer().toString('hex')
}
ECKey.prototype.toWIF = function(version) {
version = version || network.bitcoin.wif
var ECPubKey = function(input, compressed) { var buffer = this.toBuffer()
if (!(this instanceof ECPubKey)) { if (this.pub.compressed) {
return new ECPubKey(input, compressed) buffer = Buffer.concat([buffer, new Buffer([0x01])])
} }
this.import(input, compressed) return base58check.encode(buffer, version)
} }
ECPubKey.prototype.import = function(input, compressed) { //////////////////////////////////////////////////////
var decode = function(x) { return ECPointFp.decodeFrom(ecparams.getCurve(), x) }
this.pub = function ECPubKey(Q, compressed) {
input instanceof ECPointFp ? input assert(Q instanceof ECPointFp, 'Q must be an ECPointFP')
: input instanceof ECKey ? ecparams.getG().multiply(input.priv)
: input instanceof ECPubKey ? input.pub
: typeof input == "string" ? decode(convert.hexToBytes(input))
: Array.isArray(input) ? decode(input)
: Buffer.isBuffer(input) ? decode(input)
: null
assert(this.pub !== null) if (compressed == undefined) compressed = true
assert.strictEqual(typeof compressed, 'boolean', 'Invalid compression flag')
this.compressed = this.compressed = compressed
compressed ? compressed this.Q = Q
: input instanceof ECPointFp ? input.compressed
: input instanceof ECPubKey ? input.compressed
: (this.pub[0] < 4)
} }
ECPubKey.prototype.add = function(key) { // Static constructors
return ECPubKey(this.pub.add(ECPubKey(key).pub), this.compressed) ECPubKey.fromBuffer = function(buffer) {
} var type = buffer.readUInt8(0)
assert(type >= 0x02 || type <= 0x04, 'Invalid public key')
ECPubKey.prototype.multiply = function(key) { var compressed = (type !== 0x04)
return ECPubKey(this.pub.multiply(ECKey(key).priv), this.compressed) assert.strictEqual(buffer.length, compressed ? 33 : 65, 'Invalid public key')
}
ECPubKey.prototype.toBytes = function(compressed) { var Q = ECPointFp.decodeFrom(ecparams.getCurve(), buffer)
if (compressed === undefined) compressed = this.compressed return new ECPubKey(Q, compressed)
return this.pub.getEncoded(compressed)
} }
ECPubKey.fromHex = function(hex) {
ECPubKey.prototype.toHex = function(compressed) { return ECPubKey.fromBuffer(new Buffer(hex, 'hex'))
return convert.bytesToHex(this.toBytes(compressed))
}
ECPubKey.prototype.toBin = function(compressed) {
return convert.bytesToString(this.toBytes(compressed))
} }
ECPubKey.prototype.toWif = function(version) { // Operations
version = version || Network.bitcoin.pubKeyHash ECPubKey.prototype.verify = function(hash, sig) {
return ecdsa.verify(hash, sig, this.Q)
return base58check.encode(this.toBytes(), version)
} }
ECPubKey.prototype.toString = ECPubKey.prototype.toHex
ECPubKey.prototype.getAddress = function(version) { ECPubKey.prototype.getAddress = function(version) {
version = version || Network.bitcoin.pubKeyHash return new Address(crypto.hash160(this.toBuffer()), version)
return new Address(crypto.hash160(this.toBytes()), version)
} }
ECPubKey.prototype.verify = function(hash, sig) { // Export functions
return ecdsa.verify(hash, sig, this.toBytes()) ECPubKey.prototype.toBuffer = function() {
return new Buffer(this.Q.getEncoded(this.compressed))
}
ECPubKey.prototype.toHex = function() {
return this.toBuffer().toString('hex')
} }
module.exports = { module.exports = {

30
src/hdwallet.js

@ -31,8 +31,8 @@ function HDWallet(seed, networkString) {
throw new Error("Unknown network: " + this.network) throw new Error("Unknown network: " + this.network)
} }
this.priv = new ECKey(I.slice(0, 32), true) this.priv = ECKey.fromBuffer(I.slice(0, 32), true)
this.pub = this.priv.getPub() this.pub = this.priv.pub
this.index = 0 this.index = 0
this.depth = 0 this.depth = 0
} }
@ -105,17 +105,17 @@ HDWallet.fromBuffer = function(input) {
// 33 bytes: the public key or private key data (0x02 + X or 0x03 + X for // 33 bytes: the public key or private key data (0x02 + X or 0x03 + X for
// public keys, 0x00 + k for private keys) // public keys, 0x00 + k for private keys)
if (type == 'priv') { if (type == 'priv') {
hd.priv = new ECKey(input.slice(46, 78), true) hd.priv = ECKey.fromBuffer(input.slice(46, 78), true)
hd.pub = hd.priv.getPub() hd.pub = hd.priv.pub
} else { } else {
hd.pub = new ECPubKey(input.slice(45, 78), true) hd.pub = ECPubKey.fromBuffer(input.slice(45, 78), true)
} }
return hd return hd
} }
HDWallet.prototype.getIdentifier = function() { HDWallet.prototype.getIdentifier = function() {
return crypto.hash160(this.pub.toBytes()) return crypto.hash160(this.pub.toBuffer())
} }
HDWallet.prototype.getFingerprint = function() { HDWallet.prototype.getFingerprint = function() {
@ -123,7 +123,7 @@ HDWallet.prototype.getFingerprint = function() {
} }
HDWallet.prototype.getAddress = function() { HDWallet.prototype.getAddress = function() {
return new Address(crypto.hash160(this.pub.toBytes()), this.getKeyVersion()) return this.pub.getAddress(this.getKeyVersion())
} }
HDWallet.prototype.toBuffer = function(priv) { HDWallet.prototype.toBuffer = function(priv) {
@ -155,11 +155,11 @@ HDWallet.prototype.toBuffer = function(priv) {
// 0x00 + k for private keys // 0x00 + k for private keys
buffer.writeUInt8(0, 45) buffer.writeUInt8(0, 45)
new Buffer(this.priv.toBytes()).copy(buffer, 46) this.priv.toBuffer().copy(buffer, 46)
} else { } else {
// X9.62 encoding for public keys // X9.62 encoding for public keys
new Buffer(this.pub.toBytes()).copy(buffer, 45) this.pub.toBuffer().copy(buffer, 45)
} }
return buffer return buffer
@ -190,14 +190,16 @@ HDWallet.prototype.derive = function(i) {
// If 1, private derivation is used: // If 1, private derivation is used:
// let I = HMAC-SHA512(Key = cpar, Data = 0x00 || kpar || i) [Note:] // let I = HMAC-SHA512(Key = cpar, Data = 0x00 || kpar || i) [Note:]
var kPar = this.priv.toBytes().slice(0, 32) var kPar = this.priv.toBuffer().slice(0, 32)
kPar = Array.prototype.slice.call(kPar)
// FIXME: Dislikes buffers // FIXME: Dislikes buffers
I = HmacFromBytesToBytes(SHA512, [0].concat(kPar, iBytes), cPar) I = HmacFromBytesToBytes(SHA512, [0].concat(kPar, iBytes), cPar)
} else { } else {
// If 0, public derivation is used: // If 0, public derivation is used:
// let I = HMAC-SHA512(Key = cpar, Data = χ(kpar*G) || i) // let I = HMAC-SHA512(Key = cpar, Data = χ(kpar*G) || i)
var KPar = this.pub.toBytes() var KPar = this.pub.toBuffer()
KPar = Array.prototype.slice.call(KPar)
// FIXME: Dislikes buffers // FIXME: Dislikes buffers
I = HmacFromBytesToBytes(SHA512, KPar.concat(iBytes), cPar) I = HmacFromBytesToBytes(SHA512, KPar.concat(iBytes), cPar)
@ -217,13 +219,13 @@ HDWallet.prototype.derive = function(i) {
if (this.priv) { if (this.priv) {
// ki = IL + kpar (mod n). // ki = IL + kpar (mod n).
var ki = IL.add(this.priv.priv).mod(ecparams.getN()) var ki = IL.add(this.priv.D).mod(ecparams.getN())
hd.priv = new ECKey(ki, true) hd.priv = new ECKey(ki, true)
hd.pub = hd.priv.getPub() hd.pub = hd.priv.pub
} else { } else {
// Ki = (IL + kpar)*G = IL*G + Kpar // Ki = (IL + kpar)*G = IL*G + Kpar
var Ki = IL.multiply(ecparams.getG()).add(this.pub.pub) var Ki = IL.multiply(ecparams.getG()).add(this.pub.Q)
hd.pub = new ECPubKey(Ki, true) hd.pub = new ECPubKey(Ki, true)
} }

7
src/message.js

@ -27,10 +27,10 @@ function sign(key, message) {
var hash = magicHash(message) var hash = magicHash(message)
var sig = key.sign(hash) var sig = key.sign(hash)
var obj = ecdsa.parseSig(sig) var obj = ecdsa.parseSig(sig)
var i = ecdsa.calcPubKeyRecoveryParam(key.getPub().pub, obj.r, obj.s, hash) var i = ecdsa.calcPubKeyRecoveryParam(key.pub.Q, obj.r, obj.s, hash)
i += 27 i += 27
if (key.compressed) { if (key.pub.compressed) {
i += 4 i += 4
} }
@ -50,8 +50,7 @@ function verify(address, sig, message) {
sig = ecdsa.parseSigCompact(sig) sig = ecdsa.parseSigCompact(sig)
var pubKey = new ECPubKey(ecdsa.recoverPubKey(sig.r, sig.s, magicHash(message), sig.i)) var pubKey = new ECPubKey(ecdsa.recoverPubKey(sig.r, sig.s, magicHash(message), sig.i))
var isCompressed = !!(sig.i & 4) pubKey.compressed = !!(sig.i & 4)
pubKey.compressed = isCompressed
address = new Address(address) address = new Address(address)
return pubKey.getAddress(address.version).toString() === address.toString() return pubKey.getAddress(address.version).toString() === address.toString()

7
src/script.js

@ -1,10 +1,10 @@
var Opcode = require('./opcode') var Address = require('./address')
var crypto = require('./crypto') var crypto = require('./crypto')
var convert = require('./convert') var convert = require('./convert')
var Address = require('./address')
var network = require('./network') var network = require('./network')
var Opcode = require('./opcode')
var Script = function(data) { function Script(data) {
this.buffer = data || [] this.buffer = data || []
if(!Array.isArray(this.buffer)) { if(!Array.isArray(this.buffer)) {
throw new Error('expect Script to be initialized with Array, but got ' + data) throw new Error('expect Script to be initialized with Array, but got ' + data)
@ -366,6 +366,7 @@ Script.prototype.writeBytes = function(data) {
*/ */
Script.createOutputScript = function(address) { Script.createOutputScript = function(address) {
var script = new Script() var script = new Script()
address = new Address(address) address = new Address(address)
if (address.version == network.bitcoin.scriptHash || if (address.version == network.bitcoin.scriptHash ||
address.version == network.testnet.scriptHash) { address.version == network.testnet.scriptHash) {

10
src/transaction.js

@ -1,5 +1,6 @@
// FIXME: To all ye that enter here, be weary of Buffers, Arrays and Hex interchanging between the outpoints // FIXME: To all ye that enter here, be weary of Buffers, Arrays and Hex interchanging between the outpoints
var assert = require('assert')
var Address = require('./address') var Address = require('./address')
var BigInteger = require('./jsbn/jsbn') var BigInteger = require('./jsbn/jsbn')
var Script = require('./script') var Script = require('./script')
@ -217,7 +218,7 @@ Transaction.prototype.getHash = function ()
var buffer = this.serialize() var buffer = this.serialize()
var hash = crypto.hash256(buffer) var hash = crypto.hash256(buffer)
return Array.prototype.slice.call(hash, 0).reverse() return Array.prototype.slice.call(hash).reverse()
} }
Transaction.prototype.clone = function () Transaction.prototype.clone = function ()
@ -298,10 +299,10 @@ Transaction.deserialize = function(buffer) {
* Signs a standard output at some index with the given key * Signs a standard output at some index with the given key
*/ */
Transaction.prototype.sign = function(index, key, type) { Transaction.prototype.sign = function(index, key, type) {
assert(key instanceof ECKey)
type = type || SIGHASH_ALL type = type || SIGHASH_ALL
key = new ECKey(key)
var pub = key.getPub().toBytes() var pub = key.pub.toBuffer()
var hash160 = crypto.hash160(pub) var hash160 = crypto.hash160(pub)
var script = Script.createOutputScript(new Address(hash160)) var script = Script.createOutputScript(new Address(hash160))
var hash = this.hashTransactionForSignature(script, index, type) var hash = this.hashTransactionForSignature(script, index, type)
@ -315,7 +316,8 @@ Transaction.prototype.signWithKeys = function(keys, outputs, type) {
type = type || SIGHASH_ALL type = type || SIGHASH_ALL
var addrdata = keys.map(function(key) { var addrdata = keys.map(function(key) {
key = new ECKey(key) assert(key instanceof ECKey)
return { return {
key: key, key: key,
address: key.getAddress().toString() address: key.getAddress().toString()

2
test/ec.js

@ -27,7 +27,7 @@ describe('ec', function() {
describe('decodeFrom', function() { describe('decodeFrom', function() {
it('decodes valid ECPoints', function() { it('decodes valid ECPoints', function() {
var p1 = ECKey().getPub().toBytes() var p1 = ECKey.makeRandom(false).pub.toBuffer()
assert.equal(p1.length, 65) assert.equal(p1.length, 65)
var p1_q = ECPointFp.decodeFrom(ecparams.getCurve(), p1) var p1_q = ECPointFp.decodeFrom(ecparams.getCurve(), p1)

12
test/ecdsa.js

@ -25,17 +25,17 @@ describe('ecdsa', function() {
describe('sign/verify', function() { describe('sign/verify', function() {
it('Signing and Verifying', function () { it('Signing and Verifying', function () {
var s1 = new ECKey() var s1 = ECKey.makeRandom()
var sig_a = s1.sign(BigInteger.ZERO) var sig_a = s1.sign(BigInteger.ZERO)
assert.ok(sig_a, 'Sign null') assert.ok(sig_a, 'Sign null')
assert.ok(s1.verify(BigInteger.ZERO, sig_a)) assert.ok(s1.pub.verify(BigInteger.ZERO, sig_a))
var message = new BigInteger(1024, rng).toByteArrayUnsigned() var message = new Buffer(1024) // More or less random :P
var hash = crypto.sha256(message) var hash = crypto.sha256(message)
var sig_b = s1.sign(hash) var sig_b = s1.sign(hash)
assert.ok(sig_b, 'Sign random string') assert.ok(sig_b, 'Sign random string')
assert.ok(s1.verify(hash, sig_b)) assert.ok(s1.pub.verify(hash, sig_b))
var message2 = new Buffer( var message2 = new Buffer(
'12dce2c169986b3346827ffb2305cf393984627f5f9722a1b1368e933c8d' + '12dce2c169986b3346827ffb2305cf393984627f5f9722a1b1368e933c8d' +
@ -60,7 +60,7 @@ describe('ecdsa', function() {
}) })
it('should sign with low S value', function() { it('should sign with low S value', function() {
var priv = new ECKey('ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458') var priv = ECKey.fromHex('ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458')
var message = 'Vires in numeris' var message = 'Vires in numeris'
var signature = priv.sign(message) var signature = priv.sign(message)
var parsed = ecdsa.parseSig(signature) var parsed = ecdsa.parseSig(signature)
@ -69,7 +69,7 @@ describe('ecdsa', function() {
// https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures // https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#low-s-values-in-signatures
assert.ok(parsed.s.compareTo(ecparams.getN().divide(BigInteger.valueOf(2))) <= 0) assert.ok(parsed.s.compareTo(ecparams.getN().divide(BigInteger.valueOf(2))) <= 0)
assert.ok(priv.verify(message, signature)) assert.ok(priv.pub.verify(message, signature))
}) })
}) })
}) })

87
test/eckey.js

@ -1,9 +1,8 @@
var assert = require('assert') var assert = require('assert')
var Address = require('../src/address.js')
var ECKey = require('../src/eckey.js').ECKey var ECKey = require('../src/eckey.js').ECKey
var ECPubKey = require('../src/eckey.js').ECPubKey var ECPubKey = require('../src/eckey.js').ECPubKey
var convert = require('../src/convert.js') var convert = require('../src/convert.js')
var bytesToHex = convert.bytesToHex
var hexToBytes = convert.hexToBytes
var Address = require('../src/address') var Address = require('../src/address')
var Network = require('../src/network') var Network = require('../src/network')
var testnet = Network.testnet.pubKeyHash var testnet = Network.testnet.pubKeyHash
@ -14,20 +13,10 @@ describe('ECKey', function() {
var priv = '18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725' var priv = '18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725'
var pub = '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b235' + var pub = '0450863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b235' +
'22cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6' '22cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba6'
var key = new ECKey(priv) var key = ECKey.fromHex(priv, false)
assert.equal(key.getPub().toHex(), pub) assert.equal(key.pub.toHex(), pub)
assert.equal(key.compressed, false) assert.equal(key.pub.compressed, false)
})
it('parses base64', function() {
var priv = 'VYdB+iv47y5FaUVIPdQInkgATrABeuD1lACUoM4x7tU='
var pub = '042f43c16c08849fed20a35bb7b1947bbf0923c52d613ee13b5c665a1e10d24b2' +
'8be909a70f5f87c1adb79fbcd1b3f17d20aa91c04fc355112dba2ce9b1cbf013b'
var key = new ECKey(priv)
assert.equal(key.getPub().toHex(), pub)
assert.equal(key.compressed, false)
}) })
it('parses WIF', function() { it('parses WIF', function() {
@ -35,32 +24,32 @@ describe('ECKey', function() {
var pub = '044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0' + var pub = '044f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0' +
'f0b704075871aa385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1' 'f0b704075871aa385b6b1b8ead809ca67454d9683fcf2ba03456d6fe2c4abe2b07f0fbdbb2f1c1'
var addr = '1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a' var addr = '1MsHWS1BnwMc3tLE8G35UXsS58fKipzB7a'
var key = new ECKey(priv) var key = ECKey.fromWIF(priv)
assert.equal(key.compressed, false) assert.equal(key.pub.compressed, false)
assert.equal(key.getPub().toHex(), pub) assert.equal(key.pub.toHex(), pub)
assert.equal(key.getAddress().toString(), addr) assert.equal(key.pub.getAddress().toString(), addr)
}) })
it('parses compressed WIF', function() { it('parses compressed WIF', function() {
var priv = 'KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp' var priv = 'KwntMbt59tTsj8xqpqYqRRWufyjGunvhSyeMo3NTYpFYzZbXJ5Hp'
var pub = '034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa' var pub = '034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa'
var addr = '1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9' var addr = '1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9'
var key = new ECKey(priv) var key = ECKey.fromWIF(priv)
assert.equal(key.compressed, true) assert.equal(key.pub.compressed, true)
assert.equal(key.getPub().toHex(), pub) assert.equal(key.pub.toHex(), pub)
assert.equal(key.getAddress().toString(), addr) assert.equal(key.pub.getAddress().toString(), addr)
}) })
it('alternative constructor syntax', function() { it('alternative constructor syntax', function() {
var priv = 'ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458' var priv = 'ca48ec9783cf3ad0dfeff1fc254395a2e403cbbc666477b61b45e31d3b8ab458'
var pub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199' + var pub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199' +
'283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566' '283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566'
var key = ECKey(priv, false) var key = ECKey.fromHex(priv, false)
assert.equal(key.getPub().toHex(), pub) assert.equal(key.pub.toHex(), pub)
assert.equal(key.compressed, false) assert.equal(key.pub.compressed, false)
assert.equal(key.toHex(), priv) assert.equal(key.toHex(), priv)
}) })
}) })
@ -80,7 +69,9 @@ describe('ECKey', function() {
] ]
var pubkeys = cpubkeys.map(function(x) { var pubkeys = cpubkeys.map(function(x) {
return ECPubKey(x).toHex(false) var pk = ECPubKey.fromHex(x)
pk.compressed = false
return pk.toHex()
}) })
it('bitcoin', function() { it('bitcoin', function() {
@ -96,14 +87,13 @@ describe('ECKey', function() {
] ]
for (var i = 0; i < addresses.length; ++i) { for (var i = 0; i < addresses.length; ++i) {
var priv = new ECKey(privkeys[i], false) var pub = ECPubKey.fromHex(pubkeys[i])
var pub = new ECPubKey(pubkeys[i], false) var cpub = ECPubKey.fromHex(cpubkeys[i])
var cpub = new ECPubKey(cpubkeys[i], true) cpub.compressed = true
var addr = addresses[i] var addr = addresses[i]
var caddr = compressedAddresses[i] var caddr = compressedAddresses[i]
assert.equal(priv.getAddress().toString(), addr)
assert.equal(pub.getAddress().toString(), addr) assert.equal(pub.getAddress().toString(), addr)
assert.equal(cpub.getAddress().toString(), caddr) assert.equal(cpub.getAddress().toString(), caddr)
} }
@ -122,14 +112,13 @@ describe('ECKey', function() {
] ]
for (var i = 0; i < addresses.length; ++i) { for (var i = 0; i < addresses.length; ++i) {
var priv = new ECKey(privkeys[i], false) var pub = ECPubKey.fromHex(pubkeys[i])
var pub = new ECPubKey(pubkeys[i], false) var cpub = ECPubKey.fromHex(cpubkeys[i])
var cpub = new ECPubKey(cpubkeys[i], true) cpub.compressed = true
var addr = addresses[i] var addr = addresses[i]
var caddr = compressedAddresses[i] var caddr = compressedAddresses[i]
assert.equal(priv.getAddress().toString(), addr)
assert.equal(pub.getAddress().toString(), addr) assert.equal(pub.getAddress().toString(), addr)
assert.equal(cpub.getAddress().toString(), caddr) assert.equal(cpub.getAddress().toString(), caddr)
} }
@ -142,27 +131,27 @@ describe('ECKey', function() {
var message = 'Vires in numeris' var message = 'Vires in numeris'
it('should verify against the private key', function() { it('should verify against the private key', function() {
var priv = new ECKey(hpriv) var priv = ECKey.fromHex(hpriv)
var signature = priv.sign(message) var signature = priv.sign(message)
assert(priv.verify(message, signature)) assert(priv.pub.verify(message, signature))
}) })
it('should verify against the public key', function() { it('should verify against the public key', function() {
var priv = new ECKey(hpriv) var priv = ECKey.fromHex(hpriv)
var pub = new ECPubKey(hcpub, true) var pub = ECPubKey.fromHex(hcpub, true)
var signature = priv.sign(message) var signature = priv.sign(message)
assert(pub.verify(message, signature)) assert(pub.verify(message, signature))
}) })
it('should not verify against the wrong private key', function() { it('should not verify against the wrong private key', function() {
var priv1 = new ECKey(hpriv) var priv1 = ECKey.fromHex(hpriv)
var priv2 = new ECKey('1111111111111111111111111111111111111111111111111111111111111111') var priv2 = ECKey.fromHex('1111111111111111111111111111111111111111111111111111111111111111')
var signature = priv1.sign(message) var signature = priv1.sign(message)
assert(!priv2.verify(message, signature)) assert(!priv2.pub.verify(message, signature))
}) })
}) })
@ -171,17 +160,17 @@ describe('ECKey', function() {
var hpub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566' var hpub = '044b12d9d7c77db68388b6ff7c89046174c871546436806bcd80d07c28ea81199283fbec990dad6fb98f93f712d50cb874dd717de6a184158d63886dda3090f566'
it('using toHex should support compression', function() { it('using toHex should support compression', function() {
var pub = new ECPubKey(hpub) var pub = ECPubKey.fromHex(hcpub)
assert.equal(pub.toHex(true), hcpub) assert.equal(pub.toHex(), hcpub)
assert.equal(pub.toHex(false), hpub) assert.equal(pub.compressed, true)
}) })
it('using toBytes should support compression', function() { it('using toHex should support uncompressed', function() {
var pub = new ECPubKey(hpub) var pub = ECPubKey.fromHex(hpub)
assert.equal(bytesToHex(pub.toBytes(true)), hcpub) assert.equal(pub.toHex(), hpub)
assert.equal(bytesToHex(pub.toBytes(false)), hpub) assert.equal(pub.compressed, false)
}) })
}) })
}) })

28
test/hdwallet.js

@ -32,7 +32,7 @@ describe('HDWallet', function() {
}) })
describe('constructor & seed deserialization', function() { describe('constructor & seed deserialization', function() {
var expectedPrivateKey = '0fd71c652e847ba7ea7956e3cf3fc0a0985871846b1b2c23b9c6a29a38cee86001' var expectedPrivateKey = '0fd71c652e847ba7ea7956e3cf3fc0a0985871846b1b2c23b9c6a29a38cee860'
var seed = new Buffer([ var seed = new Buffer([
99, 114, 97, 122, 121, 32, 104, 111, 114, 115, 101, 32, 98, 99, 114, 97, 122, 121, 32, 104, 111, 114, 115, 101, 32, 98,
97, 116, 116, 101, 114, 121, 32, 115, 116, 97, 112, 108, 101 97, 116, 116, 101, 114, 121, 32, 115, 116, 97, 112, 108, 101
@ -63,8 +63,8 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getIdentifier()), '3442193e1bb70916e914552172cd4e2dbc9df811') assert.equal(b2h(hd.getIdentifier()), '3442193e1bb70916e914552172cd4e2dbc9df811')
assert.equal(b2h(hd.getFingerprint()), '3442193e') assert.equal(b2h(hd.getFingerprint()), '3442193e')
assert.equal(hd.getAddress().toString(), '15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma') assert.equal(hd.getAddress().toString(), '15mKKb2eos1hWa6tisdPwwDC1a5J1y9nma')
assert.equal(hd.priv.toHex(), 'e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b3501') assert.equal(hd.priv.toHex(), 'e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35')
assert.equal(hd.priv.toWif(), 'L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW') assert.equal(hd.priv.toWIF(), 'L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW')
assert.equal(hd.pub.toHex(), '0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2') assert.equal(hd.pub.toHex(), '0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2')
assert.equal(b2h(hd.chaincode), '873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508') assert.equal(b2h(hd.chaincode), '873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508')
assert.equal(hd.toHex(false), '0488b21e000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2') assert.equal(hd.toHex(false), '0488b21e000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2')
@ -78,7 +78,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), '5c1bd648') assert.equal(b2h(hd.getFingerprint()), '5c1bd648')
assert.equal(hd.getAddress().toString(), '19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh') assert.equal(hd.getAddress().toString(), '19Q2WoS5hSS6T8GjhK8KZLMgmWaq4neXrh')
assert.equal(hd.priv.toHex().slice(0, 64), 'edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea') assert.equal(hd.priv.toHex().slice(0, 64), 'edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea')
assert.equal(hd.priv.toWif(), 'L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT') assert.equal(hd.priv.toWIF(), 'L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT')
assert.equal(hd.pub.toHex(), '035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56') assert.equal(hd.pub.toHex(), '035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56')
assert.equal(b2h(hd.chaincode), '47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141') assert.equal(b2h(hd.chaincode), '47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141')
assert.equal(hd.toHex(false), '0488b21e013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56') assert.equal(hd.toHex(false), '0488b21e013442193e8000000047fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56')
@ -92,7 +92,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), 'bef5a2f9') assert.equal(b2h(hd.getFingerprint()), 'bef5a2f9')
assert.equal(hd.getAddress().toString(), '1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj') assert.equal(hd.getAddress().toString(), '1JQheacLPdM5ySCkrZkV66G2ApAXe1mqLj')
assert.equal(hd.priv.toHex().slice(0, 64), '3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368') assert.equal(hd.priv.toHex().slice(0, 64), '3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368')
assert.equal(hd.priv.toWif(), 'KyFAjQ5rgrKvhXvNMtFB5PCSKUYD1yyPEe3xr3T34TZSUHycXtMM') assert.equal(hd.priv.toWIF(), 'KyFAjQ5rgrKvhXvNMtFB5PCSKUYD1yyPEe3xr3T34TZSUHycXtMM')
assert.equal(hd.pub.toHex(), '03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c') assert.equal(hd.pub.toHex(), '03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c')
assert.equal(b2h(hd.chaincode), '2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19') assert.equal(b2h(hd.chaincode), '2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19')
assert.equal(hd.toHex(false), '0488b21e025c1bd648000000012a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c1903501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c') assert.equal(hd.toHex(false), '0488b21e025c1bd648000000012a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c1903501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c')
@ -106,7 +106,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), 'ee7ab90c') assert.equal(b2h(hd.getFingerprint()), 'ee7ab90c')
assert.equal(hd.getAddress().toString(), '1NjxqbA9aZWnh17q1UW3rB4EPu79wDXj7x') assert.equal(hd.getAddress().toString(), '1NjxqbA9aZWnh17q1UW3rB4EPu79wDXj7x')
assert.equal(hd.priv.toHex().slice(0, 64), 'cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca') assert.equal(hd.priv.toHex().slice(0, 64), 'cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca')
assert.equal(hd.priv.toWif(), 'L43t3od1Gh7Lj55Bzjj1xDAgJDcL7YFo2nEcNaMGiyRZS1CidBVU') assert.equal(hd.priv.toWIF(), 'L43t3od1Gh7Lj55Bzjj1xDAgJDcL7YFo2nEcNaMGiyRZS1CidBVU')
assert.equal(hd.pub.toHex(), '0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2') assert.equal(hd.pub.toHex(), '0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2')
assert.equal(b2h(hd.chaincode), '04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f') assert.equal(b2h(hd.chaincode), '04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f')
assert.equal(hd.toHex(false), '0488b21e03bef5a2f98000000204466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2') assert.equal(hd.toHex(false), '0488b21e03bef5a2f98000000204466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2')
@ -120,7 +120,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), 'd880d7d8') assert.equal(b2h(hd.getFingerprint()), 'd880d7d8')
assert.equal(hd.getAddress().toString(), '1LjmJcdPnDHhNTUgrWyhLGnRDKxQjoxAgt') assert.equal(hd.getAddress().toString(), '1LjmJcdPnDHhNTUgrWyhLGnRDKxQjoxAgt')
assert.equal(hd.priv.toHex().slice(0, 64), '0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4') assert.equal(hd.priv.toHex().slice(0, 64), '0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4')
assert.equal(hd.priv.toWif(), 'KwjQsVuMjbCP2Zmr3VaFaStav7NvevwjvvkqrWd5Qmh1XVnCteBR') assert.equal(hd.priv.toWIF(), 'KwjQsVuMjbCP2Zmr3VaFaStav7NvevwjvvkqrWd5Qmh1XVnCteBR')
assert.equal(hd.pub.toHex(), '02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29') assert.equal(hd.pub.toHex(), '02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29')
assert.equal(b2h(hd.chaincode), 'cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd') assert.equal(b2h(hd.chaincode), 'cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd')
assert.equal(hd.toHex(false), '0488b21e04ee7ab90c00000002cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29') assert.equal(hd.toHex(false), '0488b21e04ee7ab90c00000002cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29')
@ -134,7 +134,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), 'd69aa102') assert.equal(b2h(hd.getFingerprint()), 'd69aa102')
assert.equal(hd.getAddress().toString(), '1LZiqrop2HGR4qrH1ULZPyBpU6AUP49Uam') assert.equal(hd.getAddress().toString(), '1LZiqrop2HGR4qrH1ULZPyBpU6AUP49Uam')
assert.equal(hd.priv.toHex().slice(0, 64), '471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8') assert.equal(hd.priv.toHex().slice(0, 64), '471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8')
assert.equal(hd.priv.toWif(), 'Kybw8izYevo5xMh1TK7aUr7jHFCxXS1zv8p3oqFz3o2zFbhRXHYs') assert.equal(hd.priv.toWIF(), 'Kybw8izYevo5xMh1TK7aUr7jHFCxXS1zv8p3oqFz3o2zFbhRXHYs')
assert.equal(hd.pub.toHex(), '022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011') assert.equal(hd.pub.toHex(), '022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011')
assert.equal(b2h(hd.chaincode), 'c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e') assert.equal(b2h(hd.chaincode), 'c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e')
assert.equal(hd.toHex(false), '0488b21e05d880d7d83b9aca00c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011') assert.equal(hd.toHex(false), '0488b21e05d880d7d83b9aca00c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011')
@ -151,7 +151,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), 'bd16bee5') assert.equal(b2h(hd.getFingerprint()), 'bd16bee5')
assert.equal(hd.getAddress().toString(), '1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg') assert.equal(hd.getAddress().toString(), '1JEoxevbLLG8cVqeoGKQiAwoWbNYSUyYjg')
assert.equal(hd.priv.toHex().slice(0, 64), '4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e') assert.equal(hd.priv.toHex().slice(0, 64), '4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e')
assert.equal(hd.priv.toWif(), 'KyjXhyHF9wTphBkfpxjL8hkDXDUSbE3tKANT94kXSyh6vn6nKaoy') assert.equal(hd.priv.toWIF(), 'KyjXhyHF9wTphBkfpxjL8hkDXDUSbE3tKANT94kXSyh6vn6nKaoy')
assert.equal(hd.pub.toHex(), '03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7') assert.equal(hd.pub.toHex(), '03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7')
assert.equal(b2h(hd.chaincode), '60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689') assert.equal(b2h(hd.chaincode), '60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689')
assert.equal(hd.toHex(false), '0488b21e00000000000000000060499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd968903cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7') assert.equal(hd.toHex(false), '0488b21e00000000000000000060499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd968903cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7')
@ -165,7 +165,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), '5a61ff8e') assert.equal(b2h(hd.getFingerprint()), '5a61ff8e')
assert.equal(hd.getAddress().toString(), '19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ') assert.equal(hd.getAddress().toString(), '19EuDJdgfRkwCmRzbzVBHZWQG9QNWhftbZ')
assert.equal(hd.priv.toHex().slice(0, 64), 'abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e') assert.equal(hd.priv.toHex().slice(0, 64), 'abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e')
assert.equal(hd.priv.toWif(), 'L2ysLrR6KMSAtx7uPqmYpoTeiRzydXBattRXjXz5GDFPrdfPzKbj') assert.equal(hd.priv.toWIF(), 'L2ysLrR6KMSAtx7uPqmYpoTeiRzydXBattRXjXz5GDFPrdfPzKbj')
assert.equal(hd.pub.toHex(), '02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea') assert.equal(hd.pub.toHex(), '02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea')
assert.equal(b2h(hd.chaincode), 'f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c') assert.equal(b2h(hd.chaincode), 'f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c')
assert.equal(hd.toHex(false), '0488b21e01bd16bee500000000f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea') assert.equal(hd.toHex(false), '0488b21e01bd16bee500000000f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea')
@ -179,7 +179,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), 'd8ab4937') assert.equal(b2h(hd.getFingerprint()), 'd8ab4937')
assert.equal(hd.getAddress().toString(), '1Lke9bXGhn5VPrBuXgN12uGUphrttUErmk') assert.equal(hd.getAddress().toString(), '1Lke9bXGhn5VPrBuXgN12uGUphrttUErmk')
assert.equal(hd.priv.toHex().slice(0, 64), '877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93') assert.equal(hd.priv.toHex().slice(0, 64), '877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93')
assert.equal(hd.priv.toWif(), 'L1m5VpbXmMp57P3knskwhoMTLdhAAaXiHvnGLMribbfwzVRpz2Sr') assert.equal(hd.priv.toWIF(), 'L1m5VpbXmMp57P3knskwhoMTLdhAAaXiHvnGLMribbfwzVRpz2Sr')
assert.equal(hd.pub.toHex(), '03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b') assert.equal(hd.pub.toHex(), '03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b')
assert.equal(b2h(hd.chaincode), 'be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9') assert.equal(b2h(hd.chaincode), 'be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9')
assert.equal(hd.toHex(false), '0488b21e025a61ff8effffffffbe17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d903c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b') assert.equal(hd.toHex(false), '0488b21e025a61ff8effffffffbe17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d903c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b')
@ -193,7 +193,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), '78412e3a') assert.equal(b2h(hd.getFingerprint()), '78412e3a')
assert.equal(hd.getAddress().toString(), '1BxrAr2pHpeBheusmd6fHDP2tSLAUa3qsW') assert.equal(hd.getAddress().toString(), '1BxrAr2pHpeBheusmd6fHDP2tSLAUa3qsW')
assert.equal(hd.priv.toHex().slice(0, 64), '704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7') assert.equal(hd.priv.toHex().slice(0, 64), '704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7')
assert.equal(hd.priv.toWif(), 'KzyzXnznxSv249b4KuNkBwowaN3akiNeEHy5FWoPCJpStZbEKXN2') assert.equal(hd.priv.toWIF(), 'KzyzXnznxSv249b4KuNkBwowaN3akiNeEHy5FWoPCJpStZbEKXN2')
assert.equal(hd.pub.toHex(), '03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9') assert.equal(hd.pub.toHex(), '03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9')
assert.equal(b2h(hd.chaincode), 'f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb') assert.equal(b2h(hd.chaincode), 'f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb')
assert.equal(hd.toHex(false), '0488b21e03d8ab493700000001f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9') assert.equal(hd.toHex(false), '0488b21e03d8ab493700000001f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9')
@ -207,7 +207,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), '31a507b8') assert.equal(b2h(hd.getFingerprint()), '31a507b8')
assert.equal(hd.getAddress().toString(), '15XVotxCAV7sRx1PSCkQNsGw3W9jT9A94R') assert.equal(hd.getAddress().toString(), '15XVotxCAV7sRx1PSCkQNsGw3W9jT9A94R')
assert.equal(hd.priv.toHex().slice(0, 64), 'f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d') assert.equal(hd.priv.toHex().slice(0, 64), 'f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d')
assert.equal(hd.priv.toWif(), 'L5KhaMvPYRW1ZoFmRjUtxxPypQ94m6BcDrPhqArhggdaTbbAFJEF') assert.equal(hd.priv.toWIF(), 'L5KhaMvPYRW1ZoFmRjUtxxPypQ94m6BcDrPhqArhggdaTbbAFJEF')
assert.equal(hd.pub.toHex(), '02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0') assert.equal(hd.pub.toHex(), '02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0')
assert.equal(b2h(hd.chaincode), '637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29') assert.equal(b2h(hd.chaincode), '637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29')
assert.equal(hd.toHex(false), '0488b21e0478412e3afffffffe637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e2902d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0') assert.equal(hd.toHex(false), '0488b21e0478412e3afffffffe637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e2902d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0')
@ -221,7 +221,7 @@ describe('HDWallet', function() {
assert.equal(b2h(hd.getFingerprint()), '26132fdb') assert.equal(b2h(hd.getFingerprint()), '26132fdb')
assert.equal(hd.getAddress().toString(), '14UKfRV9ZPUp6ZC9PLhqbRtxdihW9em3xt') assert.equal(hd.getAddress().toString(), '14UKfRV9ZPUp6ZC9PLhqbRtxdihW9em3xt')
assert.equal(hd.priv.toHex().slice(0, 64), 'bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23') assert.equal(hd.priv.toHex().slice(0, 64), 'bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23')
assert.equal(hd.priv.toWif(), 'L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK') assert.equal(hd.priv.toWIF(), 'L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK')
assert.equal(hd.pub.toHex(), '024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c') assert.equal(hd.pub.toHex(), '024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c')
assert.equal(b2h(hd.chaincode), '9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271') assert.equal(b2h(hd.chaincode), '9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271')
assert.equal(hd.toHex(false), '0488b21e0531a507b8000000029452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c') assert.equal(hd.toHex(false), '0488b21e0531a507b8000000029452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c')

17
test/message.js

@ -2,7 +2,6 @@ var assert = require('assert')
var convert = require('../').convert var convert = require('../').convert
var ECKey = require('../src/eckey').ECKey var ECKey = require('../src/eckey').ECKey
var Message = require('../').Message var Message = require('../').Message
var testnet = require('../').network.testnet.pubKeyHash
describe('Message', function() { describe('Message', function() {
var msg var msg
@ -54,14 +53,14 @@ describe('Message', function() {
describe('signing', function() { describe('signing', function() {
describe('using the uncompressed public key', function(){ describe('using the uncompressed public key', function(){
it('gives same signature as a compressed public key', function() { it('gives same signature as a compressed public key', function() {
var key = new ECKey(null) // uncompressed var key = ECKey.makeRandom(false) // uncompressed
var sig = Message.sign(key, msg) var sig = Message.sign(key, msg)
var compressedKey = new ECKey(key, true) // compressed clone var compressedKey = new ECKey(key.D, true) // compressed clone
var csig = Message.sign(compressedKey, msg) // FIXME: bad compression support var csig = Message.sign(compressedKey, msg)
var addr = key.getPub().getAddress() var addr = key.pub.getAddress()
var caddr = compressedKey.getPub().getAddress() var caddr = compressedKey.pub.getAddress()
assert.ok(Message.verify(addr, sig, msg)) assert.ok(Message.verify(addr, sig, msg))
assert.ok(Message.verify(caddr, csig, msg)) assert.ok(Message.verify(caddr, csig, msg))
assert.notDeepEqual(sig.slice(0, 2), csig.slice(0, 2)) // unequal compression flags assert.notDeepEqual(sig.slice(0, 2), csig.slice(0, 2)) // unequal compression flags
@ -71,10 +70,12 @@ describe('Message', function() {
describe('testnet address', function(){ describe('testnet address', function(){
it('works', function(){ it('works', function(){
var key = new ECKey(null) var testnet = require('../').network.testnet
var key = ECKey.makeRandom()
var sig = Message.sign(key, msg) var sig = Message.sign(key, msg)
var addr = key.getAddress(testnet) var addr = key.pub.getAddress(testnet.pubKeyHash)
assert(Message.verify(addr, sig, msg)) assert(Message.verify(addr, sig, msg))
}) })
}) })

8
test/transaction.js

@ -166,10 +166,10 @@ describe('Transaction', function() {
tx.addOutput("15mMHKL96tWAUtqF3tbVf99Z8arcmnJrr3:40000") tx.addOutput("15mMHKL96tWAUtqF3tbVf99Z8arcmnJrr3:40000")
tx.addOutput("1Bu3bhwRmevHLAy1JrRB6AfcxfgDG2vXRd:50000") tx.addOutput("1Bu3bhwRmevHLAy1JrRB6AfcxfgDG2vXRd:50000")
var key = new ECKey('L44f7zxJ5Zw4EK9HZtyAnzCYz2vcZ5wiJf9AuwhJakiV4xVkxBeb') var key = ECKey.fromWIF('L44f7zxJ5Zw4EK9HZtyAnzCYz2vcZ5wiJf9AuwhJakiV4xVkxBeb')
tx.sign(0, key) tx.sign(0, key)
var pub = key.getPub().toBytes() var pub = key.pub.toBuffer()
var script = prevTx.outs[0].script.buffer var script = prevTx.outs[0].script.buffer
var sig = tx.ins[0].script.chunks[0] var sig = tx.ins[0].script.chunks[0]
@ -185,8 +185,8 @@ describe('Transaction', function() {
}) })
it('returns true for valid signature', function(){ it('returns true for valid signature', function(){
var key = new ECKey('L44f7zxJ5Zw4EK9HZtyAnzCYz2vcZ5wiJf9AuwhJakiV4xVkxBeb') var key = ECKey.fromWIF('L44f7zxJ5Zw4EK9HZtyAnzCYz2vcZ5wiJf9AuwhJakiV4xVkxBeb')
var pub = key.getPub().toBytes() var pub = key.pub.toBuffer()
var script = prevTx.outs[0].script.buffer var script = prevTx.outs[0].script.buffer
var sig = validTx.ins[0].script.chunks[0] var sig = validTx.ins[0].script.chunks[0]

Loading…
Cancel
Save