docs+cleanup: inline hot-path functions, fix stale comments

- Add `inline` to hot-path tiny functions: U256.isZero, U256.testBit,
  FieldP.reduceSelf, FieldP.neg, MutablePoint.isInfinity. These are
  called thousands of times per EC operation; inline eliminates virtual
  call overhead (mostly helps Kotlin/Native; JVM JIT already inlines).
- Fix stale comment: G_TABLE_SIZE is 1024 for w=12 (was "64 for w=8")

https://claude.ai/code/session_01BhU63WUe9AhikZxRdw3Lpg
This commit is contained in:
Claude
2026-04-06 19:42:47 +00:00
parent 494ca22bdf
commit f9ec821107
3 changed files with 7 additions and 7 deletions
@@ -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.
@@ -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.
@@ -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