Added kdfForSizeInBytes method to KDF with tests and a new factory method to UniversalRing.

This commit is contained in:
Sergey Chernov 2026-05-30 12:07:22 +03:00
parent d6b171229f
commit a77fdd79c1
4 changed files with 28 additions and 1 deletions

1
.idea/misc.xml generated
View File

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

View File

@ -229,6 +229,8 @@ class UniversalRing(
companion object { companion object {
val EMPTY = UniversalRing(keyWithTags = emptyMap()) val EMPTY = UniversalRing(keyWithTags = emptyMap())
fun new(): UniversalRing = UniversalRing(keyWithTags = emptyMap())
/** /**
* Join a collection of keyrings together (same as reducing with `+`). Correctly * Join a collection of keyrings together (same as reducing with `+`). Correctly
* works if there is no keyring (returns [EMPTY]), or only one keyring (returns * works if there is no keyring (returns [EMPTY]), or only one keyring (returns

View File

@ -47,6 +47,12 @@ sealed class KDF {
fun kdfForSize(numberOfKeys: Int,salt: UByteArray = Argon.randomSalt()): KDF = fun kdfForSize(numberOfKeys: Int,salt: UByteArray = Argon.randomSalt()): KDF =
creteDefault(SymmetricKey.keyLength * numberOfKeys, this, salt) creteDefault(SymmetricKey.keyLength * numberOfKeys, this, salt)
fun kdfForSizeInBytes(sizeInBytes: Int, complexity: Complexity, domain: String): KDF {
val salt = Hash.Blake2b.deriveSalt(domain, Argon.saltSize)
return creteDefault(sizeInBytes, complexity, salt)
}
/** /**
* Derive multiple keys from the password. Derivation params will be included in the key ids, see * Derive multiple keys from the password. Derivation params will be included in the key ids, see
* [SymmetricKey.id] as [KeyId.kdp]. * [SymmetricKey.id] as [KeyId.kdp].

View File

@ -9,6 +9,7 @@
*/ */
import kotlinx.coroutines.test.runTest import kotlinx.coroutines.test.runTest
import net.sergeych.crypto2.Hash
import net.sergeych.crypto2.KDF import net.sergeych.crypto2.KDF
import net.sergeych.crypto2.initCrypto import net.sergeych.crypto2.initCrypto
import kotlin.test.Test import kotlin.test.Test
@ -16,6 +17,7 @@ import kotlin.test.assertContentEquals
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertFailsWith import kotlin.test.assertFailsWith
import kotlin.test.assertIs
class KDFTest { class KDFTest {
@Test @Test
@ -57,6 +59,24 @@ class KDFTest {
assertEquals(3, kk.size) assertEquals(3, kk.size)
} }
@Test
fun complexityKdfForSizeInBytesTest() = runTest {
initCrypto()
val size = KDF.Argon.minKeySize + 17
val domain = "kdf-size-in-bytes-test"
val expectedSalt = Hash.Blake2b.deriveSalt(domain, KDF.Argon.saltSize)
val kdf = KDF.Complexity.Sensitive.kdfForSizeInBytes(size, KDF.Complexity.FixedLow, domain)
assertIs<KDF.Argon>(kdf)
assertEquals(KDF.Argon.create(KDF.Complexity.FixedLow, expectedSalt, size), kdf)
assertEquals(size, kdf.keySize)
assertContentEquals(expectedSalt, kdf.salt)
assertFalse {
kdf.salt contentEquals Hash.Blake2b.deriveSalt("$domain-other", KDF.Argon.saltSize)
}
}
@Test @Test
fun deriveFromBytesTest() = runTest { fun deriveFromBytesTest() = runTest {
initCrypto() initCrypto()