UNPKG

@bsv/sdk

Version:

BSV Blockchain Software Development Kit

95 lines (82 loc) 2.77 kB
import PrivateKey from './PrivateKey.js' import BigNumber from './BigNumber.js' import Curve from './Curve.js' import Random from './Random.js' import { fromBase58, toBase58 } from './utils.js' export class PointInFiniteField { x: BigNumber y: BigNumber constructor (x: BigNumber, y: BigNumber) { const P = new Curve().p // arithmetic is mod P this.x = x.umod(P) this.y = y.umod(P) } toString (): string { return toBase58(this.x.toArray()) + '.' + toBase58(this.y.toArray()) } static fromString (str: string): PointInFiniteField { const [x, y] = str.split('.') return new PointInFiniteField( new BigNumber(fromBase58(x)), new BigNumber(fromBase58(y)) ) } } /** * Polynomial class * * This class is used to create a polynomial with a given threshold and a private key. * The polynomial is used to create shares of the private key. * * @param key - The private key to split * @param threshold - The number of shares required to recombine the private key * * @example * const key = new PrivateKey() * const threshold = 2 * const polynomial = new Polynomial(key, threshold) * */ export default class Polynomial { readonly points: PointInFiniteField[] readonly threshold: number constructor (points: PointInFiniteField[], threshold?: number) { this.points = points this.threshold = threshold ?? points.length // ✅ Handles undefined safely } static fromPrivateKey (key: PrivateKey, threshold: number): Polynomial { const P = new Curve().p // arithmetic is mod P // The key is the y-intercept of the polynomial where x=0. const points = [ new PointInFiniteField(new BigNumber(0), new BigNumber(key.toArray())) ] // The other values are random for (let i = 1; i < threshold; i++) { const randomX = new BigNumber(Random(32)).umod(P) const randomY = new BigNumber(Random(32)).umod(P) points.push(new PointInFiniteField(randomX, randomY)) } return new Polynomial(points) } // Evaluate the polynomial at x by using Lagrange interpolation valueAt (x: BigNumber): BigNumber { const P = new Curve().p // arithmetic is mod P let y = new BigNumber(0) for (let i = 0; i < this.threshold; i++) { let term = this.points[i].y for (let j = 0; j < this.threshold; j++) { if (i !== j) { const xj = this.points[j].x const xi = this.points[i].x const numerator = x.sub(xj).umod(P) const denominator = xi.sub(xj).umod(P) const denominatorInverse = denominator.invm(P) const fraction = numerator.mul(denominatorInverse).umod(P) term = term.mul(fraction).umod(P) } } y = y.add(term).umod(P) } return y } }