| 'use strict'; |
| |
| var utils = require('../utils'); |
| var assert = utils.assert; |
| var parseBytes = utils.parseBytes; |
| var cachedProperty = utils.cachedProperty; |
| |
| /** |
| * @param {EDDSA} eddsa - instance |
| * @param {Object} params - public/private key parameters |
| * |
| * @param {Array<Byte>} [params.secret] - secret seed bytes |
| * @param {Point} [params.pub] - public key point (aka `A` in eddsa terms) |
| * @param {Array<Byte>} [params.pub] - public key point encoded as bytes |
| * |
| */ |
| function KeyPair(eddsa, params) { |
| this.eddsa = eddsa; |
| this._secret = parseBytes(params.secret); |
| if (eddsa.isPoint(params.pub)) |
| this._pub = params.pub; |
| else |
| this._pubBytes = parseBytes(params.pub); |
| } |
| |
| KeyPair.fromPublic = function fromPublic(eddsa, pub) { |
| if (pub instanceof KeyPair) |
| return pub; |
| return new KeyPair(eddsa, { pub: pub }); |
| }; |
| |
| KeyPair.fromSecret = function fromSecret(eddsa, secret) { |
| if (secret instanceof KeyPair) |
| return secret; |
| return new KeyPair(eddsa, { secret: secret }); |
| }; |
| |
| KeyPair.prototype.secret = function secret() { |
| return this._secret; |
| }; |
| |
| cachedProperty(KeyPair, 'pubBytes', function pubBytes() { |
| return this.eddsa.encodePoint(this.pub()); |
| }); |
| |
| cachedProperty(KeyPair, 'pub', function pub() { |
| if (this._pubBytes) |
| return this.eddsa.decodePoint(this._pubBytes); |
| return this.eddsa.g.mul(this.priv()); |
| }); |
| |
| cachedProperty(KeyPair, 'privBytes', function privBytes() { |
| var eddsa = this.eddsa; |
| var hash = this.hash(); |
| var lastIx = eddsa.encodingLength - 1; |
| |
| var a = hash.slice(0, eddsa.encodingLength); |
| a[0] &= 248; |
| a[lastIx] &= 127; |
| a[lastIx] |= 64; |
| |
| return a; |
| }); |
| |
| cachedProperty(KeyPair, 'priv', function priv() { |
| return this.eddsa.decodeInt(this.privBytes()); |
| }); |
| |
| cachedProperty(KeyPair, 'hash', function hash() { |
| return this.eddsa.hash().update(this.secret()).digest(); |
| }); |
| |
| cachedProperty(KeyPair, 'messagePrefix', function messagePrefix() { |
| return this.hash().slice(this.eddsa.encodingLength); |
| }); |
| |
| KeyPair.prototype.sign = function sign(message) { |
| assert(this._secret, 'KeyPair can only verify'); |
| return this.eddsa.sign(message, this); |
| }; |
| |
| KeyPair.prototype.verify = function verify(message, sig) { |
| return this.eddsa.verify(message, sig, this); |
| }; |
| |
| KeyPair.prototype.getSecret = function getSecret(enc) { |
| assert(this._secret, 'KeyPair is public only'); |
| return utils.encode(this.secret(), enc); |
| }; |
| |
| KeyPair.prototype.getPublic = function getPublic(enc) { |
| return utils.encode(this.pubBytes(), enc); |
| }; |
| |
| module.exports = KeyPair; |