From 9e9f6c31646f935406fd7133f734039fcb1fad9d Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 25 Mar 2026 11:48:37 -0400 Subject: [PATCH] Completing the transition from NIP-44 architecture specific tests to commontTest --- .../quartz/nip44Encryption/Nip44v1Test.kt | 94 --------- .../quartz/nip44Encryption/Nip44v2Test.kt | 185 ------------------ .../nip44Encryption/Nip44v2BaseTest.kt} | 2 +- .../nip44Encryption/TestPackageClasses.kt | 0 .../quartz/nip44Encryption/Nip44v1Test.kt | 91 --------- .../nip44Encryption/TestPackageClasses.kt | 103 ---------- 6 files changed, 1 insertion(+), 474 deletions(-) delete mode 100644 quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt delete mode 100644 quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt rename quartz/src/{iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt => commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2BaseTest.kt} (99%) rename quartz/src/{androidDeviceTest => commonTest}/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt (100%) delete mode 100644 quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt delete mode 100644 quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt diff --git a/quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt b/quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt deleted file mode 100644 index fc97ca488..000000000 --- a/quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2025 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.nip44Encryption - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray -import com.vitorpamplona.quartz.nip01Core.core.toHexKey -import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair -import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class Nip44v1Test { - private val nip44v1 = Nip44v1() - - @Test - fun testSharedSecretCompatibilityWithCoracle() { - val privateKey = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561" - val publicKey = "765cd7cf91d3ad07423d114d5a39c61d52b2cdbc18ba055ddbbeec71fbe2aa2f" - - val key = - nip44v1.getSharedSecret( - privateKey = privateKey.hexToByteArray(), - pubKey = publicKey.hexToByteArray(), - ) - - assertEquals("577c966f499dddd8e8dcc34e8f352e283cc177e53ae372794947e0b8ede7cfd8", key.toHexKey()) - } - - @Test - fun testSharedSecret() { - val sender = KeyPair() - val receiver = KeyPair() - - val sharedSecret1 = nip44v1.getSharedSecret(sender.privKey!!, receiver.pubKey) - val sharedSecret2 = nip44v1.getSharedSecret(receiver.privKey!!, sender.pubKey) - - assertEquals(sharedSecret1.toHexKey(), sharedSecret2.toHexKey()) - - val secretKey1 = KeyPair(privKey = sharedSecret1) - val secretKey2 = KeyPair(privKey = sharedSecret2) - - assertEquals(secretKey1.pubKey.toHexKey(), secretKey2.pubKey.toHexKey()) - assertEquals(secretKey1.privKey?.toHexKey(), secretKey2.privKey?.toHexKey()) - } - - @Test - fun encryptDecrypt() { - val msg = "Hi" - - val privateKey = Nip01Crypto.privKeyCreate() - val publicKey = Nip01Crypto.pubKeyCreate(privateKey) - - val encrypted = nip44v1.encrypt(msg, privateKey, publicKey) - val decrypted = nip44v1.decrypt(encrypted, privateKey, publicKey) - - assertEquals(msg, decrypted) - } - - @Test - fun encryptDecryptSharedSecret() { - val msg = "Hi" - - val privateKey = Nip01Crypto.privKeyCreate() - val publicKey = Nip01Crypto.pubKeyCreate(privateKey) - - val sharedSecret = nip44v1.getSharedSecret(privateKey, publicKey) - - val encrypted = nip44v1.encrypt(msg, sharedSecret) - val decrypted = nip44v1.decrypt(encrypted, sharedSecret) - - assertEquals(msg, decrypted) - } -} diff --git a/quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt b/quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt deleted file mode 100644 index a17fb31d7..000000000 --- a/quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2025 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.nip44Encryption - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.vitorpamplona.quartz.nip01Core.core.JsonMapper -import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray -import com.vitorpamplona.quartz.nip01Core.core.toHexKey -import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair -import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto -import com.vitorpamplona.quartz.utils.RandomInstance -import com.vitorpamplona.quartz.utils.sha256.sha256 -import junit.framework.TestCase.assertNotNull -import junit.framework.TestCase.assertNull -import junit.framework.TestCase.fail -import kotlinx.serialization.json.decodeFromStream -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -@RunWith(AndroidJUnit4::class) -class Nip44v2Test { - private val vectors: VectorFile = - JsonMapper.jsonInstance.decodeFromStream( - javaClass.classLoader.getResourceAsStream("nip44.vectors.json"), - ) - - private val nip44v2 = Nip44v2() - - @Test - fun conversationKeyTest() { - for (v in vectors.v2?.valid?.getConversationKey!!) { - val conversationKey = - nip44v2.getConversationKey(v.sec1!!.hexToByteArray(), v.pub2!!.hexToByteArray()) - - assertEquals(v.conversationKey, conversationKey.toHexKey()) - } - } - - @Test - fun paddingTest() { - for (v in vectors.v2?.valid?.calcPaddedLen!!) { - val actual = nip44v2.calcPaddedLen(v[0]) - assertEquals(v[1], actual) - } - } - - @Test - fun testCompressedWith02Keys() { - val privateKeyA = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561".hexToByteArray() - val privateKeyB = "65f039136f8da8d3e87b4818746b53318d5481e24b2673f162815144223a0b5a".hexToByteArray() - - val publicKeyA = Nip01Crypto.pubKeyCreate(privateKeyA) - val publicKeyB = Nip01Crypto.pubKeyCreate(privateKeyB) - - assertEquals( - nip44v2.getConversationKey(privateKeyA, publicKeyB).toHexKey(), - nip44v2.getConversationKey(privateKeyB, publicKeyA).toHexKey(), - ) - } - - @Test - fun testCompressedWith03Keys() { - val privateKeyA = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561".hexToByteArray() - val privateKeyB = "e6159851715b4aa6190c22b899b0c792847de0a4435ac5b678f35738351c43b0".hexToByteArray() - - val publicKeyA = Nip01Crypto.pubKeyCreate(privateKeyA) - val publicKeyB = Nip01Crypto.pubKeyCreate(privateKeyB) - - assertEquals( - nip44v2.getConversationKey(privateKeyA, publicKeyB).toHexKey(), - nip44v2.getConversationKey(privateKeyB, publicKeyA).toHexKey(), - ) - } - - @Test - fun encryptDecryptTest() { - for (v in vectors.v2?.valid?.encryptDecrypt!!) { - val pub2 = KeyPair(v.sec2!!.hexToByteArray()) - val conversationKey1 = nip44v2.getConversationKey(v.sec1!!.hexToByteArray(), pub2.pubKey) - assertEquals(v.conversationKey, conversationKey1.toHexKey()) - - val ciphertext = - nip44v2 - .encryptWithNonce( - v.plaintext!!, - conversationKey1, - v.nonce!!.hexToByteArray(), - ).encodePayload() - - assertEquals(v.payload, ciphertext) - - val pub1 = KeyPair(v.sec1.hexToByteArray()) - val conversationKey2 = nip44v2.getConversationKey(v.sec2.hexToByteArray(), pub1.pubKey) - assertEquals(v.conversationKey, conversationKey2.toHexKey()) - - val decrypted = nip44v2.decrypt(v.payload!!, conversationKey2) - assertEquals(v.plaintext, decrypted) - } - } - - @Test - fun encryptDecryptLongTest() { - for (v in vectors.v2?.valid?.encryptDecryptLongMsg!!) { - val conversationKey = v.conversationKey!!.hexToByteArray() - val plaintext = v.pattern!!.repeat(v.repeat!!) - - assertEquals(v.plaintextSha256, sha256Hex(plaintext.toByteArray(Charsets.UTF_8))) - - val ciphertext = - nip44v2 - .encryptWithNonce( - plaintext, - conversationKey, - v.nonce!!.hexToByteArray(), - ).encodePayload() - - assertEquals(v.payloadSha256, sha256Hex(ciphertext.toByteArray(Charsets.UTF_8))) - - val decrypted = nip44v2.decrypt(ciphertext, conversationKey) - - assertEquals(plaintext, decrypted) - } - } - - @Test - fun extendedMessageLengths() { - for (v in vectors.v2?.invalid?.encryptMsgLengths!!) { - val key = RandomInstance.bytes(32) - try { - val input = "a".repeat(v) - val result = nip44v2.encrypt(input, key) - val decrypted = nip44v2.decrypt(result, key) - assertEquals(input, decrypted) - } catch (e: Exception) { - assertNotNull(e) - } - } - } - - @Test - fun invalidDecrypt() { - for (v in vectors.v2?.invalid?.decrypt!!) { - try { - val result = nip44v2.decrypt(v.payload!!, v.conversationKey!!.hexToByteArray()) - assertNull(result) - // fail("Should Throw for ${v.note}") - } catch (e: Exception) { - assertNotNull(e) - } - } - } - - @Test - fun invalidConversationKey() { - for (v in vectors.v2?.invalid?.getConversationKey!!) { - try { - nip44v2.getConversationKey(v.sec1!!.hexToByteArray(), v.pub2!!.hexToByteArray()) - fail("Should Throw for ${v.note}") - } catch (e: Exception) { - assertNotNull(e) - } - } - } - - private fun sha256Hex(data: ByteArray) = sha256(data).toHexKey() -} diff --git a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2BaseTest.kt similarity index 99% rename from quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt rename to quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2BaseTest.kt index 7e0b09ef4..5ddbde8c1 100644 --- a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2Test.kt +++ b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v2BaseTest.kt @@ -34,7 +34,7 @@ import kotlin.test.assertNotNull import kotlin.test.assertNull import kotlin.test.fail -class Nip44v2Test { +class Nip44v2BaseTest { private val vectors: VectorFile = JsonMapper.jsonInstance.decodeFromString( TestResourceLoader().loadString("nip44.vectors.json"), diff --git a/quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt b/quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt similarity index 100% rename from quartz/src/androidDeviceTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt rename to quartz/src/commonTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt diff --git a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt b/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt deleted file mode 100644 index 57838941b..000000000 --- a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/Nip44v1Test.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2025 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.nip44Encryption - -import com.vitorpamplona.quartz.nip01Core.core.hexToByteArray -import com.vitorpamplona.quartz.nip01Core.core.toHexKey -import com.vitorpamplona.quartz.nip01Core.crypto.KeyPair -import com.vitorpamplona.quartz.nip01Core.crypto.Nip01Crypto -import kotlin.test.Test -import kotlin.test.assertEquals - -class Nip44v1Test { - private val nip44v1 = Nip44v1() - - @Test - fun testSharedSecretCompatibilityWithCoracle() { - val privateKey = "f410f88bcec6cbfda04d6a273c7b1dd8bba144cd45b71e87109cfa11dd7ed561" - val publicKey = "765cd7cf91d3ad07423d114d5a39c61d52b2cdbc18ba055ddbbeec71fbe2aa2f" - - val key = - nip44v1.getSharedSecret( - privateKey = privateKey.hexToByteArray(), - pubKey = publicKey.hexToByteArray(), - ) - - assertEquals("577c966f499dddd8e8dcc34e8f352e283cc177e53ae372794947e0b8ede7cfd8", key.toHexKey()) - } - - @Test - fun testSharedSecret() { - val sender = KeyPair() - val receiver = KeyPair() - - val sharedSecret1 = nip44v1.getSharedSecret(sender.privKey!!, receiver.pubKey) - val sharedSecret2 = nip44v1.getSharedSecret(receiver.privKey!!, sender.pubKey) - - assertEquals(sharedSecret1.toHexKey(), sharedSecret2.toHexKey()) - - val secretKey1 = KeyPair(privKey = sharedSecret1) - val secretKey2 = KeyPair(privKey = sharedSecret2) - - assertEquals(secretKey1.pubKey.toHexKey(), secretKey2.pubKey.toHexKey()) - assertEquals(secretKey1.privKey?.toHexKey(), secretKey2.privKey?.toHexKey()) - } - - @Test - fun encryptDecrypt() { - val msg = "Hi" - - val privateKey = Nip01Crypto.privKeyCreate() - val publicKey = Nip01Crypto.pubKeyCreate(privateKey) - - val encrypted = nip44v1.encrypt(msg, privateKey, publicKey) - val decrypted = nip44v1.decrypt(encrypted, privateKey, publicKey) - - assertEquals(msg, decrypted) - } - - @Test - fun encryptDecryptSharedSecret() { - val msg = "Hi" - - val privateKey = Nip01Crypto.privKeyCreate() - val publicKey = Nip01Crypto.pubKeyCreate(privateKey) - - val sharedSecret = nip44v1.getSharedSecret(privateKey, publicKey) - - val encrypted = nip44v1.encrypt(msg, sharedSecret) - val decrypted = nip44v1.decrypt(encrypted, sharedSecret) - - assertEquals(msg, decrypted) - } -} diff --git a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt b/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt deleted file mode 100644 index 4eccbf19b..000000000 --- a/quartz/src/iosTest/kotlin/com/vitorpamplona/quartz/nip44Encryption/TestPackageClasses.kt +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2025 Vitor Pamplona - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -package com.vitorpamplona.quartz.nip44Encryption - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable - -@Serializable -data class VectorFile( - val v2: V2? = V2(), -) - -@Serializable -data class V2( - val valid: Valid? = Valid(), - val invalid: Invalid? = Invalid(), -) - -@Serializable -data class Valid( - @SerialName("get_conversation_key") val getConversationKey: ArrayList = arrayListOf(), - @SerialName("get_message_keys") val getMessageKeys: GetMessageKeys? = GetMessageKeys(), - @SerialName("calc_padded_len") val calcPaddedLen: ArrayList> = arrayListOf(), - @SerialName("encrypt_decrypt") val encryptDecrypt: ArrayList = arrayListOf(), - @SerialName("encrypt_decrypt_long_msg") - val encryptDecryptLongMsg: ArrayList = arrayListOf(), -) - -@Serializable -data class Invalid( - @SerialName("encrypt_msg_lengths") val encryptMsgLengths: ArrayList = arrayListOf(), - @SerialName("get_conversation_key") val getConversationKey: ArrayList = arrayListOf(), - @SerialName("decrypt") val decrypt: ArrayList = arrayListOf(), -) - -@Serializable -data class GetConversationKey( - val sec1: String? = null, - val pub2: String? = null, - val note: String? = null, - @SerialName("conversation_key") val conversationKey: String? = null, -) - -@Serializable -data class GetMessageKeys( - @SerialName("conversation_key") val conversationKey: String? = null, - val keys: ArrayList = arrayListOf(), -) - -@Serializable -data class Keys( - @SerialName("nonce") val nonce: String? = null, - @SerialName("chacha_key") val chachaKey: String? = null, - @SerialName("chacha_nonce") val chachaNonce: String? = null, - @SerialName("hmac_key") val hmacKey: String? = null, -) - -@Serializable -data class EncryptDecrypt( - val sec1: String? = null, - val sec2: String? = null, - @SerialName("conversation_key") val conversationKey: String? = null, - val nonce: String? = null, - val plaintext: String? = null, - val payload: String? = null, -) - -@Serializable -data class EncryptDecryptLongMsg( - @SerialName("conversation_key") val conversationKey: String? = null, - val nonce: String? = null, - val pattern: String? = null, - val repeat: Int? = null, - @SerialName("plaintext_sha256") val plaintextSha256: String? = null, - @SerialName("payload_sha256") val payloadSha256: String? = null, -) - -@Serializable -data class Decrypt( - @SerialName("conversation_key") val conversationKey: String? = null, - val nonce: String? = null, - val plaintext: String? = null, - val payload: String? = null, - val note: String? = null, -)