bitcoinjs-lib/src/eckey.js

189 lines
5.7 KiB
JavaScript
Raw Normal View History

var Address = require('./address')
var assert = require('assert')
var convert = require('./convert')
var base58 = require('./base58')
var BigInteger = require('./jsbn/jsbn')
var ecdsa = require('./ecdsa')
var ECPointFp = require('./jsbn/ec').ECPointFp
var sec = require('./jsbn/sec')
var Network = require('./network')
var util = require('./util')
var ecparams = sec("secp256k1")
// input can be nothing, array of bytes, hex string, or base58 string
2014-03-25 02:44:43 +11:00
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)
}
2014-03-28 19:57:06 +11:00
ECKey.prototype.import = function (input, compressed) {
function has(li, v) { return li.indexOf(v) >= 0 }
function fromBin(x) { return BigInteger.fromByteArrayUnsigned(x) }
this.priv =
input instanceof ECKey ? input.priv
: input instanceof BigInteger ? input.mod(ecparams.getN())
: Array.isArray(input) ? fromBin(input.slice(0, 32))
: typeof input != "string" ? null
: input.length == 44 ? fromBin(convert.base64ToBytes(input))
: input.length == 51 && input[0] == '5' ? fromBin(base58.checkDecode(input))
: input.length == 51 && input[0] == '9' ? fromBin(base58.checkDecode(input))
: input.length == 52 && has('LK', input[0]) ? fromBin(base58.checkDecode(input).slice(0, 32))
: input.length == 52 && input[0] == 'c' ? fromBin(base58.checkDecode(input).slice(0, 32))
: has([64,65],input.length) ? fromBin(convert.hexToBytes(input.slice(0, 64)))
: null
assert(this.priv !== null)
this.compressed =
compressed !== undefined ? compressed
: input instanceof ECKey ? input.compressed
: 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)
}
ECKey.prototype.getPub = function(compressed) {
2014-03-31 11:47:47 +08:00
if (compressed === undefined) compressed = this.compressed
return ECPubKey(ecparams.getG().multiply(this.priv), compressed)
}
ECKey.prototype.toBin = function() {
2014-03-31 11:47:47 +08:00
return convert.bytesToString(this.toBytes())
}
2014-03-22 18:17:54 +11:00
ECKey.version_bytes = {
0: 128,
111: 239
}
2014-03-22 18:17:54 +11:00
ECKey.prototype.toWif = function(version) {
2014-03-31 11:47:47 +08:00
version = version || Network.mainnet.addressVersion
2014-03-22 18:17:54 +11:00
2014-03-31 11:47:47 +08:00
return base58.checkEncode(this.toBytes(), ECKey.version_bytes[version])
2014-03-22 18:17:54 +11:00
}
ECKey.prototype.toHex = function() {
2014-03-31 11:47:47 +08:00
return convert.bytesToHex(this.toBytes())
}
ECKey.prototype.toBytes = function() {
2014-03-31 11:47:47 +08:00
var bytes = this.priv.toByteArrayUnsigned()
if (this.compressed) bytes.push(1)
return bytes
2013-11-18 23:47:56 -05:00
}
ECKey.prototype.toBase64 = function() {
2014-03-31 11:47:47 +08:00
return convert.bytesToBase64(this.toBytes())
}
ECKey.prototype.toString = ECKey.prototype.toHex
2014-03-22 18:17:54 +11:00
ECKey.prototype.getAddress = function(version) {
2014-03-31 11:47:47 +08:00
return this.getPub().getAddress(version)
}
ECKey.prototype.add = function(key) {
2014-03-31 11:47:47 +08:00
return ECKey(this.priv.add(ECKey(key).priv), this.compressed)
}
ECKey.prototype.multiply = function(key) {
2014-03-31 11:47:47 +08:00
return ECKey(this.priv.multiply(ECKey(key).priv), this.compressed)
}
2014-03-25 02:44:43 +11:00
ECKey.prototype.sign = function(hash) {
2014-03-31 11:47:47 +08:00
return ecdsa.sign(hash, this.priv)
2014-03-25 02:44:43 +11:00
}
ECKey.prototype.verify = function(hash, sig) {
return this.getPub().verify(hash, sig)
}
var ECPubKey = function(input, compressed) {
if (!(this instanceof ECPubKey)) {
return new ECPubKey(input, compressed)
}
2014-03-28 19:57:06 +11:00
this.import(input, compressed)
2014-01-08 17:13:26 -05:00
}
ECPubKey.prototype.import = function(input, compressed) {
var decode = function(x) { return ECPointFp.decodeFrom(ecparams.getCurve(), x) }
this.pub =
input instanceof ECPointFp ? input
: 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)
: null
assert(this.pub !== null)
this.compressed =
compressed ? compressed
: input instanceof ECPointFp ? input.compressed
: input instanceof ECPubKey ? input.compressed
: (this.pub[0] < 4)
}
ECPubKey.prototype.add = function(key) {
2014-03-31 11:47:47 +08:00
return ECPubKey(this.pub.add(ECPubKey(key).pub), this.compressed)
}
ECPubKey.prototype.multiply = function(key) {
2014-03-31 11:47:47 +08:00
return ECPubKey(this.pub.multiply(ECKey(key).priv), this.compressed)
}
2014-01-11 13:56:23 +07:00
ECPubKey.prototype.toBytes = function(compressed) {
2014-03-31 11:47:47 +08:00
if (compressed === undefined) compressed = this.compressed
return this.pub.getEncoded(compressed)
}
ECPubKey.prototype.toHex = function(compressed) {
2014-03-31 11:47:47 +08:00
return convert.bytesToHex(this.toBytes(compressed))
}
ECPubKey.prototype.toBin = function(compressed) {
2014-03-31 11:47:47 +08:00
return convert.bytesToString(this.toBytes(compressed))
}
2014-03-22 18:17:54 +11:00
ECPubKey.prototype.toWif = function(version) {
2014-03-31 11:47:47 +08:00
version = version || Network.mainnet.addressVersion
2014-03-22 18:17:54 +11:00
2014-03-31 11:47:47 +08:00
return base58.checkEncode(this.toBytes(), version)
2014-01-16 14:02:21 +07:00
}
ECPubKey.prototype.toString = ECPubKey.prototype.toHex
2014-01-16 14:02:21 +07:00
2014-03-22 18:17:54 +11:00
ECPubKey.prototype.getAddress = function(version) {
2014-03-31 11:47:47 +08:00
version = version || Network.mainnet.addressVersion
2014-03-31 11:47:47 +08:00
return new Address(util.sha256ripe160(this.toBytes()), version)
}
2014-03-25 02:44:43 +11:00
ECPubKey.prototype.verify = function(hash, sig) {
return ecdsa.verify(hash, sig, this.toBytes())
}
2014-03-22 18:17:54 +11:00
module.exports = {
2014-03-24 03:19:39 +08:00
ECKey: ECKey,
ECPubKey: ECPubKey
2014-03-25 02:44:43 +11:00
}