forked from sergeych/crypto2
more sugar to be like unicrypto by functions
This commit is contained in:
parent
a6c7dafb70
commit
78383fbece
@ -5,7 +5,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "0.4.1-SNAPSHOT"
|
version = "0.4.2-SNAPSHOT"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -436,6 +436,17 @@ sealed class Container {
|
|||||||
fun create(plainData: UByteArray, builder: Builder.() -> Unit) =
|
fun create(plainData: UByteArray, builder: Builder.() -> Unit) =
|
||||||
Builder(plainData).also { it.builder() }.build()
|
Builder(plainData).also { it.builder() }.build()
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
inline fun <reified T>encrypt(plainData: T, vararg keys: EncryptingKey): UByteArray =
|
||||||
|
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())}
|
||||||
|
|
||||||
|
fun decryptAsUBytes(cipherData: UByteArray, vararg keys: DecryptingKey): UByteArray? =
|
||||||
|
decode(cipherData).decryptWith(*keys)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create container using one or more [EncryptingKey] and a builder, see [create]
|
* Create container using one or more [EncryptingKey] and a builder, see [create]
|
||||||
* for builder usage sample.
|
* for builder usage sample.
|
||||||
|
@ -14,7 +14,7 @@ object PBKD {
|
|||||||
* with [deriveKey]
|
* with [deriveKey]
|
||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
class Params(
|
data class Params(
|
||||||
val kdf: KDF,
|
val kdf: KDF,
|
||||||
@Unsigned
|
@Unsigned
|
||||||
val startOffset: Int,
|
val startOffset: Int,
|
||||||
@ -76,7 +76,9 @@ object PBKD {
|
|||||||
require(keysCount > 0) { "keysCount must be positive" }
|
require(keysCount > 0) { "keysCount must be positive" }
|
||||||
val keyLength = SymmetricKey.keyLength
|
val keyLength = SymmetricKey.keyLength
|
||||||
val totalSize = keysCount * keyLength
|
val totalSize = keysCount * keyLength
|
||||||
val kdf = KDF.Argon.create(complexity, salt, totalSize)
|
check(salt.size >= KDF.Argon.saltSize)
|
||||||
|
val salt2 = if( salt.size > KDF.Argon.saltSize) salt.sliceArray( 0 ..< KDF.Argon.saltSize) else salt
|
||||||
|
val kdf = KDF.Argon.create(complexity, salt2, totalSize)
|
||||||
return (0 ..< keysCount).map { Params(kdf, it*keyLength, keyLength).deriveKey(password) }
|
return (0 ..< keysCount).map { Params(kdf, it*keyLength, keyLength).deriveKey(password) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package net.sergeych.crypto2
|
|||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
import net.sergeych.bipack.BipackEncoder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multi-signed data box. Do not use the constructori directly, use [SealedBox.create]
|
* Multi-signed data box. Do not use the constructori directly, use [SealedBox.create]
|
||||||
@ -65,6 +66,7 @@ class SealedBox(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val encoded: UByteArray by lazy { BipackEncoder.encode(this).toUByteArray() }
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
@ -80,5 +82,9 @@ class SealedBox(
|
|||||||
fun create(data: UByteArray, vararg keys: SigningSecretKey): SealedBox {
|
fun create(data: UByteArray, vararg keys: SigningSecretKey): SealedBox {
|
||||||
return SealedBox(data, keys.map { it.seal(data) }, false)
|
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
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import com.ionspin.kotlin.crypto.pwhash.*
|
|||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import net.sergeych.bipack.Unsigned
|
import net.sergeych.bipack.Unsigned
|
||||||
|
import net.sergeych.crypto2.PBKD.Params
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
sealed class KDF {
|
sealed class KDF {
|
||||||
@ -16,6 +17,16 @@ sealed class KDF {
|
|||||||
|
|
||||||
abstract fun derive(password: String): UByteArray
|
abstract fun derive(password: String): UByteArray
|
||||||
|
|
||||||
|
fun deriveMultiple(password: String,count: Int) : List<SymmetricKey> {
|
||||||
|
val bytes = derive(password)
|
||||||
|
val ks = SymmetricKey.keyLength
|
||||||
|
check( ks * count <= bytes.size ) { "KDF is too short for $count keys: ${bytes.size} we need ${ks*count}"}
|
||||||
|
return (0 ..< count).map {
|
||||||
|
val base = it*ks
|
||||||
|
Params(this, base, ks).deriveKey(password)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("argon")
|
@SerialName("argon")
|
||||||
data class Argon(
|
data class Argon(
|
||||||
@ -114,6 +125,13 @@ sealed class KDF {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@Suppress("unused")
|
||||||
|
fun creteDefault(keySize: Int, complexity: Complexity, salt: UByteArray = Argon.randomSalt()): KDF {
|
||||||
|
return Argon.create(complexity,salt,keySize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data class Instance(val kdf: KDF,val password: String)
|
data class Instance(val kdf: KDF,val password: String)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import net.sergeych.crypto2.PBKD
|
|||||||
import net.sergeych.crypto2.initCrypto
|
import net.sergeych.crypto2.initCrypto
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
class PBKDTest {
|
class PBKDTest {
|
||||||
|
|
||||||
@ -32,5 +33,17 @@ class PBKDTest {
|
|||||||
assertEquals(i.kdp, kx.id.kdp)
|
assertEquals(i.kdp, kx.id.kdp)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
val (y1,y2,y3) = k1.id.kdp!!.kdf.deriveMultiple("foobar", 3)
|
||||||
|
for( (a,b) in listOf(y1,y2,y3).zip(listOf(k1,k2,k3))) {
|
||||||
|
assertEquals(a,b)
|
||||||
|
assertNotNull(a.id.kdp)
|
||||||
|
assertNotNull(b.id.kdp)
|
||||||
|
assertEquals(a.id.kdp, b.id.kdp)
|
||||||
|
assertEquals(a.id, b.id)
|
||||||
|
}
|
||||||
|
assertEquals(k1, y1)
|
||||||
|
assertEquals(k2, y2)
|
||||||
|
assertEquals(k3, y3)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user