var BigInteger = require('./jsbn/jsbn'); var sec = require('./jsbn/sec'); var base58 = require('./base58'); var Crypto = require('./crypto-js/crypto'); var util = require('./util'); var conv = require('./convert'); var Address = require('./address'); var ecdsa = require('./ecdsa'); var ECPointFp = require('./jsbn/ec').ECPointFp; var ecparams = sec("secp256k1"); // input can be nothing, array of bytes, hex string, or base58 string var ECKey = function (input) { if (!(this instanceof ECKey)) { return new ECKey(input); } this.compressed = !!ECKey.compressByDefault; if (!input) { // Generate new key var n = ecparams.getN(); this.priv = ecdsa.getBigRandom(n); } else this.import(input) }; /** * Whether public keys should be returned compressed by default. */ ECKey.compressByDefault = false; /** * Set whether the public key should be returned compressed or not. */ ECKey.prototype.setCompressed = function (v) { this.compressed = !!v; }; /** * Return public key in DER encoding. */ ECKey.prototype.getPub = function () { return this.getPubPoint().getEncoded(this.compressed); }; /** * Return public point as ECPoint object. */ ECKey.prototype.getPubPoint = function () { if (!this.pub) this.pub = ecparams.getG().multiply(this.priv); return this.pub; }; /** * Get the pubKeyHash for this key. * * This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as * a byte array. */ ECKey.prototype.getPubKeyHash = function () { if (this.pubKeyHash) return this.pubKeyHash; return this.pubKeyHash = util.sha256ripe160(this.getPub()); }; ECKey.prototype.getBitcoinAddress = function (version) { var hash = this.getPubKeyHash(); var addr = new Address(hash,version); return addr; }; ECKey.prototype.setPub = function (pub) { this.pub = ECPointFp.decodeFrom(ecparams.getCurve(), pub); this.compressed = (pub[0] < 4) return this }; ECKey.prototype.export = function (format) { var bytes = this.priv.toByteArrayUnsigned(); if (this.compressed) bytes.push(1) return format === "base58" ? base58.checkEncode(bytes,128) : format === "bin" ? conv.bytesToString(bytes) : format === "bytes" ? bytes : format === "hex" ? conv.bytesToHex(bytes) : bytes }; ECKey.prototype.getExportedPrivateKey = ECKey.prototype.export; ECKey.prototype.toString = function (format) { return ''+this.export(format) } ECKey.prototype.sign = function (hash) { return ecdsa.sign(hash, this.priv); }; ECKey.prototype.verify = function (hash, sig) { return ecdsa.verify(hash, sig, this.getPub()); }; /** * Parse an exported private key contained in a string. */ ECKey.prototype.import = function (input) { if (input instanceof ECKey) { this.priv = input.priv; this.compressed = input.compressed; } else if (input instanceof BigInteger) { // Input is a private key value this.priv = input; this.compressed = ECKey.compressByDefault; } else if (util.isArray(input)) { // Prepend zero byte to prevent interpretation as negative integer this.priv = BigInteger.fromByteArrayUnsigned(input.slice(0,32)); this.compressed = (input.length == 33); } else if ("string" == typeof input) { if (input.length == 51 && input[0] == '5') { // Base58 encoded private key this.priv = BigInteger.fromByteArrayUnsigned(base58.checkDecode(input)); this.compressed = false; } else if (input.length == 52 && (input[0] === 'K' || input[0] === 'L')) { // Base58 encoded private key this.priv = BigInteger.fromByteArrayUnsigned(base58.checkDecode(input)); this.compressed = true; } else if (input.length >= 64) { // hex string? this.priv = BigInteger.fromByteArrayUnsigned(conv.hexToBytes(input.slice(0,64))); this.compressed = (input.length == 66) } } }; module.exports = ECKey;