feat: mechanical IntArray→LongArray replacement (WIP — broken, needs manual fixes)

Bulk sed replacement of IntArray(8)→LongArray(4), IntArray(16)→LongArray(8),
intArrayOf→longArrayOf across all remaining files. This creates many compile
errors that need manual fixing:
- Type declarations still say IntArray where LongArray is needed
- Constants still have 8 values (32-bit) instead of 4 (64-bit)
- Loop bounds still reference 8 instead of 4
- toInt() casts on longArrayOf elements
- mulShift384 internals broken for new layout

https://claude.ai/code/session_01BhU63WUe9AhikZxRdw3Lpg
This commit is contained in:
Claude
2026-04-06 01:14:04 +00:00
parent 55016ff093
commit 69f222c6d5
11 changed files with 218 additions and 218 deletions
@@ -39,7 +39,7 @@ class FieldPTest {
@Test
fun addZeroIdentity() {
val a = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val zero = IntArray(8)
val zero = LongArray(4)
assertEquals(toHex(a), toHex(FieldP.add(a, zero)))
}
@@ -62,7 +62,7 @@ class FieldPTest {
@Test
fun mulOneIdentity() {
val a = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(a), toHex(FieldP.mul(a, one)))
}
@@ -72,7 +72,7 @@ class FieldPTest {
fun addNearP() {
// (p - 1) + 1 = p ≡ 0 (mod p)
val pMinus1 = hex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e")
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val result = FieldP.add(pMinus1, one)
assertTrue(U256.isZero(result))
}
@@ -89,8 +89,8 @@ class FieldPTest {
@Test
fun subUnderflow() {
// 0 - 1 ≡ p - 1 (mod p)
val zero = IntArray(8)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val zero = LongArray(4)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val result = FieldP.sub(zero, one)
val expected = hex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e") // p-1
assertEquals(toHex(expected), toHex(result))
@@ -106,7 +106,7 @@ class FieldPTest {
@Test
fun negZeroIsZero() {
assertTrue(U256.isZero(FieldP.neg(IntArray(8))))
assertTrue(U256.isZero(FieldP.neg(LongArray(4))))
}
@Test
@@ -149,13 +149,13 @@ class FieldPTest {
val a = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val aInv = FieldP.inv(a)
val product = FieldP.mul(a, aInv)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(product))
}
@Test
fun invOfOne() {
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(FieldP.inv(one)))
}
@@ -170,8 +170,8 @@ class FieldPTest {
@Test
fun halfOfEven() {
val out = IntArray(8)
val four = intArrayOf(4, 0, 0, 0, 0, 0, 0, 0)
val out = LongArray(4)
val four = longArrayOf(4, 0, 0, 0, 0, 0, 0, 0)
FieldP.half(out, four)
assertEquals(2, out[0])
for (i in 1 until 8) assertEquals(0, out[i])
@@ -180,8 +180,8 @@ class FieldPTest {
@Test
fun halfOfOdd() {
// half(1) = (1 + p) / 2 = (p + 1) / 2
val out = IntArray(8)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val out = LongArray(4)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
FieldP.half(out, one)
// Verify: 2 * half(1) = 1 mod p
val doubled = FieldP.add(out, out)
@@ -192,7 +192,7 @@ class FieldPTest {
@Test
fun halfThenDoubleRoundTrips() {
val a = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val out = IntArray(8)
val out = LongArray(4)
FieldP.half(out, a)
val doubled = FieldP.add(out, out)
assertEquals(toHex(a), toHex(doubled))
@@ -213,7 +213,7 @@ class FieldPTest {
@Test
fun sqrtOfNonResidue() {
// 3 is not a quadratic residue mod p (for secp256k1's p)
val three = intArrayOf(3, 0, 0, 0, 0, 0, 0, 0)
val three = longArrayOf(3, 0, 0, 0, 0, 0, 0, 0)
assertNull(FieldP.sqrt(three))
}
@@ -223,7 +223,7 @@ class FieldPTest {
val gx = ECPoint.GX
val gy = ECPoint.GY
val x3 = FieldP.mul(FieldP.sqr(gx), gx)
val y2 = FieldP.add(x3, intArrayOf(7, 0, 0, 0, 0, 0, 0, 0))
val y2 = FieldP.add(x3, longArrayOf(7, 0, 0, 0, 0, 0, 0, 0))
val root = FieldP.sqrt(y2)!!
// root should be gy or -gy
val isGy = U256.cmp(root, gy) == 0
@@ -240,7 +240,7 @@ class FieldPTest {
val result = FieldP.mul(pMinus1, pMinus1)
assertTrue(U256.cmp(result, FieldP.P) < 0, "Result should be < p")
// (p-1)² ≡ 1 (mod p)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(result))
}
@@ -250,7 +250,7 @@ class FieldPTest {
fun inPlaceAdd() {
val a = hex("0000000000000000000000000000000000000000000000000000000000000005")
val b = hex("0000000000000000000000000000000000000000000000000000000000000003")
val out = IntArray(8)
val out = LongArray(4)
FieldP.add(out, a, b)
assertEquals(8, out[0])
}
@@ -258,7 +258,7 @@ class FieldPTest {
@Test
fun inPlaceSqr() {
val a = hex("0000000000000000000000000000000000000000000000000000000000000005")
val out = IntArray(8)
val out = LongArray(4)
FieldP.sqr(out, a)
assertEquals(25, out[0]) // 5² = 25
}
@@ -267,7 +267,7 @@ class FieldPTest {
fun halfOfPMinus1() {
// half(p-1) should equal (p-1)/2
val pMinus1 = hex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2e")
val out = IntArray(8)
val out = LongArray(4)
FieldP.half(out, pMinus1)
// Verify: 2 * half(p-1) = p-1
val doubled = FieldP.add(out, out)
@@ -276,23 +276,23 @@ class FieldPTest {
@Test
fun invOfTwo() {
val two = intArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val two = longArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val inv2 = FieldP.inv(two)
val product = FieldP.mul(two, inv2)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(product))
}
@Test
fun sqrtOfZero() {
val zero = IntArray(8)
val zero = LongArray(4)
val root = FieldP.sqrt(zero)
assertTrue(root != null && U256.isZero(root))
}
@Test
fun sqrtOfOne() {
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val root = FieldP.sqrt(one)!!
assertEquals(toHex(one), toHex(root))
}
@@ -50,7 +50,7 @@ class GlvTest {
@Test
fun splitScalarZero() {
val split = Glv.splitScalar(IntArray(8))
val split = Glv.splitScalar(LongArray(4))
assertTrue(U256.isZero(split.k1) && U256.isZero(split.k2))
}
@@ -106,7 +106,7 @@ class GlvTest {
// β³ ≡ 1 (mod p) — the defining property of the cube root of unity
val b2 = FieldP.sqr(Glv.BETA)
val b3 = FieldP.mul(b2, Glv.BETA)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(b3))
}
@@ -115,8 +115,8 @@ class GlvTest {
// λ·G should equal (β·Gx, Gy)
val result = MutablePoint()
ECPoint.mulG(result, LAMBDA)
val rx = IntArray(8)
val ry = IntArray(8)
val rx = LongArray(4)
val ry = LongArray(4)
ECPoint.toAffine(result, rx, ry)
assertEquals(toHex(FieldP.mul(ECPoint.GX, Glv.BETA)), toHex(rx))
assertEquals(toHex(ECPoint.GY), toHex(ry))
@@ -127,7 +127,7 @@ class GlvTest {
@Test
fun wnafReconstructionSmall() {
// wNAF digits should reconstruct to the original scalar
val k = intArrayOf(17, 0, 0, 0, 0, 0, 0, 0) // 17 = 10001 in binary
val k = longArrayOf(17, 0, 0, 0, 0, 0, 0, 0) // 17 = 10001 in binary
val digits = Glv.wnaf(k, 5, 256)
assertEquals(k[0], reconstructWnaf(digits)[0])
}
@@ -180,7 +180,7 @@ class GlvTest {
@Test
fun wnafSmallMaxBits() {
// wNAF with maxBits=129 (used for GLV half-scalars)
val k = intArrayOf(0x12345678.toInt(), 0x9ABCDEF0.toInt(), 0x11111111, 0x22222222, 0, 0, 0, 0)
val k = longArrayOf(0x12345678.toInt(), 0x9ABCDEF0.toInt(), 0x11111111, 0x22222222, 0, 0, 0, 0)
val digits = Glv.wnaf(k, 5, 129)
val reconstructed = reconstructWnaf(digits)
for (i in 0 until 4) assertEquals(k[i], reconstructed[i], "Limb $i mismatch for 129-bit wNAF")
@@ -193,16 +193,16 @@ class GlvTest {
// s·G + 0·P = s·G
val s = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val p = MutablePoint()
ECPoint.mulG(p, intArrayOf(2, 0, 0, 0, 0, 0, 0, 0))
ECPoint.mulG(p, longArrayOf(2, 0, 0, 0, 0, 0, 0, 0))
val combined = MutablePoint()
ECPoint.mulDoubleG(combined, s, p, IntArray(8))
val cx = IntArray(8)
val cy = IntArray(8)
ECPoint.mulDoubleG(combined, s, p, LongArray(4))
val cx = LongArray(4)
val cy = LongArray(4)
ECPoint.toAffine(combined, cx, cy)
val direct = MutablePoint()
ECPoint.mulG(direct, s)
val dx = IntArray(8)
val dy = IntArray(8)
val dx = LongArray(4)
val dy = LongArray(4)
ECPoint.toAffine(direct, dx, dy)
assertEquals(toHex(dx), toHex(cx))
}
@@ -211,9 +211,9 @@ class GlvTest {
/** Reconstruct a scalar from wNAF digits using Horner's method. */
private fun reconstructWnaf(digits: IntArray): IntArray {
var acc = IntArray(8)
var acc = LongArray(4)
for (bit in digits.size - 1 downTo 0) {
val doubled = IntArray(8)
val doubled = LongArray(4)
var carry = 0L
for (j in 0 until 8) {
carry += (acc[j].toLong() and 0xFFFFFFFFL) * 2L
@@ -33,8 +33,8 @@ class KeyCodecTest {
@Test
fun liftXGenerator() {
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(KeyCodec.liftX(x, y, ECPoint.GX))
assertEquals(toHex(ECPoint.GX), toHex(x))
assertTrue(KeyCodec.hasEvenY(y))
@@ -43,25 +43,25 @@ class KeyCodecTest {
@Test
fun liftXInvalidFieldElement() {
// p itself is not a valid x
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertFalse(KeyCodec.liftX(x, y, FieldP.P))
}
@Test
fun liftXNotOnCurve() {
// x=2: y² = 8+7 = 15. 15 is not a quadratic residue mod p.
val x = IntArray(8)
val y = IntArray(8)
val two = intArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val x = LongArray(4)
val y = LongArray(4)
val two = longArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
// This may or may not be on the curve — just check it doesn't crash
KeyCodec.liftX(x, y, two) // result doesn't matter, just no exception
}
@Test
fun liftXAlwaysReturnsEvenY() {
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(KeyCodec.liftX(x, y, ECPoint.GX))
assertTrue(KeyCodec.hasEvenY(y), "liftX should always return even y")
}
@@ -70,14 +70,14 @@ class KeyCodecTest {
@Test
fun hasEvenYForEvenValue() {
assertTrue(KeyCodec.hasEvenY(intArrayOf(2, 0, 0, 0, 0, 0, 0, 0)))
assertTrue(KeyCodec.hasEvenY(intArrayOf(0, 0, 0, 0, 0, 0, 0, 0)))
assertTrue(KeyCodec.hasEvenY(longArrayOf(2, 0, 0, 0, 0, 0, 0, 0)))
assertTrue(KeyCodec.hasEvenY(longArrayOf(0, 0, 0, 0, 0, 0, 0, 0)))
}
@Test
fun hasEvenYForOddValue() {
assertFalse(KeyCodec.hasEvenY(intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)))
assertFalse(KeyCodec.hasEvenY(intArrayOf(3, 0, 0, 0, 0, 0, 0, 0)))
assertFalse(KeyCodec.hasEvenY(longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)))
assertFalse(KeyCodec.hasEvenY(longArrayOf(3, 0, 0, 0, 0, 0, 0, 0)))
}
// ==================== parsePublicKey ====================
@@ -86,8 +86,8 @@ class KeyCodecTest {
fun parseCompressedEvenY() {
val compressed = KeyCodec.serializeCompressed(ECPoint.GX, ECPoint.GY)
assertEquals(0x02.toByte(), compressed[0])
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(KeyCodec.parsePublicKey(compressed, x, y))
assertEquals(toHex(ECPoint.GX), toHex(x))
assertEquals(toHex(ECPoint.GY), toHex(y))
@@ -98,8 +98,8 @@ class KeyCodecTest {
val negGy = FieldP.neg(ECPoint.GY)
val compressed = KeyCodec.serializeCompressed(ECPoint.GX, negGy)
assertEquals(0x03.toByte(), compressed[0])
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(KeyCodec.parsePublicKey(compressed, x, y))
assertEquals(toHex(ECPoint.GX), toHex(x))
assertEquals(toHex(negGy), toHex(y))
@@ -109,8 +109,8 @@ class KeyCodecTest {
fun parseUncompressed() {
val uncompressed = KeyCodec.serializeUncompressed(ECPoint.GX, ECPoint.GY)
assertEquals(0x04.toByte(), uncompressed[0])
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(KeyCodec.parsePublicKey(uncompressed, x, y))
assertEquals(toHex(ECPoint.GX), toHex(x))
assertEquals(toHex(ECPoint.GY), toHex(y))
@@ -118,8 +118,8 @@ class KeyCodecTest {
@Test
fun parseInvalidSizes() {
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertFalse(KeyCodec.parsePublicKey(ByteArray(0), x, y))
assertFalse(KeyCodec.parsePublicKey(ByteArray(10), x, y))
assertFalse(KeyCodec.parsePublicKey(ByteArray(32), x, y))
@@ -130,8 +130,8 @@ class KeyCodecTest {
@Test
fun parseInvalidPrefix() {
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertFalse(KeyCodec.parsePublicKey(ByteArray(33), x, y)) // prefix 0x00
assertFalse(KeyCodec.parsePublicKey(ByteArray(65), x, y)) // prefix 0x00
}
@@ -143,8 +143,8 @@ class KeyCodecTest {
fake[0] = 0x04
fake[1] = 0x01 // x = 1 (padded)
fake[33] = 0x01 // y = 1 (padded) — 1² ≠ 1³ + 7
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertFalse(KeyCodec.parsePublicKey(fake, x, y))
}
@@ -153,8 +153,8 @@ class KeyCodecTest {
@Test
fun compressDecompressRoundTrip() {
val compressed = KeyCodec.serializeCompressed(ECPoint.GX, ECPoint.GY)
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(KeyCodec.parsePublicKey(compressed, x, y))
val recompressed = KeyCodec.serializeCompressed(x, y)
assertEquals(compressed.toList(), recompressed.toList())
@@ -163,8 +163,8 @@ class KeyCodecTest {
@Test
fun uncompressedRoundTrip() {
val uncompressed = KeyCodec.serializeUncompressed(ECPoint.GX, ECPoint.GY)
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(KeyCodec.parsePublicKey(uncompressed, x, y))
val reser = KeyCodec.serializeUncompressed(x, y)
assertEquals(uncompressed.toList(), reser.toList())
@@ -40,7 +40,7 @@ class PointTest {
fun generatorIsOnCurve() {
// y² = x³ + 7
val x3 = FieldP.mul(FieldP.sqr(ECPoint.GX), ECPoint.GX)
val y2expected = FieldP.add(x3, intArrayOf(7, 0, 0, 0, 0, 0, 0, 0))
val y2expected = FieldP.add(x3, longArrayOf(7, 0, 0, 0, 0, 0, 0, 0))
val y2actual = FieldP.sqr(ECPoint.GY)
assertEquals(toHex(y2expected), toHex(y2actual))
}
@@ -54,16 +54,16 @@ class PointTest {
p.setAffine(ECPoint.GX, ECPoint.GY)
val doubled = MutablePoint()
ECPoint.doublePoint(doubled, p)
val dx = IntArray(8)
val dy = IntArray(8)
val dx = LongArray(4)
val dy = LongArray(4)
ECPoint.toAffine(doubled, dx, dy)
// 2·G via scalar multiplication
val two = intArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val two = longArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val mulResult = MutablePoint()
ECPoint.mulG(mulResult, two)
val mx = IntArray(8)
val my = IntArray(8)
val mx = LongArray(4)
val my = LongArray(4)
ECPoint.toAffine(mulResult, mx, my)
assertEquals(toHex(mx), toHex(dx))
@@ -76,15 +76,15 @@ class PointTest {
val p = MutablePoint()
p.setAffine(ECPoint.GX, ECPoint.GY)
ECPoint.doublePoint(p, p)
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
ECPoint.toAffine(p, x, y)
val two = intArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val two = longArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val expected = MutablePoint()
ECPoint.mulG(expected, two)
val ex = IntArray(8)
val ey = IntArray(8)
val ex = LongArray(4)
val ey = LongArray(4)
ECPoint.toAffine(expected, ex, ey)
assertEquals(toHex(ex), toHex(x))
@@ -107,14 +107,14 @@ class PointTest {
g.setAffine(ECPoint.GX, ECPoint.GY)
val sum = MutablePoint()
ECPoint.addPoints(sum, g, g)
val sx = IntArray(8)
val sy = IntArray(8)
val sx = LongArray(4)
val sy = LongArray(4)
ECPoint.toAffine(sum, sx, sy)
val doubled = MutablePoint()
ECPoint.doublePoint(doubled, g)
val dx = IntArray(8)
val dy = IntArray(8)
val dx = LongArray(4)
val dy = LongArray(4)
ECPoint.toAffine(doubled, dx, dy)
assertEquals(toHex(dx), toHex(sx))
@@ -130,15 +130,15 @@ class PointTest {
val result = MutablePoint()
ECPoint.addPoints(result, g, inf)
val rx = IntArray(8)
val ry = IntArray(8)
val rx = LongArray(4)
val ry = LongArray(4)
ECPoint.toAffine(result, rx, ry)
assertEquals(toHex(ECPoint.GX), toHex(rx))
val result2 = MutablePoint()
ECPoint.addPoints(result2, inf, g)
val r2x = IntArray(8)
val r2y = IntArray(8)
val r2x = LongArray(4)
val r2y = LongArray(4)
ECPoint.toAffine(result2, r2x, r2y)
assertEquals(toHex(ECPoint.GX), toHex(r2x))
}
@@ -161,15 +161,15 @@ class PointTest {
@Test
fun addMixedMatchesFull() {
// addMixed should produce the same result as addPoints when q is affine
val three = intArrayOf(3, 0, 0, 0, 0, 0, 0, 0)
val three = longArrayOf(3, 0, 0, 0, 0, 0, 0, 0)
val p = MutablePoint()
ECPoint.mulG(p, three) // 3G in Jacobian (z ≠ 1)
// Add G as affine
val mixed = MutablePoint()
ECPoint.addMixed(mixed, p, ECPoint.GX, ECPoint.GY)
val mx = IntArray(8)
val my = IntArray(8)
val mx = LongArray(4)
val my = LongArray(4)
ECPoint.toAffine(mixed, mx, my)
// Add G as Jacobian
@@ -177,8 +177,8 @@ class PointTest {
gJac.setAffine(ECPoint.GX, ECPoint.GY)
val full = MutablePoint()
ECPoint.addPoints(full, p, gJac)
val fx = IntArray(8)
val fy = IntArray(8)
val fx = LongArray(4)
val fy = LongArray(4)
ECPoint.toAffine(full, fx, fy)
assertEquals(toHex(fx), toHex(mx))
@@ -191,8 +191,8 @@ class PointTest {
inf.setInfinity()
val result = MutablePoint()
ECPoint.addMixed(result, inf, ECPoint.GX, ECPoint.GY)
val rx = IntArray(8)
val ry = IntArray(8)
val rx = LongArray(4)
val ry = LongArray(4)
ECPoint.toAffine(result, rx, ry)
assertEquals(toHex(ECPoint.GX), toHex(rx))
}
@@ -201,11 +201,11 @@ class PointTest {
@Test
fun mulGByOne() {
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val result = MutablePoint()
ECPoint.mulG(result, one)
val rx = IntArray(8)
val ry = IntArray(8)
val rx = LongArray(4)
val ry = LongArray(4)
ECPoint.toAffine(result, rx, ry)
assertEquals(toHex(ECPoint.GX), toHex(rx))
assertEquals(toHex(ECPoint.GY), toHex(ry))
@@ -213,7 +213,7 @@ class PointTest {
@Test
fun mulGByZeroIsInfinity() {
val zero = IntArray(8)
val zero = LongArray(4)
val result = MutablePoint()
ECPoint.mulG(result, zero)
assertTrue(result.isInfinity())
@@ -233,16 +233,16 @@ class PointTest {
val k = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val gResult = MutablePoint()
ECPoint.mulG(gResult, k)
val gx = IntArray(8)
val gy = IntArray(8)
val gx = LongArray(4)
val gy = LongArray(4)
ECPoint.toAffine(gResult, gx, gy)
val g = MutablePoint()
g.setAffine(ECPoint.GX, ECPoint.GY)
val mResult = MutablePoint()
ECPoint.mul(mResult, g, k)
val mx = IntArray(8)
val my = IntArray(8)
val mx = LongArray(4)
val my = LongArray(4)
ECPoint.toAffine(mResult, mx, my)
assertEquals(toHex(mx), toHex(gx))
@@ -256,14 +256,14 @@ class PointTest {
val e = hex("3982f19bef1615bccfbb05e321c10e1d4cba3df0e841c2e41eeb6016347653c3")
val p = MutablePoint()
val two = intArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val two = longArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
ECPoint.mulG(p, two) // P = 2·G
// Combined
val combined = MutablePoint()
ECPoint.mulDoubleG(combined, s, p, e)
val cx = IntArray(8)
val cy = IntArray(8)
val cx = LongArray(4)
val cy = LongArray(4)
ECPoint.toAffine(combined, cx, cy)
// Separate
@@ -273,8 +273,8 @@ class PointTest {
ECPoint.mul(eP, p, e)
val sep = MutablePoint()
ECPoint.addPoints(sep, sG, eP)
val sx = IntArray(8)
val sy = IntArray(8)
val sx = LongArray(4)
val sy = LongArray(4)
ECPoint.toAffine(sep, sx, sy)
assertEquals(toHex(sx), toHex(cx))
@@ -285,8 +285,8 @@ class PointTest {
@Test
fun liftXGenerator() {
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(ECPoint.liftX(x, y, ECPoint.GX))
assertEquals(toHex(ECPoint.GX), toHex(x))
// liftX returns even y
@@ -296,8 +296,8 @@ class PointTest {
@Test
fun liftXInvalidX() {
// p itself is not a valid x coordinate
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertFalse(ECPoint.liftX(x, y, FieldP.P))
}
@@ -306,8 +306,8 @@ class PointTest {
@Test
fun compressDecompressRoundTrip() {
val compressed = ECPoint.serializeCompressed(ECPoint.GX, ECPoint.GY)
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(ECPoint.parsePublicKey(compressed, x, y))
assertEquals(toHex(ECPoint.GX), toHex(x))
assertEquals(toHex(ECPoint.GY), toHex(y))
@@ -316,8 +316,8 @@ class PointTest {
@Test
fun uncompressedRoundTrip() {
val uncompressed = ECPoint.serializeUncompressed(ECPoint.GX, ECPoint.GY)
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(ECPoint.parsePublicKey(uncompressed, x, y))
assertEquals(toHex(ECPoint.GX), toHex(x))
assertEquals(toHex(ECPoint.GY), toHex(y))
@@ -325,8 +325,8 @@ class PointTest {
@Test
fun parseInvalidKey() {
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertFalse(ECPoint.parsePublicKey(ByteArray(10), x, y))
assertFalse(ECPoint.parsePublicKey(ByteArray(33), x, y)) // wrong prefix (0x00)
}
@@ -338,13 +338,13 @@ class PointTest {
p.setAffine(ECPoint.GX, ECPoint.GY)
val result = MutablePoint()
ECPoint.addMixed(result, p, ECPoint.GX, ECPoint.GY)
val rx = IntArray(8)
val ry = IntArray(8)
val rx = LongArray(4)
val ry = LongArray(4)
ECPoint.toAffine(result, rx, ry)
val doubled = MutablePoint()
ECPoint.doublePoint(doubled, p)
val dx = IntArray(8)
val dy = IntArray(8)
val dx = LongArray(4)
val dy = LongArray(4)
ECPoint.toAffine(doubled, dx, dy)
assertEquals(toHex(dx), toHex(rx))
}
@@ -369,8 +369,8 @@ class PointTest {
val pubkey = Secp256k1.pubkeyCreate(privKeyBytes)
val compressed = Secp256k1.pubKeyCompress(pubkey)
assertEquals(0x03.toByte(), compressed[0]) // Odd y → 03 prefix
val x = IntArray(8)
val y = IntArray(8)
val x = LongArray(4)
val y = LongArray(4)
assertTrue(ECPoint.parsePublicKey(compressed, x, y))
// Round-trip: compress again should give same result
val recompressed = ECPoint.serializeCompressed(x, y)
@@ -43,7 +43,7 @@ class ScalarNTest {
@Test
fun isValidZero() {
assertFalse(ScalarN.isValid(IntArray(8)))
assertFalse(ScalarN.isValid(LongArray(4)))
}
@Test
@@ -63,7 +63,7 @@ class ScalarNTest {
@Test
fun addZeroIdentity() {
val a = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
assertEquals(toHex(a), toHex(ScalarN.add(a, IntArray(8))))
assertEquals(toHex(a), toHex(ScalarN.add(a, LongArray(4))))
}
@Test
@@ -96,7 +96,7 @@ class ScalarNTest {
@Test
fun mulOneIdentity() {
val a = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(a), toHex(ScalarN.mul(a, one)))
}
@@ -124,7 +124,7 @@ class ScalarNTest {
val a = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val aInv = ScalarN.inv(a)
val product = ScalarN.mul(a, aInv)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(product))
}
@@ -134,7 +134,7 @@ class ScalarNTest {
fun addNearN() {
// (n-1) + 1 should wrap to 0
val nMinus1 = hex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140")
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertTrue(U256.isZero(ScalarN.add(nMinus1, one)))
}
@@ -142,9 +142,9 @@ class ScalarNTest {
fun addNearNWrap() {
// (n-1) + 2 should give 1
val nMinus1 = hex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140")
val two = intArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val two = longArrayOf(2, 0, 0, 0, 0, 0, 0, 0)
val result = ScalarN.add(nMinus1, two)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(result))
}
@@ -153,13 +153,13 @@ class ScalarNTest {
// (n-1) * (n-1) ≡ 1 mod n (since (n-1) ≡ -1 and (-1)² = 1)
val nMinus1 = hex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140")
val result = ScalarN.mul(nMinus1, nMinus1)
val one = intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
val one = longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)
assertEquals(toHex(one), toHex(result))
}
@Test
fun negOfZeroIsZero() {
assertTrue(U256.isZero(ScalarN.neg(IntArray(8))))
assertTrue(U256.isZero(ScalarN.neg(LongArray(4))))
}
@Test
@@ -37,13 +37,13 @@ class U256Test {
// ==================== isZero / cmp ====================
@Test
fun isZeroTrue() = assertTrue(U256.isZero(IntArray(8)))
fun isZeroTrue() = assertTrue(U256.isZero(LongArray(4)))
@Test
fun isZeroFalse() = assertFalse(U256.isZero(intArrayOf(1, 0, 0, 0, 0, 0, 0, 0)))
fun isZeroFalse() = assertFalse(U256.isZero(longArrayOf(1, 0, 0, 0, 0, 0, 0, 0)))
@Test
fun isZeroHighBit() = assertFalse(U256.isZero(intArrayOf(0, 0, 0, 0, 0, 0, 0, 1)))
fun isZeroHighBit() = assertFalse(U256.isZero(longArrayOf(0, 0, 0, 0, 0, 0, 0, 1)))
@Test
fun cmpEqual() = assertEquals(0, U256.cmp(hex("0000000000000000000000000000000000000000000000000000000000000001"), hex("0000000000000000000000000000000000000000000000000000000000000001")))
@@ -58,7 +58,7 @@ class U256Test {
@Test
fun addSimple() {
val out = IntArray(8)
val out = LongArray(4)
val carry = U256.addTo(out, hex("0000000000000000000000000000000000000000000000000000000000000001"), hex("0000000000000000000000000000000000000000000000000000000000000002"))
assertEquals("0000000000000000000000000000000000000000000000000000000000000003", toHex(out))
assertEquals(0, carry)
@@ -66,7 +66,7 @@ class U256Test {
@Test
fun addOverflow() {
val out = IntArray(8)
val out = LongArray(4)
val carry = U256.addTo(out, hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), hex("0000000000000000000000000000000000000000000000000000000000000001"))
assertEquals("0000000000000000000000000000000000000000000000000000000000000000", toHex(out))
assertEquals(1, carry)
@@ -74,14 +74,14 @@ class U256Test {
@Test
fun addLimbCarry() {
val out = IntArray(8)
val out = LongArray(4)
U256.addTo(out, hex("00000000000000000000000000000000000000000000000000000000ffffffff"), hex("0000000000000000000000000000000000000000000000000000000000000001"))
assertEquals("0000000000000000000000000000000000000000000000000000000100000000", toHex(out))
}
@Test
fun subSimple() {
val out = IntArray(8)
val out = LongArray(4)
val borrow = U256.subTo(out, hex("0000000000000000000000000000000000000000000000000000000000000003"), hex("0000000000000000000000000000000000000000000000000000000000000001"))
assertEquals("0000000000000000000000000000000000000000000000000000000000000002", toHex(out))
assertEquals(0, borrow)
@@ -89,7 +89,7 @@ class U256Test {
@Test
fun subUnderflow() {
val out = IntArray(8)
val out = LongArray(4)
val borrow = U256.subTo(out, hex("0000000000000000000000000000000000000000000000000000000000000000"), hex("0000000000000000000000000000000000000000000000000000000000000001"))
assertEquals("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", toHex(out))
assertEquals(1, borrow)
@@ -99,7 +99,7 @@ class U256Test {
@Test
fun mulWideSmall() {
val out = IntArray(16)
val out = LongArray(8)
U256.mulWide(out, hex("0000000000000000000000000000000000000000000000000000000000000003"), hex("0000000000000000000000000000000000000000000000000000000000000007"))
// 3 * 7 = 21 = 0x15
assertEquals(0x15, out[0])
@@ -109,8 +109,8 @@ class U256Test {
@Test
fun mulWideLarge() {
// (2^128 - 1)² consistency: mulWide and sqrWide should match
val out1 = IntArray(16)
val out2 = IntArray(16)
val out1 = LongArray(8)
val out2 = LongArray(8)
val maxHalf = hex("00000000000000000000000000000000ffffffffffffffffffffffffffffffff")
U256.mulWide(out1, maxHalf, maxHalf)
U256.sqrWide(out2, maxHalf)
@@ -123,9 +123,9 @@ class U256Test {
fun sqrWideMatchesMulWide() {
// sqrWide(a) should produce the same result as mulWide(a, a)
val a = hex("67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530")
val mulResult = IntArray(16)
val mulResult = LongArray(8)
U256.mulWide(mulResult, a, a)
val sqrResult = IntArray(16)
val sqrResult = LongArray(8)
U256.sqrWide(sqrResult, a)
for (i in 0 until 16) {
assertEquals(mulResult[i], sqrResult[i], "Limb $i mismatch")
@@ -136,9 +136,9 @@ class U256Test {
fun sqrWideMaxValue() {
// (2^256 - 1)^2 should match mulWide
val maxVal = hex("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
val mulResult = IntArray(16)
val mulResult = LongArray(8)
U256.mulWide(mulResult, maxVal, maxVal)
val sqrResult = IntArray(16)
val sqrResult = LongArray(8)
U256.sqrWide(sqrResult, maxVal)
for (i in 0 until 16) {
assertEquals(mulResult[i], sqrResult[i], "Limb $i mismatch for max value sqr")
@@ -201,7 +201,7 @@ class U256Test {
@Test
fun xorBasic() {
val out = IntArray(8)
val out = LongArray(4)
U256.xorTo(out, hex("ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00"), hex("0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"))
assertEquals("f00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00f", toHex(out))
}
@@ -221,7 +221,7 @@ class U256Test {
@Test
fun copyIntoTest() {
val src = hex("67e56582298859ddae725f972992a07c6c4fb9f62a8fff58ce3ca926a1063530")
val dst = IntArray(8)
val dst = LongArray(4)
U256.copyInto(dst, src)
for (i in 0 until 8) assertEquals(src[i], dst[i])
}