]> git.codecow.com Git - libnemo.git/commitdiff
Remove string handling from byte casting to bigint. Remove some redundant or unused...
authorChris Duncan <chris@zoso.dev>
Wed, 3 Dec 2025 23:46:18 +0000 (15:46 -0800)
committerChris Duncan <chris@zoso.dev>
Wed, 3 Dec 2025 23:46:18 +0000 (15:46 -0800)
src/lib/crypto/secp256k1.ts

index 683b37ab1ca8b7be58597c5f5674bb46bd9019d2..7e66c8094ea302069a4b1ce7a94738e5f5cc0ed6 100644 (file)
@@ -385,7 +385,7 @@ export class Secp256k1 {
                const length = bytes.length
                const head = bytes[0]
                const tail = bytes.subarray(1)
-               const x = this.sliceBytesNumBE(tail, 0, this.L)
+               const x = this.bytesToBigint(tail.subarray(0, this.L))
                // No actual validation is done here: use .assertValidity()
                if (length === comp && (head === 0x02 || head === 0x03)) {
                        // Equation is y² == x³ + ax + b. We calculate y from x.
@@ -397,7 +397,7 @@ export class Secp256k1 {
                        p = this.Point(x, y, 1n)
                }
                // Uncompressed 65-byte point, 0x04 prefix
-               if (length === uncomp && head === 0x04) p = this.Point(x, this.sliceBytesNumBE(tail, this.L, this.L2), 1n)
+               if (length === uncomp && 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')
        }
@@ -415,8 +415,14 @@ export class Secp256k1 {
                return this.G.multiplyUnsafe(u1).add(R.multiplyUnsafe(u2)).assertValidity()
        }
 
-       static bytesToBigint = (b: Bytes): bigint => BigInt('0x' + (this.bytesToHex(b) || '0'))
-       static sliceBytesNumBE = (b: Bytes, from: number, to: number) => this.bytesToBigint(b.subarray(from, to))
+       static bytesToBigint (b: Bytes): bigint {
+               let int = BigInt(b[0]), len = b.length
+               for (let i = 1; i < len; i++) {
+                       int <<= 8n
+                       int |= BigInt(b[i])
+               }
+               return int
+       }
 
        /** Number to 32b. Must be 0 <= num < 2²⁵⁶. validate, pad, to bytes. */
        static bigintTo32Bytes (num: bigint): Bytes {
@@ -426,13 +432,13 @@ export class Secp256k1 {
                        .padStart(this.L2, '0')
                )
        }
+
        /** Normalize private key to scalar (bigint). Verifies scalar is in range 1<s<N */
        static secretKeyToScalar (secretKey: Bytes): bigint {
                const num = this.bytesToBigint(this.abytes(secretKey, this.L, 'secret key'))
                return this.bigintInRange(num, 1n, this.N, 'invalid secret key: outside of range')
        }
-       /** For Signature malleability, validates sig.s is bigger than N/2. */
-       static highS = (n: bigint): boolean => n > this.N >> 1n
+
        /** Creates 33/65-byte public key from 32-byte private key. */
        static getPublicKey (privKey: Bytes, isCompressed = true): Bytes {
                return this.G.multiply(this.secretKeyToScalar(privKey)).toBytes(isCompressed)
@@ -505,9 +511,6 @@ export class Secp256k1 {
                        addRecoveryBit: (bit: number): RecoveredSignature => {
                                return this.Signature(r, s, bit) as RecoveredSignature
                        },
-                       hasHighS: (): boolean => {
-                               return this.highS(s)
-                       },
                        toBytes: (format: ECDSASignatureFormat = this.SIG_COMPACT): Bytes => {
                                const res = this.concatBytes(this.bigintTo32Bytes(r), this.bigintTo32Bytes(s))
                                if (format === this.SIG_RECOVERED) {
@@ -526,8 +529,8 @@ export class Secp256k1 {
                        recoveryBit = b[0]
                        b = b.subarray(1)
                }
-               const r = this.sliceBytesNumBE(b, 0, this.L)
-               const s = this.sliceBytesNumBE(b, this.L, this.L2)
+               const r = this.bytesToBigint(b.subarray(0, this.L))
+               const s = this.bytesToBigint(b.subarray(this.L, this.L2))
                return this.Signature(r, s, recoveryBit)
        }