From fba35559f486fd7edc158a343df139a67fc03aeb Mon Sep 17 00:00:00 2001 From: Vexta Project Date: Tue, 8 Sep 2026 21:39:06 +0000 Subject: [PATCH] Prepare v0.7.0 release build --- app/src/main/assets/pq-core-mldsa.sig | Bin 3309 -> 0 bytes app/src/main/assets/pq-core-sphincs.sig | Bin 7856 -> 0 bytes .../wallet/VextaTransactionSender.kt | 354 ------------ .../org/vextaproject/wallet/WalletActivity.kt | 505 ------------------ 4 files changed, 859 deletions(-) delete mode 100644 app/src/main/assets/pq-core-mldsa.sig delete mode 100644 app/src/main/assets/pq-core-sphincs.sig diff --git a/app/src/main/assets/pq-core-mldsa.sig b/app/src/main/assets/pq-core-mldsa.sig deleted file mode 100644 index 2511d9b81e2b280029bd434ef2f6d009dc073fda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3309 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 diff --git a/app/src/main/assets/pq-core-sphincs.sig b/app/src/main/assets/pq-core-sphincs.sig deleted file mode 100644 index 15317594b67a5b65aa400345ad8a1b6494d51391..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7856 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 OB`MtQ0i=$UjjBEYJv1`_ diff --git a/app/src/main/java/org/vextaproject/wallet/VextaTransactionSender.kt b/app/src/main/java/org/vextaproject/wallet/VextaTransactionSender.kt index 24edd58..5c6f857 100644 --- a/app/src/main/java/org/vextaproject/wallet/VextaTransactionSender.kt +++ b/app/src/main/java/org/vextaproject/wallet/VextaTransactionSender.kt @@ -548,76 +548,6 @@ object VextaTransactionSender { return doubleSha256(preimage) } - fun runPqrSignatureHashSelfTest(): Pair { - val selected = listOf( - BlockScanner.SpendableUtxo( - txid = - "0000000000000000000000000000000000000000000000000000000000000001", - outputIndex = 3L, - value = 987654L, - height = 1, - addressIndex = 0, - isCoinbase = false, - addressType = BlockScanner.AddressType.MLDSA - ) - ) - - val outputs = listOf( - TransactionOutputData( - value = 123456L, - script = byteArrayOf(0x51) - ) - ) - - val program = - ByteArray(32) { index -> - index.toByte() - } - - val v2 = calculatePqrSignatureHash( - selected = selected, - outputs = outputs, - inputIndex = 0, - witnessVersion = 2, - witnessProgram = program, - amount = 987654L, - version = 2, - lockTime = 500L, - inputSequence = 0xfffffffeL - ) - - val v3 = calculatePqrSignatureHash( - selected = selected, - outputs = outputs, - inputIndex = 0, - witnessVersion = 3, - witnessProgram = program, - amount = 987654L, - version = 2, - lockTime = 500L, - inputSequence = 0xfffffffeL - ) - - val v2CoreHex = v2.reversedArray().toHex() - val v3CoreHex = v3.reversedArray().toHex() - - check( - v2CoreHex == - "ba39c447b4577db974473a1e7ed2182686672f2900045a40aee6b4dc5811995b" - ) { - "PQR V2 signature hash self-test failed: $v2CoreHex" - } - - check( - v3CoreHex == - "dab3188530f1094ef87087451da77bfba77dfc6e63d1730bb9d0475cebe76618" - ) { - "PQR V3 signature hash self-test failed: $v3CoreHex" - } - - return v2CoreHex to v3CoreHex - } - private fun createPqWitness( signature: ByteArray, publicKey: ByteArray @@ -636,290 +566,6 @@ object VextaTransactionSender { } } - fun runPqWitnessSelfTest(): List { - val seed = - ByteArray(64) { index -> - index.toByte() - } - - val mldsa = - requireNotNull( - VextaPQ.mldsaKeypairFromSeed(seed) - ) - - val sphincs = - requireNotNull( - VextaPQ.sphincsKeypairFromSeed(seed) - ) - - val message = - "Vexta PQ witness self-test" - .toByteArray(Charsets.UTF_8) - - val mldsaSignature = - requireNotNull( - VextaPQ.mldsaSign( - message, - mldsa[1] - ) - ) - - val sphincsSignature = - requireNotNull( - VextaPQ.sphincsSign( - message, - sphincs[1] - ) - ) - - val mldsaWitness = - createPqWitness( - mldsaSignature, - mldsa[0] - ) - - val sphincsWitness = - createPqWitness( - sphincsSignature, - sphincs[0] - ) - - check(mldsaWitness.pushCount == 2) - check(mldsaWitness.getPush(0).size == 3309) - check(mldsaWitness.getPush(1).size == 1952) - - check(sphincsWitness.pushCount == 2) - check(sphincsWitness.getPush(0).size == 7856) - check(sphincsWitness.getPush(1).size == 32) - - mldsa[1].fill(0) - sphincs[1].fill(0) - - return listOf( - "MLDSA_WITNESS_PUSHES=${mldsaWitness.pushCount}", - "MLDSA_SIG_BYTES=${mldsaWitness.getPush(0).size}", - "MLDSA_PUBKEY_BYTES=${mldsaWitness.getPush(1).size}", - "SLHDSA_WITNESS_PUSHES=${sphincsWitness.pushCount}", - "SLHDSA_SIG_BYTES=${sphincsWitness.getPush(0).size}", - "SLHDSA_PUBKEY_BYTES=${sphincsWitness.getPush(1).size}", - "PQ_WITNESS_RESULT=PASS" - ) - } - - fun runPqSignedTransactionSelfTest(): List { - val recipientAddress = - "vtx1z6engqms3emse5lycna6yt7gd6svu7nfd28dccr7mfs8s54pz8rysd6lu5u" - - val recipientScript = - addressToScript(recipientAddress) - - val changePubKeyHash = - ByteArray(20) { index -> - (0x40 + index).toByte() - } - - val changeScript = - byteArrayOf(0x00, 0x14) + changePubKeyHash - - val amountSatoshis = 100_000L - val utxoValue = 10_000_000L - - fun testType( - addressType: BlockScanner.AddressType, - witnessVersion: Int, - expectedSignatureBytes: Int, - expectedPublicKeyBytes: Int, - txidSuffix: String - ): List { - val seed = - ByteArray(64) { index -> - index.toByte() - } - - val keyPair = - when (addressType) { - BlockScanner.AddressType.MLDSA -> - requireNotNull( - VextaPQ.mldsaKeypairFromSeed(seed) - ) - - BlockScanner.AddressType.SLHDSA -> - requireNotNull( - VextaPQ.sphincsKeypairFromSeed(seed) - ) - - BlockScanner.AddressType.STANDARD -> - error("Standard is not a PQ self-test type") - } - - require(keyPair.size == 2) - - val publicKey = keyPair[0] - val secretKey = keyPair[1] - - val syntheticTxid = - txidSuffix.padStart(64, '0') - - val utxo = - BlockScanner.SpendableUtxo( - txid = syntheticTxid, - outputIndex = 0L, - value = utxoValue, - height = 1, - addressIndex = 0, - isCoinbase = false, - addressType = addressType - ) - - val pqSigningKeys = - mapOf( - (addressType to 0) to - PqSigningKey( - addressType = addressType, - publicKey = publicKey, - secretKey = secretKey - ) - ) - - val created = - createAndSign( - spendableUtxos = listOf(utxo), - recipientAddress = recipientAddress, - amountSatoshis = amountSatoshis, - privateKeysByIndex = emptyMap(), - pqSigningKeys = pqSigningKeys, - changePubKeyHash = changePubKeyHash, - chainHeight = 10_000 - ) - - val parsed = - Transaction( - MainNetParams.get(), - created.rawTransaction - ) - - check(parsed.inputs.size == 1) - - val witness = - parsed.getInput(0L).getWitness() - - check(witness.pushCount == 2) - - val signature = - witness.getPush(0) - - val parsedPublicKey = - witness.getPush(1) - - check(signature.size == expectedSignatureBytes) - check(parsedPublicKey.size == expectedPublicKeyBytes) - check(parsedPublicKey.contentEquals(publicKey)) - - check( - parsed.txId.toString() == - created.txid - ) - - val witnessProgram = - MessageDigest - .getInstance("SHA-256") - .digest(publicKey) - - val outputs = - mutableListOf( - TransactionOutputData( - value = created.amount, - script = recipientScript - ) - ) - - if (created.change > 0L) { - outputs.add( - TransactionOutputData( - value = created.change, - script = changeScript - ) - ) - } - - val signatureHash = - calculatePqrSignatureHash( - selected = listOf(utxo), - outputs = outputs, - inputIndex = 0, - witnessVersion = witnessVersion, - witnessProgram = witnessProgram, - amount = utxo.value, - version = 2, - lockTime = 0L, - inputSequence = sequence - ) - - val verified = - when (addressType) { - BlockScanner.AddressType.MLDSA -> - VextaPQ.mldsaVerify( - signature, - signatureHash, - publicKey - ) - - BlockScanner.AddressType.SLHDSA -> - VextaPQ.sphincsVerify( - signature, - signatureHash, - publicKey - ) - - BlockScanner.AddressType.STANDARD -> - false - } - - check(verified) - - seed.fill(0) - signatureHash.fill(0) - - return listOf( - "${addressType.name}_SIGNED_TX_BYTES=" + - created.rawTransaction.size, - "${addressType.name}_SIGNED_TX_WITNESS_PUSHES=" + - witness.pushCount, - "${addressType.name}_SIGNED_TX_SIG_BYTES=" + - signature.size, - "${addressType.name}_SIGNED_TX_PUBKEY_BYTES=" + - parsedPublicKey.size, - "${addressType.name}_SIGNED_TX_VERIFY=$verified", - "${addressType.name}_SIGNED_TX_TXID_MATCH=true" - ) - } - - val results = - mutableListOf() - - results += - testType( - addressType = BlockScanner.AddressType.MLDSA, - witnessVersion = 2, - expectedSignatureBytes = 3309, - expectedPublicKeyBytes = 1952, - txidSuffix = "01" - ) - - results += - testType( - addressType = BlockScanner.AddressType.SLHDSA, - witnessVersion = 3, - expectedSignatureBytes = 7856, - expectedPublicKeyBytes = 32, - txidSuffix = "02" - ) - - results += "PQ_SIGNED_TX_RESULT=PASS" - - return results - } - private fun serializeTransaction( selected: List, outputs: List, diff --git a/app/src/main/java/org/vextaproject/wallet/WalletActivity.kt b/app/src/main/java/org/vextaproject/wallet/WalletActivity.kt index 254622a..97e0ad1 100644 --- a/app/src/main/java/org/vextaproject/wallet/WalletActivity.kt +++ b/app/src/main/java/org/vextaproject/wallet/WalletActivity.kt @@ -352,13 +352,6 @@ class WalletActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - if ( - applicationInfo.flags and - android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE != 0 - ) { - runPqCompatibilitySelfTest() - } - onBackPressedDispatcher.addCallback( this, object : OnBackPressedCallback(true) { @@ -445,504 +438,6 @@ class WalletActivity : FragmentActivity() { } } - private fun runPqCompatibilitySelfTest() { - Thread { - try { - val seed = ByteArray(64) { index -> - index.toByte() - } - - val mldsa = - requireNotNull( - VextaPQ.mldsaKeypairFromSeed(seed) - ) - - val sphincs = - requireNotNull( - VextaPQ.sphincsKeypairFromSeed(seed) - ) - - require(mldsa.size == 2) - require(sphincs.size == 2) - - fun sha256Hex(data: ByteArray): String = - MessageDigest - .getInstance("SHA-256") - .digest(data) - .joinToString("") { byte -> - "%02x".format(byte.toInt() and 0xff) - } - - val results = listOf( - "MLDSA_PK" to sha256Hex(mldsa[0]), - "MLDSA_SK" to sha256Hex(mldsa[1]), - "SPHINCS_PK" to sha256Hex(sphincs[0]), - "SPHINCS_SK" to sha256Hex(sphincs[1]) - ) - - results.forEach { (name, hash) -> - android.util.Log.i( - "VextaPQTest", - "$name=$hash" - ) - } - - val passed = - results[0].second == - "d666806e11cee19a7c989f7445f90dd419cf4d2d51db8c0fdb4c0f0a542238c9" && - results[1].second == - "9f1e24f47795fe50040384e3d6183988047170fa2d866406b70fe0a3f8216063" && - results[2].second == - "9d5b69aa74c4939468bae5108568a4d0926f2532c96b0742eda0a7eff4c99c3e" && - results[3].second == - "c6222658caa895a591af74d9f8c85d160962d253a782edf95875bbb3acee0a07" - - android.util.Log.i( - "VextaPQTest", - if (passed) { - "KEYGEN_RESULT=PASS" - } else { - "KEYGEN_RESULT=FAIL" - } - ) - - - val mldsaKeyId = - MessageDigest - .getInstance("SHA-256") - .digest(mldsa[0]) - - val sphincsKeyId = - MessageDigest - .getInstance("SHA-256") - .digest(sphincs[0]) - - val mldsaAddress = - encodeSegwitAddress( - "vtx", - 2, - mldsaKeyId - ) - - val sphincsAddress = - encodeSegwitAddress( - "vtx", - 3, - sphincsKeyId - ) - - android.util.Log.i( - "VextaPQTest", - "MLDSA_ADDRESS=$mldsaAddress" - ) - - android.util.Log.i( - "VextaPQTest", - "SLHDSA_ADDRESS=$sphincsAddress" - ) - - val addressPassed = - mldsaAddress == - "vtx1z6engqms3emse5lycna6yt7gd6svu7nfd28dccr7mfs8s54pz8rysd6lu5u" && - sphincsAddress == - "vtx1rn4dkn2n5cjfeg696u5gg269y6zfx7ffje94swshd5zn7laxfnslqfc63ay" - - android.util.Log.i( - "VextaPQTest", - "ADDRESS_RESULT=" + - if (addressPassed) "PASS" - else "FAIL" - ) - - fun derivePqSeedMaterial( - walletSeed: ByteArray, - algorithm: Int, - counter: Int - ): ByteArray { - val domain = - "Vexta-PQ-HD-v1" - .toByteArray(Charsets.US_ASCII) - - val data = ByteArray( - domain.size + 1 + 4 - ) - - System.arraycopy( - domain, - 0, - data, - 0, - domain.size - ) - - var offset = domain.size - - data[offset++] = - algorithm.toByte() - - data[offset++] = - ((counter ushr 24) and 0xff).toByte() - data[offset++] = - ((counter ushr 16) and 0xff).toByte() - data[offset++] = - ((counter ushr 8) and 0xff).toByte() - data[offset] = - (counter and 0xff).toByte() - - val mac = - javax.crypto.Mac.getInstance( - "HmacSHA512" - ) - - mac.init( - javax.crypto.spec.SecretKeySpec( - walletSeed, - "HmacSHA512" - ) - ) - - return mac.doFinal(data) - } - - val pqHdWalletSeed = - ByteArray(32) { index -> - index.toByte() - } - - val pqHdVectors = listOf( - "MLDSA_COUNTER_0" to - derivePqSeedMaterial( - pqHdWalletSeed, - 2, - 0 - ), - "MLDSA_COUNTER_1" to - derivePqSeedMaterial( - pqHdWalletSeed, - 2, - 1 - ), - "SLHDSA_COUNTER_0" to - derivePqSeedMaterial( - pqHdWalletSeed, - 3, - 0 - ), - "SLHDSA_COUNTER_1" to - derivePqSeedMaterial( - pqHdWalletSeed, - 3, - 1 - ) - ) - - pqHdVectors.forEach { (name, value) -> - android.util.Log.i( - "VextaPQTest", - "$name=${value.joinToString("") { - "%02x".format( - it.toInt() and 0xff - ) - }}" - ) - } - - val pqHdPassed = - pqHdVectors[0].second.contentEquals( - hexToBytes( - "0b5d81161cee1dd59cba10551b48069b2d38deabaec25ce2553777f2ee1574d8a9b5dd1cc72b84f5a6f97a943a060484b048f7ae06433ef73519c9c47136a8e6" - ) - ) && - pqHdVectors[1].second.contentEquals( - hexToBytes( - "96afee1e425cdc5cef6f2a5e565669e059f77538d432b00598c2ce4dae777de58a9ca26ea8c8f63d54a3b9b25554c9db4f4b2f3ff8a83954db44f94c46c7919b" - ) - ) && - pqHdVectors[2].second.contentEquals( - hexToBytes( - "62789e270793f5ca638ceba587a63c8931e1fa8f6ae300d79219b56351d71899905391fd9739652b11db87176ecba328cbac551b6b685961afe9c35346ec0d34" - ) - ) && - pqHdVectors[3].second.contentEquals( - hexToBytes( - "8e445ae4bb057ce26190c032115adeebbda64f6768904dd56147f4832981fb762e7d683b639c2bff6034c93223f71d3ca3d12bad887cb139d3c62da1f8487fa2" - ) - ) - - android.util.Log.i( - "VextaPQTest", - "PQ_HD_RESULT=" + - if (pqHdPassed) "PASS" - else "FAIL" - ) - - val message = - "Vexta PQ Android signature test" - .toByteArray(Charsets.UTF_8) - - val mldsaSignature = - requireNotNull( - VextaPQ.mldsaSign( - message, - mldsa[1] - ) - ) - - val mldsaVerified = - VextaPQ.mldsaVerify( - mldsaSignature, - message, - mldsa[0] - ) - - android.util.Log.i( - "VextaPQTest", - "MLDSA_SIG_BYTES=${mldsaSignature.size}" - ) - - android.util.Log.i( - "VextaPQTest", - "MLDSA_VERIFY=$mldsaVerified" - ) - - val sphincsSignature = - requireNotNull( - VextaPQ.sphincsSign( - message, - sphincs[1] - ) - ) - - val sphincsVerified = - VextaPQ.sphincsVerify( - sphincsSignature, - message, - sphincs[0] - ) - - android.util.Log.i( - "VextaPQTest", - "SPHINCS_SIG_BYTES=${sphincsSignature.size}" - ) - - android.util.Log.i( - "VextaPQTest", - "SPHINCS_VERIFY=$sphincsVerified" - ) - - java.io.File( - filesDir, - "pq-test-message.bin" - ).writeBytes(message) - - java.io.File( - filesDir, - "pq-mldsa.sig" - ).writeBytes(mldsaSignature) - - java.io.File( - filesDir, - "pq-sphincs.sig" - ).writeBytes(sphincsSignature) - - android.util.Log.i( - "VextaPQTest", - "SIGNATURE_FILES_WRITTEN=true" - ) - - val signatureTestPassed = - passed && - mldsaSignature.size == 3309 && - mldsaVerified && - sphincsSignature.size == 7856 && - sphincsVerified - - val coreMldsaSignature = - assets.open("pq-core-mldsa.sig").use { - it.readBytes() - } - - val coreSphincsSignature = - assets.open("pq-core-sphincs.sig").use { - it.readBytes() - } - - val coreMldsaVerified = - VextaPQ.mldsaVerify( - coreMldsaSignature, - message, - mldsa[0] - ) - - val coreSphincsVerified = - VextaPQ.sphincsVerify( - coreSphincsSignature, - message, - sphincs[0] - ) - - android.util.Log.i( - "VextaPQTest", - "CORE_TO_ANDROID_MLDSA=$coreMldsaVerified" - ) - - android.util.Log.i( - "VextaPQTest", - "CORE_TO_ANDROID_SPHINCS=$coreSphincsVerified" - ) - - val (pqrV2, pqrV3) = - VextaTransactionSender - .runPqrSignatureHashSelfTest() - - android.util.Log.i( - "VextaPQTest", - "PQR_V2=$pqrV2" - ) - - android.util.Log.i( - "VextaPQTest", - "PQR_V3=$pqrV3" - ) - - val pqrPassed = - pqrV2 == - "ba39c447b4577db974473a1e7ed2182686672f2900045a40aee6b4dc5811995b" && - pqrV3 == - "dab3188530f1094ef87087451da77bfba77dfc6e63d1730bb9d0475cebe76618" - - android.util.Log.i( - "VextaPQTest", - "PQR_HASH_RESULT=" + - if (pqrPassed) "PASS" - else "FAIL" - ) - - val pqWitnessResults = - VextaTransactionSender - .runPqWitnessSelfTest() - - pqWitnessResults.forEach { result -> - android.util.Log.i( - "VextaPQTest", - result - ) - } - - val pqWitnessPassed = - pqWitnessResults.contains( - "PQ_WITNESS_RESULT=PASS" - ) - - val pqSignedTxResults = - VextaTransactionSender - .runPqSignedTransactionSelfTest() - - pqSignedTxResults.forEach { result -> - android.util.Log.i( - "VextaPQTest", - result - ) - } - - val pqSignedTxPassed = - pqSignedTxResults.contains( - "PQ_SIGNED_TX_RESULT=PASS" - ) - - val finalPassed = - signatureTestPassed && - coreMldsaVerified && - coreSphincsVerified && - pqrPassed && - pqWitnessPassed && - pqSignedTxPassed - - android.util.Log.i( - "VextaPQTest", - if (finalPassed) { - "RESULT=PASS" - } else { - "RESULT=FAIL" - } - ) - } catch (error: Throwable) { - android.util.Log.e( - "VextaPQTest", - "RESULT=ERROR", - error - ) - } - }.start() - } - - override fun onResume() { - super.onResume() - - if ( - Build.VERSION.SDK_INT < Build.VERSION_CODES.O || - packageManager.canRequestPackageInstalls() - ) { - if (pendingUpdateUri != null) { - openDownloadedUpdate() - } - } - - if ( - walletExists() && - mainWalletVisible && - !blockchainScanRunning - ) { - window.decorView.postDelayed({ - if ( - !isFinishing && - !isDestroyed && - mainWalletVisible && - !blockchainScanRunning - ) { - startBackgroundHeaderSyncAndScan() - } - }, 400L) - } - } - - @Deprecated("Deprecated in Java") - override fun onBackPressed() { - if (!walletExists()) { - super.onBackPressed() - return - } - - if (!mainWalletVisible) { - showMainWallet() - return - } - - val now = System.currentTimeMillis() - - if (now - lastExitSwipeAt <= 2_000L) { - finishAndRemoveTask() - } else { - lastExitSwipeAt = now - Toast.makeText( - this, - "Swipe again to exit", - Toast.LENGTH_SHORT - ).show() - } - } - - override fun onDestroy() { - refreshHandler.removeCallbacks(refreshRunnable) - - try { - unregisterReceiver(updateReceiver) - } catch (_: IllegalArgumentException) { - } - - super.onDestroy() - } - private fun createPaymentNotificationChannel() { val manager = getSystemService(