From: Chris Duncan Date: Fri, 5 Dec 2025 22:13:42 +0000 (-0800) Subject: BIP-32 specifies compressed public key serialization, so remove references to uncompr... X-Git-Url: https://git.codecow.com/?a=commitdiff_plain;h=dad872eec47c499ef9cc1c439d7413cb358993f5;p=libnemo.git BIP-32 specifies compressed public key serialization, so remove references to uncompressed possibilities. --- diff --git a/src/lib/crypto/secp256k1.ts b/src/lib/crypto/secp256k1.ts index 50c0068..6b5cf9f 100644 --- a/src/lib/crypto/secp256k1.ts +++ b/src/lib/crypto/secp256k1.ts @@ -11,33 +11,22 @@ * noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */ +/** Alias to Uint8Array. */ +type Bytes = Uint8Array + +/** Point in 3d xyz coordinates. */ type Point = { X: bigint Y: bigint Z: bigint } -/** Alias to Uint8Array. */ -type Bytes = Uint8Array - /** Point in 2d xy affine coordinates. */ type AffinePoint = { x: bigint y: bigint } -/** Type arithmetic to enable validation of literal integer types */ -type EnsureNumber = A extends number ? A : never -type Length = EnsureNumber -type Tuple = Length extends N ? Accumulator : Tuple -type Add = Length<[...Tuple, ...Tuple]> - -/** Public key length definitions */ -type Secp256k1Lengths = { - compressed: Add - uncompressed: Add -} - export class Secp256k1 { /** * Curve params. secp256k1 is short weierstrass / koblitz curve. Equation is y² == x³ + ax + b. @@ -58,10 +47,7 @@ export class Secp256k1 { static L: 32 = 32 // field / group byte length static L2: 64 = 64 - static pkLength: Secp256k1Lengths = { - compressed: 33, - uncompressed: 65 - } + static pkLength: 33 = 33 // ## Helpers // ---------- @@ -259,7 +245,7 @@ export class Secp256k1 { const tail = bytes.subarray(1) const x = this.bytesToBigint(tail.subarray(0, this.L)) // No actual validation is done here: use .assertValidity() - if (length === this.pkLength.compressed && (head === 0x02 || head === 0x03)) { + if (length === this.pkLength && (head === 0x02 || head === 0x03)) { // Equation is y² == x³ + ax + b. We calculate y from x. // y = √y²; there are two solutions: y, -y. Determine proper solution based on prefix let y = this.lift_x(x) @@ -268,18 +254,15 @@ export class Secp256k1 { if (evenH !== evenY) y = this.M(-y) p = this.Point(x, y, 1n) } - // Uncompressed 65-byte point, 0x04 prefix - if (length === this.pkLength.uncompressed && head === 0x04) p = this.Point(x, this.bytesToBigint(tail.subarray(this.L, this.L2)), 1n) // Validate point return this.isValidPoint(p) } /** Converts point to 33/65-byte Uint8Array. */ - static pointToBytes (p: Point, isCompressed = true): Bytes { + static pointToBytes (p: Point): Bytes { const { x, y } = this.Affine(this.isValidPoint(p)) const x32b = this.bigintTo32Bytes(x) - if (isCompressed) return this.concatBytes(this.getPrefix(y), x32b) - return this.concatBytes(Uint8Array.of(0x04), x32b, this.bigintTo32Bytes(y)) + return this.concatBytes(this.getPrefix(y), x32b) } /** Generator / base point */ @@ -326,16 +309,15 @@ export class Secp256k1 { } /** Creates 33/65-byte public key from 32-byte private key. */ - static getPublicKey (sk: Bytes, isCompressed = true): Bytes { - const pk = this.pointToBytes(this.wNAF(this.secretKeyToScalar(sk)).p, isCompressed) + static getPublicKey (sk: Bytes): Bytes { + const pk = this.pointToBytes(this.wNAF(this.secretKeyToScalar(sk)).p) return this.isValidPublicKey(pk) ? pk : this.err('derived invalid public key from secret key') } - static isValidPublicKey (pk: Bytes, isCompressed?: boolean): boolean { + static isValidPublicKey (pk: Bytes): boolean { try { const l = pk.length - if (isCompressed === true && l !== this.pkLength.compressed) return false - if (isCompressed === false && l !== this.pkLength.uncompressed) return false + if (l !== this.pkLength) return false return !!this.pointFromBytes(pk) } catch (error) { return false