137 lines
4.7 KiB
Kotlin
137 lines
4.7 KiB
Kotlin
/*
|
|
* Copyright (c) 2025. Sergey S. Chernov - All Rights Reserved
|
|
*
|
|
* You may use, distribute and modify this code under the
|
|
* terms of the private license, which you must obtain from the author
|
|
*
|
|
* To obtain the license, contact the author: https://t.me/real_sergeych or email to
|
|
* real dot sergeych at gmail.
|
|
*/
|
|
|
|
import kotlinx.coroutines.test.runTest
|
|
import net.sergeych.crypto2.Hash
|
|
import net.sergeych.crypto2.KDF
|
|
import net.sergeych.crypto2.initCrypto
|
|
import kotlin.test.Test
|
|
import kotlin.test.assertContentEquals
|
|
import kotlin.test.assertEquals
|
|
import kotlin.test.assertFalse
|
|
import kotlin.test.assertIs
|
|
|
|
class KDFTest {
|
|
@Test
|
|
fun testCacheKey() = runTest{
|
|
initCrypto()
|
|
val k1 = KDF.Argon.create(KDF.Complexity.Interactive, KDF.Argon.randomSalt(), 128)
|
|
val k2 = KDF.Argon.create(KDF.Complexity.Interactive, k1.salt, 128)
|
|
|
|
assertEquals(k1, k2)
|
|
assertEquals(k1.hashCode(), k2.hashCode())
|
|
|
|
val key1 = KDF.Instance(k1, "foo")
|
|
val key2 = KDF.Instance(k2, "foo")
|
|
val key3 = KDF.Instance(k2, "bar")
|
|
|
|
assertEquals(key1, key2)
|
|
assertEquals(key1.hashCode(), key2.hashCode())
|
|
assertFalse { key3 == key2 }
|
|
assertFalse { key3.hashCode() == key2.hashCode() }
|
|
|
|
val m = mutableMapOf<KDF.Instance, String>()
|
|
m[key1] = "foo"
|
|
m[key2] = "bar"
|
|
m[key3] = "foobar"
|
|
|
|
assertEquals("bar", m[key1])
|
|
assertEquals("bar", m[key2])
|
|
assertEquals("foobar", m[key3])
|
|
|
|
val set1 = setOf(key1, key2, key3)
|
|
val set2 = setOf(key3, key2, key1)
|
|
assertEquals(set2, set1)
|
|
}
|
|
|
|
@Test
|
|
fun complexityTest() = runTest{
|
|
initCrypto()
|
|
val kk = KDF.Complexity.Interactive.kdfForSize(3).deriveMultipleKeys("lala", 3)
|
|
assertEquals(3, kk.size)
|
|
}
|
|
|
|
@Test
|
|
fun complexityKdfForSizeInBytesTest() = runTest {
|
|
initCrypto()
|
|
val size = KDF.Argon.minKeySize + 17
|
|
val expectedSalt = UByteArray(KDF.Argon.saltSize) { (it + 3).toUByte() }
|
|
|
|
val kdf = KDF.Complexity.FixedLow.kdfForSizeInBytes(size, expectedSalt)
|
|
assertIs<KDF.Argon>(kdf)
|
|
|
|
assertEquals(KDF.Argon.create(KDF.Complexity.FixedLow, expectedSalt, size), kdf)
|
|
assertEquals(size, kdf.keySize)
|
|
assertContentEquals(expectedSalt, kdf.salt)
|
|
}
|
|
|
|
@Test
|
|
fun createDefaultNormalizesSaltTest() = runTest {
|
|
initCrypto()
|
|
val size = KDF.Argon.minKeySize + 19
|
|
val shortSalt = ubyteArrayOf(1u, 2u, 3u, 4u, 5u)
|
|
val longSalt = UByteArray(KDF.Argon.saltSize + 7) { (it * 5).toUByte() }
|
|
val expectedShortSalt = Hash.Blake2b.deriveSaltFormBytes(shortSalt, KDF.Argon.saltSize)
|
|
val expectedLongSalt = Hash.Blake2b.deriveSaltFormBytes(longSalt, KDF.Argon.saltSize)
|
|
|
|
val shortKdf = KDF.createDefault(size, KDF.Complexity.FixedLow, shortSalt)
|
|
val longKdf = KDF.Complexity.FixedLow.kdfForSizeInBytes(size, longSalt)
|
|
|
|
assertIs<KDF.Argon>(shortKdf)
|
|
assertIs<KDF.Argon>(longKdf)
|
|
assertEquals(KDF.Argon.saltSize, shortKdf.salt.size)
|
|
assertEquals(KDF.Argon.saltSize, longKdf.salt.size)
|
|
assertContentEquals(expectedShortSalt, shortKdf.salt)
|
|
assertContentEquals(expectedLongSalt, longKdf.salt)
|
|
}
|
|
|
|
@Test
|
|
fun deriveFromBytesTest() = runTest {
|
|
initCrypto()
|
|
val salt = UByteArray(KDF.Argon.saltSize) { it.toUByte() }
|
|
val kdf = KDF.Argon.create(KDF.Complexity.Interactive, salt, 80)
|
|
val source = UByteArray(47) { (it * 3).toUByte() }
|
|
|
|
val b1 = kdf.deriveFromBytes(source)
|
|
val b2 = kdf.deriveFromBytes(source)
|
|
val b3 = kdf.deriveFromBytes(source + 1u)
|
|
|
|
assertEquals(80, b1.size)
|
|
assertContentEquals(b1, b2)
|
|
assertFalse { b1 contentEquals b3 }
|
|
}
|
|
|
|
@Test
|
|
fun complexityDeriveFromBytesTest() = runTest {
|
|
initCrypto()
|
|
val salt = UByteArray(KDF.Argon.saltSize) { (it + 1).toUByte() }
|
|
val source = UByteArray(23) { (it + 7).toUByte() }
|
|
|
|
val b1 = KDF.Complexity.Interactive.derive(source, salt, 64)
|
|
val b2 = KDF.Argon.create(KDF.Complexity.Interactive, salt, 64).deriveFromBytes(source)
|
|
|
|
assertContentEquals(b1, b2)
|
|
assertEquals(64, b1.size)
|
|
}
|
|
|
|
@Test
|
|
fun deriveFromBytesUsesKeySizeTest() = runTest {
|
|
initCrypto()
|
|
val salt = UByteArray(KDF.Argon.saltSize) { it.toUByte() }
|
|
val source = ubyteArrayOf(1u, 2u, 3u)
|
|
val shortKdf = KDF.Argon.create(KDF.Complexity.Interactive, salt, 64)
|
|
val longKdf = KDF.Argon.create(KDF.Complexity.Interactive, salt, 96)
|
|
|
|
assertEquals(64, shortKdf.deriveFromBytes(source).size)
|
|
assertEquals(96, longKdf.deriveFromBytes(source).size)
|
|
}
|
|
|
|
}
|