2014-03-29 19:32:57 +11:00
|
|
|
var assert = require('assert')
|
2014-04-04 05:10:12 +11:00
|
|
|
var base58check = require('./base58check')
|
2014-03-29 19:32:57 +11:00
|
|
|
var ecdsa = require('./ecdsa')
|
2014-05-05 13:23:22 +10:00
|
|
|
var networks = require('./networks')
|
2014-04-17 19:08:16 +10:00
|
|
|
var secureRandom = require('secure-random')
|
2013-02-17 00:39:15 -05:00
|
|
|
|
2014-05-13 16:44:29 +10:00
|
|
|
var BigInteger = require('bigi')
|
|
|
|
var ECPubKey = require('./ecpubkey')
|
2013-02-17 00:39:15 -05:00
|
|
|
|
2014-04-22 02:19:30 +10:00
|
|
|
var sec = require('./sec')
|
2014-04-18 06:17:41 +10:00
|
|
|
var ecparams = sec('secp256k1')
|
2014-03-29 19:32:57 +11:00
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
function ECKey(D, compressed) {
|
2014-04-18 06:17:41 +10:00
|
|
|
assert(D.compareTo(BigInteger.ZERO) > 0, 'Private key must be greater than 0')
|
|
|
|
assert(D.compareTo(ecparams.getN()) < 0, 'Private key must be less than the curve order')
|
2014-03-29 19:32:57 +11:00
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
var Q = ecparams.getG().multiply(D)
|
2014-03-29 19:32:57 +11:00
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
this.D = D
|
|
|
|
this.pub = new ECPubKey(Q, compressed)
|
2014-03-29 19:32:57 +11:00
|
|
|
}
|
2013-02-17 00:39:15 -05:00
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
// Static constructors
|
|
|
|
ECKey.fromWIF = function(string) {
|
|
|
|
var decode = base58check.decode(string)
|
|
|
|
var payload = decode.payload
|
2014-05-16 13:46:06 +10:00
|
|
|
var compressed = false
|
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
if (payload.length === 33) {
|
2014-04-18 06:17:41 +10:00
|
|
|
assert.strictEqual(payload[32], 0x01, 'Invalid WIF string')
|
2014-01-11 15:51:31 +07:00
|
|
|
|
2014-05-16 13:46:06 +10:00
|
|
|
payload = payload.slice(0, -1)
|
|
|
|
compressed = true
|
2014-04-17 19:08:16 +10:00
|
|
|
}
|
|
|
|
|
2014-05-16 13:46:06 +10:00
|
|
|
assert.equal(payload.length, 32, 'Invalid WIF payload length')
|
|
|
|
|
2014-05-17 17:06:02 +10:00
|
|
|
var D = BigInteger.fromBuffer(payload)
|
2014-05-16 13:46:06 +10:00
|
|
|
return new ECKey(D, compressed)
|
2014-01-11 15:51:31 +07:00
|
|
|
}
|
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
ECKey.makeRandom = function(compressed, rng) {
|
|
|
|
rng = rng || secureRandom
|
2014-04-09 18:06:50 +10:00
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
var buffer = new Buffer(rng(32))
|
2014-04-22 02:19:30 +10:00
|
|
|
var D = BigInteger.fromBuffer(buffer)
|
2014-04-17 19:08:16 +10:00
|
|
|
D = D.mod(ecparams.getN())
|
2014-04-09 18:06:50 +10:00
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
return new ECKey(D, compressed)
|
2013-11-18 23:47:56 -05:00
|
|
|
}
|
2013-02-17 00:39:15 -05:00
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
// Export functions
|
|
|
|
ECKey.prototype.toWIF = function(version) {
|
2014-05-05 13:23:22 +10:00
|
|
|
version = version || networks.bitcoin.wif
|
2014-03-25 02:44:43 +11:00
|
|
|
|
2014-05-16 13:46:06 +10:00
|
|
|
var buffer = this.D.toBuffer(32)
|
2014-04-17 19:08:16 +10:00
|
|
|
if (this.pub.compressed) {
|
2014-04-18 06:17:41 +10:00
|
|
|
buffer = Buffer.concat([buffer, new Buffer([0x01])])
|
2014-03-28 18:14:46 +11:00
|
|
|
}
|
|
|
|
|
2014-04-17 19:08:16 +10:00
|
|
|
return base58check.encode(buffer, version)
|
2014-01-08 17:13:26 -05:00
|
|
|
}
|
2014-01-04 13:26:03 -05:00
|
|
|
|
2014-05-16 13:46:06 +10:00
|
|
|
// Operations
|
|
|
|
ECKey.prototype.sign = function(hash) {
|
2014-05-17 15:06:52 +10:00
|
|
|
return ecdsa.sign(ecparams, hash, this.D)
|
2014-05-16 13:46:06 +10:00
|
|
|
}
|
|
|
|
|
2014-05-13 16:44:29 +10:00
|
|
|
module.exports = ECKey
|