perf: eliminate ULong.constructor-impl NOOP calls in unsigned comparisons
Bytecode analysis revealed that every `a.toULong() < b.toULong()`
comparison generates 2 invokestatic calls to ULong.constructor-impl
(NOOPs that return the input unchanged) plus Long.compareUnsigned.
Across all secp256k1 hot paths, this produced 554 NOOP invokestatic
calls in the bytecode, translating to ~18,000 wasted calls per verify.
Replace all toULong() comparisons with an inline uLt() helper that
uses the XOR-with-MIN_VALUE trick directly:
(a xor Long.MIN_VALUE) < (b xor Long.MIN_VALUE)
This produces pure arithmetic bytecode (lxor, lcmp, ifge) with ZERO
method calls, eliminating all ULong.constructor-impl overhead.
Before: lload, invokestatic ULong.constructor-impl, lload,
invokestatic ULong.constructor-impl, invokestatic
Long.compareUnsigned, ifge (6 bytecodes, 3 method calls)
After: lload, ldc MIN_VALUE, lxor, lload, ldc MIN_VALUE, lxor,
lcmp, ifge (8 bytecodes, 0 method calls)
https://claude.ai/code/session_01EMY5RnXb9rnsyU2KbXrSaY
This commit is contained in:
+53
-53
@@ -110,19 +110,19 @@ internal inline fun fieldMulReduceWith(
|
|||||||
|
|
||||||
lo = a0 * b1
|
lo = a0 * b1
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
w[1] = s
|
w[1] = s
|
||||||
carry = umulh(a0, b1) + c1
|
carry = umulh(a0, b1) + c1
|
||||||
|
|
||||||
lo = a0 * b2
|
lo = a0 * b2
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
w[2] = s
|
w[2] = s
|
||||||
carry = umulh(a0, b2) + c1
|
carry = umulh(a0, b2) + c1
|
||||||
|
|
||||||
lo = a0 * b3
|
lo = a0 * b3
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
w[3] = s
|
w[3] = s
|
||||||
w[4] = umulh(a0, b3) + c1
|
w[4] = umulh(a0, b3) + c1
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a1, b0)
|
hi = umulh(a1, b0)
|
||||||
prev = w[1]
|
prev = w[1]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
w[1] = s
|
w[1] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -139,9 +139,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a1, b1)
|
hi = umulh(a1, b1)
|
||||||
prev = w[2]
|
prev = w[2]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[2] = s
|
w[2] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -149,9 +149,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a1, b2)
|
hi = umulh(a1, b2)
|
||||||
prev = w[3]
|
prev = w[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[3] = s
|
w[3] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -159,9 +159,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a1, b3)
|
hi = umulh(a1, b3)
|
||||||
prev = w[4]
|
prev = w[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[4] = s
|
w[4] = s
|
||||||
w[5] = hi + c1 + c2
|
w[5] = hi + c1 + c2
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a2, b0)
|
hi = umulh(a2, b0)
|
||||||
prev = w[2]
|
prev = w[2]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
w[2] = s
|
w[2] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -178,9 +178,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a2, b1)
|
hi = umulh(a2, b1)
|
||||||
prev = w[3]
|
prev = w[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[3] = s
|
w[3] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -188,9 +188,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a2, b2)
|
hi = umulh(a2, b2)
|
||||||
prev = w[4]
|
prev = w[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[4] = s
|
w[4] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -198,9 +198,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a2, b3)
|
hi = umulh(a2, b3)
|
||||||
prev = w[5]
|
prev = w[5]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[5] = s
|
w[5] = s
|
||||||
w[6] = hi + c1 + c2
|
w[6] = hi + c1 + c2
|
||||||
|
|
||||||
@@ -209,7 +209,7 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a3, b0)
|
hi = umulh(a3, b0)
|
||||||
prev = w[3]
|
prev = w[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
w[3] = s
|
w[3] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -217,9 +217,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a3, b1)
|
hi = umulh(a3, b1)
|
||||||
prev = w[4]
|
prev = w[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[4] = s
|
w[4] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -227,9 +227,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a3, b2)
|
hi = umulh(a3, b2)
|
||||||
prev = w[5]
|
prev = w[5]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[5] = s
|
w[5] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -237,9 +237,9 @@ internal inline fun fieldMulReduceWith(
|
|||||||
hi = umulh(a3, b3)
|
hi = umulh(a3, b3)
|
||||||
prev = w[6]
|
prev = w[6]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[6] = s
|
w[6] = s
|
||||||
w[7] = hi + c1 + c2
|
w[7] = hi + c1 + c2
|
||||||
|
|
||||||
@@ -280,13 +280,13 @@ internal inline fun fieldSqrReduceWith(
|
|||||||
|
|
||||||
lo = a0 * a2
|
lo = a0 * a2
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
w[2] = s
|
w[2] = s
|
||||||
carry = umulh(a0, a2) + c1
|
carry = umulh(a0, a2) + c1
|
||||||
|
|
||||||
lo = a0 * a3
|
lo = a0 * a3
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
w[3] = s
|
w[3] = s
|
||||||
w[4] = umulh(a0, a3) + c1
|
w[4] = umulh(a0, a3) + c1
|
||||||
|
|
||||||
@@ -294,7 +294,7 @@ internal inline fun fieldSqrReduceWith(
|
|||||||
hi = umulh(a1, a2)
|
hi = umulh(a1, a2)
|
||||||
prev = w[3]
|
prev = w[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
w[3] = s
|
w[3] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -302,9 +302,9 @@ internal inline fun fieldSqrReduceWith(
|
|||||||
hi = umulh(a1, a3)
|
hi = umulh(a1, a3)
|
||||||
prev = w[4]
|
prev = w[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
w[4] = s
|
w[4] = s
|
||||||
w[5] = hi + c1 + c2
|
w[5] = hi + c1 + c2
|
||||||
|
|
||||||
@@ -312,7 +312,7 @@ internal inline fun fieldSqrReduceWith(
|
|||||||
hi = umulh(a2, a3)
|
hi = umulh(a2, a3)
|
||||||
prev = w[5]
|
prev = w[5]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
w[5] = s
|
w[5] = s
|
||||||
w[6] = hi + c1
|
w[6] = hi + c1
|
||||||
|
|
||||||
@@ -342,44 +342,44 @@ internal inline fun fieldSqrReduceWith(
|
|||||||
hi = umulh(a0, a0)
|
hi = umulh(a0, a0)
|
||||||
w[0] = lo
|
w[0] = lo
|
||||||
s = w[1] + hi
|
s = w[1] + hi
|
||||||
c1 = if (s.toULong() < w[1].toULong()) 1L else 0L
|
c1 = if (uLt(s, w[1])) 1L else 0L
|
||||||
w[1] = s
|
w[1] = s
|
||||||
var dCarry = c1
|
var dCarry = c1
|
||||||
|
|
||||||
lo = a1 * a1
|
lo = a1 * a1
|
||||||
hi = umulh(a1, a1)
|
hi = umulh(a1, a1)
|
||||||
s = w[2] + lo
|
s = w[2] + lo
|
||||||
c1 = if (s.toULong() < w[2].toULong()) 1L else 0L
|
c1 = if (uLt(s, w[2])) 1L else 0L
|
||||||
s += dCarry
|
s += dCarry
|
||||||
c2 = if (s.toULong() < dCarry.toULong()) 1L else 0L
|
c2 = if (uLt(s, dCarry)) 1L else 0L
|
||||||
w[2] = s
|
w[2] = s
|
||||||
prev = w[3] + hi
|
prev = w[3] + hi
|
||||||
val c3a = if (prev.toULong() < w[3].toULong()) 1L else 0L
|
val c3a = if (uLt(prev, w[3])) 1L else 0L
|
||||||
prev += c1 + c2
|
prev += c1 + c2
|
||||||
val c4a = if (prev.toULong() < (c1 + c2).toULong()) 1L else 0L
|
val c4a = if (uLt(prev, c1 + c2)) 1L else 0L
|
||||||
w[3] = prev
|
w[3] = prev
|
||||||
dCarry = c3a + c4a
|
dCarry = c3a + c4a
|
||||||
|
|
||||||
lo = a2 * a2
|
lo = a2 * a2
|
||||||
hi = umulh(a2, a2)
|
hi = umulh(a2, a2)
|
||||||
s = w[4] + lo
|
s = w[4] + lo
|
||||||
c1 = if (s.toULong() < w[4].toULong()) 1L else 0L
|
c1 = if (uLt(s, w[4])) 1L else 0L
|
||||||
s += dCarry
|
s += dCarry
|
||||||
c2 = if (s.toULong() < dCarry.toULong()) 1L else 0L
|
c2 = if (uLt(s, dCarry)) 1L else 0L
|
||||||
w[4] = s
|
w[4] = s
|
||||||
prev = w[5] + hi
|
prev = w[5] + hi
|
||||||
val c3b = if (prev.toULong() < w[5].toULong()) 1L else 0L
|
val c3b = if (uLt(prev, w[5])) 1L else 0L
|
||||||
prev += c1 + c2
|
prev += c1 + c2
|
||||||
val c4b = if (prev.toULong() < (c1 + c2).toULong()) 1L else 0L
|
val c4b = if (uLt(prev, c1 + c2)) 1L else 0L
|
||||||
w[5] = prev
|
w[5] = prev
|
||||||
dCarry = c3b + c4b
|
dCarry = c3b + c4b
|
||||||
|
|
||||||
lo = a3 * a3
|
lo = a3 * a3
|
||||||
hi = umulh(a3, a3)
|
hi = umulh(a3, a3)
|
||||||
s = w[6] + lo
|
s = w[6] + lo
|
||||||
c1 = if (s.toULong() < w[6].toULong()) 1L else 0L
|
c1 = if (uLt(s, w[6])) 1L else 0L
|
||||||
s += dCarry
|
s += dCarry
|
||||||
c2 = if (s.toULong() < dCarry.toULong()) 1L else 0L
|
c2 = if (uLt(s, dCarry)) 1L else 0L
|
||||||
w[6] = s
|
w[6] = s
|
||||||
prev = w[7] + hi
|
prev = w[7] + hi
|
||||||
prev += c1 + c2
|
prev += c1 + c2
|
||||||
@@ -412,34 +412,34 @@ internal inline fun reduceWideInline(
|
|||||||
hcLo = w[4] * c
|
hcLo = w[4] * c
|
||||||
hcHi = umulh(w[4], c)
|
hcHi = umulh(w[4], c)
|
||||||
s1 = w[0] + hcLo
|
s1 = w[0] + hcLo
|
||||||
c1 = if (s1.toULong() < w[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
var carry = hcHi + c1
|
var carry = hcHi + c1
|
||||||
|
|
||||||
hcLo = w[5] * c
|
hcLo = w[5] * c
|
||||||
hcHi = umulh(w[5], c)
|
hcHi = umulh(w[5], c)
|
||||||
s1 = w[1] + hcLo
|
s1 = w[1] + hcLo
|
||||||
c1 = if (s1.toULong() < w[1].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[1])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[1] = s2
|
out[1] = s2
|
||||||
carry = hcHi + c1 + c2
|
carry = hcHi + c1 + c2
|
||||||
|
|
||||||
hcLo = w[6] * c
|
hcLo = w[6] * c
|
||||||
hcHi = umulh(w[6], c)
|
hcHi = umulh(w[6], c)
|
||||||
s1 = w[2] + hcLo
|
s1 = w[2] + hcLo
|
||||||
c1 = if (s1.toULong() < w[2].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[2])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[2] = s2
|
out[2] = s2
|
||||||
carry = hcHi + c1 + c2
|
carry = hcHi + c1 + c2
|
||||||
|
|
||||||
hcLo = w[7] * c
|
hcLo = w[7] * c
|
||||||
hcHi = umulh(w[7], c)
|
hcHi = umulh(w[7], c)
|
||||||
s1 = w[3] + hcLo
|
s1 = w[3] + hcLo
|
||||||
c1 = if (s1.toULong() < w[3].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[3])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[3] = s2
|
out[3] = s2
|
||||||
carry = hcHi + c1 + c2
|
carry = hcHi + c1 + c2
|
||||||
|
|
||||||
@@ -448,27 +448,27 @@ internal inline fun reduceWideInline(
|
|||||||
val ccLo = carry * c
|
val ccLo = carry * c
|
||||||
val ccHi = umulh(carry, c)
|
val ccHi = umulh(carry, c)
|
||||||
s1 = out[0] + ccLo
|
s1 = out[0] + ccLo
|
||||||
c1 = if (s1.toULong() < out[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, out[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
var prop = ccHi + c1
|
var prop = ccHi + c1
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[1] + prop
|
s1 = out[1] + prop
|
||||||
prop = if (s1.toULong() < out[1].toULong()) 1L else 0L
|
prop = if (uLt(s1, out[1])) 1L else 0L
|
||||||
out[1] = s1
|
out[1] = s1
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[2] + prop
|
s1 = out[2] + prop
|
||||||
prop = if (s1.toULong() < out[2].toULong()) 1L else 0L
|
prop = if (uLt(s1, out[2])) 1L else 0L
|
||||||
out[2] = s1
|
out[2] = s1
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[3] + prop
|
s1 = out[3] + prop
|
||||||
prop = if (s1.toULong() < out[3].toULong()) 1L else 0L
|
prop = if (uLt(s1, out[3])) 1L else 0L
|
||||||
out[3] = s1
|
out[3] = s1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[0] + c
|
s1 = out[0] + c
|
||||||
c1 = if (s1.toULong() < out[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, out[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
if (c1 != 0L) {
|
if (c1 != 0L) {
|
||||||
out[1]++
|
out[1]++
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ internal object FieldP {
|
|||||||
if (carry != 0) {
|
if (carry != 0) {
|
||||||
// Overflow past 2^256: add 2^256 mod p = 2^32 + 977 = 0x1000003D1
|
// Overflow past 2^256: add 2^256 mod p = 2^32 + 977 = 0x1000003D1
|
||||||
val s1 = out[0] + 4294968273L
|
val s1 = out[0] + 4294968273L
|
||||||
val c1 = if (s1.toULong() < out[0].toULong()) 1L else 0L
|
val c1 = if (uLt(s1, out[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
if (c1 != 0L) {
|
if (c1 != 0L) {
|
||||||
out[1]++
|
out[1]++
|
||||||
@@ -95,7 +95,7 @@ internal object FieldP {
|
|||||||
if (borrow != 0) {
|
if (borrow != 0) {
|
||||||
// Add P = [P0, -1, -1, -1].
|
// Add P = [P0, -1, -1, -1].
|
||||||
val s0 = out[0] + P0
|
val s0 = out[0] + P0
|
||||||
val c0 = if (s0.toULong() < out[0].toULong()) 1L else 0L
|
val c0 = if (uLt(s0, out[0])) 1L else 0L
|
||||||
out[0] = s0
|
out[0] = s0
|
||||||
// For limbs 1-3: adding P[i]=-1 with carry c:
|
// For limbs 1-3: adding P[i]=-1 with carry c:
|
||||||
// c=1 → result unchanged, carry out=1 (identity propagation)
|
// c=1 → result unchanged, carry out=1 (identity propagation)
|
||||||
@@ -173,7 +173,7 @@ internal object FieldP {
|
|||||||
}
|
}
|
||||||
// P - a: limb 0 is P0 - a[0], limbs 1-3 are (-1) - a[i] = ~a[i]
|
// P - a: limb 0 is P0 - a[0], limbs 1-3 are (-1) - a[i] = ~a[i]
|
||||||
out[0] = P0 - a[0]
|
out[0] = P0 - a[0]
|
||||||
val borrow = if (a[0].toULong() > P0.toULong()) 1L else 0L
|
val borrow = if (uLt(P0, a[0])) 1L else 0L
|
||||||
// ~a[i] - borrow. New borrow only if ~a[i] == 0 (i.e., a[i] == -1) and borrow == 1
|
// ~a[i] - borrow. New borrow only if ~a[i] == 0 (i.e., a[i] == -1) and borrow == 1
|
||||||
out[1] = a[1].inv() - borrow
|
out[1] = a[1].inv() - borrow
|
||||||
val b1 = if (a[1] == -1L && borrow != 0L) 1L else 0L
|
val b1 = if (a[1] == -1L && borrow != 0L) 1L else 0L
|
||||||
@@ -200,28 +200,28 @@ internal object FieldP {
|
|||||||
// Conditional add: out = a + (P & mask), unrolled
|
// Conditional add: out = a + (P & mask), unrolled
|
||||||
// Limb 0
|
// Limb 0
|
||||||
s1 = a[0] + p0
|
s1 = a[0] + p0
|
||||||
c1 = if (s1.toULong() < a[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
var carry = c1
|
var carry = c1
|
||||||
// Limb 1
|
// Limb 1
|
||||||
s1 = a[1] + mask
|
s1 = a[1] + mask
|
||||||
c1 = if (s1.toULong() < a[1].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[1])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[1] = s2
|
out[1] = s2
|
||||||
carry = c1 + c2
|
carry = c1 + c2
|
||||||
// Limb 2
|
// Limb 2
|
||||||
s1 = a[2] + mask
|
s1 = a[2] + mask
|
||||||
c1 = if (s1.toULong() < a[2].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[2])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[2] = s2
|
out[2] = s2
|
||||||
carry = c1 + c2
|
carry = c1 + c2
|
||||||
// Limb 3
|
// Limb 3
|
||||||
s1 = a[3] + mask
|
s1 = a[3] + mask
|
||||||
c1 = if (s1.toULong() < a[3].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[3])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[3] = s2
|
out[3] = s2
|
||||||
carry = c1 + c2
|
carry = c1 + c2
|
||||||
|
|
||||||
@@ -405,7 +405,7 @@ internal object FieldP {
|
|||||||
hcLo = w[4] * c
|
hcLo = w[4] * c
|
||||||
hcHi = unsignedMultiplyHigh(w[4], c)
|
hcHi = unsignedMultiplyHigh(w[4], c)
|
||||||
s1 = w[0] + hcLo
|
s1 = w[0] + hcLo
|
||||||
c1 = if (s1.toULong() < w[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
var carry = hcHi + c1
|
var carry = hcHi + c1
|
||||||
|
|
||||||
@@ -413,9 +413,9 @@ internal object FieldP {
|
|||||||
hcLo = w[5] * c
|
hcLo = w[5] * c
|
||||||
hcHi = unsignedMultiplyHigh(w[5], c)
|
hcHi = unsignedMultiplyHigh(w[5], c)
|
||||||
s1 = w[1] + hcLo
|
s1 = w[1] + hcLo
|
||||||
c1 = if (s1.toULong() < w[1].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[1])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[1] = s2
|
out[1] = s2
|
||||||
carry = hcHi + c1 + c2
|
carry = hcHi + c1 + c2
|
||||||
|
|
||||||
@@ -423,9 +423,9 @@ internal object FieldP {
|
|||||||
hcLo = w[6] * c
|
hcLo = w[6] * c
|
||||||
hcHi = unsignedMultiplyHigh(w[6], c)
|
hcHi = unsignedMultiplyHigh(w[6], c)
|
||||||
s1 = w[2] + hcLo
|
s1 = w[2] + hcLo
|
||||||
c1 = if (s1.toULong() < w[2].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[2])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[2] = s2
|
out[2] = s2
|
||||||
carry = hcHi + c1 + c2
|
carry = hcHi + c1 + c2
|
||||||
|
|
||||||
@@ -433,9 +433,9 @@ internal object FieldP {
|
|||||||
hcLo = w[7] * c
|
hcLo = w[7] * c
|
||||||
hcHi = unsignedMultiplyHigh(w[7], c)
|
hcHi = unsignedMultiplyHigh(w[7], c)
|
||||||
s1 = w[3] + hcLo
|
s1 = w[3] + hcLo
|
||||||
c1 = if (s1.toULong() < w[3].toULong()) 1L else 0L
|
c1 = if (uLt(s1, w[3])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[3] = s2
|
out[3] = s2
|
||||||
carry = hcHi + c1 + c2
|
carry = hcHi + c1 + c2
|
||||||
|
|
||||||
@@ -444,21 +444,21 @@ internal object FieldP {
|
|||||||
val ccLo = carry * c
|
val ccLo = carry * c
|
||||||
val ccHi = unsignedMultiplyHigh(carry, c)
|
val ccHi = unsignedMultiplyHigh(carry, c)
|
||||||
s1 = out[0] + ccLo
|
s1 = out[0] + ccLo
|
||||||
c1 = if (s1.toULong() < out[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, out[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
// Propagate carry (unrolled, with early exit)
|
// Propagate carry (unrolled, with early exit)
|
||||||
var prop = ccHi + c1
|
var prop = ccHi + c1
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[1] + prop
|
s1 = out[1] + prop
|
||||||
prop = if (s1.toULong() < out[1].toULong()) 1L else 0L
|
prop = if (uLt(s1, out[1])) 1L else 0L
|
||||||
out[1] = s1
|
out[1] = s1
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[2] + prop
|
s1 = out[2] + prop
|
||||||
prop = if (s1.toULong() < out[2].toULong()) 1L else 0L
|
prop = if (uLt(s1, out[2])) 1L else 0L
|
||||||
out[2] = s1
|
out[2] = s1
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[3] + prop
|
s1 = out[3] + prop
|
||||||
prop = if (s1.toULong() < out[3].toULong()) 1L else 0L
|
prop = if (uLt(s1, out[3])) 1L else 0L
|
||||||
out[3] = s1
|
out[3] = s1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,7 +466,7 @@ internal object FieldP {
|
|||||||
// Overflow past 256 bits: 2^256 ≡ C (mod p)
|
// Overflow past 256 bits: 2^256 ≡ C (mod p)
|
||||||
if (prop != 0L) {
|
if (prop != 0L) {
|
||||||
s1 = out[0] + c
|
s1 = out[0] + c
|
||||||
c1 = if (s1.toULong() < out[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, out[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
if (c1 != 0L) {
|
if (c1 != 0L) {
|
||||||
out[1]++
|
out[1]++
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ internal object Glv {
|
|||||||
for (i in limb until s.size) {
|
for (i in limb until s.size) {
|
||||||
val old = s[i]
|
val old = s[i]
|
||||||
s[i] = old + if (i == limb) addVal else 1L
|
s[i] = old + if (i == limb) addVal else 1L
|
||||||
if (s[i].toULong() >= old.toULong() || (i == limb && addVal == 0L)) break
|
if (!uLt(s[i], old) || (i == limb && addVal == 0L)) break
|
||||||
// overflowed — carry to next limb
|
// overflowed — carry to next limb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -198,9 +198,9 @@ internal object ScalarN {
|
|||||||
0L
|
0L
|
||||||
}
|
}
|
||||||
val s1 = hiTimesNC[i] + loVal
|
val s1 = hiTimesNC[i] + loVal
|
||||||
val c1 = if (s1.toULong() < hiTimesNC[i].toULong()) 1L else 0L
|
val c1 = if (uLt(s1, hiTimesNC[i])) 1L else 0L
|
||||||
val s2 = s1 + carry
|
val s2 = s1 + carry
|
||||||
val c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
val c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
w[i] = s2
|
w[i] = s2
|
||||||
carry = c1 + c2
|
carry = c1 + c2
|
||||||
}
|
}
|
||||||
@@ -238,9 +238,9 @@ internal object ScalarN {
|
|||||||
saved3
|
saved3
|
||||||
}
|
}
|
||||||
val s1 = loVal + hi2NC[i]
|
val s1 = loVal + hi2NC[i]
|
||||||
val c1 = if (s1.toULong() < loVal.toULong()) 1L else 0L
|
val c1 = if (uLt(s1, loVal)) 1L else 0L
|
||||||
val s2 = s1 + c2
|
val s2 = s1 + c2
|
||||||
val cc = if (s2.toULong() < s1.toULong()) 1L else 0L
|
val cc = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[i] = s2
|
out[i] = s2
|
||||||
c2 = c1 + cc
|
c2 = c1 + cc
|
||||||
}
|
}
|
||||||
@@ -252,13 +252,13 @@ internal object ScalarN {
|
|||||||
val c1lo = ov * N_COMPLEMENT[1]
|
val c1lo = ov * N_COMPLEMENT[1]
|
||||||
val c1hi = unsignedMultiplyHigh(ov, N_COMPLEMENT[1])
|
val c1hi = unsignedMultiplyHigh(ov, N_COMPLEMENT[1])
|
||||||
val s0 = out[0] + c0lo
|
val s0 = out[0] + c0lo
|
||||||
val carry0 = if (s0.toULong() < out[0].toULong()) 1L else 0L
|
val carry0 = if (uLt(s0, out[0])) 1L else 0L
|
||||||
out[0] = s0
|
out[0] = s0
|
||||||
val s1 = out[1] + c0hi + c1lo + carry0
|
val s1 = out[1] + c0hi + c1lo + carry0
|
||||||
val carry1 = if (s1.toULong() < out[1].toULong()) 1L else 0L
|
val carry1 = if (uLt(s1, out[1])) 1L else 0L
|
||||||
out[1] = s1
|
out[1] = s1
|
||||||
val s2 = out[2] + c1hi + ov + carry1
|
val s2 = out[2] + c1hi + ov + carry1
|
||||||
val carry2 = if (s2.toULong() < out[2].toULong()) 1L else 0L
|
val carry2 = if (uLt(s2, out[2])) 1L else 0L
|
||||||
out[2] = s2
|
out[2] = s2
|
||||||
out[3] += carry2
|
out[3] += carry2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,28 @@ package com.vitorpamplona.quartz.utils.secp256k1
|
|||||||
// Package structure: U256 → FieldP/ScalarN → Glv/KeyCodec → Point → Secp256k1
|
// Package structure: U256 → FieldP/ScalarN → Glv/KeyCodec → Point → Secp256k1
|
||||||
// =====================================================================================
|
// =====================================================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unsigned less-than comparison without ULong inline class overhead.
|
||||||
|
*
|
||||||
|
* Kotlin's `uLt(a, b)` generates 2 invokestatic calls to
|
||||||
|
* ULong.constructor-impl (NOOPs that return the input unchanged) plus
|
||||||
|
* Long.compareUnsigned per comparison. On ART, these extra invokestatic
|
||||||
|
* calls add ~2-3ns each × ~18,000 comparisons per verify = ~36-54μs.
|
||||||
|
*
|
||||||
|
* This inline function uses the XOR-with-MIN_VALUE trick directly,
|
||||||
|
* producing pure arithmetic bytecode with ZERO method calls:
|
||||||
|
* lload a, ldc MIN_VALUE, lxor, lload b, ldc MIN_VALUE, lxor, lcmp, ifge
|
||||||
|
*
|
||||||
|
* vs the toULong() path:
|
||||||
|
* lload a, invokestatic ULong.constructor-impl, lload b,
|
||||||
|
* invokestatic ULong.constructor-impl, invokestatic Long.compareUnsigned, ifge
|
||||||
|
*/
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
internal inline fun uLt(
|
||||||
|
a: Long,
|
||||||
|
b: Long,
|
||||||
|
): Boolean = (a xor Long.MIN_VALUE) < (b xor Long.MIN_VALUE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Raw 256-bit unsigned integer arithmetic using 4×64-bit limbs.
|
* Raw 256-bit unsigned integer arithmetic using 4×64-bit limbs.
|
||||||
*/
|
*/
|
||||||
@@ -58,7 +80,7 @@ internal object U256 {
|
|||||||
): Int {
|
): Int {
|
||||||
for (i in 3 downTo 0) {
|
for (i in 3 downTo 0) {
|
||||||
if (a[i] != b[i]) {
|
if (a[i] != b[i]) {
|
||||||
return if (a[i].toULong() < b[i].toULong()) -1 else 1
|
return if (uLt(a[i], b[i])) -1 else 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
@@ -77,31 +99,31 @@ internal object U256 {
|
|||||||
|
|
||||||
// Limb 0 (no carry input)
|
// Limb 0 (no carry input)
|
||||||
s1 = a[0] + b[0]
|
s1 = a[0] + b[0]
|
||||||
c1 = if (s1.toULong() < a[0].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[0])) 1L else 0L
|
||||||
out[0] = s1
|
out[0] = s1
|
||||||
var carry = c1
|
var carry = c1
|
||||||
|
|
||||||
// Limb 1
|
// Limb 1
|
||||||
s1 = a[1] + b[1]
|
s1 = a[1] + b[1]
|
||||||
c1 = if (s1.toULong() < a[1].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[1])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[1] = s2
|
out[1] = s2
|
||||||
carry = c1 + c2
|
carry = c1 + c2
|
||||||
|
|
||||||
// Limb 2
|
// Limb 2
|
||||||
s1 = a[2] + b[2]
|
s1 = a[2] + b[2]
|
||||||
c1 = if (s1.toULong() < a[2].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[2])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[2] = s2
|
out[2] = s2
|
||||||
carry = c1 + c2
|
carry = c1 + c2
|
||||||
|
|
||||||
// Limb 3
|
// Limb 3
|
||||||
s1 = a[3] + b[3]
|
s1 = a[3] + b[3]
|
||||||
c1 = if (s1.toULong() < a[3].toULong()) 1L else 0L
|
c1 = if (uLt(s1, a[3])) 1L else 0L
|
||||||
s2 = s1 + carry
|
s2 = s1 + carry
|
||||||
c2 = if (s2.toULong() < s1.toULong()) 1L else 0L
|
c2 = if (uLt(s2, s1)) 1L else 0L
|
||||||
out[3] = s2
|
out[3] = s2
|
||||||
carry = c1 + c2
|
carry = c1 + c2
|
||||||
|
|
||||||
@@ -121,31 +143,31 @@ internal object U256 {
|
|||||||
|
|
||||||
// Limb 0 (no borrow input)
|
// Limb 0 (no borrow input)
|
||||||
d1 = a[0] - b[0]
|
d1 = a[0] - b[0]
|
||||||
c1 = if (a[0].toULong() < b[0].toULong()) 1L else 0L
|
c1 = if (uLt(a[0], b[0])) 1L else 0L
|
||||||
out[0] = d1
|
out[0] = d1
|
||||||
var borrow = c1
|
var borrow = c1
|
||||||
|
|
||||||
// Limb 1
|
// Limb 1
|
||||||
d1 = a[1] - b[1]
|
d1 = a[1] - b[1]
|
||||||
c1 = if (a[1].toULong() < b[1].toULong()) 1L else 0L
|
c1 = if (uLt(a[1], b[1])) 1L else 0L
|
||||||
d2 = d1 - borrow
|
d2 = d1 - borrow
|
||||||
c2 = if (d1.toULong() < borrow.toULong()) 1L else 0L
|
c2 = if (uLt(d1, borrow)) 1L else 0L
|
||||||
out[1] = d2
|
out[1] = d2
|
||||||
borrow = c1 + c2
|
borrow = c1 + c2
|
||||||
|
|
||||||
// Limb 2
|
// Limb 2
|
||||||
d1 = a[2] - b[2]
|
d1 = a[2] - b[2]
|
||||||
c1 = if (a[2].toULong() < b[2].toULong()) 1L else 0L
|
c1 = if (uLt(a[2], b[2])) 1L else 0L
|
||||||
d2 = d1 - borrow
|
d2 = d1 - borrow
|
||||||
c2 = if (d1.toULong() < borrow.toULong()) 1L else 0L
|
c2 = if (uLt(d1, borrow)) 1L else 0L
|
||||||
out[2] = d2
|
out[2] = d2
|
||||||
borrow = c1 + c2
|
borrow = c1 + c2
|
||||||
|
|
||||||
// Limb 3
|
// Limb 3
|
||||||
d1 = a[3] - b[3]
|
d1 = a[3] - b[3]
|
||||||
c1 = if (a[3].toULong() < b[3].toULong()) 1L else 0L
|
c1 = if (uLt(a[3], b[3])) 1L else 0L
|
||||||
d2 = d1 - borrow
|
d2 = d1 - borrow
|
||||||
c2 = if (d1.toULong() < borrow.toULong()) 1L else 0L
|
c2 = if (uLt(d1, borrow)) 1L else 0L
|
||||||
out[3] = d2
|
out[3] = d2
|
||||||
borrow = c1 + c2
|
borrow = c1 + c2
|
||||||
|
|
||||||
@@ -187,19 +209,19 @@ internal object U256 {
|
|||||||
|
|
||||||
lo = a0 * b1
|
lo = a0 * b1
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
out[1] = s
|
out[1] = s
|
||||||
carry = unsignedMultiplyHigh(a0, b1) + c1
|
carry = unsignedMultiplyHigh(a0, b1) + c1
|
||||||
|
|
||||||
lo = a0 * b2
|
lo = a0 * b2
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
out[2] = s
|
out[2] = s
|
||||||
carry = unsignedMultiplyHigh(a0, b2) + c1
|
carry = unsignedMultiplyHigh(a0, b2) + c1
|
||||||
|
|
||||||
lo = a0 * b3
|
lo = a0 * b3
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
out[3] = s
|
out[3] = s
|
||||||
out[4] = unsignedMultiplyHigh(a0, b3) + c1
|
out[4] = unsignedMultiplyHigh(a0, b3) + c1
|
||||||
|
|
||||||
@@ -208,7 +230,7 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a1, b0)
|
hi = unsignedMultiplyHigh(a1, b0)
|
||||||
prev = out[1]
|
prev = out[1]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
out[1] = s
|
out[1] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -216,9 +238,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a1, b1)
|
hi = unsignedMultiplyHigh(a1, b1)
|
||||||
prev = out[2]
|
prev = out[2]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[2] = s
|
out[2] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -226,9 +248,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a1, b2)
|
hi = unsignedMultiplyHigh(a1, b2)
|
||||||
prev = out[3]
|
prev = out[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[3] = s
|
out[3] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -236,9 +258,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a1, b3)
|
hi = unsignedMultiplyHigh(a1, b3)
|
||||||
prev = out[4]
|
prev = out[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[4] = s
|
out[4] = s
|
||||||
out[5] = hi + c1 + c2
|
out[5] = hi + c1 + c2
|
||||||
|
|
||||||
@@ -247,7 +269,7 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a2, b0)
|
hi = unsignedMultiplyHigh(a2, b0)
|
||||||
prev = out[2]
|
prev = out[2]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
out[2] = s
|
out[2] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -255,9 +277,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a2, b1)
|
hi = unsignedMultiplyHigh(a2, b1)
|
||||||
prev = out[3]
|
prev = out[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[3] = s
|
out[3] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -265,9 +287,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a2, b2)
|
hi = unsignedMultiplyHigh(a2, b2)
|
||||||
prev = out[4]
|
prev = out[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[4] = s
|
out[4] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -275,9 +297,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a2, b3)
|
hi = unsignedMultiplyHigh(a2, b3)
|
||||||
prev = out[5]
|
prev = out[5]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[5] = s
|
out[5] = s
|
||||||
out[6] = hi + c1 + c2
|
out[6] = hi + c1 + c2
|
||||||
|
|
||||||
@@ -286,7 +308,7 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a3, b0)
|
hi = unsignedMultiplyHigh(a3, b0)
|
||||||
prev = out[3]
|
prev = out[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
out[3] = s
|
out[3] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -294,9 +316,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a3, b1)
|
hi = unsignedMultiplyHigh(a3, b1)
|
||||||
prev = out[4]
|
prev = out[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[4] = s
|
out[4] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -304,9 +326,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a3, b2)
|
hi = unsignedMultiplyHigh(a3, b2)
|
||||||
prev = out[5]
|
prev = out[5]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[5] = s
|
out[5] = s
|
||||||
carry = hi + c1 + c2
|
carry = hi + c1 + c2
|
||||||
|
|
||||||
@@ -314,9 +336,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a3, b3)
|
hi = unsignedMultiplyHigh(a3, b3)
|
||||||
prev = out[6]
|
prev = out[6]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[6] = s
|
out[6] = s
|
||||||
out[7] = hi + c1 + c2
|
out[7] = hi + c1 + c2
|
||||||
}
|
}
|
||||||
@@ -353,13 +375,13 @@ internal object U256 {
|
|||||||
|
|
||||||
lo = a0 * a2
|
lo = a0 * a2
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
out[2] = s
|
out[2] = s
|
||||||
carry = unsignedMultiplyHigh(a0, a2) + c1
|
carry = unsignedMultiplyHigh(a0, a2) + c1
|
||||||
|
|
||||||
lo = a0 * a3
|
lo = a0 * a3
|
||||||
s = lo + carry
|
s = lo + carry
|
||||||
c1 = if (s.toULong() < lo.toULong()) 1L else 0L
|
c1 = if (uLt(s, lo)) 1L else 0L
|
||||||
out[3] = s
|
out[3] = s
|
||||||
out[4] = unsignedMultiplyHigh(a0, a3) + c1
|
out[4] = unsignedMultiplyHigh(a0, a3) + c1
|
||||||
|
|
||||||
@@ -368,7 +390,7 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a1, a2)
|
hi = unsignedMultiplyHigh(a1, a2)
|
||||||
prev = out[3]
|
prev = out[3]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
out[3] = s
|
out[3] = s
|
||||||
carry = hi + c1
|
carry = hi + c1
|
||||||
|
|
||||||
@@ -376,9 +398,9 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a1, a3)
|
hi = unsignedMultiplyHigh(a1, a3)
|
||||||
prev = out[4]
|
prev = out[4]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
s += carry
|
s += carry
|
||||||
c2 = if (s.toULong() < carry.toULong()) 1L else 0L
|
c2 = if (uLt(s, carry)) 1L else 0L
|
||||||
out[4] = s
|
out[4] = s
|
||||||
out[5] = hi + c1 + c2
|
out[5] = hi + c1 + c2
|
||||||
|
|
||||||
@@ -387,7 +409,7 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a2, a3)
|
hi = unsignedMultiplyHigh(a2, a3)
|
||||||
prev = out[5]
|
prev = out[5]
|
||||||
s = prev + lo
|
s = prev + lo
|
||||||
c1 = if (s.toULong() < prev.toULong()) 1L else 0L
|
c1 = if (uLt(s, prev)) 1L else 0L
|
||||||
out[5] = s
|
out[5] = s
|
||||||
out[6] = hi + c1
|
out[6] = hi + c1
|
||||||
|
|
||||||
@@ -419,7 +441,7 @@ internal object U256 {
|
|||||||
hi = unsignedMultiplyHigh(a0, a0)
|
hi = unsignedMultiplyHigh(a0, a0)
|
||||||
out[0] = lo // out[0] was 0
|
out[0] = lo // out[0] was 0
|
||||||
s = out[1] + hi
|
s = out[1] + hi
|
||||||
c1 = if (s.toULong() < out[1].toULong()) 1L else 0L
|
c1 = if (uLt(s, out[1])) 1L else 0L
|
||||||
out[1] = s
|
out[1] = s
|
||||||
var dCarry = c1
|
var dCarry = c1
|
||||||
|
|
||||||
@@ -427,14 +449,14 @@ internal object U256 {
|
|||||||
lo = a1 * a1
|
lo = a1 * a1
|
||||||
hi = unsignedMultiplyHigh(a1, a1)
|
hi = unsignedMultiplyHigh(a1, a1)
|
||||||
s = out[2] + lo
|
s = out[2] + lo
|
||||||
c1 = if (s.toULong() < out[2].toULong()) 1L else 0L
|
c1 = if (uLt(s, out[2])) 1L else 0L
|
||||||
s += dCarry
|
s += dCarry
|
||||||
c2 = if (s.toULong() < dCarry.toULong()) 1L else 0L
|
c2 = if (uLt(s, dCarry)) 1L else 0L
|
||||||
out[2] = s
|
out[2] = s
|
||||||
prev = out[3] + hi
|
prev = out[3] + hi
|
||||||
val c3a = if (prev.toULong() < out[3].toULong()) 1L else 0L
|
val c3a = if (uLt(prev, out[3])) 1L else 0L
|
||||||
prev += c1 + c2
|
prev += c1 + c2
|
||||||
val c4a = if (prev.toULong() < (c1 + c2).toULong()) 1L else 0L
|
val c4a = if (uLt(prev, c1 + c2)) 1L else 0L
|
||||||
out[3] = prev
|
out[3] = prev
|
||||||
dCarry = c3a + c4a
|
dCarry = c3a + c4a
|
||||||
|
|
||||||
@@ -442,14 +464,14 @@ internal object U256 {
|
|||||||
lo = a2 * a2
|
lo = a2 * a2
|
||||||
hi = unsignedMultiplyHigh(a2, a2)
|
hi = unsignedMultiplyHigh(a2, a2)
|
||||||
s = out[4] + lo
|
s = out[4] + lo
|
||||||
c1 = if (s.toULong() < out[4].toULong()) 1L else 0L
|
c1 = if (uLt(s, out[4])) 1L else 0L
|
||||||
s += dCarry
|
s += dCarry
|
||||||
c2 = if (s.toULong() < dCarry.toULong()) 1L else 0L
|
c2 = if (uLt(s, dCarry)) 1L else 0L
|
||||||
out[4] = s
|
out[4] = s
|
||||||
prev = out[5] + hi
|
prev = out[5] + hi
|
||||||
val c3b = if (prev.toULong() < out[5].toULong()) 1L else 0L
|
val c3b = if (uLt(prev, out[5])) 1L else 0L
|
||||||
prev += c1 + c2
|
prev += c1 + c2
|
||||||
val c4b = if (prev.toULong() < (c1 + c2).toULong()) 1L else 0L
|
val c4b = if (uLt(prev, c1 + c2)) 1L else 0L
|
||||||
out[5] = prev
|
out[5] = prev
|
||||||
dCarry = c3b + c4b
|
dCarry = c3b + c4b
|
||||||
|
|
||||||
@@ -457,12 +479,12 @@ internal object U256 {
|
|||||||
lo = a3 * a3
|
lo = a3 * a3
|
||||||
hi = unsignedMultiplyHigh(a3, a3)
|
hi = unsignedMultiplyHigh(a3, a3)
|
||||||
s = out[6] + lo
|
s = out[6] + lo
|
||||||
c1 = if (s.toULong() < out[6].toULong()) 1L else 0L
|
c1 = if (uLt(s, out[6])) 1L else 0L
|
||||||
s += dCarry
|
s += dCarry
|
||||||
c2 = if (s.toULong() < dCarry.toULong()) 1L else 0L
|
c2 = if (uLt(s, dCarry)) 1L else 0L
|
||||||
out[6] = s
|
out[6] = s
|
||||||
prev = out[7] + hi
|
prev = out[7] + hi
|
||||||
val c3c = if (prev.toULong() < out[7].toULong()) 1L else 0L
|
val c3c = if (uLt(prev, out[7])) 1L else 0L
|
||||||
prev += c1 + c2
|
prev += c1 + c2
|
||||||
out[7] = prev
|
out[7] = prev
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user