Continuing Argon 2 work
This commit is contained in:
parent
803288cbc4
commit
1e0a5b516e
@ -312,6 +312,9 @@ kotlin {
|
|||||||
val linuxArm64Test by getting {
|
val linuxArm64Test by getting {
|
||||||
dependsOn(nativeTest)
|
dependsOn(nativeTest)
|
||||||
}
|
}
|
||||||
|
all {
|
||||||
|
languageSettings.enableLanguageFeature("InlineClasses")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,12 +13,10 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.ionspin.kotlin.crypto.keyderivation
|
package com.ionspin.kotlin.crypto.keyderivation
|
||||||
|
|
||||||
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b
|
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b
|
||||||
import com.ionspin.kotlin.crypto.util.*
|
import com.ionspin.kotlin.crypto.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Further resources and examples of implementation:
|
* Further resources and examples of implementation:
|
||||||
@ -63,9 +61,17 @@ class Argon2 internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ExperimentalStdlibApi
|
@ExperimentalStdlibApi
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
fun Array<UByte>.xor(target : Array<UByte>, other : Array<UByte>) {
|
||||||
|
if (this.size != other.size || this.size != target.size) {
|
||||||
|
throw RuntimeException("Invalid array sizes, this ${this.size}, other ${other.size}")
|
||||||
|
}
|
||||||
|
target.mapIndexed { index, _ -> this[index] xor other[index]}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun argonBlake2bArbitraryLenghtHash(input: Array<UByte>, length: UInt): Array<UByte> {
|
fun argonBlake2bArbitraryLenghtHash(input: Array<UByte>, length: UInt): Array<UByte> {
|
||||||
if (length <= 64U) {
|
if (length <= 64U) {
|
||||||
@ -88,9 +94,11 @@ class Argon2 internal constructor(
|
|||||||
return concat
|
return concat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun compressionFunctionG(x: Array<UByte>, y: Array<UByte>): Array<UByte> {
|
fun compressionFunctionG(x: Array<UByte>, y: Array<UByte>): Array<UByte> {
|
||||||
val r = Array<UByte>(1024) { 0U } // view as 8x8 matrix of 16 byte registers
|
val r = x xor y
|
||||||
x.forEachIndexed { index, it -> r[index] = it xor y[index] }
|
// val r = Array<UByte>(1024) { 0U } // view as 8x8 matrix of 16 byte registers
|
||||||
|
// x.forEachIndexed { index, it -> r[index] = it xor y[index] } // R = X xor Y
|
||||||
val q = Array<UByte>(1024) { 0U }
|
val q = Array<UByte>(1024) { 0U }
|
||||||
val z = Array<UByte>(1024) { 0U }
|
val z = Array<UByte>(1024) { 0U }
|
||||||
// Do the argon/blake2b mixing on rows
|
// Do the argon/blake2b mixing on rows
|
||||||
@ -115,7 +123,7 @@ class Argon2 internal constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Z = Z xor R
|
// Z = Z xor R
|
||||||
r.forEachIndexed { index, it -> z[index] = it xor z[index] }
|
z.xor(z, r)
|
||||||
return z
|
return z
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,19 +176,23 @@ class Argon2 internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun computeIndexes(
|
private fun computeIndexes(
|
||||||
block: Array<Array<Array<UByte>>>,
|
indexContext: IndexContext,
|
||||||
pass: Long,
|
matrix : Array<Array<Array<UByte>>>
|
||||||
lane: Int,
|
|
||||||
column: Int,
|
|
||||||
blockCount: UInt,
|
|
||||||
iterationCount: UInt,
|
|
||||||
type: ArgonType,
|
|
||||||
laneCounter : Int
|
|
||||||
|
|
||||||
): Pair<Int, Int> {
|
): Pair<Int, Int> {
|
||||||
|
val block = indexContext.indexMatrix
|
||||||
|
val parallelism = indexContext.parallelism
|
||||||
|
val pass = indexContext.pass
|
||||||
|
val lane = indexContext.lane
|
||||||
|
val column = indexContext.column
|
||||||
|
val blockCount = indexContext.blockCount
|
||||||
|
val iterationCount = indexContext.iterationCount
|
||||||
|
val type = indexContext.type
|
||||||
|
val laneCounter = indexContext.laneCounter
|
||||||
|
|
||||||
var counter = laneCounter
|
var counter = laneCounter
|
||||||
val sliceNumber = column / 4
|
val sliceNumber = column / 4
|
||||||
val sliceLength = blockCount / 4U
|
val sliceLength = blockCount / 4U
|
||||||
|
|
||||||
val (j1, j2) = when (type) {
|
val (j1, j2) = when (type) {
|
||||||
ArgonType.Argon2i -> {
|
ArgonType.Argon2i -> {
|
||||||
val firstPass = compressionFunctionG(
|
val firstPass = compressionFunctionG(
|
||||||
@ -205,36 +217,43 @@ class Argon2 internal constructor(
|
|||||||
counter.toUInt().toLittleEndianUByteArray() +
|
counter.toUInt().toLittleEndianUByteArray() +
|
||||||
Array<UByte>(968) { 0U }
|
Array<UByte>(968) { 0U }
|
||||||
)
|
)
|
||||||
Pair(firstPass, secondPass)
|
Pair(1U, 1U)
|
||||||
}
|
}
|
||||||
ArgonType.Argon2d -> {
|
ArgonType.Argon2d -> {
|
||||||
Pair(
|
Pair(
|
||||||
(block[laneCounter][column - 1].sliceArray(0..3).fromLittleEndianArrayToUInt()),
|
(matrix[laneCounter][column - 1].sliceArray(0..3).fromLittleEndianArrayToUInt()),
|
||||||
(block[laneCounter][column - 1].sliceArray(4..7).fromLittleEndianArrayToUInt())
|
(matrix[laneCounter][column - 1].sliceArray(4..7).fromLittleEndianArrayToUInt())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ArgonType.Argon2id -> {
|
ArgonType.Argon2id -> {
|
||||||
Pair(emptyArray<UByte>(), emptyArray<UByte>())
|
Pair(1U, 1U)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val l = if (pass == 0L && sliceNumber == 0) {
|
||||||
|
2U
|
||||||
|
} else {
|
||||||
|
j2 % parallelism
|
||||||
|
}
|
||||||
|
|
||||||
|
// val availableIndices = if ()
|
||||||
|
|
||||||
|
|
||||||
return Pair(1, 1)
|
return Pair(1, 1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun populateSegment(
|
data class IndexContext(
|
||||||
matrix: Array<Array<Array<UByte>>>,
|
val indexMatrix: Array<UByte>,
|
||||||
pass: Long,
|
val parallelism: UInt,
|
||||||
lane: Int,
|
val pass: Long,
|
||||||
column: Int,
|
val lane: Int,
|
||||||
blockCount: UInt,
|
val column: Int,
|
||||||
iterationCount: UInt,
|
val blockCount: UInt,
|
||||||
type: ArgonType,
|
val iterationCount: UInt,
|
||||||
laneCounter : Int
|
val type: ArgonType,
|
||||||
) {
|
val laneCounter: Int
|
||||||
//TODO handle segment by segment
|
)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal fun derive(
|
internal fun derive(
|
||||||
password: Array<UByte>,
|
password: Array<UByte>,
|
||||||
@ -257,11 +276,11 @@ class Argon2 internal constructor(
|
|||||||
associatedData.size.toUInt().toLittleEndianUByteArray() + associatedData
|
associatedData.size.toUInt().toLittleEndianUByteArray() + associatedData
|
||||||
)
|
)
|
||||||
|
|
||||||
val blockCount = (memorySize / (4U * parallelism)) * (4U * parallelism) //
|
val blockCount = (memorySize / (4U * parallelism)) * (4U * parallelism) // TODO hmmm
|
||||||
val columnCount = blockCount / parallelism
|
val columnCount = blockCount / parallelism
|
||||||
|
|
||||||
//TODO pass handling
|
//TODO pass handling
|
||||||
val allPasses = (0 .. numberOfIterations.toLong()).map { pass ->
|
val allPasses = (0..numberOfIterations.toLong()).map { pass ->
|
||||||
//Allocate memory as Array of parallelism rows and columnCount colums
|
//Allocate memory as Array of parallelism rows and columnCount colums
|
||||||
val matrix = Array(parallelism.toInt()) {
|
val matrix = Array(parallelism.toInt()) {
|
||||||
Array(columnCount.toInt()) {
|
Array(columnCount.toInt()) {
|
||||||
@ -291,7 +310,7 @@ class Argon2 internal constructor(
|
|||||||
for (j in 1..columnCount.toInt()) {
|
for (j in 1..columnCount.toInt()) {
|
||||||
|
|
||||||
val counter = 0 //TODO handle counter
|
val counter = 0 //TODO handle counter
|
||||||
computeIndexes(matrix, pass, i, j, blockCount, numberOfIterations, type)
|
computeIndexes(matrix, parallelism, pass, i, j, blockCount, numberOfIterations, type)
|
||||||
val iPrim = -1
|
val iPrim = -1
|
||||||
val jPrim = -1
|
val jPrim = -1
|
||||||
matrix[i][j] = compressionFunctionG(matrix[i][j - 1], matrix[iPrim][jPrim])
|
matrix[i][j] = compressionFunctionG(matrix[i][j - 1], matrix[iPrim][jPrim])
|
||||||
|
@ -70,7 +70,7 @@ infix fun Array<UByte>.xor(other : Array<UByte>) : Array<UByte> {
|
|||||||
if (this.size != other.size) {
|
if (this.size != other.size) {
|
||||||
throw RuntimeException("Operands of different sizes are not supported yet")
|
throw RuntimeException("Operands of different sizes are not supported yet")
|
||||||
}
|
}
|
||||||
return this.copyOf().mapIndexed { index, it -> it xor other[index] }.toTypedArray()
|
return Array(this.size) { this[it] xor other [it]}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
@ -141,22 +141,22 @@ fun Array<UByte>.fromBigEndianArrayToULong() : ULong {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
fun Array<UByte>.fromLittleEndianArrayToUInt() : ULong {
|
fun Array<UByte>.fromLittleEndianArrayToUInt() : UInt {
|
||||||
if (this.size > 4) {
|
if (this.size > 4) {
|
||||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||||
}
|
}
|
||||||
var ulong = this.foldIndexed(0UL) { index, acc, uByte -> acc or (uByte.toULong() shl (index * 8))}
|
var uint = this.foldIndexed(0U) { index, acc, uByte -> acc or (uByte.toUInt() shl (index * 8))}
|
||||||
return ulong
|
return uint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
fun Array<UByte>.fromBigEndianArrayToUInt() : ULong {
|
fun Array<UByte>.fromBigEndianArrayToUInt() : UInt {
|
||||||
if (this.size > 4) {
|
if (this.size > 4) {
|
||||||
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
throw RuntimeException("ore than 8 bytes in input, potential overflow")
|
||||||
}
|
}
|
||||||
var ulong = this.foldIndexed(0UL) { index, acc, uByte -> acc or (uByte.toULong() shl (24 - (index * 8))) }
|
var uint = this.foldIndexed(0U) { index, acc, uByte -> acc or (uByte.toUInt() shl (24 - (index * 8))) }
|
||||||
return ulong
|
return uint
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalUnsignedTypes
|
@ExperimentalUnsignedTypes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user