Comprehensive point arithmetic for elliptic curve points including addition, doubling, scalar multiplication, and encoding/decoding. Points are represented in Jacobian coordinates for efficient computation.
Creates an elliptic curve point in Jacobian coordinates.
/**
* Creates an elliptic curve point in Jacobian coordinates
* @param {Curve} curve - The curve this point belongs to
* @param {BigInteger} x - X coordinate in Jacobian representation
* @param {BigInteger} y - Y coordinate in Jacobian representation
* @param {BigInteger} z - Z coordinate in Jacobian representation
*/
function Point(curve, x, y, z);Factory methods for creating points from different coordinate systems.
/**
* Creates point from affine coordinates
* @param {Curve} curve - The curve for this point
* @param {BigInteger} x - X coordinate in affine representation
* @param {BigInteger} y - Y coordinate in affine representation
* @returns {Point} Point in Jacobian coordinates
*/
Point.fromAffine = function(curve, x, y);
/**
* Decodes point from compressed or uncompressed byte format
* @param {Curve} curve - The curve for this point
* @param {Buffer} buffer - Encoded point data
* @returns {Point} Decoded point with compression flag set
*/
Point.decodeFrom = function(curve, buffer);Usage Example:
const ecurve = require('ecurve');
const BigInteger = require('bigi');
const Buffer = require('safe-buffer').Buffer;
const curve = ecurve.getCurveByName('secp256k1');
// Create point from affine coordinates
const x = new BigInteger('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 16);
const y = new BigInteger('483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8', 16);
const point = ecurve.Point.fromAffine(curve, x, y);
// Decode from compressed format
const compressed = Buffer.from('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798', 'hex');
const decodedPoint = ecurve.Point.decodeFrom(curve, compressed);Core elliptic curve point operations.
/**
* Checks if this point equals another point
* @param {Point} other - Point to compare with
* @returns {boolean} True if points are equal
*/
point.equals = function(other);
/**
* Returns the additive inverse of this point
* @returns {Point} Negated point
*/
point.negate = function();
/**
* Adds another point to this point
* @param {Point} b - Point to add
* @returns {Point} Sum of the two points
*/
point.add = function(b);
/**
* Doubles this point (adds point to itself)
* @returns {Point} Point doubled
*/
point.twice = function();Usage Example:
const ecurve = require('ecurve');
const curve = ecurve.getCurveByName('secp256k1');
const point1 = curve.G; // Generator point
const point2 = curve.G.twice(); // 2*G
// Point addition
const sum = point1.add(point2); // G + 2*G = 3*G
// Point negation
const negated = point1.negate(); // -G
// Point equality
console.log(point1.equals(curve.G)); // true
console.log(point1.equals(point2)); // falseEfficient scalar multiplication using Non-Adjacent Form (NAF) algorithm.
/**
* Scalar multiplication using Non-Adjacent Form algorithm
* @param {BigInteger} k - Scalar multiplier
* @returns {Point} Result of k * this
*/
point.multiply = function(k);
/**
* Simultaneous multiplication: this*j + x*k
* @param {BigInteger} j - Scalar for this point
* @param {Point} x - Second point
* @param {BigInteger} k - Scalar for second point
* @returns {Point} Result of this*j + x*k
*/
point.multiplyTwo = function(j, x, k);Usage Example:
const ecurve = require('ecurve');
const BigInteger = require('bigi');
const curve = ecurve.getCurveByName('secp256k1');
const privateKey = new BigInteger('18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725', 16);
// Generate public key via scalar multiplication
const publicKey = curve.G.multiply(privateKey);
// Simultaneous multiplication for signature verification
// Typically used in ECDSA: R = k*G + r*publicKey
const k = new BigInteger('1234567890abcdef', 16);
const r = new BigInteger('fedcba0987654321', 16);
const R = curve.G.multiplyTwo(k, publicKey, r);Convert points to and from byte representations.
/**
* Encodes point to compressed or uncompressed byte format
* @param {boolean} [compressed] - If true, use compressed format. Defaults to point.compressed
* @returns {Buffer} Encoded point data
*/
point.getEncoded = function(compressed);
/**
* Returns string representation of point coordinates
* @returns {string} String representation
*/
point.toString = function();Usage Example:
const ecurve = require('ecurve');
const curve = ecurve.getCurveByName('secp256k1');
const point = curve.G;
// Get compressed encoding (33 bytes)
const compressed = point.getEncoded(true);
console.log(compressed.toString('hex'));
// Output: 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
// Get uncompressed encoding (65 bytes)
const uncompressed = point.getEncoded(false);
console.log(uncompressed.toString('hex'));
// Output: 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798...
// String representation
console.log(point.toString());
// Output: (55066263022277343669578718895168534326250603453777594175500187360389116729240,32670510020758816978083085130507043184471273380659243275938904335757337482424)interface PointProperties {
/** Reference to the curve this point belongs to */
curve: Curve;
/** X coordinate in Jacobian representation */
x: BigInteger;
/** Y coordinate in Jacobian representation */
y: BigInteger;
/** Z coordinate in Jacobian representation */
z: BigInteger;
/** Flag indicating if point should be encoded compressed */
compressed: boolean;
/** Modular inverse of z coordinate (cached getter) */
zInv: BigInteger;
/** X coordinate in affine representation (getter) */
affineX: BigInteger;
/** Y coordinate in affine representation (getter) */
affineY: BigInteger;
}Usage Example:
const ecurve = require('ecurve');
const curve = ecurve.getCurveByName('secp256k1');
const point = curve.G;
// Access Jacobian coordinates
console.log('Jacobian X:', point.x.toString(16));
console.log('Jacobian Y:', point.y.toString(16));
console.log('Jacobian Z:', point.z.toString(16));
// Access affine coordinates (computed on demand)
console.log('Affine X:', point.affineX.toString(16));
console.log('Affine Y:', point.affineY.toString(16));
// Compression flag
point.compressed = true;
console.log('Will encode compressed:', point.compressed);