npmtest-bitcore (v2017.4.24)

Code coverage report for node-npmtest-bitcore/node_modules/bitcore-lib/lib/crypto/point.js

Statements: 34.69% (17 / 49)      Branches: 0% (0 / 20)      Functions: 0% (0 / 8)      Lines: 34.69% (17 / 49)      Ignored: none     

All files » node-npmtest-bitcore/node_modules/bitcore-lib/lib/crypto/ » point.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147    1 1 1 1 1                           1           1                     1                         1                     1       1               1       1               1                         1                                                               1                           1    
'use strict';
 
var BN = require('./bn');
var BufferUtil = require('../util/buffer');
var ec = require('elliptic').curves.secp256k1;
var ecPoint = ec.curve.point.bind(ec.curve);
var ecPointFromX = ec.curve.pointFromX.bind(ec.curve);
 
/**
 *
 * Instantiate a valid secp256k1 Point from the X and Y coordinates.
 *
 * @param {BN|String} x - The X coordinate
 * @param {BN|String} y - The Y coordinate
 * @link https://github.com/indutny/elliptic
 * @augments elliptic.curve.point
 * @throws {Error} A validation error if exists
 * @returns {Point} An instance of Point
 * @constructor
 */
var Point = function Point(x, y, isRed) {
  var point = ecPoint(x, y, isRed);
  point.validate();
  return point;
};
 
Point.prototype = Object.getPrototypeOf(ec.curve.point());
 
/**
 *
 * Instantiate a valid secp256k1 Point from only the X coordinate
 *
 * @param {boolean} odd - If the Y coordinate is odd
 * @param {BN|String} x - The X coordinate
 * @throws {Error} A validation error if exists
 * @returns {Point} An instance of Point
 */
Point.fromX = function fromX(odd, x){
  var point = ecPointFromX(odd, x);
  point.validate();
  return point;
};
 
/**
 *
 * Will return a secp256k1 ECDSA base point.
 *
 * @link https://en.bitcoin.it/wiki/Secp256k1
 * @returns {Point} An instance of the base point.
 */
Point.getG = function getG() {
  return ec.curve.g;
};
 
/**
 *
 * Will return the max of range of valid private keys as governed by the secp256k1 ECDSA standard.
 *
 * @link https://en.bitcoin.it/wiki/Private_key#Range_of_valid_ECDSA_private_keys
 * @returns {BN} A BN instance of the number of points on the curve
 */
Point.getN = function getN() {
  return new BN(ec.curve.n.toArray());
};
 
Point.prototype._getX = Point.prototype.getX;
 
/**
 *
 * Will return the X coordinate of the Point
 *
 * @returns {BN} A BN instance of the X coordinate
 */
Point.prototype.getX = function getX() {
  return new BN(this._getX().toArray());
};
 
Point.prototype._getY = Point.prototype.getY;
 
/**
 *
 * Will return the Y coordinate of the Point
 *
 * @returns {BN} A BN instance of the Y coordinate
 */
Point.prototype.getY = function getY() {
  return new BN(this._getY().toArray());
};
 
/**
 *
 * Will determine if the point is valid
 *
 * @link https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
 * @param {Point} An instance of Point
 * @throws {Error} A validation error if exists
 * @returns {Point} An instance of the same Point
 */
Point.prototype.validate = function validate() {
 
  if (this.isInfinity()){
    throw new Error('Point cannot be equal to Infinity');
  }
 
  if (this.getX().cmp(BN.Zero) === 0 || this.getY().cmp(BN.Zero) === 0){
    throw new Error('Invalid x,y value for curve, cannot equal 0.');
  }
 
  var p2 = ecPointFromX(this.getY().isOdd(), this.getX());
 
  if (p2.y.cmp(this.y) !== 0) {
    throw new Error('Invalid y value for curve.');
  }
 
  var xValidRange = (this.getX().gt(BN.Minus1) && this.getX().lt(Point.getN()));
  var yValidRange = (this.getY().gt(BN.Minus1) && this.getY().lt(Point.getN()));
 
  if ( !xValidRange || !yValidRange ) {
    throw new Error('Point does not lie on the curve');
  }
 
  //todo: needs test case
  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;