/** Public key length definitions */
type Secp256k1Lengths = {
- publicKey: Add<typeof Secp256k1.L, 1>
- publicKeyUncompressed: Add<typeof Secp256k1.L2, 1>
+ compressed: Add<typeof Secp256k1.L, 1>
+ uncompressed: Add<typeof Secp256k1.L2, 1>
}
export class Secp256k1 {
static L: 32 = 32 // field / group byte length
static L2: 64 = 64
- static lengths: Secp256k1Lengths = {
- publicKey: 33,
- publicKeyUncompressed: 65
+ static publicKeyLength: Secp256k1Lengths = {
+ compressed: 33,
+ uncompressed: 65
}
// ## Helpers
/** Convert Uint8Array or hex string to Point. */
static pointFromBytes (bytes: Bytes): Point {
this.abytes(bytes)
- const { publicKey: comp, publicKeyUncompressed: uncomp } = this.lengths // e.g. for 32-byte: 33, 65
let p: Point | undefined = undefined
const length = bytes.length
const head = bytes[0]
const tail = bytes.subarray(1)
const x = this.bytesToBigint(tail.subarray(0, this.L))
// No actual validation is done here: use .assertValidity()
- if (length === comp && (head === 0x02 || head === 0x03)) {
+ if (length === this.publicKeyLength.compressed && (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)
p = this.Point(x, y, 1n)
}
// Uncompressed 65-byte point, 0x04 prefix
- if (length === uncomp && head === 0x04) p = this.Point(x, this.bytesToBigint(tail.subarray(this.L, this.L2)), 1n)
+ if (length === this.publicKeyLength.uncompressed && head === 0x04) p = this.Point(x, this.bytesToBigint(tail.subarray(this.L, this.L2)), 1n)
// Validate point
return p ? p.assertValidity() : this.err('bad point: not on curve')
}
}
static isValidPublicKey (publicKey: Bytes, isCompressed?: boolean): boolean {
- const { publicKey: comp, publicKeyUncompressed } = this.lengths
try {
const l = publicKey.length
- if (isCompressed === true && l !== comp) return false
- if (isCompressed === false && l !== publicKeyUncompressed) return false
+ if (isCompressed === true && l !== this.publicKeyLength.compressed) return false
+ if (isCompressed === false && l !== this.publicKeyLength.uncompressed) return false
return !!this.pointFromBytes(publicKey)
} catch (error) {
return false