bitcoinjs-lib/src/ecpair.js

110 lines
2.8 KiB
JavaScript
Raw Normal View History

2018-06-25 08:24:37 +02:00
const ecc = require('tiny-secp256k1')
const randomBytes = require('randombytes')
const typeforce = require('typeforce')
const types = require('./types')
const wif = require('wif')
2014-10-17 04:31:01 +02:00
2018-06-25 08:24:37 +02:00
const NETWORKS = require('./networks')
2014-10-17 04:31:01 +02:00
// TODO: why is the function name toJSON weird?
function isPoint (x) { return ecc.isPoint(x) }
2018-06-25 08:24:37 +02:00
const isOptions = typeforce.maybe(typeforce.compile({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
}))
2015-08-19 07:12:55 +02:00
2014-10-17 04:31:01 +02:00
function ECPair (d, Q, options) {
2015-08-19 07:12:55 +02:00
options = options || {}
2014-10-17 04:31:01 +02:00
this.compressed = options.compressed === undefined ? true : options.compressed
this.network = options.network || NETWORKS.bitcoin
2014-10-17 04:31:01 +02:00
this.__d = d || null
this.__Q = null
if (Q) this.__Q = ecc.pointCompress(Q, this.compressed)
}
2015-08-11 09:01:47 +02:00
Object.defineProperty(ECPair.prototype, 'privateKey', {
enumerable: false,
get: function () { return this.__d }
})
2014-10-17 04:31:01 +02:00
Object.defineProperty(ECPair.prototype, 'publicKey', { get: function () {
if (!this.__Q) this.__Q = ecc.pointFromScalar(this.__d, this.compressed)
return this.__Q
}})
2015-03-19 03:25:41 +01:00
ECPair.prototype.toWIF = function () {
if (!this.__d) throw new Error('Missing private key')
return wif.encode(this.network.wif, this.__d, this.compressed)
}
2015-03-19 03:25:41 +01:00
ECPair.prototype.sign = function (hash) {
if (!this.__d) throw new Error('Missing private key')
return ecc.sign(hash, this.__d)
}
2014-10-17 04:31:01 +02:00
ECPair.prototype.verify = function (hash, signature) {
return ecc.verify(hash, this.publicKey, signature)
2014-10-17 04:31:01 +02:00
}
function fromPrivateKey (buffer, options) {
typeforce(types.Buffer256bit, buffer)
if (!ecc.isPrivate(buffer)) throw new TypeError('Private key not in range [1, n)')
typeforce(isOptions, options)
return new ECPair(buffer, null, options)
}
function fromPublicKey (buffer, options) {
typeforce(isPoint, buffer)
typeforce(isOptions, options)
return new ECPair(null, buffer, options)
}
function fromWIF (string, network) {
const decoded = wif.decode(string)
const version = decoded.version
2014-10-17 04:31:01 +02:00
// list of networks?
if (types.Array(network)) {
network = network.filter(function (x) {
return version === x.wif
2016-02-24 11:08:40 +01:00
}).pop()
if (!network) throw new Error('Unknown network version')
// otherwise, assume a network object (or default to bitcoin)
} else {
network = network || NETWORKS.bitcoin
if (version !== network.wif) throw new Error('Invalid network version')
2015-07-28 08:42:57 +02:00
}
return fromPrivateKey(decoded.privateKey, {
compressed: decoded.compressed,
2014-10-17 04:31:01 +02:00
network: network
})
}
function makeRandom (options) {
typeforce(isOptions, options)
2014-10-17 04:31:01 +02:00
options = options || {}
const rng = options.rng || randomBytes
2014-10-17 04:31:01 +02:00
let d
2015-08-21 08:46:18 +02:00
do {
d = rng(32)
typeforce(types.Buffer256bit, d)
} while (!ecc.isPrivate(d))
2014-10-17 04:31:01 +02:00
return fromPrivateKey(d, options)
2015-09-21 09:37:21 +02:00
}
module.exports = {
makeRandom,
fromPrivateKey,
fromPublicKey,
fromWIF
2014-10-17 04:31:01 +02:00
}