From c7d3bc13826336b1be36ecd0309ef3374f2ce237 Mon Sep 17 00:00:00 2001 From: Curtis Date: Tue, 3 Oct 2023 14:10:14 +0100 Subject: [PATCH] feat(BAE): updating jsMain Ed25519 keys for use in TS (#92) --- .../atala/prism/apollo/utils/KMMEdKeyPair.kt | 3 + .../prism/apollo/utils/KMMX25519KeyPair.kt | 3 + .../prism/apollo/utils/Curve25519Parser.kt | 31 ++++++++++ .../atala/prism/apollo/utils/KMMEdKeyPair.kt | 4 +- .../prism/apollo/utils/KMMEdPrivateKey.kt | 26 +++++++- .../prism/apollo/utils/KMMEdPublicKey.kt | 27 ++++++++- .../prism/apollo/utils/KMMX25519KeyPair.kt | 7 +-- .../prism/apollo/utils/KMMX25519PrivateKey.kt | 35 ++++++++++- .../prism/apollo/utils/KMMX25519PublicKey.kt | 19 +++++- .../prism/apollo/utils/external/Ellipticjs.kt | 4 +- .../prism/apollo/utils/KMMEdKeyPairTests.kt | 58 ++++++++++++++++++ .../prism/apollo/utils/KMMX25519Tests.kt | 60 +++++++++++++++++++ 12 files changed, 262 insertions(+), 15 deletions(-) create mode 100644 base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt create mode 100644 base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519Tests.kt diff --git a/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt b/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt index 92ea96a04..b8db96119 100644 --- a/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt +++ b/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt @@ -1,5 +1,8 @@ package io.iohk.atala.prism.apollo.utils +import kotlin.js.ExperimentalJsExport + +@ExperimentalJsExport expect class KMMEdKeyPair(privateKey: KMMEdPrivateKey, publicKey: KMMEdPublicKey) { val privateKey: KMMEdPrivateKey val publicKey: KMMEdPublicKey diff --git a/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt b/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt index 1db666c29..9ab36a3c7 100644 --- a/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt +++ b/base-asymmetric-encryption/src/commonMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt @@ -1,5 +1,8 @@ package io.iohk.atala.prism.apollo.utils +import kotlin.js.ExperimentalJsExport + +@ExperimentalJsExport expect class KMMX25519KeyPair(privateKey: KMMX25519PrivateKey, publicKey: KMMX25519PublicKey) { val privateKey: KMMX25519PrivateKey val publicKey: KMMX25519PublicKey diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt new file mode 100644 index 000000000..898d9eb8f --- /dev/null +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/Curve25519Parser.kt @@ -0,0 +1,31 @@ +package io.iohk.atala.prism.apollo.utils + +import io.iohk.atala.prism.apollo.base64.base64UrlDecodedBytes +import node.buffer.Buffer + +@ExperimentalJsExport +@JsExport +object Curve25519Parser { + val encodedLength = 43 + val rawLength = 32 + + /** + * Resolve the given ByteArray into the raw key value + * @param bytes - ByteArray to be parsed, either Encoded or Raw data + * @throws Error - if [bytes] is neither Encoded nor Raw + * @return Buffer - raw key value + */ + fun parseRaw(bytes: ByteArray): Buffer { + val buffer = Buffer.from(bytes) + + if (buffer.length == encodedLength) { + return Buffer.from(buffer.toByteArray().decodeToString().base64UrlDecodedBytes) + } + + if (buffer.length == rawLength) { + return buffer + } + + throw Error("invalid raw key") + } +} diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt index 9447a9de1..41be7b9b4 100644 --- a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPair.kt @@ -22,11 +22,11 @@ actual class KMMEdKeyPair actual constructor( override fun generateKeyPair(): KMMEdKeyPair { val ed25519 = eddsa("ed25519") val rnd = rand(32) - val secret = Buffer.from(rnd).toByteArray() + val secret = Buffer.from(rnd) val keypair = ed25519.keyFromSecret(secret) val public = keypair.getPublic() - return KMMEdKeyPair(KMMEdPrivateKey(secret), KMMEdPublicKey(public)) + return KMMEdKeyPair(KMMEdPrivateKey(secret.toByteArray()), KMMEdPublicKey(public)) } } } diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt index dc5781a40..ce63236b8 100644 --- a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPrivateKey.kt @@ -1,19 +1,43 @@ package io.iohk.atala.prism.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.external.eddsa import node.buffer.Buffer @ExperimentalJsExport @JsExport -actual class KMMEdPrivateKey(val raw: ByteArray) { +actual class KMMEdPrivateKey(bytes: ByteArray) { + val raw: Buffer private val keyPair: eddsa.KeyPair init { val ed25519 = eddsa("ed25519") + raw = Curve25519Parser.parseRaw(bytes) keyPair = ed25519.keyFromSecret(raw) } + /** + * Base64 url encodes the raw value + * @return Buffer + */ + fun getEncoded(): Buffer { + return Buffer.from(raw.toByteArray().base64UrlEncoded) + } + + /** + * PublicKey associated with this PrivateKey + * @return KMMEdPublicKey + */ + fun publicKey(): KMMEdPublicKey { + return KMMEdPublicKey(keyPair.getPublic()) + } + + /** + * Cryptographically sign a given [message] + * @param message - the ByteArray to be signed + * @return ByteArray - signature Hex converted to ByteArray + */ actual fun sign(message: ByteArray): ByteArray { val sig = keyPair.sign(Buffer.from(message)) diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPublicKey.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPublicKey.kt index de086e82c..dd7046cd8 100644 --- a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPublicKey.kt +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdPublicKey.kt @@ -1,19 +1,42 @@ package io.iohk.atala.prism.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.external.eddsa import node.buffer.Buffer +import node.buffer.BufferEncoding @ExperimentalJsExport @JsExport -actual class KMMEdPublicKey(val raw: ByteArray) { +actual class KMMEdPublicKey(bytes: ByteArray) { + val raw: Buffer private val keyPair: eddsa.KeyPair init { val ed25519 = eddsa("ed25519") - keyPair = ed25519.keyFromPublic(raw) + raw = Curve25519Parser.parseRaw(bytes) + val pub = raw.toString(BufferEncoding.hex) + + // TODO: Report a bug in elliptic, this method is not expecting a Buffer (bytes) + // Internally it expects to find an array, if not Buffer.slice.concat fails when Array.slice.concat doesn't + // Must keep this... + keyPair = ed25519.keyFromPublic(pub) + } + + /** + * Base64 url encodes the raw value + * @return Buffer + */ + fun getEncoded(): Buffer { + return Buffer.from(raw.toByteArray().base64UrlEncoded.encodeToByteArray()) } + /** + * Confirm a message signature was signed with the corresponding PrivateKey + * @param message - the message that was signed + * @param sig - signature + * @return Boolean + */ actual fun verify(message: ByteArray, sig: ByteArray): Boolean { return keyPair.verify(Buffer.from(message), sig.decodeToString()) } diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt index e8fa1386d..ef42836e9 100644 --- a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519KeyPair.kt @@ -1,6 +1,5 @@ package io.iohk.atala.prism.apollo.utils -import io.iohk.atala.prism.apollo.base64.base64UrlEncoded import io.iohk.atala.prism.apollo.utils.external.generateKeyPair as stableLibGenerateKeyPair @ExperimentalJsExport @@ -12,12 +11,10 @@ actual class KMMX25519KeyPair actual constructor( actual companion object : X25519KeyPairGeneration { override fun generateKeyPair(): KMMX25519KeyPair { val keyPair = stableLibGenerateKeyPair() - val secretBytes = keyPair.secretKey.buffer.toByteArray().base64UrlEncoded.encodeToByteArray() - val publicBytes = keyPair.publicKey.buffer.toByteArray().base64UrlEncoded.encodeToByteArray() return KMMX25519KeyPair( - KMMX25519PrivateKey(secretBytes), - KMMX25519PublicKey(publicBytes) + KMMX25519PrivateKey(keyPair.secretKey.buffer.toByteArray()), + KMMX25519PublicKey(keyPair.publicKey.buffer.toByteArray()) ) } } diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PrivateKey.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PrivateKey.kt index 28ee02f9f..196fde0fa 100644 --- a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PrivateKey.kt +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PrivateKey.kt @@ -1,5 +1,38 @@ package io.iohk.atala.prism.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded +import io.iohk.atala.prism.apollo.utils.external.KeyPair +import io.iohk.atala.prism.apollo.utils.external.generateKeyPairFromSeed +import node.buffer.Buffer + @ExperimentalJsExport @JsExport -actual class KMMX25519PrivateKey(val raw: ByteArray) +actual class KMMX25519PrivateKey(bytes: ByteArray) { + val raw: Buffer + + init { + raw = Curve25519Parser.parseRaw(bytes) + } + + /** + * Base64 url encodes the raw value + * @return Buffer + */ + fun getEncoded(): Buffer { + return Buffer.from(raw.toByteArray().base64UrlEncoded) + } + + /** + * PublicKey associated with this PrivateKey + * @return KMMX25519PublicKey + */ + fun publicKey(): KMMX25519PublicKey { + val publicBytes = getInstance().publicKey.buffer.toByteArray() + + return KMMX25519PublicKey(publicBytes) + } + + private fun getInstance(): KeyPair { + return generateKeyPairFromSeed(raw) + } +} diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PublicKey.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PublicKey.kt index f2dbcbd4d..a78bb1437 100644 --- a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PublicKey.kt +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519PublicKey.kt @@ -1,5 +1,22 @@ package io.iohk.atala.prism.apollo.utils +import io.iohk.atala.prism.apollo.base64.base64UrlEncoded +import node.buffer.Buffer + @ExperimentalJsExport @JsExport -actual class KMMX25519PublicKey(val raw: ByteArray) +actual class KMMX25519PublicKey(bytes: ByteArray) { + val raw: Buffer + + init { + raw = Curve25519Parser.parseRaw(bytes) + } + + /** + * Base64 url encodes the raw value + * @return Buffer + */ + fun getEncoded(): Buffer { + return Buffer.from(raw.toByteArray().base64UrlEncoded.encodeToByteArray()) + } +} diff --git a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ellipticjs.kt b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ellipticjs.kt index f11911cb0..3311a0c67 100644 --- a/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ellipticjs.kt +++ b/base-asymmetric-encryption/src/jsMain/kotlin/io/iohk/atala/prism/apollo/utils/external/Ellipticjs.kt @@ -3,7 +3,6 @@ // @file:Suppress("INTERFACE_WITH_SUPERCLASS", "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS") @file:JsModule("elliptic") -/* ktlint-disable */ package io.iohk.atala.prism.apollo.utils.external import node.buffer.Buffer @@ -232,7 +231,7 @@ open external class eddsa(name: String /* "ed25519" */) { open fun keyFromPublic(pub: _eddsa_KeyPair): _eddsa_KeyPair open fun keyFromPublic(pub: base.BasePoint): _eddsa_KeyPair open fun keyFromSecret(secret: String): _eddsa_KeyPair - open fun keyFromSecret(secret: ByteArray): _eddsa_KeyPair + open fun keyFromSecret(secret: Buffer): _eddsa_KeyPair open fun makeSignature(sig: _eddsa_Signature): _eddsa_Signature open fun makeSignature(sig: String): _eddsa_Signature open fun decodePoint(bytes: String): base.BasePoint @@ -268,4 +267,3 @@ open external class eddsa(name: String /* "ed25519" */) { set(value) = definedExternally } } -/* ktlint-disable */ diff --git a/base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPairTests.kt b/base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPairTests.kt index fbbd49f3a..843bc4ff9 100644 --- a/base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPairTests.kt +++ b/base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMEdKeyPairTests.kt @@ -1,11 +1,23 @@ +@file:Suppress("ktlint") + package io.iohk.atala.prism.apollo.utils +import node.buffer.Buffer import kotlin.test.Test import kotlin.test.assertFalse import kotlin.test.assertNotNull import kotlin.test.assertTrue class KMMEdKeyPairTests { + private val raw = arrayOf(234, 155, 38, 115, 124, 211, 171, 185, 149, 186, 77, 255, 240, 94, 209, 65, 63, 214, 168, 213, 146, 68, 68, 196, 167, 211, 183, 80, 14, 166, 239, 217) + private val rawBytes = Buffer.from(raw).toByteArray() + private val encoded = arrayOf(54, 112, 115, 109, 99, 51, 122, 84, 113, 55, 109, 86, 117, 107, 51, 95, 56, 70, 55, 82, 81, 84, 95, 87, 113, 78, 87, 83, 82, 69, 84, 69, 112, 57, 79, 51, 85, 65, 54, 109, 55, 57, 107) + private val encodedBytes = Buffer.from(encoded).toByteArray() + private val publicRaw = arrayOf(207, 230, 188, 131, 200, 191, 223, 38, 163, 19, 244, 3, 35, 18, 5, 238, 195, 245, 155, 246, 139, 41, 51, 159, 202, 2, 46, 72, 150, 167, 68, 8) + private val publicRawBytes = Buffer.from(publicRaw).toByteArray() + private val publicEncoded = arrayOf(122, 45, 97, 56, 103, 56, 105, 95, 51, 121, 97, 106, 69, 95, 81, 68, 73, 120, 73, 70, 55, 115, 80, 49, 109, 95, 97, 76, 75, 84, 79, 102, 121, 103, 73, 117, 83, 74, 97, 110, 82, 65, 103) + private val publicEncodedBytes = Buffer.from(publicEncoded).toByteArray() + @Test fun testGenerateKeyPair() { val keyPair = KMMEdKeyPair.generateKeyPair() @@ -15,6 +27,38 @@ class KMMEdKeyPairTests { assertNotNull(keyPair.publicKey) } + @Test + fun testConstructorRaw() { + val key = KMMEdPrivateKey(rawBytes) + + assertTrue(key.raw.toByteArray() contentEquals rawBytes) + assertTrue(key.getEncoded().toByteArray() contentEquals encodedBytes) + } + + @Test + fun testConstructorEncoded() { + val key = KMMEdPrivateKey(encodedBytes) + + assertTrue(key.raw.toByteArray() contentEquals rawBytes) + assertTrue(key.getEncoded().toByteArray() contentEquals encodedBytes) + } + + @Test + fun testGetEncoded() { + val key = KMMEdPrivateKey(rawBytes) + + assertTrue(key.getEncoded().toByteArray() contentEquals encodedBytes) + } + + @Test + fun testPublicKey() { + val privateKey = KMMEdPrivateKey(rawBytes) + val publicKey = privateKey.publicKey() + + assertTrue(publicKey.raw.toByteArray() contentEquals publicRawBytes) + assertTrue(publicKey.getEncoded().toByteArray() contentEquals publicEncodedBytes) + } + @Test fun testSignMessage() { val keyPair = KMMEdKeyPair.generateKeyPair() @@ -24,6 +68,20 @@ class KMMEdKeyPairTests { assertNotNull(sig) } + @Test + fun testSignMessageKnownValue() { + val privateKey = KMMEdPrivateKey(rawBytes) + val message = "testing".encodeToByteArray() + val sig = privateKey.sign(message) + val sigStr = Buffer.from(sig).toString() + val expectedBytes = byteArrayOf(67, 68, 57, 67, 68, 69, 52, 67, 49, 54, 50, 51, 65, 69, 57, 65, 51, 48, 55, 51, 69, 66, 50, 52, 49, 48, 67, 53, 53, 48, 52, 57, 53, 52, 70, 51, 57, 69, 68, 67, 68, 55, 66, 68, 57, 49, 57, 67, 54, 67, 49, 54, 67, 68, 54, 51, 52, 56, 48, 55, 50, 56, 53, 69, 66, 51, 70, 57, 69, 69, 51, 52, 52, 51, 57, 49, 66, 55, 65, 51, 55, 69, 54, 53, 53, 70, 56, 51, 49, 70, 68, 48, 57, 70, 50, 50, 52, 53, 68, 55, 66, 70, 50, 67, 48, 57, 70, 66, 69, 67, 57, 55, 55, 51, 50, 50, 49, 69, 65, 48, 52, 50, 70, 69, 69, 49, 48, 48) + val expectedStr = Buffer.from(expectedBytes).toString() + + assertNotNull(sig) + assertTrue(expectedBytes contentEquals sig) + assertTrue(expectedStr contentEquals sigStr) + } + @Test fun testVerifyMessage() { val keyPair = KMMEdKeyPair.generateKeyPair() diff --git a/base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519Tests.kt b/base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519Tests.kt new file mode 100644 index 000000000..65439bb08 --- /dev/null +++ b/base-asymmetric-encryption/src/jsTest/kotlin/io/iohk/atala/prism/apollo/utils/KMMX25519Tests.kt @@ -0,0 +1,60 @@ +@file:Suppress("ktlint") + +package io.iohk.atala.prism.apollo.utils + +import node.buffer.Buffer +import kotlin.test.Test +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class KMMX25519Tests { + private val raw = arrayOf(51, 115, 246, 68, 98, 108, 130, 79, 66, 173, 201, 51, 112, 98, 163, 196, 188, 34, 100, 148, 28, 98, 236, 251, 234, 41, 3, 175, 80, 1, 64, 152) + private val rawBytes = Buffer.from(raw).toByteArray() + private val encoded = arrayOf(77, 51, 80, 50, 82, 71, 74, 115, 103, 107, 57, 67, 114, 99, 107, 122, 99, 71, 75, 106, 120, 76, 119, 105, 90, 74, 81, 99, 89, 117, 122, 55, 54, 105, 107, 68, 114, 49, 65, 66, 81, 74, 103) + private val encodedBytes = Buffer.from(encoded).toByteArray() + private val publicRaw = arrayOf(212, 97, 242, 116, 254, 39, 85, 254, 32, 125, 72, 58, 203, 231, 151, 68, 217, 36, 15, 137, 108, 58, 150, 193, 48, 67, 203, 34, 115, 180, 148, 27) + private val publicRawBytes = Buffer.from(publicRaw).toByteArray() + private val publicEncoded = arrayOf(49, 71, 72, 121, 100, 80, 52, 110, 86, 102, 52, 103, 102, 85, 103, 54, 121, 45, 101, 88, 82, 78, 107, 107, 68, 52, 108, 115, 79, 112, 98, 66, 77, 69, 80, 76, 73, 110, 79, 48, 108, 66, 115) + private val publicEncodedBytes = Buffer.from(publicEncoded).toByteArray() + + @Test + fun testGenerateKeyPair() { + val keyPair = KMMX25519KeyPair.generateKeyPair() + + assertNotNull(keyPair) + assertNotNull(keyPair.privateKey) + assertNotNull(keyPair.publicKey) + } + + @Test + fun testConstructorRaw() { + val key = KMMX25519PrivateKey(rawBytes) + + assertTrue(key.raw.toByteArray() contentEquals rawBytes) + assertTrue(key.getEncoded().toByteArray() contentEquals encodedBytes) + } + + @Test + fun testConstructorEncoded() { + val key = KMMX25519PrivateKey(encodedBytes) + + assertTrue(key.raw.toByteArray() contentEquals rawBytes) + assertTrue(key.getEncoded().toByteArray() contentEquals encodedBytes) + } + + @Test + fun testGetEncoded() { + val key = KMMX25519PrivateKey(rawBytes) + + assertTrue(key.getEncoded().toByteArray() contentEquals encodedBytes) + } + + @Test + fun testPublicKey() { + val privateKey = KMMX25519PrivateKey(rawBytes) + val publicKey = privateKey.publicKey() + + assertTrue(publicKey.raw.toByteArray() contentEquals publicRawBytes) + assertTrue(publicKey.getEncoded().toByteArray() contentEquals publicEncodedBytes) + } +}