123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- '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, options) {
- return this.ec.verify(msg, signature, this, undefined, options);
- };
- KeyPair.prototype.inspect = function inspect() {
- return '<Key priv: ' + (this.priv && this.priv.toString(16, 2)) +
- ' pub: ' + (this.pub && this.pub.inspect()) + ' >';
- };
|