From 5c97e857fc07eea5ab927497fa279d0059c98946 Mon Sep 17 00:00:00 2001 From: sergeych Date: Mon, 24 Jun 2024 15:01:42 +0700 Subject: [PATCH] PBKD semi ready, before key refactoring --- .../kotlin/net/sergeych/crypto2/PBKD.kt | 56 ++++++++++++------- .../kotlin/net/sergeych/crypto2/kdf.kt | 6 +- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt b/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt index c544a80..e14bad9 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/PBKD.kt @@ -2,7 +2,6 @@ package net.sergeych.crypto2 import com.ionspin.kotlin.crypto.util.encodeToUByteArray import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient import net.sergeych.bipack.BipackEncoder import net.sergeych.bipack.Unsigned import net.sergeych.synctools.ProtectedOp @@ -10,17 +9,31 @@ import net.sergeych.synctools.invoke object PBKD { + /** + * Parameters to generate a reasonably secure data bytes with [deriveUBytes] or a [SymmetricKey] + * with [deriveKey] + */ @Serializable class Params( val kdf: KDF, @Unsigned val startOffset: Int, - @Transient - private var precalculatedKey: SymmetricKey?=null + @Unsigned + val length: Int, ) { /** - * Derive a key from the password in the idempotent manner. + * Derive UByteArray from the password in the idempotent way. + * Could be used to construct keys, IVs, tokens, whatever. + * Most often [deriveKey] is used instead which derives the key. + */ + fun deriveUBytes(password: String): UByteArray { + val bytes = generate(kdf, password) + return bytes.sliceArray(startOffset.. { - TODO() + fun deriveMultipleKeys(password: String,keysCount: Int, + complexity: KDF.Complexity = KDF.Complexity.Moderate, + salt: UByteArray = KDF.Argon.randomSalt() + ): List { + require(keysCount > 0) { "keysCount must be positive" } + val keyLength = SymmetricKey.keyLength + val totalSize = keysCount * keyLength + val kdf = KDF.Argon.create(complexity, salt, totalSize) + return (0 ..< keysCount).map { Params(kdf, it*keyLength, keyLength).deriveKey(password) } } private val op = ProtectedOp() diff --git a/src/commonMain/kotlin/net/sergeych/crypto2/kdf.kt b/src/commonMain/kotlin/net/sergeych/crypto2/kdf.kt index a8b8d1d..1149979 100644 --- a/src/commonMain/kotlin/net/sergeych/crypto2/kdf.kt +++ b/src/commonMain/kotlin/net/sergeych/crypto2/kdf.kt @@ -55,10 +55,8 @@ sealed class KDF { } } - override fun derive(password: String): UByteArray { - TODO() - //PasswordHash.pwhash(keySize, ) - } + override fun derive(password: String): UByteArray = + PasswordHash.pwhash(keySize, password, salt, instructionsComplexity, memComplexity, algorithm.code) override fun equals(other: Any?): Boolean { if (this === other) return true