From fe5f07da3fcf1976a84f18abb86ee5bc89a2a28d Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Mon, 6 Apr 2026 17:55:54 -0400 Subject: [PATCH] Moves the hex operations to our own functions --- .../nip44Encryption/crypto/XChaCha20Test.kt | 3 ++- .../quartz/utils/secp256k1/FieldPTest.kt | 9 ++++----- .../quartz/utils/secp256k1/GlvTest.kt | 9 ++++----- .../quartz/utils/secp256k1/KeyCodecTest.kt | 3 ++- .../quartz/utils/secp256k1/PointTest.kt | 15 +++++---------- .../quartz/utils/secp256k1/ScalarNTest.kt | 9 ++++----- .../quartz/utils/secp256k1/U256Test.kt | 13 ++++++------- 7 files changed, 27 insertions(+), 34 deletions(-) diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/XChaCha20Test.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/XChaCha20Test.kt index 71c14f07e..6d6d17f48 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/XChaCha20Test.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/crypto/XChaCha20Test.kt @@ -20,12 +20,13 @@ */ package com.vitorpamplona.quartz.nip44Encryption.crypto +import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray import kotlin.test.Test import kotlin.test.assertContentEquals /** Test vectors from libsodium xchacha20.c */ class XChaCha20Test { - private fun hex(s: String): ByteArray = s.chunked(2).map { it.toInt(16).toByte() }.toByteArray() + private fun hex(s: String): ByteArray = s.hexToByteArray() // HChaCha20 test vectors from libsodium data class HChaCha20TV( diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldPTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldPTest.kt index 96555adab..dbee6eda0 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldPTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/FieldPTest.kt @@ -20,6 +20,8 @@ */ package com.vitorpamplona.quartz.utils.secp256k1 +import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.core.toHexKey import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNull @@ -27,12 +29,9 @@ import kotlin.test.assertTrue /** Tests for field arithmetic modulo p. */ class FieldPTest { - private fun hex(s: String) = - U256.fromBytes( - s.chunked(2).map { it.toInt(16).toByte() }.toByteArray(), - ) + private fun hex(s: String) = U256.fromBytes(s.hexToByteArray()) - private fun toHex(a: LongArray) = U256.toBytes(a).joinToString("") { "%02x".format(it) } + private fun toHex(a: LongArray) = U256.toBytes(a).toHexKey() // ==================== Basic identities ==================== diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/GlvTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/GlvTest.kt index 557128d3a..02f64310b 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/GlvTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/GlvTest.kt @@ -20,18 +20,17 @@ */ package com.vitorpamplona.quartz.utils.secp256k1 +import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.core.toHexKey import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue /** Comprehensive tests for GLV endomorphism and wNAF encoding. */ class GlvTest { - private fun toHex(a: LongArray) = U256.toBytes(a).joinToString("") { "%02x".format(it) } + private fun toHex(a: LongArray) = U256.toBytes(a).toHexKey() - private fun hex(s: String) = - U256.fromBytes( - s.chunked(2).map { it.toInt(16).toByte() }.toByteArray(), - ) + private fun hex(s: String) = U256.fromBytes(s.hexToByteArray()) @Suppress("ktlint:standard:property-naming") private val LAMBDA = hex("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72") diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/KeyCodecTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/KeyCodecTest.kt index bc68ba70e..ce93125bb 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/KeyCodecTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/KeyCodecTest.kt @@ -20,6 +20,7 @@ */ package com.vitorpamplona.quartz.utils.secp256k1 +import com.vitorpamplona.quartz.nip01Core.core.toHexKey import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -27,7 +28,7 @@ import kotlin.test.assertTrue /** Tests for KeyCodec: key parsing, serialization, liftX, hasEvenY. */ class KeyCodecTest { - private fun toHex(a: LongArray) = U256.toBytes(a).joinToString("") { "%02x".format(it) } + private fun toHex(a: LongArray) = U256.toBytes(a).toHexKey() // ==================== liftX ==================== diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/PointTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/PointTest.kt index d0cc6eb9e..84ac2ddb5 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/PointTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/PointTest.kt @@ -20,6 +20,8 @@ */ package com.vitorpamplona.quartz.utils.secp256k1 +import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.core.toHexKey import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -27,12 +29,9 @@ import kotlin.test.assertTrue /** Tests for elliptic curve point operations. */ class PointTest { - private fun hex(s: String) = - U256.fromBytes( - s.chunked(2).map { it.toInt(16).toByte() }.toByteArray(), - ) + private fun hex(s: String) = U256.fromBytes(s.hexToByteArray()) - private fun toHex(a: LongArray) = U256.toBytes(a).joinToString("") { "%02x".format(it) } + private fun toHex(a: LongArray) = U256.toBytes(a).toHexKey() // ==================== Generator point ==================== @@ -361,11 +360,7 @@ class PointTest { @Test fun parseCompressedOddY() { - val privKeyBytes = - "65f039136f8da8d3e87b4818746b53318d5481e24b2673f162815144223a0b5a" - .chunked(2) - .map { it.toInt(16).toByte() } - .toByteArray() + val privKeyBytes = "65f039136f8da8d3e87b4818746b53318d5481e24b2673f162815144223a0b5a".hexToByteArray() val pubkey = Secp256k1.pubkeyCreate(privKeyBytes) val compressed = Secp256k1.pubKeyCompress(pubkey) assertEquals(0x03.toByte(), compressed[0]) // Odd y → 03 prefix diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/ScalarNTest.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/ScalarNTest.kt index c3e3728c6..888d99595 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/ScalarNTest.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/ScalarNTest.kt @@ -20,6 +20,8 @@ */ package com.vitorpamplona.quartz.utils.secp256k1 +import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.core.toHexKey import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -27,12 +29,9 @@ import kotlin.test.assertTrue /** Tests for scalar arithmetic modulo n. */ class ScalarNTest { - private fun hex(s: String) = - U256.fromBytes( - s.chunked(2).map { it.toInt(16).toByte() }.toByteArray(), - ) + private fun hex(s: String) = U256.fromBytes(s.hexToByteArray()) - private fun toHex(a: LongArray) = U256.toBytes(a).joinToString("") { "%02x".format(it) } + private fun toHex(a: LongArray) = U256.toBytes(a).toHexKey() // ==================== isValid ==================== diff --git a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256Test.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256Test.kt index f1e22e1cd..390e714ed 100644 --- a/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256Test.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/utils/secp256k1/U256Test.kt @@ -20,6 +20,8 @@ */ package com.vitorpamplona.quartz.utils.secp256k1 +import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray +import com.vitorpamplona.quartz.nip01Core.core.toHexKey import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -27,12 +29,9 @@ import kotlin.test.assertTrue /** Tests for 256-bit unsigned integer arithmetic. */ class U256Test { - private fun hex(s: String) = - U256.fromBytes( - s.chunked(2).map { it.toInt(16).toByte() }.toByteArray(), - ) + private fun hex(s: String) = U256.fromBytes(s.hexToByteArray()) - private fun toHex(a: LongArray) = U256.toBytes(a).joinToString("") { "%02x".format(it) } + private fun toHex(a: LongArray) = U256.toBytes(a).toHexKey() // ==================== isZero / cmp ==================== @@ -150,10 +149,10 @@ class U256Test { @Test fun bytesRoundTrip() { val hex = "67E56582298859DDAE725F972992A07C6C4FB9F62A8FFF58CE3CA926A1063530" - val bytes = hex.chunked(2).map { it.toInt(16).toByte() }.toByteArray() + val bytes = hex.hexToByteArray() val limbs = U256.fromBytes(bytes) val back = U256.toBytes(limbs) - assertEquals(hex.lowercase(), back.joinToString("") { "%02x".format(it) }) + assertEquals(hex.lowercase(), back.toHexKey()) } @Test