bitcoinjs-lib/src/ecpair.js

132 lines
3.1 KiB
JavaScript
Raw Normal View History

2016-04-27 16:42:25 +10:00
var baddress = require('./address')
2014-10-17 13:31:01 +11:00
var bcrypto = require('./crypto')
var ecdsa = require('./ecdsa')
var randomBytes = require('randombytes')
2015-08-11 17:01:47 +10:00
var typeforce = require('typeforce')
var types = require('./types')
var wif = require('wif')
2014-10-17 13:31:01 +11:00
2015-08-19 15:12:55 +10:00
var NETWORKS = require('./networks')
2014-10-17 13:31:01 +11:00
var BigInteger = require('bigi')
2015-08-25 20:43:32 +10:00
var ecurve = require('ecurve')
var secp256k1 = ecdsa.__curve
2015-08-19 15:12:55 +10:00
2014-10-17 13:31:01 +11:00
function ECPair (d, Q, options) {
2015-08-19 15:12:55 +10:00
if (options) {
typeforce({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
}, options)
}
2014-10-17 13:31:01 +11:00
2015-08-19 15:12:55 +10:00
options = options || {}
2014-10-17 13:31:01 +11:00
if (d) {
2015-08-11 17:01:47 +10:00
if (d.signum() <= 0) throw new Error('Private key must be greater than 0')
2015-08-19 15:12:55 +10:00
if (d.compareTo(secp256k1.n) >= 0) throw new Error('Private key must be less than the curve order')
2015-08-11 17:01:47 +10:00
if (Q) throw new TypeError('Unexpected publicKey parameter')
2014-10-17 13:31:01 +11:00
2015-03-19 13:25:41 +11:00
this.d = d
2014-10-17 13:31:01 +11:00
} else {
2015-08-11 17:01:47 +10:00
typeforce(types.ECPoint, Q)
2015-03-19 13:25:41 +11:00
this.__Q = Q
2014-10-17 13:31:01 +11:00
}
2015-08-11 17:01:47 +10:00
this.compressed = options.compressed === undefined ? true : options.compressed
this.network = options.network || NETWORKS.bitcoin
2014-10-17 13:31:01 +11:00
}
2015-03-19 13:25:41 +11:00
Object.defineProperty(ECPair.prototype, 'Q', {
2015-03-19 13:35:25 +11:00
get: function () {
2015-03-19 13:25:41 +11:00
if (!this.__Q && this.d) {
2015-08-19 15:12:55 +10:00
this.__Q = secp256k1.G.multiply(this.d)
2015-03-19 13:25:41 +11:00
}
return this.__Q
}
})
2014-10-17 13:31:01 +11:00
ECPair.fromPublicKeyBuffer = function (buffer, network) {
2015-08-19 15:12:55 +10:00
var Q = ecurve.Point.decodeFrom(secp256k1, buffer)
2014-10-17 13:31:01 +11:00
return new ECPair(null, Q, {
compressed: Q.compressed,
network: network
})
}
ECPair.fromWIF = function (string, network) {
var decoded = wif.decode(string)
var version = decoded.version
2014-10-17 13:31:01 +11:00
// [network, ...]
if (types.Array(network)) {
network = network.filter(function (network) {
return version === network.wif
2016-02-24 13:08:40 +03:00
}).pop()
if (!network) throw new Error('Unknown network version')
// network
} else {
network = network || NETWORKS.bitcoin
if (version !== network.wif) throw new Error('Invalid network version')
2015-07-28 16:42:57 +10:00
}
2016-02-24 13:08:40 +03:00
var d = BigInteger.fromBuffer(decoded.privateKey)
2014-10-17 13:31:01 +11:00
return new ECPair(d, null, {
compressed: decoded.compressed,
2014-10-17 13:31:01 +11:00
network: network
})
}
ECPair.makeRandom = function (options) {
options = options || {}
var rng = options.rng || randomBytes
2015-08-21 16:46:18 +10:00
var d
do {
var buffer = rng(32)
typeforce(types.Buffer256bit, buffer)
d = BigInteger.fromBuffer(buffer)
2015-09-09 00:35:54 +10:00
} while (d.signum() <= 0 || d.compareTo(secp256k1.n) >= 0)
2014-10-17 13:31:01 +11:00
return new ECPair(d, null, options)
}
ECPair.prototype.getAddress = function () {
2016-04-27 16:42:25 +10:00
return baddress.toBase58Check(bcrypto.hash160(this.getPublicKeyBuffer()), this.getNetwork().pubKeyHash)
2014-10-17 13:31:01 +11:00
}
2015-09-21 17:37:21 +10:00
ECPair.prototype.getNetwork = function () {
return this.network
}
2014-10-17 13:31:01 +11:00
ECPair.prototype.getPublicKeyBuffer = function () {
return this.Q.getEncoded(this.compressed)
}
ECPair.prototype.sign = function (hash) {
2015-08-11 17:03:10 +10:00
if (!this.d) throw new Error('Missing private key')
2014-10-17 13:31:01 +11:00
2015-08-25 20:43:32 +10:00
return ecdsa.sign(hash, this.d)
2014-10-17 13:31:01 +11:00
}
ECPair.prototype.toWIF = function () {
if (!this.d) throw new Error('Missing private key')
return wif.encode(this.network.wif, this.d.toBuffer(32), this.compressed)
}
2014-10-17 13:31:01 +11:00
ECPair.prototype.verify = function (hash, signature) {
2015-08-25 20:43:32 +10:00
return ecdsa.verify(hash, signature, this.Q)
2014-10-17 13:31:01 +11:00
}
module.exports = ECPair