From 6431d4896a23022ccedb4e469fcee0f3119c2fc0 Mon Sep 17 00:00:00 2001 From: sergeych Date: Mon, 19 Aug 2024 11:58:52 +0200 Subject: [PATCH] use asByteArray _view_ where possible (optimization) --- .idea/misc.xml | 1 - README.md | 8 ++++++++ build.gradle.kts | 2 +- .../kotlin/net/sergeych/crypto2/Container.kt | 4 ++-- .../kotlin/net/sergeych/crypto2/Contrail.kt | 4 ++-- .../kotlin/net/sergeych/crypto2/DecryptingKey.kt | 4 ++-- src/commonMain/kotlin/net/sergeych/crypto2/Hash.kt | 4 ++-- src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt | 2 +- src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt | 2 +- .../kotlin/net/sergeych/crypto2/SealedBox.kt | 13 +++++++++++-- .../kotlin/net/sergeych/crypto2/SecretKey.kt | 2 +- .../kotlin/net/sergeych/crypto2/WithFill.kt | 2 +- .../kotlin/net/sergeych/crypto2/utools.kt | 4 ++-- .../kotlin/net/sergeych/tools/pack_tools.kt | 4 ++-- .../kotlin/net/sergeych/utools/packing.kt | 2 +- .../khash/keccak/extensions/PublicExtensions.kt | 2 +- src/commonTest/kotlin/KeysTest.kt | 12 ++++++++++++ 17 files changed, 50 insertions(+), 22 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 76d6398..efbe595 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ - diff --git a/README.md b/README.md index 5cd6974..dc92809 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,14 @@ Cryptographic API works exactly the same and compiles to any platform supported All primitives meant to send over the network or store are `kotlinx.serialization` compatible, serializers included. +# Usage + +```kotlin +dependencies { + maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven") +} +``` + # Supported platforms: ## Javascript diff --git a/build.gradle.kts b/build.gradle.kts index 81c30fb..9e6a0cc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,7 @@ plugins { } group = "net.sergeych" -version = "0.4.2" +version = "0.4.3" repositories { mavenCentral() diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/Container.kt b/src/commonMain/kotlin/net/sergeych/crypto2/Container.kt index 9192b36..30ccd9a 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/Container.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/Container.kt @@ -442,7 +442,7 @@ sealed class Container { createWith(BipackEncoder.encode(plainData).toUByteArray(), *keys).encoded inline fun decrypt(cipherData: UByteArray, vararg keys: DecryptingKey): T? = - decryptAsUBytes(cipherData,*keys)?.let { BipackDecoder.decode(it.toByteArray())} + decryptAsUBytes(cipherData,*keys)?.let { BipackDecoder.decode(it.asByteArray())} fun decryptAsUBytes(cipherData: UByteArray, vararg keys: DecryptingKey): UByteArray? = decode(cipherData).decryptWith(*keys) @@ -465,7 +465,7 @@ sealed class Container { create(plainData) { key(*keys) } fun decode(encoded: UByteArray): Container { - return BipackDecoder.decode(encoded.toByteArray()) + return BipackDecoder.decode(encoded.asByteArray()) } } diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/Contrail.kt b/src/commonMain/kotlin/net/sergeych/crypto2/Contrail.kt index 7239674..db12b02 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/Contrail.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/Contrail.kt @@ -11,13 +11,13 @@ object Contrail { /** * Create a contrail by adding a crc byte to the end of [data]. The Result is always one byte longer. */ - fun create(data: UByteArray): UByteArray = data + CRC.crc8(data.toByteArray()) + fun create(data: UByteArray): UByteArray = data + CRC.crc8(data.asByteArray()) /** * Check the contrail is valid. */ fun isValid(data: UByteArray): Boolean = CRC.crc8( - data.copyOfRange(0, data.size - 1).toByteArray() + data.copyOfRange(0, data.size - 1).asByteArray() ) == data.last() diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/DecryptingKey.kt b/src/commonMain/kotlin/net/sergeych/crypto2/DecryptingKey.kt index 1fcc13e..13d1a17 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/DecryptingKey.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/DecryptingKey.kt @@ -19,7 +19,7 @@ interface DecryptingKey : NonceBased, KeyInstance { */ fun decrypt(cipherData: UByteArray): UByteArray = protectDecryption { - val wn: WithNonce = cipherData.toByteArray().decodeFromBipack() + val wn: WithNonce = cipherData.asByteArray().decodeFromBipack() decryptWithNonce(wn.cipherData, wn.nonce) } @@ -31,4 +31,4 @@ interface DecryptingKey : NonceBased, KeyInstance { } inline fun DecryptingKey.decryptObject(cipherData: UByteArray): T = - BipackDecoder.decode(decrypt(cipherData).toByteArray()) \ No newline at end of file + BipackDecoder.decode(decrypt(cipherData).asByteArray()) \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/Hash.kt b/src/commonMain/kotlin/net/sergeych/crypto2/Hash.kt index 705a4b1..8e96b18 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/Hash.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/Hash.kt @@ -9,8 +9,8 @@ import org.komputing.khash.keccak.KeccakParameter enum class Hash(val perform: (UByteArray)->UByteArray) { Blake2b({ GenericHash.genericHash(it) }), Blake2b2l({ blake2b2l(it) }), - Sha3_384({ Keccak.digest(it.toByteArray(), KeccakParameter.SHA3_384).toUByteArray()}), - Sha3_256({ Keccak.digest(it.toByteArray(), KeccakParameter.SHA3_256).toUByteArray()}), + Sha3_384({ Keccak.digest(it.asByteArray(), KeccakParameter.SHA3_384).asUByteArray()}), + Sha3_256({ Keccak.digest(it.asByteArray(), KeccakParameter.SHA3_256).asUByteArray()}), } private val defaultSuffix1 = "All lay loads on a willing horse".encodeToUByteArray() diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt b/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt index 9385d11..80a4950 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt @@ -96,7 +96,7 @@ object PBKD { fun key(kdf: KDF, password: String): BinaryId = BinaryId.createFromBytes( 0, - BipackEncoder.encode(kdf) + blake2b3l(password.encodeToUByteArray()).toByteArray() + BipackEncoder.encode(kdf) + blake2b3l(password.encodeToUByteArray()).asByteArray() ) private val cache = HashMap() diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt b/src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt index dbbc1a9..c47e270 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/Seal.kt @@ -145,6 +145,6 @@ class Seal( * Int the rare case you need a packed seal alone, unpack it. Normally just add seal to some [Serializable] * class, it is serializable. */ - fun unpack(packed: UByteArray): Seal = packed.toByteArray().decodeFromBipack() + fun unpack(packed: UByteArray): Seal = packed.asByteArray().decodeFromBipack() } } \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/SealedBox.kt b/src/commonMain/kotlin/net/sergeych/crypto2/SealedBox.kt index 44347b0..0a616be 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/SealedBox.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/SealedBox.kt @@ -3,7 +3,9 @@ package net.sergeych.crypto2 import kotlinx.datetime.Instant import kotlinx.serialization.Serializable import kotlinx.serialization.Transient +import net.sergeych.bipack.BipackDecoder import net.sergeych.bipack.BipackEncoder +import net.sergeych.bipack.decodeFromBipack /** * Multi-signed data box. Do not use the constructori directly, use [SealedBox.create] @@ -14,7 +16,7 @@ import net.sergeych.bipack.BipackEncoder * Signatures, [Seal], incorporate creation time and optional expiration which are * also signed and checked upon deserialization. * - * It is serializable and checks integrity __on deserialization__k. If any of seals does not + * It is serializable and checks integrity __on deserialization__. If any of seals does not * match the signed [message], it throws [IllegalSignatureException] _on deserialization_. * E.g., if you have it deserialized, it is ok, check it contains all needed keys among * signers. @@ -79,12 +81,19 @@ class SealedBox( * @param keys a list of keys to sign with, should be at least one key. * @throws IllegalArgumentException if keys are not specified. */ - fun create(data: UByteArray, vararg keys: SigningSecretKey): SealedBox { + fun create(data: UByteArray, vararg keys: SigningKey): SealedBox { return SealedBox(data, keys.map { it.seal(data) }, false) } inline fun encode(value: T, vararg keys: SigningSecretKey): UByteArray = create(BipackEncoder.encode(value).toUByteArray(), *keys).encoded + /** + * Unpack and check sealed box, returning deserialized contained value + * @throws IllegalSignatureException + */ + inline fun decode(packedSealedBox: UByteArray): T = + BipackDecoder.decode(packedSealedBox.asByteArray()).message.decodeFromBipack() + } } \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/SecretKey.kt b/src/commonMain/kotlin/net/sergeych/crypto2/SecretKey.kt index 3737146..131c89e 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/SecretKey.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/SecretKey.kt @@ -62,7 +62,7 @@ class SecretKey( * Decrypt without a nonce as edwards curve decryption does not need it */ override fun decrypt(cipherData: UByteArray): UByteArray { - val message: Asymmetric.Message = BipackDecoder.decode(cipherData.toByteArray()) + val message: Asymmetric.Message = BipackDecoder.decode(cipherData.asByteArray()) return message.decrypt(this) } diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/WithFill.kt b/src/commonMain/kotlin/net/sergeych/crypto2/WithFill.kt index 34badd4..0f16ec1 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/WithFill.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/WithFill.kt @@ -32,6 +32,6 @@ class WithFill private constructor( * extract binary data from filled */ fun decode(data: UByteArray): UByteArray = - BipackDecoder.decode(data.toByteArray()).data + BipackDecoder.decode(data.asByteArray()).data } } \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/utools.kt b/src/commonMain/kotlin/net/sergeych/crypto2/utools.kt index 5ff80d8..f4b150d 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/utools.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/utools.kt @@ -5,6 +5,6 @@ package net.sergeych.crypto2 import net.sergeych.bintools.toDump import net.sergeych.mp_tools.encodeToBase64Url -fun UByteArray.toDump(wide: Boolean = false) = toByteArray().toDump(wide) +fun UByteArray.toDump(wide: Boolean = false) = asByteArray().toDump(wide) -fun UByteArray.encodeToBase64Url(): String = toByteArray().encodeToBase64Url() \ No newline at end of file +fun UByteArray.encodeToBase64Url(): String = asByteArray().encodeToBase64Url() \ No newline at end of file diff --git a/src/commonMain/kotlin/net/sergeych/tools/pack_tools.kt b/src/commonMain/kotlin/net/sergeych/tools/pack_tools.kt index b1ae126..d616ee9 100644 --- a/src/commonMain/kotlin/net/sergeych/tools/pack_tools.kt +++ b/src/commonMain/kotlin/net/sergeych/tools/pack_tools.kt @@ -4,7 +4,7 @@ import net.sergeych.bipack.BipackDecoder import net.sergeych.bipack.BipackEncoder -inline fun bipack(value: T): UByteArray = BipackEncoder.encode(value).toUByteArray() +inline fun bipack(value: T): UByteArray = BipackEncoder.encode(value).asUByteArray() -inline fun biunpack(value: UByteArray): T = BipackDecoder.decode(value.toByteArray()) +inline fun biunpack(value: UByteArray): T = BipackDecoder.decode(value.asByteArray()) diff --git a/src/commonMain/kotlin/net/sergeych/utools/packing.kt b/src/commonMain/kotlin/net/sergeych/utools/packing.kt index 0b5ac85..7040e8e 100644 --- a/src/commonMain/kotlin/net/sergeych/utools/packing.kt +++ b/src/commonMain/kotlin/net/sergeych/utools/packing.kt @@ -43,4 +43,4 @@ fun pack(serializer: KSerializer, element: T?): UByteArray = @Suppress("UNCHECKED_CAST") fun unpack(serializer: KSerializer, encoded: UByteArray): T = if (encoded.isEmpty()) null as T - else BipackDecoder.decode(encoded.toByteArray().toDataSource(),serializer) + else BipackDecoder.decode(encoded.asByteArray().toDataSource(),serializer) diff --git a/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/PublicExtensions.kt b/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/PublicExtensions.kt index 563ac88..05acc04 100644 --- a/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/PublicExtensions.kt +++ b/src/commonMain/kotlin/org/komputing/khash/keccak/extensions/PublicExtensions.kt @@ -12,7 +12,7 @@ fun ByteArray.digestKeccak(parameter: KeccakParameter): ByteArray { } fun UByteArray.digestKeccak(parameter: KeccakParameter): UByteArray { - return Keccak.digest(this.toByteArray(), parameter).toUByteArray() + return Keccak.digest(this.asByteArray(), parameter).toUByteArray() } /** diff --git a/src/commonTest/kotlin/KeysTest.kt b/src/commonTest/kotlin/KeysTest.kt index 2184303..9450aee 100644 --- a/src/commonTest/kotlin/KeysTest.kt +++ b/src/commonTest/kotlin/KeysTest.kt @@ -250,4 +250,16 @@ class KeysTest { val k1: UniversalKey = biunpack(d) as SymmetricKey assertEquals(k, k1) } + + @Test + fun verifyingKeySerializationTest() = runTest { + initCrypto() + val k = SigningSecretKey.new() + val s1 = pack(k) + val s2 = pack(k.verifyingKey) + val dk1 = unpack(s1) + val dk2 = unpack(s2) + assertEquals(k, dk1) + assertEquals(k.verifyingKey, dk2) + } } \ No newline at end of file