Prepare v0.7.0 release build
This commit is contained in:
parent
59ee1e0bb9
commit
fba35559f4
4 changed files with 0 additions and 859 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -548,76 +548,6 @@ object VextaTransactionSender {
|
||||||
return doubleSha256(preimage)
|
return doubleSha256(preimage)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runPqrSignatureHashSelfTest(): Pair<String, String> {
|
|
||||||
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(
|
private fun createPqWitness(
|
||||||
signature: ByteArray,
|
signature: ByteArray,
|
||||||
publicKey: ByteArray
|
publicKey: ByteArray
|
||||||
|
|
@ -636,290 +566,6 @@ object VextaTransactionSender {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runPqWitnessSelfTest(): List<String> {
|
|
||||||
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<String> {
|
|
||||||
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<String> {
|
|
||||||
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<String>()
|
|
||||||
|
|
||||||
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(
|
private fun serializeTransaction(
|
||||||
selected: List<BlockScanner.SpendableUtxo>,
|
selected: List<BlockScanner.SpendableUtxo>,
|
||||||
outputs: List<TransactionOutputData>,
|
outputs: List<TransactionOutputData>,
|
||||||
|
|
|
||||||
|
|
@ -352,13 +352,6 @@ class WalletActivity : FragmentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
if (
|
|
||||||
applicationInfo.flags and
|
|
||||||
android.content.pm.ApplicationInfo.FLAG_DEBUGGABLE != 0
|
|
||||||
) {
|
|
||||||
runPqCompatibilitySelfTest()
|
|
||||||
}
|
|
||||||
|
|
||||||
onBackPressedDispatcher.addCallback(
|
onBackPressedDispatcher.addCallback(
|
||||||
this,
|
this,
|
||||||
object : OnBackPressedCallback(true) {
|
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() {
|
private fun createPaymentNotificationChannel() {
|
||||||
val manager =
|
val manager =
|
||||||
getSystemService(
|
getSystemService(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue