use asByteArray _view_ where possible (optimization)

This commit is contained in:
Sergey Chernov 2024-08-19 11:58:52 +02:00
parent b5ac0c4e7e
commit 6431d4896a
17 changed files with 50 additions and 22 deletions

1
.idea/misc.xml generated
View File

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="FrameworkDetectionExcludesConfiguration">

View File

@ -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

View File

@ -5,7 +5,7 @@ plugins {
}
group = "net.sergeych"
version = "0.4.2"
version = "0.4.3"
repositories {
mavenCentral()

View File

@ -442,7 +442,7 @@ sealed class Container {
createWith(BipackEncoder.encode<T>(plainData).toUByteArray(), *keys).encoded
inline fun <reified T>decrypt(cipherData: UByteArray, vararg keys: DecryptingKey): T? =
decryptAsUBytes(cipherData,*keys)?.let { BipackDecoder.decode<T>(it.toByteArray())}
decryptAsUBytes(cipherData,*keys)?.let { BipackDecoder.decode<T>(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())
}
}

View File

@ -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()

View File

@ -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 <reified T>DecryptingKey.decryptObject(cipherData: UByteArray): T =
BipackDecoder.decode<T>(decrypt(cipherData).toByteArray())
BipackDecoder.decode<T>(decrypt(cipherData).asByteArray())

View File

@ -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()

View File

@ -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<BinaryId, Entry>()

View File

@ -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()
}
}

View File

@ -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 <reified T>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 <reified T>decode(packedSealedBox: UByteArray): T =
BipackDecoder.decode<SealedBox>(packedSealedBox.asByteArray()).message.decodeFromBipack()
}
}

View File

@ -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)
}

View File

@ -32,6 +32,6 @@ class WithFill private constructor(
* extract binary data from filled
*/
fun decode(data: UByteArray): UByteArray =
BipackDecoder.decode<WithFill>(data.toByteArray()).data
BipackDecoder.decode<WithFill>(data.asByteArray()).data
}
}

View File

@ -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()
fun UByteArray.encodeToBase64Url(): String = asByteArray().encodeToBase64Url()

View File

@ -4,7 +4,7 @@ import net.sergeych.bipack.BipackDecoder
import net.sergeych.bipack.BipackEncoder
inline fun <reified T>bipack(value: T): UByteArray = BipackEncoder.encode(value).toUByteArray()
inline fun <reified T>bipack(value: T): UByteArray = BipackEncoder.encode(value).asUByteArray()
inline fun <reified T>biunpack(value: UByteArray): T = BipackDecoder.decode(value.toByteArray())
inline fun <reified T>biunpack(value: UByteArray): T = BipackDecoder.decode(value.asByteArray())

View File

@ -43,4 +43,4 @@ fun <T>pack(serializer: KSerializer<T>, element: T?): UByteArray =
@Suppress("UNCHECKED_CAST")
fun <T: Any?> unpack(serializer: KSerializer<T>, encoded: UByteArray): T =
if (encoded.isEmpty()) null as T
else BipackDecoder.decode(encoded.toByteArray().toDataSource(),serializer)
else BipackDecoder.decode(encoded.asByteArray().toDataSource(),serializer)

View File

@ -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()
}
/**

View File

@ -250,4 +250,16 @@ class KeysTest {
val k1: UniversalKey = biunpack<UniversalKey>(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<SigningSecretKey>(s1)
val dk2 = unpack<VerifyingPublicKey>(s2)
assertEquals(k, dk1)
assertEquals(k.verifyingKey, dk2)
}
}