| 'use strict'; | 
|   | 
| var BN = require('bn.js'); | 
| var utils = require('../utils'); | 
| var assert = utils.assert; | 
|   | 
| function KeyPair(ec, options) { | 
|   this.ec = ec; | 
|   this.priv = null; | 
|   this.pub = null; | 
|   | 
|   // KeyPair(ec, { priv: ..., pub: ... }) | 
|   if (options.priv) | 
|     this._importPrivate(options.priv, options.privEnc); | 
|   if (options.pub) | 
|     this._importPublic(options.pub, options.pubEnc); | 
| } | 
| module.exports = KeyPair; | 
|   | 
| KeyPair.fromPublic = function fromPublic(ec, pub, enc) { | 
|   if (pub instanceof KeyPair) | 
|     return pub; | 
|   | 
|   return new KeyPair(ec, { | 
|     pub: pub, | 
|     pubEnc: enc, | 
|   }); | 
| }; | 
|   | 
| KeyPair.fromPrivate = function fromPrivate(ec, priv, enc) { | 
|   if (priv instanceof KeyPair) | 
|     return priv; | 
|   | 
|   return new KeyPair(ec, { | 
|     priv: priv, | 
|     privEnc: enc, | 
|   }); | 
| }; | 
|   | 
| KeyPair.prototype.validate = function validate() { | 
|   var pub = this.getPublic(); | 
|   | 
|   if (pub.isInfinity()) | 
|     return { result: false, reason: 'Invalid public key' }; | 
|   if (!pub.validate()) | 
|     return { result: false, reason: 'Public key is not a point' }; | 
|   if (!pub.mul(this.ec.curve.n).isInfinity()) | 
|     return { result: false, reason: 'Public key * N != O' }; | 
|   | 
|   return { result: true, reason: null }; | 
| }; | 
|   | 
| KeyPair.prototype.getPublic = function getPublic(compact, enc) { | 
|   // compact is optional argument | 
|   if (typeof compact === 'string') { | 
|     enc = compact; | 
|     compact = null; | 
|   } | 
|   | 
|   if (!this.pub) | 
|     this.pub = this.ec.g.mul(this.priv); | 
|   | 
|   if (!enc) | 
|     return this.pub; | 
|   | 
|   return this.pub.encode(enc, compact); | 
| }; | 
|   | 
| KeyPair.prototype.getPrivate = function getPrivate(enc) { | 
|   if (enc === 'hex') | 
|     return this.priv.toString(16, 2); | 
|   else | 
|     return this.priv; | 
| }; | 
|   | 
| KeyPair.prototype._importPrivate = function _importPrivate(key, enc) { | 
|   this.priv = new BN(key, enc || 16); | 
|   | 
|   // Ensure that the priv won't be bigger than n, otherwise we may fail | 
|   // in fixed multiplication method | 
|   this.priv = this.priv.umod(this.ec.curve.n); | 
| }; | 
|   | 
| KeyPair.prototype._importPublic = function _importPublic(key, enc) { | 
|   if (key.x || key.y) { | 
|     // Montgomery points only have an `x` coordinate. | 
|     // Weierstrass/Edwards points on the other hand have both `x` and | 
|     // `y` coordinates. | 
|     if (this.ec.curve.type === 'mont') { | 
|       assert(key.x, 'Need x coordinate'); | 
|     } else if (this.ec.curve.type === 'short' || | 
|                this.ec.curve.type === 'edwards') { | 
|       assert(key.x && key.y, 'Need both x and y coordinate'); | 
|     } | 
|     this.pub = this.ec.curve.point(key.x, key.y); | 
|     return; | 
|   } | 
|   this.pub = this.ec.curve.decodePoint(key, enc); | 
| }; | 
|   | 
| // ECDH | 
| KeyPair.prototype.derive = function derive(pub) { | 
|   if(!pub.validate()) { | 
|     assert(pub.validate(), 'public point not validated'); | 
|   } | 
|   return pub.mul(this.priv).getX(); | 
| }; | 
|   | 
| // ECDSA | 
| KeyPair.prototype.sign = function sign(msg, enc, options) { | 
|   return this.ec.sign(msg, this, enc, options); | 
| }; | 
|   | 
| KeyPair.prototype.verify = function verify(msg, signature) { | 
|   return this.ec.verify(msg, signature, this); | 
| }; | 
|   | 
| KeyPair.prototype.inspect = function inspect() { | 
|   return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) + | 
|          ' pub: ' + (this.pub && this.pub.inspect()) + ' >'; | 
| }; |