diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt new file mode 100644 index 0000000..7a2c2a6 --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt @@ -0,0 +1,92 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.hash.MultipartHash +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 23-Jun-2020 + */ +inline class EncryptableString(val content: String) : Encryptable { + override fun toEncryptableForm(): UByteArray { + return content.encodeToUByteArray() + } + + override fun fromEncryptableForm(): (UByteArray) -> EncryptableString { + return { uByteArray -> + EncryptableString(uByteArray.toByteArray().decodeToString()) + } + } + + fun asString() : String = content + + +} + +fun String.asEncryptableString() : EncryptableString { + return EncryptableString(this) +} + +interface Encryptable { + fun toEncryptableForm() : UByteArray + fun fromEncryptableForm() : (UByteArray) -> T +} + +data class HashedData(val hash: UByteArray) { + fun toHexString() : String { + return hash.toHexString() + } +} + +data class SymmetricKey(val value : UByteArray) { + companion object { + + } +} + +data class EncryptedData constructor(val ciphertext: UByteArray, val nonce: UByteArray) { + +} + +interface HashApi { + fun hash(data: UByteArray, key : UByteArray = ubyteArrayOf()) : HashedData + fun multipartHash(key: UByteArray? = null) : MultipartHash +} + +interface EncryptionApi { + fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray = ubyteArrayOf()) : EncryptedData + fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T + fun multipartEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption + fun multipartDecryptProcessStart(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification + +} + +interface AuthenticatedEncryption { + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray + fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray + +} + +data class EncryptedDataPart(val data : UByteArray) +data class DecryptedDataPart(val data : UByteArray) + +data class MultipartEncryptedDataDescriptor(val data: UByteArray, val nonce: UByteArray) + +class InvalidTagException : RuntimeException("Tag mismatch! Encrypted data is corrupted or tampered with.") + +interface MultipartAuthenticatedVerification { + fun verifyPartialData(data: EncryptedDataPart) + fun finalizeVerificationAndPrepareDecryptor() : MultipartAuthenticatedDecryption +} + +interface MultipartAuthenticatedDecryption { + fun decryptPartialData(data: EncryptedDataPart) : DecryptedDataPart +} + +interface MultipartAuthenticatedEncryption { + fun encryptPartialData(data: UByteArray) : EncryptedDataPart + fun finish() : MultipartEncryptedDataDescriptor + +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoInitializer.kt similarity index 70% rename from multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt rename to multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoInitializer.kt index e836850..c97df6b 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoInitializer.kt @@ -5,8 +5,10 @@ package com.ionspin.kotlin.crypto * ugljesa.jovanovic@ionspin.com * on 27-May-2020 */ -interface CryptoProvider { +interface CryptoInitializer { suspend fun initialize() + fun isInitialized() : Boolean -} \ No newline at end of file + +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/PrimitivesApi.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/PrimitivesApi.kt new file mode 100644 index 0000000..300f80c --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/PrimitivesApi.kt @@ -0,0 +1,37 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties +import com.ionspin.kotlin.crypto.hash.sha.Sha256 +import com.ionspin.kotlin.crypto.hash.sha.Sha512 +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 23-Jun-2020 + */ +interface PrimitivesApi { + fun hashBlake2bMultipart(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): Blake2bMultipart + fun hashBlake2b(message: UByteArray, key: UByteArray = ubyteArrayOf(), hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): UByteArray + + fun hashSha256Multipart(): Sha256 + fun hashSha256(message: UByteArray) : UByteArray + + fun hashSha512Multipart(): Sha512 + fun hashSha512(message: UByteArray) : UByteArray + + fun deriveKey( + password: String, + salt: String? = null, + key: String, + associatedData: String, + parallelism: Int = 16, + tagLength: Int = 64, + memory: Int = 4096, + numberOfIterations: Int = 10, + ) : ArgonResult + +} + + diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/Aes256Gcm.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/Aes256Gcm.kt deleted file mode 100644 index 66c665e..0000000 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/Aes256Gcm.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.ionspin.kotlin.crypto.authenticated - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 14-Jun-2020 - */ -interface Aes256GcmStateless { - - fun encrypt(message: UByteArray, additionalData: UByteArray, rawData : UByteArray, key: Aes256GcmKey) : Aes256GcmEncryptionResult - - fun decrypt(encryptedData: UByteArray, nonce: UByteArray, key : Aes256GcmKey) : UByteArray -} - -data class Aes256GcmEncryptionResult(val cyphertext : UByteArray, val additionalData: UByteArray, val nonce: UByteArray, val tag: UByteArray) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other == null || this::class != other::class) return false - - other as Aes256GcmEncryptionResult - - if (cyphertext != other.cyphertext) return false - if (additionalData != other.additionalData) return false - if (nonce != other.nonce) return false - if (tag != other.tag) return false - - return true - } - - override fun hashCode(): Int { - var result = cyphertext.hashCode() - result = 31 * result + additionalData.hashCode() - result = 31 * result + nonce.hashCode() - result = 31 * result + tag.hashCode() - return result - } -} - - -interface Aes256GcmKey { - val key : UByteArray -} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/AuthenticatedSymmetricEncryption.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/AuthenticatedSymmetricEncryption.kt deleted file mode 100644 index 00f6865..0000000 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/AuthenticatedSymmetricEncryption.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.ionspin.kotlin.crypto.authenticated - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 22-Jun-2020 - */ -interface AuthenticatedEncryption { - fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray - fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray - -} - -data class EncryptedDataPart(val data : UByteArray) -data class DecryptedDataPart(val data : UByteArray) - -data class MultipartEncryptedDataDescriptor(val data: UByteArray, val nonce: UByteArray) - - - - -interface MultipartAuthenticatedVerification { - fun verifyPartialData(data: EncryptedDataPart) - fun finalizeVerificationAndPrepareDecryptor() : MultipartAuthenticatedDecryption -} - -interface MultipartAuthenticatedDecryption { - fun decryptPartialData(data: EncryptedDataPart) : DecryptedDataPart -} - -interface MultipartAuthenticatedEncryption { - fun encryptPartialData(data: UByteArray) : EncryptedDataPart - fun finish() : MultipartEncryptedDataDescriptor - -} - diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/HashFunction.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/HashFunction.kt index 1f0a49e..a0478e2 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/HashFunction.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/HashFunction.kt @@ -27,7 +27,7 @@ interface HashFunction { } -interface MultiPartHash : HashFunction { +interface MultipartHash : HashFunction { fun update(data : UByteArray) fun digest() : UByteArray diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bMultipart.kt similarity index 82% rename from multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt rename to multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bMultipart.kt index eeff721..0cc7cb2 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bMultipart.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.crypto.hash.Hash -import com.ionspin.kotlin.crypto.hash.MultiPartHash +import com.ionspin.kotlin.crypto.hash.MultipartHash /** * Created by Ugljesa Jovanovic @@ -13,12 +13,12 @@ object Blake2bProperties { const val MAX_HASH_BYTES = 64 } -interface Blake2b : MultiPartHash { +interface Blake2bMultipart : MultipartHash { override val MAX_HASH_BYTES: Int get() = Blake2bProperties.MAX_HASH_BYTES } -interface Blake2bStateless : Hash { +interface Blake2b : Hash { override val MAX_HASH_BYTES: Int get() = Blake2bProperties.MAX_HASH_BYTES diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt index f806b80..90c2dcd 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha import com.ionspin.kotlin.crypto.hash.Hash -import com.ionspin.kotlin.crypto.hash.MultiPartHash +import com.ionspin.kotlin.crypto.hash.MultipartHash /** * Created by Ugljesa Jovanovic @@ -12,7 +12,7 @@ object Sha256Properties { const val MAX_HASH_BYTES = 32 } -interface Sha256 : MultiPartHash { +interface Sha256 : MultipartHash { override val MAX_HASH_BYTES: Int get() = Sha256Properties.MAX_HASH_BYTES } @@ -23,4 +23,4 @@ interface StatelessSha256 : Hash { fun digest( inputMessage: UByteArray = ubyteArrayOf() ): UByteArray -} \ No newline at end of file +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt index a5c672e..e176c1a 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha import com.ionspin.kotlin.crypto.hash.Hash -import com.ionspin.kotlin.crypto.hash.MultiPartHash +import com.ionspin.kotlin.crypto.hash.MultipartHash /** * Created by Ugljesa Jovanovic @@ -11,15 +11,15 @@ import com.ionspin.kotlin.crypto.hash.MultiPartHash object Sha512Properties { const val MAX_HASH_BYTES = 64 } -interface Sha512 : MultiPartHash { +interface Sha512 : MultipartHash { override val MAX_HASH_BYTES: Int get() = Sha256Properties.MAX_HASH_BYTES } -interface StatelessSha512 : Hash { +interface MultipartSha512 : Hash { override val MAX_HASH_BYTES: Int get() = Sha512Properties.MAX_HASH_BYTES fun digest( inputMessage: UByteArray = ubyteArrayOf() ): UByteArray -} \ No newline at end of file +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt index 3a6463b..bdd0031 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt @@ -23,4 +23,13 @@ package com.ionspin.kotlin.crypto.keyderivation */ interface KeyDerivationFunction { fun derive() : UByteArray -} \ No newline at end of file +} + +data class ArgonResult( + val hashBytes: UByteArray, + val salt: UByteArray +) { + val hashString by lazy { hashBytes.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } + val saltString by lazy { salt.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } + +} diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt index 0d4d849..a7a0ec6 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt @@ -3,7 +3,9 @@ package com.ionspin.kotlin.crypto import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart import com.ionspin.kotlin.crypto.hash.sha.* +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult /** * Created by Ugljesa Jovanovic @@ -11,18 +13,27 @@ import com.ionspin.kotlin.crypto.hash.sha.* * on 24-May-2020 */ -object Crypto : CryptoProvider { +object CryptoInitializerDelegated : CryptoInitializer { + private var initialized = false override suspend fun initialize() { Initializer.initialize() + initialized = true } fun initializeWithCallback(done: () -> Unit) { + initialized = true Initializer.initializeWithCallback(done) } + override fun isInitialized(): Boolean { + return initialized + } +} + +object CryptoPrimitives : PrimitivesApi { object Blake2b { - fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b { + fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart { checkInitialization() return Blake2bDelegated(key, hashLength) } @@ -63,12 +74,135 @@ object Crypto : CryptoProvider { } } + override fun hashBlake2bMultipart(key: UByteArray?, hashLength: Int): Blake2bMultipart { + checkInitialization() + return Blake2bDelegated(key, hashLength) + } + + override fun hashBlake2b(message: UByteArray, key: UByteArray, hashLength: Int): UByteArray { + checkInitialization() + return Blake2bDelegatedStateless.digest(message, key, hashLength) + } + + override fun hashSha256Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha256 { + checkInitialization() + return Sha256Delegated() + } + + override fun hashSha256(message: UByteArray): UByteArray { + checkInitialization() + return Sha256StatelessDelegated.digest(inputMessage = message) + } + + override fun hashSha512Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha512 { + checkInitialization() + return Sha512Delegated() + } + + override fun hashSha512(message: UByteArray): UByteArray { + checkInitialization() + return Sha512StatelessDelegated.digest(inputMessage = message) + } + + override fun deriveKey( + password: String, + salt: String?, + key: String, + associatedData: String, + parallelism: Int, + tagLength: Int, + memory: Int, + numberOfIterations: Int + ): ArgonResult { +// return Argon2Delegated.derive( +// password, +// salt, +// key, +// associatedData, +// parallelism, +// tagLength, +// memory, +// numberOfIterations +// ) + TODO() + } + } -object SimpleCrypto { - fun hash(message: String): UByteArray { - return ubyteArrayOf(0U) +fun SymmetricKey.Companion.randomKey() : SymmetricKey { + return SymmetricKey(SRNG.getRandomBytes(32)) +} + +object Crypto { + + object Hash : HashApi { + override fun hash(data: UByteArray, key : UByteArray) : HashedData { + return HashedData(Blake2bDelegatedStateless.digest(data, key)) + } + + override fun multipartHash(key: UByteArray?) : com.ionspin.kotlin.crypto.hash.MultipartHash { + return Blake2bDelegated(key) + } + } + + object Encryption : EncryptionApi { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData { + if (key.value.size != 32) { + throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}") + } + val nonce = SRNG.getRandomBytes(24) + return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce) + + } + + override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { + return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData)) + + } + + override fun multipartEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption { + return MultipartAuthenticatedEncryptor(key, additionalData) + } + + override fun multipartDecryptProcessStart(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification { + return MultiplatformAuthenticatedVerificator(key, dataDescriptor, additionalData) + } + } +} + +class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption { + val primitive = XChaCha20Poly1305Pure(key.value, additionalData) + override fun encryptPartialData(data: UByteArray): EncryptedDataPart { + return EncryptedDataPart(primitive.encryptPartialData(data)) + } + + override fun finish(): MultipartEncryptedDataDescriptor { + val finished = primitive.finish() + return MultipartEncryptedDataDescriptor(finished.first, finished.second) + } + +} + +class MultiplatformAuthenticatedVerificator internal constructor(key: SymmetricKey, multipartEncryptedDataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification { + val primitive = XChaCha20Poly1305Pure(key.value, additionalData) + val tag = multipartEncryptedDataDescriptor.data.sliceArray( + multipartEncryptedDataDescriptor.data.size - 16 until multipartEncryptedDataDescriptor.data.size + ) + override fun verifyPartialData(data: EncryptedDataPart) { + primitive.verifyPartialData(data.data) + } + + override fun finalizeVerificationAndPrepareDecryptor(): MultipartAuthenticatedDecryption { + primitive.checkTag(tag) + return MultipartAuthenticatedDecryptor(primitive) + } + +} + +class MultipartAuthenticatedDecryptor internal constructor(val encryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption { + override fun decryptPartialData(data: EncryptedDataPart): DecryptedDataPart { + return DecryptedDataPart(encryptor.decrypt(data.data)) } } diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index 1e15a51..4887631 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -23,9 +23,9 @@ package com.ionspin.kotlin.crypto.hash.blake2b */ -expect class Blake2bDelegated(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES) : Blake2b +expect class Blake2bDelegated(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES) : Blake2bMultipart -expect object Blake2bDelegatedStateless : Blake2bStateless +expect object Blake2bDelegatedStateless : Blake2b diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index 13a809d..e2bc79b 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -26,4 +26,4 @@ package com.ionspin.kotlin.crypto.hash.sha expect class Sha512Delegated() : Sha512 -expect object Sha512StatelessDelegated : StatelessSha512 \ No newline at end of file +expect object Sha512StatelessDelegated : MultipartSha512 diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index 25eb586..fa53403 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -1,8 +1,6 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.crypto.getSodium -import com.ionspin.kotlin.crypto.hash.sha.Sha256StatelessDelegated -import com.ionspin.kotlin.crypto.util.toHexString import org.khronos.webgl.Uint8Array import org.khronos.webgl.get @@ -13,7 +11,7 @@ import org.khronos.webgl.get */ -actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2b { +actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart { override val MAX_HASH_BYTES: Int = 64 @@ -43,7 +41,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLengt -actual object Blake2bDelegatedStateless : Blake2bStateless { +actual object Blake2bDelegatedStateless : Blake2b { override val MAX_HASH_BYTES: Int = 64 override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { @@ -59,4 +57,4 @@ actual object Blake2bDelegatedStateless : Blake2bStateless { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index 4d68c4d..2774b8d 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -1,6 +1,5 @@ package com.ionspin.kotlin.crypto.hash.sha -import com.ionspin.kotlin.crypto.getSodium import com.ionspin.kotlin.crypto.getSodium import org.khronos.webgl.Uint8Array @@ -35,7 +34,7 @@ actual class Sha512Delegated : Sha512 { } -actual object Sha512StatelessDelegated : StatelessSha512 { +actual object Sha512StatelessDelegated : MultipartSha512 { override fun digest(inputMessage: UByteArray): UByteArray { val hashed = getSodium().crypto_hash_sha512(Uint8Array(inputMessage.toByteArray().toTypedArray())) @@ -45,4 +44,4 @@ actual object Sha512StatelessDelegated : StatelessSha512 { } return hash } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index 7ab8196..7e06995 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -8,7 +8,7 @@ import com.ionspin.kotlin.crypto.Initializer.sodium */ -actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2b { +actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart { val state = ByteArray(sodium.crypto_generichash_statebytes()) @@ -28,7 +28,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLengt } -actual object Blake2bDelegatedStateless : Blake2bStateless { +actual object Blake2bDelegatedStateless : Blake2b { override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { @@ -37,4 +37,4 @@ actual object Blake2bDelegatedStateless : Blake2bStateless { return hashed.toUByteArray() } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index ca00e48..312a61a 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -30,11 +30,11 @@ actual class Sha512Delegated : Sha512 { } -actual object Sha512StatelessDelegated : StatelessSha512 { +actual object Sha512StatelessDelegated : MultipartSha512 { override fun digest(inputMessage: UByteArray): UByteArray { val hashed = ByteArray(Sha512Properties.MAX_HASH_BYTES) Initializer.sodium.crypto_hash_sha512(hashed, inputMessage.toByteArray(), inputMessage.size.toLong()) return hashed.toUByteArray() } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt new file mode 100644 index 0000000..e1caffb --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt @@ -0,0 +1,164 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.authenticated.* +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure +import com.ionspin.kotlin.crypto.hash.sha.Sha256Pure +import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult +import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Pure + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 24-May-2020 + */ +object CryptoInitializerPure : CryptoInitializer { + override suspend fun initialize() { + //Nothing to do atm. + } + + fun initializeWithCallback(done: () -> Unit) { + done() + } + + override fun isInitialized(): Boolean { + return true + } +} + +object CryptoPrimitives : PrimitivesApi { + private fun checkInitialization() { + CryptoInitializerPure.isInitialized() + } + + override fun hashBlake2bMultipart(key: UByteArray?, hashLength: Int): Blake2bMultipart { + checkInitialization() + return Blake2bPure(key, hashLength) + } + + override fun hashBlake2b(message: UByteArray, key: UByteArray, hashLength: Int): UByteArray { + checkInitialization() + return Blake2bPure.digest(message, key, hashLength) + } + + override fun hashSha256Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha256 { + checkInitialization() + return Sha256Pure() + } + + override fun hashSha256(message: UByteArray): UByteArray { + checkInitialization() + return Sha256Pure.digest(inputMessage = message) + } + + override fun hashSha512Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha512 { + checkInitialization() + return Sha512Pure() + } + + override fun hashSha512(message: UByteArray): UByteArray { + checkInitialization() + return Sha512Pure.digest(inputMessage = message) + } + + override fun deriveKey( + password: String, + salt: String?, + key: String, + associatedData: String, + parallelism: Int, + tagLength: Int, + memory: Int, + numberOfIterations: Int + ): ArgonResult { + return Argon2Pure.derive( + password, + salt, + key, + associatedData, + parallelism, + tagLength, + memory, + numberOfIterations + ) + } +} + +fun SymmetricKey.Companion.randomKey() : SymmetricKey { + return SymmetricKey(SRNG.getRandomBytes(32)) +} + +object Crypto { + + object Hash : HashApi { + override fun hash(data: UByteArray, key : UByteArray) : HashedData { + return HashedData(Blake2bPure.digest(data, key)) + } + + override fun multipartHash(key: UByteArray?) : com.ionspin.kotlin.crypto.hash.MultipartHash { + return Blake2bPure(key) + } + } + + object Encryption : EncryptionApi { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData { + if (key.value.size != 32) { + throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}") + } + val nonce = SRNG.getRandomBytes(24) + return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce) + + } + + override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { + return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData)) + + } + + override fun multipartEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption { + return MultipartAuthenticatedEncryptor(key, additionalData) + } + + override fun multipartDecryptProcessStart(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification { + return MultiplatformAuthenticatedVerificator(key, dataDescriptor, additionalData) + } + } +} + +class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption { + val primitive = XChaCha20Poly1305Pure(key.value, additionalData) + override fun encryptPartialData(data: UByteArray): EncryptedDataPart { + return EncryptedDataPart(primitive.encryptPartialData(data)) + } + + override fun finish(): MultipartEncryptedDataDescriptor { + val finished = primitive.finish() + return MultipartEncryptedDataDescriptor(finished.first, finished.second) + } + +} + +class MultiplatformAuthenticatedVerificator internal constructor(key: SymmetricKey, multipartEncryptedDataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification { + val primitive = XChaCha20Poly1305Pure(key.value, additionalData) + val tag = multipartEncryptedDataDescriptor.data.sliceArray( + multipartEncryptedDataDescriptor.data.size - 16 until multipartEncryptedDataDescriptor.data.size + ) + override fun verifyPartialData(data: EncryptedDataPart) { + primitive.verifyPartialData(data.data) + } + + override fun finalizeVerificationAndPrepareDecryptor(): MultipartAuthenticatedDecryption { + primitive.checkTag(tag) + return MultipartAuthenticatedDecryptor(primitive) + } + +} + +class MultipartAuthenticatedDecryptor internal constructor(val encryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption { + override fun decryptPartialData(data: EncryptedDataPart): DecryptedDataPart { + return DecryptedDataPart(encryptor.decrypt(data.data)) + } + +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt deleted file mode 100644 index 0c1745c..0000000 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt +++ /dev/null @@ -1,185 +0,0 @@ -package com.ionspin.kotlin.crypto - -import com.ionspin.kotlin.crypto.authenticated.* -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure -import com.ionspin.kotlin.crypto.hash.encodeToUByteArray -import com.ionspin.kotlin.crypto.hash.sha.Sha256Pure -import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure -import com.ionspin.kotlin.crypto.util.toHexString - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 24-May-2020 - */ -typealias Blake2bPureStateless = Blake2bPure.Companion -typealias Sha256PureStateless = Sha256Pure.Companion -typealias Sha512PureStateless = Sha512Pure.Companion - -object Primitives : CryptoProvider { - override suspend fun initialize() { - //Nothing to do atm. - } - - fun initializeWithCallback(done: () -> Unit) { - done() - } - - object Blake2b { - fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b { - checkInitialization() - return Blake2bPure(key, hashLength) - } - - fun stateless(message: UByteArray, key: UByteArray = ubyteArrayOf(), hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): UByteArray { - checkInitialization() - return Blake2bPureStateless.digest(message, key, hashLength) - } - } - - object Sha256 { - fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha256 { - checkInitialization() - return Sha256Pure() - } - - fun stateless(message: UByteArray) : UByteArray{ - checkInitialization() - return Sha256PureStateless.digest(inputMessage = message) - } - } - - object Sha512 { - fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha512 { - checkInitialization() - return Sha512Pure() - } - - fun stateless(message: UByteArray) : UByteArray { - checkInitialization() - return Sha512PureStateless.digest(inputMessage = message) - } - } - - - private fun checkInitialization() { - // Nothing to do atm - } - -} - -inline class EncryptableString(val content: String) : Encryptable { - override fun toEncryptableForm(): UByteArray { - return content.encodeToUByteArray() - } - - override fun fromEncryptableForm(): (UByteArray) -> EncryptableString { - return { uByteArray -> - EncryptableString(uByteArray.toByteArray().decodeToString()) - } - } - - fun asString() : String = content - - -} - -fun String.asEncryptableString() : EncryptableString { - return EncryptableString(this) -} - -interface Encryptable { - fun toEncryptableForm() : UByteArray - fun fromEncryptableForm() : (UByteArray) -> T -} - -data class HashedData(val hash: UByteArray) { - fun toHexString() : String { - return hash.toHexString() - } -} - -data class SymmetricKey(val value : UByteArray) { - companion object { - fun randomKey() : SymmetricKey { - return SymmetricKey(SRNG.getRandomBytes(32)) - } - } -} - -data class EncryptedData internal constructor(val ciphertext: UByteArray, val nonce: UByteArray) { - -} - -object PublicApi { - - object Hashing { - fun hash(data: UByteArray, key : UByteArray = ubyteArrayOf()) : HashedData { - return HashedData(Blake2bPureStateless.digest(data, key)) - } - - fun multipartHash(key: UByteArray? = null) : com.ionspin.kotlin.crypto.hash.MultiPartHash { - return Blake2bPure(key) - } - } - object Encryption { - fun authenticatedEncryption(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray = ubyteArrayOf()) : EncryptedData { - if (key.value.size != 32) { - throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}") - } - val nonce = SRNG.getRandomBytes(24) - return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce) - - } - - fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { - return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData)) - - } - - fun multipartAuthenticatedEncrypt(key: SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption { - return MultipartAuthenticatedEncryptor(key, additionalData) - } - - fun getMultipartVerificator(key: SymmetricKey, dataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification { - return MultiplatformAuthenticatedVerificator(key, dataDescriptor, additionalData) - } - } -} - -class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey, additionalData: UByteArray) : MultipartAuthenticatedEncryption { - val primitive = XChaCha20Poly1305Pure(key.value, additionalData) - override fun encryptPartialData(data: UByteArray): EncryptedDataPart { - return EncryptedDataPart(primitive.encryptPartialData(data)) - } - - override fun finish(): MultipartEncryptedDataDescriptor { - val finished = primitive.finish() - return MultipartEncryptedDataDescriptor(finished.first, finished.second) - } - -} - -class MultiplatformAuthenticatedVerificator internal constructor(key: SymmetricKey, multipartEncryptedDataDescriptor: MultipartEncryptedDataDescriptor, additionalData: UByteArray) : MultipartAuthenticatedVerification { - val primitive = XChaCha20Poly1305Pure(key.value, additionalData) - val tag = multipartEncryptedDataDescriptor.data.sliceArray( - multipartEncryptedDataDescriptor.data.size - 16 until multipartEncryptedDataDescriptor.data.size - ) - override fun verifyPartialData(data: EncryptedDataPart) { - primitive.encryptPartialData(data.data) - } - - override fun finalizeVerificationAndPrepareDecryptor(): MultipartAuthenticatedDecryption { - primitive.finalizeVerificationAndPrepareDecryptor(tag) - return MultipartAuthenticatedDecryptor(primitive) - } - -} - -class MultipartAuthenticatedDecryptor internal constructor(val encryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption { - override fun decryptPartialData(data: EncryptedDataPart): DecryptedDataPart { - encryptor.decrypt(data.data) - } - -} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt index a7b3708..8184fdc 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt @@ -1,5 +1,7 @@ package com.ionspin.kotlin.crypto.authenticated +import com.ionspin.kotlin.crypto.InvalidTagException +import com.ionspin.kotlin.crypto.MultipartAuthenticatedDecryption import com.ionspin.kotlin.crypto.SRNG import com.ionspin.kotlin.crypto.mac.Poly1305 import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure @@ -58,7 +60,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray) cipherTextWithoutTag.size.toULong().toLittleEndianUByteArray() val calculatedTag = Poly1305.poly1305Authenticate(authKey, macData) if (!calculatedTag.contentEquals(tag)) { - RuntimeException("Bad tag!") //TODO replace with specific exception + throw InvalidTagException() } //4. Decrypt data return XChaCha20Pure.xorWithKeystream(key, nonce, cipherTextWithoutTag, 1U) @@ -106,7 +108,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray) processPolyBytes(data) } - fun finalizeVerificationAndPrepareDecryptor(expectedTag: UByteArray): MultipartAuthenticatedDecryption { + fun checkTag(expectedTag: UByteArray) { val cipherTextPad = UByteArray(16 - processedBytes % 16) { 0U } val macData = cipherTextPad + additionalData.size.toULong().toLittleEndianUByteArray() + @@ -114,7 +116,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val additionalData: UByteArray) processPolyBytes(macData) val tag = updateableMacPrimitive.finalizeMac() if (!tag.contentEquals(expectedTag)) { - throw RuntimeException("Invalid tag") //TODO Replace with proper exception + throw InvalidTagException() } } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt index a3c5bef..313750c 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt @@ -28,9 +28,9 @@ import com.ionspin.kotlin.crypto.util.rotateRight */ -class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake2b { +class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake2bMultipart { - companion object : Blake2bStateless { + companion object : Blake2b { //Hack start //If this line is not included konanc 1.4-M1 fails to link because it cant find ByteArray which is //a backing class for UByteArray diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt index 7fe3eee..0617869 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt @@ -29,7 +29,7 @@ class Sha512Pure : Sha512 { override val MAX_HASH_BYTES: Int = 32 - companion object : StatelessSha512 { + companion object : MultipartSha512 { const val BLOCK_SIZE = 1024 const val BLOCK_SIZE_IN_BYTES = 128 const val CHUNK_SIZE = 80 @@ -385,4 +385,4 @@ class Sha512Pure : Sha512 { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt index c7ccc50..260aef4 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt @@ -21,6 +21,7 @@ package com.ionspin.kotlin.crypto.keyderivation.argon2 import com.ionspin.kotlin.bignum.integer.toBigInteger import com.ionspin.kotlin.crypto.Blake2bPureStateless import com.ionspin.kotlin.crypto.SRNG +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.argonBlake2bArbitraryLenghtHash import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.compressionFunctionG import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.validateArgonParameters @@ -42,14 +43,7 @@ data class SegmentPosition( val slice: Int ) -data class ArgonResult( - val hashBytes: UByteArray, - val salt: UByteArray -) { - val hashString by lazy { hashBytes.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } - val saltString by lazy { salt.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } -} diff --git a/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt b/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt index effa995..ad3577d 100644 --- a/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt +++ b/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt @@ -1,12 +1,8 @@ package com.ionspin.kotlin.crypto.sample import com.ionspin.kotlin.crypto.Crypto -import com.ionspin.kotlin.crypto.CryptoProvider -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.toHexString -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch object Sample { fun runSample() { @@ -27,4 +23,4 @@ object Sample { val statelessResult = Crypto.Blake2b.stateless("test".encodeToByteArray().toUByteArray()) println("Blake2b stateless: ${statelessResult.toHexString()}") } -} \ No newline at end of file +}