diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldP.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldP.kt index f412056729..19ad7bd9ec 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldP.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldP.kt @@ -132,7 +132,7 @@ internal object FieldP { reduceWide(out, w) } - fun neg( + inline fun neg( out: LongArray, a: LongArray, ) { @@ -298,7 +298,7 @@ internal object FieldP { // ==================== Reduction ==================== - fun reduceSelf(a: LongArray) { + inline fun reduceSelf(a: LongArray) { // Exploit P's structure: P = [P0, -1, -1, -1] where P[1..3] = 0xFFFFFFFFFFFFFFFF. // a >= P only if a[3]==a[2]==a[1]==-1 AND a[0] >= P[0]. The first check (a[3]==-1) // fails >99.99% of the time for random field elements, making this a single branch. diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/Point.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/Point.kt index 64151794f3..b2654303dc 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/Point.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/Point.kt @@ -93,7 +93,7 @@ internal class MutablePoint( val y: LongArray = LongArray(4), val z: LongArray = LongArray(4), ) { - fun isInfinity(): Boolean = U256.isZero(z) + inline fun isInfinity(): Boolean = U256.isZero(z) fun setInfinity() { for (i in 0 until 4) { @@ -163,7 +163,7 @@ internal object ECPoint { * w=12 is a good tradeoff for runtime-computed tables on JVM. */ private const val WINDOW_G = 12 - private val G_TABLE_SIZE = 1 shl (WINDOW_G - 2) // 64 for w=8 + private val G_TABLE_SIZE = 1 shl (WINDOW_G - 2) // 1024 for w=12 /** * Precomputed G odd-multiples for wNAF: gOddTable[i] = (2i+1)·G as affine, for i in 0..G_TABLE_SIZE-1. diff --git a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256.kt b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256.kt index ecd80cbd15..76fa73420c 100644 --- a/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256.kt +++ b/quartz/src/commonMain/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256.kt @@ -51,7 +51,7 @@ package com.vitorpamplona.quartz.utils.secp256k1 internal object U256 { val ZERO = LongArray(4) - fun isZero(a: LongArray): Boolean = (a[0] or a[1] or a[2] or a[3]) == 0L + inline fun isZero(a: LongArray): Boolean = (a[0] or a[1] or a[2] or a[3]) == 0L /** Unsigned comparison. Returns -1 if a < b, 0 if equal, 1 if a > b. */ fun cmp( @@ -253,8 +253,8 @@ internal object U256 { return ((a[limb] ushr shift) and 0xF).toInt() } - /** Test if bit at position pos is set. */ - fun testBit( + /** Test if bit at position pos is set. Called ~2,800× per mulG (comb table lookup). */ + inline fun testBit( a: LongArray, pos: Int, ): Boolean = (a[pos / 64] ushr (pos % 64)) and 1L == 1L