Fastest 5KB JS implementation of ed25519 EDDSA signatures compliant with RFC8032, FIPS 186-5 & ZIP215
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Complete Edwards curve point arithmetic for advanced cryptographic operations and custom implementations. The Point class provides efficient operations in extended XYZT coordinates for the ed25519 twisted Edwards curve.
The main Point class for edwards curve operations, representing points in XYZT extended coordinates.
/**
* Point in XYZT extended coordinates for efficient elliptic curve operations
* Represents points on the ed25519 twisted Edwards curve: -x² + y² = -1 + dx²y²
*/
class Point {
/** Base/generator point of the ed25519 curve */
static readonly BASE: Point;
/** Zero/identity point of the curve */
static readonly ZERO: Point;
/** Extended coordinate values */
readonly X: bigint;
readonly Y: bigint;
readonly Z: bigint;
readonly T: bigint;
/**
* Create new Point instance with XYZT extended coordinates
* @param X - X coordinate
* @param Y - Y coordinate
* @param Z - Z coordinate
* @param T - T coordinate
*/
constructor(X: bigint, Y: bigint, Z: bigint, T: bigint);
/** Affine x coordinate (computed from X/Z) */
get x(): bigint;
/** Affine y coordinate (computed from Y/Z) */
get y(): bigint;
}Factory methods for creating Point instances from various representations.
/**
* Get curve parameters for ed25519
* @returns Edwards curve parameters including field prime, group order, coefficients
*/
static CURVE(): EdwardsOpts;
/**
* Create point from affine coordinates
* @param p - Affine point with x, y coordinates
* @returns Point in extended coordinates
*/
static fromAffine(p: AffinePoint): Point;
/**
* Create point from 32-byte representation (RFC8032 section 5.1.3)
* @param hex - 32-byte point encoding
* @param zip215 - Enable ZIP215 compliance for non-canonical encodings
* @returns Point instance
*/
static fromBytes(hex: Bytes, zip215?: boolean): Point;
/**
* Create point from hex string representation
* @param hex - Hex-encoded point (64 characters)
* @param zip215 - Enable ZIP215 compliance for non-canonical encodings
* @returns Point instance
*/
static fromHex(hex: string, zip215?: boolean): Point;Usage Examples:
import { Point } from '@noble/ed25519';
// Access curve constants
const basePoint = Point.BASE;
const zeroPoint = Point.ZERO;
const curveParams = Point.CURVE();
// Create from affine coordinates
const affinePoint = Point.fromAffine({ x: 15112221349535400772501151409588531511454012693041857206046113283949847762202n, y: 46316835694926478169428394003475163141307993866256225615783033603165251855960n });
// Create from bytes
const bytes = new Uint8Array(32);
bytes[31] = 0x58; // Set y-coordinate and sign bit
const pointFromBytes = Point.fromBytes(bytes);
// Create from hex
const pointFromHex = Point.fromHex('5866666666666666666666666666666666666666666666666666666666666666');Arithmetic operations and point manipulations.
/**
* Validate that point lies on the curve
* @throws Error if point is not on curve
* @returns This point for chaining
*/
assertValidity(): this;
/**
* Check if two points are equal
* @param other - Point to compare with
* @returns True if points are equal
*/
equals(other: Point): boolean;
/**
* Check if point is the zero/identity point
* @returns True if point is zero
*/
is0(): boolean;
/**
* Negate point by flipping it over the y-coordinate
* @returns Negated point
*/
negate(): Point;
/**
* Point doubling operation
* @returns 2 * this point
*/
double(): Point;
/**
* Point addition
* @param other - Point to add
* @returns this + other
*/
add(other: Point): Point;
/**
* Point subtraction
* @param other - Point to subtract
* @returns this - other
*/
subtract(other: Point): Point;
/**
* Scalar multiplication (primary operation for cryptographic protocols)
* @param n - Scalar multiplier
* @param safe - Use safe multiplication algorithm (default: true)
* @returns n * this point
*/
multiply(n: bigint, safe?: boolean): Point;
/**
* Unsafe scalar multiplication (faster but potentially vulnerable to timing attacks)
* @param scalar - Scalar multiplier
* @returns scalar * this point
*/
multiplyUnsafe(scalar: bigint): Point;Usage Examples:
import { Point } from '@noble/ed25519';
const p1 = Point.BASE;
const p2 = Point.BASE.double();
// Basic operations
const sum = p1.add(p2);
const difference = p2.subtract(p1);
const doubled = p1.double();
const negated = p1.negate();
// Scalar multiplication
const scalar = 12345678901234567890n;
const multiplied = p1.multiply(scalar);
// Fast unsafe multiplication (use with caution)
const fastMultiplied = p1.multiplyUnsafe(scalar);
// Point validation
try {
p1.assertValidity(); // Should not throw for valid points
} catch (error) {
console.log('Invalid point');
}
// Equality check
console.log(p1.equals(Point.BASE)); // true
console.log(Point.ZERO.is0()); // trueMethods for converting between coordinate systems and encodings.
/**
* Convert to affine coordinates
* @returns Affine point with x, y coordinates
*/
toAffine(): AffinePoint;
/**
* Convert to 32-byte representation (RFC8032 section 5.1.2)
* @returns 32-byte point encoding
*/
toBytes(): Bytes;
/**
* Convert to hex string representation
* @returns 64-character hex string
*/
toHex(): string;Specialized operations for cryptographic protocols and curve analysis.
/**
* Clear cofactor by multiplying by cofactor (8 for ed25519)
* @returns Point with cleared cofactor
*/
clearCofactor(): Point;
/**
* Check if point has small order (order divides cofactor)
* @returns True if point has small order
*/
isSmallOrder(): boolean;
/**
* Check if point is torsion-free (order is not divisible by cofactor)
* @returns True if point is torsion-free
*/
isTorsionFree(): boolean;Usage Examples:
import { Point } from '@noble/ed25519';
const point = Point.BASE.multiply(123n);
// Coordinate conversion
const affine = point.toAffine();
console.log(`x: ${affine.x}, y: ${affine.y}`);
const bytes = point.toBytes();
console.log(`Point as bytes: ${bytes.length} bytes`);
const hex = point.toHex();
console.log(`Point as hex: ${hex}`);
// Round-trip conversion
const restored = Point.fromHex(hex);
console.log(point.equals(restored)); // true
// Advanced operations
const clearedCofactor = point.clearCofactor();
const hasSmallOrder = point.isSmallOrder();
const isTorsionFree = point.isTorsionFree();
console.log(`Small order: ${hasSmallOrder}, Torsion-free: ${isTorsionFree}`);Point operations throw errors for invalid inputs or operations:
import { Point } from '@noble/ed25519';
try {
// Invalid hex length
Point.fromHex('invalid');
} catch (error) {
console.log('Invalid hex encoding');
}
try {
// Invalid point that's not on curve
const invalidPoint = Point.fromAffine({ x: 0n, y: 0n });
invalidPoint.assertValidity(); // Will throw
} catch (error) {
console.log('Point not on curve');
}type Bytes = Uint8Array;
type AffinePoint = {
x: bigint;
y: bigint;
};
type EdwardsOpts = Readonly<{
/** Field prime */
p: bigint;
/** Group order */
n: bigint;
/** Cofactor */
h: bigint;
/** Curve parameter a */
a: bigint;
/** Curve parameter d */
d: bigint;
/** Generator x-coordinate */
Gx: bigint;
/** Generator y-coordinate */
Gy: bigint;
}>;