From decc1ab91ff4f033cbf0754dd176593d39892c4d Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Wed, 8 Jan 2020 21:13:41 +0100 Subject: [PATCH] Started work on argon2 implementation --- buildSrc/src/main/kotlin/Deps.kt | 2 +- .../kotlin/com/ionspin/kotlin/crypto/Util.kt | 19 +++++ .../kotlin/crypto/keyderivation/Argon2.kt | 74 +++++++++++++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Argon2.kt diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index 432d57a..a1d1631 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -21,7 +21,7 @@ object Versions { val nodePlugin = "1.3.0" val dokkaPlugin = "0.9.18" - val kotlinBigNumVersion = "0.1.5-SNAPSHOT" + val kotlinBigNumVersion = "0.1.6-SNAPSHOT" } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Util.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Util.kt index 1b222ce..81c47b8 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Util.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Util.kt @@ -87,4 +87,23 @@ fun Array.toHexString() : String { it.toString(16) } } +} + +// UInt / Array utils +@ExperimentalUnsignedTypes +fun UInt.toBigEndianUByteArray() : Array { + return Array (4) { + ((this shr (24 - (it * 8))) and 0xFFU).toUByte() + } +} +@ExperimentalUnsignedTypes +fun UInt.toLittleEndianUByteArray() : Array { + return Array (4) { + ((this shr (it * 8)) and 0xFFU).toUByte() + } +} + +@ExperimentalUnsignedTypes +operator fun UInt.plus(other : Array) : Array { + return this.toLittleEndianUByteArray() + other } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Argon2.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Argon2.kt new file mode 100644 index 0000000..9cacd68 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Argon2.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2019 Ugljesa Jovanovic + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.ionspin.kotlin.crypto.keyderivation + +import com.ionspin.kotlin.crypto.chunked +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b +import com.ionspin.kotlin.crypto.plus + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 08-Jan-2020 + */ +@ExperimentalUnsignedTypes +class Argon2 internal constructor( + val password : Array, + val salt : Array, + val parallelism : UInt, + val tagLength : UInt, + val memorySize : UInt, + val numberOfIterations : UInt, + val versionNumber : UInt, + val key : Array, + val type : ArgonType +){ + enum class ArgonType { + Argon2i, Argon2d, Argon2id + } + companion object { + + + fun hash(input : Array, length : UInt) : Array { + if (length <= 64U) { + return Blake2b.digest(length + input) + } + //We can cast to int because UInt even if MAX_VALUE divided by 32 is guaranteed not to overflow + val numberOfBlocks = (1U + ((length - 1U) / 32U) - 1U).toInt() // equivalent to ceil(length/32) - 1 + val v = Array>(numberOfBlocks) { emptyArray() } + v[0] = Blake2b.digest(length + input) + for (i in 1 until numberOfBlocks - 1) { + v[i] = Blake2b.digest(v[i-1]) + } + val remainingPartOfInput = input.copyOfRange(input.size - numberOfBlocks * 32, input.size) + v[numberOfBlocks] = Blake2b.digest(remainingPartOfInput, hashLength = remainingPartOfInput.size) + v.chunked(8) + + + + return emptyArray() + } + + } + + + + + + + +} \ No newline at end of file