]> git.codecow.com Git - libnemo.git/commitdiff
Fix inner class typings.
authorChris Duncan <chris@zoso.dev>
Sun, 30 Nov 2025 08:13:45 +0000 (00:13 -0800)
committerChris Duncan <chris@zoso.dev>
Sun, 30 Nov 2025 08:13:45 +0000 (00:13 -0800)
src/lib/crypto/secp256k1.ts

index d928ce808211617106b09f21b5ac80190888b41b..65041241e2704d66b48edb0f6ca4cb0fb14ab597 100644 (file)
@@ -14,7 +14,7 @@
 /** Alias to Uint8Array. */
 export type Bytes = Uint8Array
 /** Signature instance, which allows recovering pubkey from it. */
-export type RecoveredSignature = Secp256k1['Signature'] & { recovery: number }
+export type RecoveredSignature = Signature & { recovery: number }
 /** Weierstrass elliptic curve options. */
 export type WeierstrassOpts<T> = Readonly<{
        p: bigint
@@ -83,6 +83,9 @@ type KeygenFn = (seed?: Bytes) => KeysSecPub
 
 type MaybePromise<T> = T | Promise<T>
 
+type Point = InstanceType<typeof Secp256k1.Point>
+type Signature = InstanceType<typeof Secp256k1.Signature>
+
 export class Secp256k1 {
        /**
         * Curve params. secp256k1 is short weierstrass / koblitz curve. Equation is y² == x³ + ax + b.
@@ -258,8 +261,8 @@ export class Secp256k1 {
 
        /** Point in 3d xyz projective coordinates. 3d takes less inversions than 2d. */
        static Point = class {
-               static BASE: Secp256k1['Point']
-               static ZERO: Secp256k1['Point']
+               static BASE: Point
+               static ZERO: Point
                readonly X: bigint
                readonly Y: bigint
                readonly Z: bigint
@@ -273,15 +276,15 @@ export class Secp256k1 {
                        return Secp256k1.secp256k1_CURVE
                }
                /** Create 3d xyz point from 2d xy. (0, 0) => (0, 1, 0), not (0, 0, 1) */
-               static fromAffine (ap: AffinePoint): Secp256k1['Point'] {
+               static fromAffine (ap: AffinePoint): Point {
                        const { x, y } = ap
-                       return x === 0n && y === 0n ? Secp256k1.I : new Secp256k1.Point(x, y, 1n)
+                       return x === 0n && y === 0n ? Secp256k1.I : new this(x, y, 1n)
                }
                /** Convert Uint8Array or hex string to Point. */
-               static fromBytes (bytes: Bytes): Secp256k1['Point'] {
+               static fromBytes (bytes: Bytes): Point {
                        Secp256k1.abytes(bytes)
                        const { publicKey: comp, publicKeyUncompressed: uncomp } = Secp256k1.lengths // e.g. for 32-byte: 33, 65
-                       let p: Secp256k1['Point'] | undefined = undefined
+                       let p: Point | undefined = undefined
                        const length = bytes.length
                        const head = bytes[0]
                        const tail = bytes.subarray(1)
@@ -301,7 +304,7 @@ export class Secp256k1 {
                        // Validate point
                        return p ? p.assertValidity() : Secp256k1.err('bad point: not on curve')
                }
-               static fromHex (hex: string): Secp256k1['Point'] {
+               static fromHex (hex: string): Point {
                        return Secp256k1.Point.fromBytes(Secp256k1.hexToBytes(hex))
                }
                get x (): bigint {
@@ -311,7 +314,7 @@ export class Secp256k1 {
                        return this.toAffine().y
                }
                /** Equality check: compare points P&Q. */
-               equals (other: Secp256k1['Point']): boolean {
+               equals (other: Point): boolean {
                        const { X: X1, Y: Y1, Z: Z1 } = this
                        const { X: X2, Y: Y2, Z: Z2 } = Secp256k1.apoint(other) // checks class equality
                        const X1Z2 = Secp256k1.M(X1 * Z2)
@@ -324,11 +327,11 @@ export class Secp256k1 {
                        return this.equals(Secp256k1.I)
                }
                /** Flip point over y coordinate. */
-               negate (): Secp256k1['Point'] {
+               negate (): Point {
                        return new Secp256k1.Point(this.X, Secp256k1.M(-this.Y), this.Z)
                }
                /** Point doubling: P+P, complete formula. */
-               double (): Secp256k1['Point'] {
+               double (): Point {
                        return this.add(this)
                }
                /**
@@ -337,7 +340,7 @@ export class Secp256k1 {
                 * Cost: `12M + 0S + 3*a + 3*b3 + 23add`.
                 */
                // prettier-ignore
-               add (other: Secp256k1['Point']): Secp256k1['Point'] {
+               add (other: Point): Point {
                        const { X: X1, Y: Y1, Z: Z1 } = this
                        const { X: X2, Y: Y2, Z: Z2 } = Secp256k1.apoint(other)
                        const a = 0n
@@ -362,7 +365,7 @@ export class Secp256k1 {
                        Z3 = Secp256k1.M(Z3 + t0) // step 40
                        return new Secp256k1.Point(X3, Y3, Z3)
                }
-               subtract (other: Secp256k1['Point']): Secp256k1['Point'] {
+               subtract (other: Point): Point {
                        return this.add(Secp256k1.apoint(other).negate())
                }
                /**
@@ -372,7 +375,7 @@ export class Secp256k1 {
                 * @param n scalar by which point is multiplied
                 * @param safe safe mode guards against timing attacks; unsafe mode is faster
                 */
-               multiply (n: bigint, safe = true): Secp256k1['Point'] {
+               multiply (n: bigint, safe = true): Point {
                        if (!safe && n === 0n) return Secp256k1.I
                        Secp256k1.FnIsValidNot0(n)
                        if (n === 1n) return this
@@ -380,7 +383,7 @@ export class Secp256k1 {
                        // init result point & fake point
                        let p = Secp256k1.I
                        let f = Secp256k1.G
-                       for (let d: Secp256k1['Point'] = this; n > 0n; d = d.double(), n >>= 1n) {
+                       for (let d: Point = this; n > 0n; d = d.double(), n >>= 1n) {
                                // if bit is present, add to point
                                // if not present, add to fake, for timing safety
                                if (n & 1n) p = p.add(d)
@@ -388,7 +391,7 @@ export class Secp256k1 {
                        }
                        return p
                }
-               multiplyUnsafe (scalar: bigint): Secp256k1['Point'] {
+               multiplyUnsafe (scalar: bigint): Point {
                        return this.multiply(scalar, false)
                }
                /** Convert point to 2d xy affine point. (X, Y, Z) ∋ (x=X/Z, y=Y/Z) */
@@ -404,7 +407,7 @@ export class Secp256k1 {
                        return { x: Secp256k1.M(x * iz), y: Secp256k1.M(y * iz) }
                }
                /** Checks if the point is valid and on-curve. */
-               assertValidity (): Secp256k1['Point'] {
+               assertValidity (): Point {
                        const { x, y } = this.toAffine() // convert to 2d xy affine point.
                        Secp256k1.FpIsValidNot0(x) // must be in range 1 <= x,y < P
                        Secp256k1.FpIsValidNot0(y)
@@ -425,16 +428,16 @@ export class Secp256k1 {
        }
 
        /** Generator / base point */
-       static G: Secp256k1['Point'] = new this.Point(this.Gx, this.Gy, 1n)
+       static G: Point = new this.Point(this.Gx, this.Gy, 1n)
        /** Identity / zero point */
-       static I: Secp256k1['Point'] = new this.Point(0n, 1n, 0n)
+       static I: Point = new this.Point(0n, 1n, 0n)
        // Static aliases
        static {
                this.Point.BASE = this.G
                this.Point.ZERO = this.I
        }
        /** `Q = u1⋅G + u2⋅R`. Verifies Q is not ZERO. Unsafe: non-CT. */
-       static doubleScalarMulUns = (R: Secp256k1['Point'], u1: bigint, u2: bigint): Secp256k1['Point'] => {
+       static doubleScalarMulUns = (R: Point, u1: bigint, u2: bigint): Point => {
                return this.G.multiply(u1, false).add(R.multiply(u2, false)).assertValidity()
        }
        static bytesToNumBE = (b: Bytes): bigint => this.big('0x' + (this.bytesToHex(b) || '0'))
@@ -523,7 +526,7 @@ export class Secp256k1 {
                        if (recovery != null) this.recovery = recovery
                        Object.freeze(this)
                }
-               static fromBytes (b: Bytes, format: ECDSASignatureFormat = Secp256k1.SIG_COMPACT): Secp256k1['Signature'] {
+               static fromBytes (b: Bytes, format: ECDSASignatureFormat = Secp256k1.SIG_COMPACT): Signature {
                        Secp256k1.assertSigLength(b, format)
                        let rec: number | undefined
                        if (format === Secp256k1.SIG_RECOVERED) {
@@ -1104,7 +1107,7 @@ export class Secp256k1 {
        static pwindows = Math.ceil(this.scalarBits / this.W) + 1 // 33 for W=8, NOT 32 - see wNAF loop
        static pwindowSize = 2 ** (this.W - 1) // 128 for W=8
        static precompute = () => {
-               const points: Secp256k1['Point'][] = []
+               const points: Point[] = []
                let p = this.G
                let b = p
                for (let w = 0; w < this.pwindows; w++) {
@@ -1118,9 +1121,9 @@ export class Secp256k1 {
                }
                return points
        }
-       static Gpows: Secp256k1['Point'][] | undefined = undefined // precomputes for base point G
+       static Gpows: Point[] | undefined = undefined // precomputes for base point G
        // const-time negate
-       static ctneg = (cnd: boolean, p: Secp256k1['Point']) => {
+       static ctneg = (cnd: boolean, p: Point) => {
                const n = p.negate()
                return cnd ? n : p
        }
@@ -1136,7 +1139,7 @@ export class Secp256k1 {
         *
         * !! Precomputes can be disabled by commenting-out call of the wNAF() inside Point#multiply().
         */
-       static wNAF = (n: bigint): { p: Secp256k1['Point']; f: Secp256k1['Point'] } => {
+       static wNAF = (n: bigint): { p: Point; f: Point } => {
                const comp = this.Gpows || (this.Gpows = this.precompute())
                let p = this.I
                let f = this.G // f must be G, or could become I in the end