'use strict'; var BN = require('./bn'); var elliptic = require('elliptic'); var ec = elliptic.curves.secp256k1; var ecpoint = ec.curve.point.bind(ec.curve); var p = ec.curve.point(); var bufferUtil = require('../util/buffer'); var Point = function Point(x, y, isRed) { return ecpoint(x, y, isRed); }; Point.prototype = Object.getPrototypeOf(p); Point.fromX = ec.curve.pointFromX.bind(ec.curve); Point.getG = function() { var p = Point(ec.curve.g.getX(), ec.curve.g.getY()); return p; }; Point.getN = function() { return BN(ec.curve.n.toArray()); }; Point.prototype._getX = Point.prototype.getX; Point.prototype.getX = function() { return BN(this._getX().toArray()); }; Point.prototype._getY = Point.prototype.getY; Point.prototype.getY = function() { return BN(this._getY().toArray()); }; //https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf Point.prototype.validate = function() { /* jshint maxcomplexity: 8 */ var p2 = Point.fromX(this.getY().isOdd(), this.getX()); if (p2.y.cmp(this.y) !== 0) { throw new Error('Invalid y value of public key'); } var xValidRange = (this.getX().gt(-1) && this.getX().lt(Point.getN())); var yValidRange = (this.getY().gt(-1) && this.getY().lt(Point.getN())); if (!(xValidRange && yValidRange)) { throw new Error('Point does not lie on the curve'); } if (!(this.mul(Point.getN()).isInfinity())) { throw new Error('Point times N must be infinity'); } return this; }; Point.pointToCompressed = function pointToCompressed(point) { var xbuf = point.getX().toBuffer({size: 32}); var ybuf = point.getY().toBuffer({size: 32}); var prefix; var odd = ybuf[ybuf.length - 1] % 2; if (odd) { prefix = new Buffer([0x03]); } else { prefix = new Buffer([0x02]); } return bufferUtil.concat([prefix, xbuf]); }; module.exports = Point;