mirror of
https://github.com/greenart7c3/Amber.git
synced 2026-10-06 03:18:23 +00:00
create private zaps, decrypt private zaps
This commit is contained in:
@@ -4,10 +4,10 @@ import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.hexToByteArray
|
||||
import com.greenart7c3.nostrsigner.models.toHexKey
|
||||
import com.greenart7c3.nostrsigner.service.KeyPair
|
||||
import com.greenart7c3.nostrsigner.service.toNpub
|
||||
import com.vitorpamplona.quartz.encoders.hexToByteArray
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import fr.acinq.secp256k1.jni.BuildConfig
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
package com.greenart7c3.nostrsigner.models
|
||||
|
||||
import fr.acinq.secp256k1.Hex
|
||||
|
||||
/** Makes the distinction between String and Hex **/
|
||||
typealias HexKey = String
|
||||
|
||||
fun ByteArray.toHexKey(): HexKey {
|
||||
return Hex.encode(this)
|
||||
}
|
||||
|
||||
fun HexKey.hexToByteArray(): ByteArray {
|
||||
return Hex.decode(this)
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.greenart7c3.nostrsigner.models
|
||||
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
|
||||
class IntentData(
|
||||
val data: String,
|
||||
val name: String,
|
||||
@@ -14,5 +16,6 @@ enum class SignerType {
|
||||
NIP04_DECRYPT,
|
||||
NIP44_ENCRYPT,
|
||||
NIP44_DECRYPT,
|
||||
GET_PUBLIC_KEY
|
||||
GET_PUBLIC_KEY,
|
||||
DECRYPT_ZAP_EVENT
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ object IntentUtils {
|
||||
"nip44_decrypt" -> SignerType.NIP44_DECRYPT
|
||||
"nip44_encrypt" -> SignerType.NIP44_ENCRYPT
|
||||
"get_public_key" -> SignerType.GET_PUBLIC_KEY
|
||||
"decrypt_zap_event" -> SignerType.DECRYPT_ZAP_EVENT
|
||||
else -> SignerType.SIGN_EVENT
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.greenart7c3.nostrsigner.service
|
||||
|
||||
import com.greenart7c3.nostrsigner.models.toHexKey
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
|
||||
class KeyPair(
|
||||
privKey: ByteArray? = null,
|
||||
|
||||
@@ -2,9 +2,9 @@ package com.greenart7c3.nostrsigner.service.model
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.greenart7c3.nostrsigner.models.toHexKey
|
||||
import com.greenart7c3.nostrsigner.service.bechToBytes
|
||||
import com.greenart7c3.nostrsigner.service.nip19.Tlv
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import fr.acinq.secp256k1.Hex
|
||||
|
||||
@Immutable
|
||||
|
||||
@@ -13,11 +13,11 @@ import com.google.gson.JsonPrimitive
|
||||
import com.google.gson.JsonSerializationContext
|
||||
import com.google.gson.JsonSerializer
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.greenart7c3.nostrsigner.models.HexKey
|
||||
import com.greenart7c3.nostrsigner.models.TimeUtils
|
||||
import com.greenart7c3.nostrsigner.models.toHexKey
|
||||
import com.greenart7c3.nostrsigner.service.CryptoUtils
|
||||
import com.greenart7c3.nostrsigner.service.KeyPair
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import fr.acinq.secp256k1.Hex
|
||||
import java.lang.reflect.Type
|
||||
import java.math.BigDecimal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.greenart7c3.nostrsigner.service.model
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.greenart7c3.nostrsigner.models.HexKey
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Immutable
|
||||
|
||||
@@ -3,9 +3,9 @@ package com.greenart7c3.nostrsigner.service.model
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.greenart7c3.nostrsigner.models.HexKey
|
||||
import com.greenart7c3.nostrsigner.models.hexToByteArray
|
||||
import com.greenart7c3.nostrsigner.service.CryptoUtils
|
||||
import com.vitorpamplona.quartz.encoders.HexKey
|
||||
import com.vitorpamplona.quartz.encoders.hexToByteArray
|
||||
|
||||
@Immutable
|
||||
abstract class GeneralListEvent(
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.greenart7c3.nostrsigner.ui
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity.RESULT_OK
|
||||
import android.content.Intent
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@@ -59,7 +60,6 @@ import com.greenart7c3.nostrsigner.models.Account
|
||||
import com.greenart7c3.nostrsigner.models.IntentData
|
||||
import com.greenart7c3.nostrsigner.models.SignerType
|
||||
import com.greenart7c3.nostrsigner.models.TimeUtils
|
||||
import com.greenart7c3.nostrsigner.models.toHexKey
|
||||
import com.greenart7c3.nostrsigner.service.CryptoUtils
|
||||
import com.greenart7c3.nostrsigner.service.IntentUtils
|
||||
import com.greenart7c3.nostrsigner.service.getAppCompatActivity
|
||||
@@ -76,9 +76,22 @@ import com.vitorpamplona.quartz.crypto.CryptoUtils.getSharedSecretNIP44
|
||||
import com.vitorpamplona.quartz.crypto.Nip44Version
|
||||
import com.vitorpamplona.quartz.crypto.decodeNIP44
|
||||
import com.vitorpamplona.quartz.crypto.encodeNIP44
|
||||
import com.vitorpamplona.quartz.encoders.Bech32
|
||||
import com.vitorpamplona.quartz.encoders.hexToByteArray
|
||||
import com.vitorpamplona.quartz.encoders.toHexKey
|
||||
import com.vitorpamplona.quartz.events.LnZapPrivateEvent
|
||||
import com.vitorpamplona.quartz.events.LnZapRequestEvent
|
||||
import fr.acinq.secp256k1.Hex
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withTimeout
|
||||
import org.json.JSONObject
|
||||
import java.nio.charset.Charset
|
||||
import java.security.SecureRandom
|
||||
import javax.crypto.Cipher
|
||||
import javax.crypto.spec.IvParameterSpec
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
import com.vitorpamplona.quartz.encoders.hexToByteArray as hexToByteArray1
|
||||
|
||||
@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
|
||||
@@ -156,9 +169,11 @@ fun MainScreen(account: Account, accountStateViewModel: AccountStateViewModel, j
|
||||
}
|
||||
)
|
||||
}
|
||||
SignerType.NIP04_DECRYPT, SignerType.NIP04_ENCRYPT, SignerType.NIP44_ENCRYPT, SignerType.NIP44_DECRYPT -> {
|
||||
SignerType.NIP04_DECRYPT, SignerType.NIP04_ENCRYPT, SignerType.NIP44_ENCRYPT, SignerType.NIP44_DECRYPT, SignerType.DECRYPT_ZAP_EVENT -> {
|
||||
val key = if (it.type == SignerType.NIP04_DECRYPT || it.type == SignerType.NIP44_DECRYPT) {
|
||||
"$packageName-decryptnip4"
|
||||
} else if (it.type == SignerType.DECRYPT_ZAP_EVENT) {
|
||||
"$packageName-DECRYPT_ZAP_EVENT"
|
||||
} else {
|
||||
"$packageName-encryptnip4"
|
||||
}
|
||||
@@ -174,66 +189,132 @@ fun MainScreen(account: Account, accountStateViewModel: AccountStateViewModel, j
|
||||
it.type,
|
||||
{
|
||||
try {
|
||||
val sig = try {
|
||||
when (it.type) {
|
||||
SignerType.NIP04_DECRYPT -> {
|
||||
CryptoUtils.decrypt(
|
||||
it.data,
|
||||
account.keyPair.privKey,
|
||||
Hex.decode(it.pubKey)
|
||||
)
|
||||
}
|
||||
SignerType.NIP04_ENCRYPT -> {
|
||||
CryptoUtils.encrypt(
|
||||
it.data,
|
||||
account.keyPair.privKey,
|
||||
Hex.decode(it.pubKey)
|
||||
)
|
||||
}
|
||||
SignerType.NIP44_ENCRYPT -> {
|
||||
val sharedSecret = getSharedSecretNIP44(account.keyPair.privKey, it.pubKey.hexToByteArray1())
|
||||
coroutineScope.launch(Dispatchers.IO) {
|
||||
val sig = try {
|
||||
withTimeout(1000L) {
|
||||
async<String> {
|
||||
when (it.type) {
|
||||
SignerType.DECRYPT_ZAP_EVENT -> {
|
||||
val event = com.vitorpamplona.quartz.events.Event.fromJson(it.data) as LnZapRequestEvent
|
||||
val loggedInPrivateKey = account.keyPair.privKey
|
||||
|
||||
encodeNIP44(
|
||||
encryptNIP44(
|
||||
it.data,
|
||||
sharedSecret
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
val toDecrypt = decodeNIP44(it.data) ?: return@EncryptDecryptData
|
||||
when (toDecrypt.v) {
|
||||
Nip44Version.NIP04.versionCode -> decryptNIP04(toDecrypt, account.keyPair.privKey, it.pubKey.hexToByteArray1())
|
||||
Nip44Version.NIP44.versionCode -> decryptNIP44(toDecrypt, account.keyPair.privKey, it.pubKey.hexToByteArray1())
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
} ?: "Could not decrypt the message"
|
||||
} catch (e: Exception) {
|
||||
"Could not decrypt the message"
|
||||
}
|
||||
if (event.isPrivateZap()) {
|
||||
val recipientPK = event.zappedAuthor().firstOrNull()
|
||||
val recipientPost = event.zappedPost().firstOrNull()
|
||||
if (recipientPK == account.keyPair.pubKey.toHexKey()) {
|
||||
// if the receiver is logged in, these are the params.
|
||||
val privateKeyToUse = loggedInPrivateKey
|
||||
val pubkeyToUse = event.pubKey
|
||||
|
||||
event.getPrivateZapEvent(privateKeyToUse, pubkeyToUse)?.toJson() ?: ""
|
||||
} else {
|
||||
// if the sender is logged in, these are the params
|
||||
val altPubkeyToUse = recipientPK
|
||||
val altPrivateKeyToUse = if (recipientPost != null) {
|
||||
LnZapRequestEvent.createEncryptionPrivateKey(
|
||||
loggedInPrivateKey.toHexKey(),
|
||||
recipientPost,
|
||||
event.createdAt
|
||||
)
|
||||
} else if (recipientPK != null) {
|
||||
LnZapRequestEvent.createEncryptionPrivateKey(
|
||||
loggedInPrivateKey.toHexKey(),
|
||||
recipientPK,
|
||||
event.createdAt
|
||||
)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
try {
|
||||
if (altPrivateKeyToUse != null && altPubkeyToUse != null) {
|
||||
val altPubKeyFromPrivate = com.vitorpamplona.quartz.crypto.CryptoUtils.pubkeyCreate(altPrivateKeyToUse).toHexKey()
|
||||
|
||||
if (altPubKeyFromPrivate == event.pubKey) {
|
||||
val result = event.getPrivateZapEvent(altPrivateKeyToUse, altPubkeyToUse)
|
||||
|
||||
result?.toJson() ?: ""
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("Account", "Failed to create pubkey for ZapRequest ${event.id}", e)
|
||||
null
|
||||
}
|
||||
}
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
SignerType.NIP04_DECRYPT -> {
|
||||
CryptoUtils.decrypt(
|
||||
it.data,
|
||||
account.keyPair.privKey,
|
||||
Hex.decode(it.pubKey)
|
||||
)
|
||||
}
|
||||
SignerType.NIP04_ENCRYPT -> {
|
||||
CryptoUtils.encrypt(
|
||||
it.data,
|
||||
account.keyPair.privKey,
|
||||
Hex.decode(it.pubKey)
|
||||
)
|
||||
}
|
||||
SignerType.NIP44_ENCRYPT -> {
|
||||
val sharedSecret = getSharedSecretNIP44(account.keyPair.privKey, it.pubKey.hexToByteArray1())
|
||||
|
||||
encodeNIP44(
|
||||
encryptNIP44(
|
||||
it.data,
|
||||
sharedSecret
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
val toDecrypt = decodeNIP44(it.data) ?: return@async "Could not decrypt the message"
|
||||
when (toDecrypt.v) {
|
||||
Nip44Version.NIP04.versionCode -> decryptNIP04(toDecrypt, account.keyPair.privKey, it.pubKey.hexToByteArray1())
|
||||
Nip44Version.NIP44.versionCode -> decryptNIP44(toDecrypt, account.keyPair.privKey, it.pubKey.hexToByteArray1())
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
} ?: "Could not decrypt the message"
|
||||
}.await()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
"Could not decrypt the message"
|
||||
}
|
||||
|
||||
coroutineScope.launch {
|
||||
val activity = context.getAppCompatActivity()
|
||||
if (packageName != null) {
|
||||
account.savedApps[key] = remember.value
|
||||
LocalPreferences.saveToEncryptedStorage(account)
|
||||
val intent = Intent()
|
||||
intent.putExtra("signature", sig)
|
||||
if (sig == "Could not decrypt the message" && (it.type == SignerType.DECRYPT_ZAP_EVENT)) {
|
||||
intent.putExtra("signature", "")
|
||||
} else {
|
||||
intent.putExtra("signature", sig)
|
||||
}
|
||||
if (it.type == SignerType.NIP44_DECRYPT || it.type == SignerType.NIP04_DECRYPT) {
|
||||
intent.putExtra("id", it.id)
|
||||
}
|
||||
activity?.setResult(RESULT_OK, intent)
|
||||
} else {
|
||||
clipboardManager.setText(AnnotatedString(sig))
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.signature_copied_to_the_clipboard),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
coroutineScope.launch {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.signature_copied_to_the_clipboard),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
}
|
||||
activity?.finish()
|
||||
}
|
||||
|
||||
return@EncryptDecryptData
|
||||
} catch (e: Exception) {
|
||||
val message = if (it.type == SignerType.NIP04_ENCRYPT) "encrypt" else "decrypt"
|
||||
@@ -278,29 +359,128 @@ fun MainScreen(account: Account, accountStateViewModel: AccountStateViewModel, j
|
||||
return@EventData
|
||||
}
|
||||
|
||||
val id = event.id.hexToByteArray1()
|
||||
val sig = CryptoUtils.sign(id, account.keyPair.privKey).toHexKey()
|
||||
val localEvent = com.vitorpamplona.quartz.events.Event.fromJson(it.data)
|
||||
if (localEvent is LnZapRequestEvent) {
|
||||
val isPrivateZap = localEvent.tags.any { tag -> tag.any { t -> t == "anon" } }
|
||||
val originalNoteId = localEvent.zappedPost()[0]
|
||||
val pubkey = localEvent.zappedAuthor()[0]
|
||||
Log.d("originalNoteId", originalNoteId)
|
||||
var privkey = account.keyPair.privKey
|
||||
var pubKey = account.keyPair.pubKey.toHexKey()
|
||||
if (isPrivateZap) {
|
||||
val encryptionPrivateKey = LnZapRequestEvent.createEncryptionPrivateKey(
|
||||
privkey.toHexKey(),
|
||||
originalNoteId,
|
||||
localEvent.createdAt
|
||||
)
|
||||
val noteJson = (LnZapPrivateEvent.create(privkey, listOf(localEvent.tags[0], localEvent.tags[1]), localEvent.content)).toJson()
|
||||
val encryptedContent = encryptPrivateZapMessage(
|
||||
noteJson,
|
||||
encryptionPrivateKey,
|
||||
pubkey.hexToByteArray()
|
||||
)
|
||||
var tags = localEvent.tags.filter { !it.contains("anon") }
|
||||
tags = tags + listOf(listOf("anon", encryptedContent))
|
||||
Log.d("tags", tags.toString())
|
||||
privkey = encryptionPrivateKey // sign event with generated privkey
|
||||
pubKey = com.vitorpamplona.quartz.crypto.CryptoUtils.pubkeyCreate(encryptionPrivateKey).toHexKey() // updated event with according pubkey
|
||||
|
||||
coroutineScope.launch {
|
||||
val activity = context.getAppCompatActivity()
|
||||
if (packageName != null) {
|
||||
account.savedApps[key] = remember.value
|
||||
LocalPreferences.saveToEncryptedStorage(account)
|
||||
val intent = Intent()
|
||||
val signedEvent = Event(event.id, event.pubKey, event.createdAt, event.kind, event.tags, event.content, sig)
|
||||
intent.putExtra("event", signedEvent.toJson())
|
||||
intent.putExtra("signature", sig)
|
||||
val id = com.vitorpamplona.quartz.events.Event.generateId(
|
||||
pubKey,
|
||||
localEvent.createdAt,
|
||||
LnZapRequestEvent.kind,
|
||||
tags,
|
||||
""
|
||||
)
|
||||
val sig = com.vitorpamplona.quartz.crypto.CryptoUtils.sign(id, privkey)
|
||||
val event = LnZapRequestEvent(id.toHexKey(), pubKey, localEvent.createdAt, tags, "", sig.toHexKey())
|
||||
coroutineScope.launch {
|
||||
val activity = context.getAppCompatActivity()
|
||||
if (packageName != null) {
|
||||
account.savedApps[key] = remember.value
|
||||
LocalPreferences.saveToEncryptedStorage(account)
|
||||
val intent = Intent()
|
||||
intent.putExtra("event", event.toJson())
|
||||
intent.putExtra("signature", event.toJson())
|
||||
|
||||
activity?.setResult(RESULT_OK, intent)
|
||||
activity?.setResult(RESULT_OK, intent)
|
||||
} else {
|
||||
clipboardManager.setText(AnnotatedString(event.toJson()))
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.signature_copied_to_the_clipboard),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
activity?.finish()
|
||||
}
|
||||
} else {
|
||||
clipboardManager.setText(AnnotatedString(sig))
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.signature_copied_to_the_clipboard),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
val id = event.id.hexToByteArray1()
|
||||
val sig = CryptoUtils.sign(id, account.keyPair.privKey).toHexKey()
|
||||
|
||||
coroutineScope.launch {
|
||||
val activity = context.getAppCompatActivity()
|
||||
if (packageName != null) {
|
||||
account.savedApps[key] = remember.value
|
||||
LocalPreferences.saveToEncryptedStorage(account)
|
||||
val intent = Intent()
|
||||
val signedEvent = Event(
|
||||
event.id,
|
||||
event.pubKey,
|
||||
event.createdAt,
|
||||
event.kind,
|
||||
event.tags,
|
||||
event.content,
|
||||
sig
|
||||
)
|
||||
intent.putExtra("event", signedEvent.toJson())
|
||||
intent.putExtra("signature", sig)
|
||||
|
||||
activity?.setResult(RESULT_OK, intent)
|
||||
} else {
|
||||
clipboardManager.setText(AnnotatedString(sig))
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.signature_copied_to_the_clipboard),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
activity?.finish()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val id = event.id.hexToByteArray1()
|
||||
val sig = CryptoUtils.sign(id, account.keyPair.privKey).toHexKey()
|
||||
|
||||
coroutineScope.launch {
|
||||
val activity = context.getAppCompatActivity()
|
||||
if (packageName != null) {
|
||||
account.savedApps[key] = remember.value
|
||||
LocalPreferences.saveToEncryptedStorage(account)
|
||||
val intent = Intent()
|
||||
val signedEvent = Event(
|
||||
event.id,
|
||||
event.pubKey,
|
||||
event.createdAt,
|
||||
event.kind,
|
||||
event.tags,
|
||||
event.content,
|
||||
sig
|
||||
)
|
||||
intent.putExtra("event", signedEvent.toJson())
|
||||
intent.putExtra("signature", sig)
|
||||
|
||||
activity?.setResult(RESULT_OK, intent)
|
||||
} else {
|
||||
clipboardManager.setText(AnnotatedString(sig))
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(R.string.signature_copied_to_the_clipboard),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
activity?.finish()
|
||||
}
|
||||
activity?.finish()
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -665,3 +845,22 @@ fun EventRow(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun encryptPrivateZapMessage(msg: String, privkey: ByteArray, pubkey: ByteArray): String {
|
||||
val sharedSecret = com.vitorpamplona.quartz.crypto.CryptoUtils.getSharedSecretNIP04(privkey, pubkey)
|
||||
val iv = ByteArray(16)
|
||||
SecureRandom().nextBytes(iv)
|
||||
|
||||
val keySpec = SecretKeySpec(sharedSecret, "AES")
|
||||
val ivSpec = IvParameterSpec(iv)
|
||||
|
||||
val utf8message = msg.toByteArray(Charset.forName("utf-8"))
|
||||
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
|
||||
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec)
|
||||
val encryptedMsg = cipher.doFinal(utf8message)
|
||||
|
||||
val encryptedMsgBech32 = Bech32.encode("pzap", Bech32.eight2five(encryptedMsg), Bech32.Encoding.Bech32)
|
||||
val ivBech32 = Bech32.encode("iv", Bech32.eight2five(iv), Bech32.Encoding.Bech32)
|
||||
|
||||
return encryptedMsgBech32 + "_" + ivBech32
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user