Fix errors when calculating address blocks, add readme

This commit is contained in:
Ugljesa Jovanovic 2020-05-16 21:12:25 +02:00 committed by Ugljesa Jovanovic
parent c62727e3fb
commit 04955effe7
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
4 changed files with 76 additions and 9 deletions

View File

@ -40,7 +40,7 @@ It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be
* SHA512
* SHA256
## Symmetric cipher (Currently only available only in 0.0.3-SNAPSHOT)
## Symmetric cipher
* AES
* Modes: CBC, CTR
@ -50,7 +50,7 @@ It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be
## AEAD
More to come.
TODO()
## Integration
@ -187,6 +187,35 @@ plainText == decrypted.toHexString()
```
### Key derivation
#### Argon2
NOTE: This implementation is tested against KAT generated by reference Argon2 implementation, which does not follow
specification completely. See this issue https://github.com/P-H-C/phc-winner-argon2/issues/183
```kotlin
val argon2Instance = Argon2(
password = "Password",
salt = "RandomSalt",
parallelism = 8,
tagLength = 64U,
requestedMemorySize = 256U, //4GB
numberOfIterations = 4U,
key = "",
associatedData = "",
argonType = ArgonType.Argon2id
)
val tag = argon2Instance.derive()
val tagString = tag.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "")
val expectedTagString = "c255e3e94305817d5e09a7c771e574e3a81cc78fef5da4a9644b6df0" +
"0ba1c9b424e3dd0ce7e600b1269b14c84430708186a8a60403e1bfbda935991592b9ff37"
println("Tag: ${tagString}")
assertEquals(tagString, expectedTagString)
```

View File

@ -25,6 +25,7 @@ import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.argonBlake2bAr
import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.compressionFunctionG
import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.validateArgonParameters
import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUInt
import com.ionspin.kotlin.crypto.util.hexColumsPrint
import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray
/**
@ -164,6 +165,7 @@ class Argon2(
addressBlock: Array<UByte>?
): Pair<Int, Int> {
val segmentIndex = (column % segmentLength)
val independentIndex = segmentIndex % 128 // 128 is the number of addresses in address block
val (j1, j2) = when (argonType) {
ArgonType.Argon2d -> {
val previousBlock = if (column == 0) {
@ -176,7 +178,7 @@ class Argon2(
Pair(first32Bit, second32Bit)
}
ArgonType.Argon2i -> {
val selectedAddressBlock = addressBlock!!.sliceArray((segmentIndex * 8) until (segmentIndex * 8) + 8)
val selectedAddressBlock = addressBlock!!.sliceArray((independentIndex * 8) until (independentIndex * 8) + 8)
val first32Bit = selectedAddressBlock.sliceArray(0 until 4).fromLittleEndianArrayToUInt()
val second32Bit = selectedAddressBlock.sliceArray(4 until 8).fromLittleEndianArrayToUInt()
Pair(first32Bit, second32Bit)
@ -184,7 +186,7 @@ class Argon2(
ArgonType.Argon2id -> {
if (iteration == 0 && (slice == 0 || slice == 1)) {
val selectedAddressBlock =
addressBlock!!.sliceArray((segmentIndex * 8) until (segmentIndex * 8) + 8)
addressBlock!!.sliceArray((independentIndex * 8) until (independentIndex * 8) + 8)
val first32Bit = selectedAddressBlock.sliceArray(0 until 4).fromLittleEndianArrayToUInt()
val second32Bit = selectedAddressBlock.sliceArray(4 until 8).fromLittleEndianArrayToUInt()
Pair(first32Bit, second32Bit)
@ -338,12 +340,15 @@ class Argon2(
slice * segmentLength
}
for (column in startColumn until (slice + 1) * segmentLength) {
val segmentIndex = column - (slice * segmentLength)
//Each address block contains 128 addresses, and we use one per iteration,
//so once we do 128 iterations we need to calculate a new address block
if (useIndependentAddressing && column != 0 && column % 128 == 0) {
if (useIndependentAddressing && segmentIndex != 0 && segmentIndex % 128 == 0) {
addressBlock = populateAddressBlock(iteration, slice, lane, addressBlock!!, addressCounter)
addressCounter++
addressBlock.hexColumsPrint(16)
}
val previousColumn = if (column == 0) {
columnCount - 1

View File

@ -19,8 +19,10 @@ package com.ionspin.kotlin.crypto
import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b
import com.ionspin.kotlin.crypto.hash.sha.Sha256
import com.ionspin.kotlin.crypto.hash.sha.Sha512
import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2
import com.ionspin.kotlin.crypto.keyderivation.argon2.ArgonType
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
/**
@ -73,7 +75,7 @@ class ReadmeTest {
@ExperimentalStdlibApi
@Test
fun sha256Example() {
val input ="abc"
val input = "abc"
val result = Sha256.digest(inputString = input)
val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
assertTrue {
@ -86,9 +88,9 @@ class ReadmeTest {
@ExperimentalStdlibApi
@Test
fun sha512Example() {
val input ="abc"
val input = "abc"
val result = Sha512.digest(inputMessage = input.encodeToByteArray().map { it.toUByte() }.toTypedArray())
println(result.map {it.toString(16)})
println(result.map { it.toString(16) })
val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" +
"2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
assertTrue {
@ -124,4 +126,26 @@ class ReadmeTest {
}
@Test
fun argon2StringExample() {
val argon2Instance = Argon2(
password = "Password",
salt = "RandomSalt",
parallelism = 8,
tagLength = 64U,
requestedMemorySize = 256U, //4GB
numberOfIterations = 4U,
key = "",
associatedData = "",
argonType = ArgonType.Argon2id
)
val tag = argon2Instance.derive()
val tagString = tag.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "")
val expectedTagString = "c255e3e94305817d5e09a7c771e574e3a81cc78fef5da4a9644b6df0" +
"0ba1c9b424e3dd0ce7e600b1269b14c84430708186a8a60403e1bfbda935991592b9ff37"
println("Tag: ${tagString}")
assertEquals(tagString, expectedTagString)
}
}

View File

@ -72,6 +72,15 @@ class UtilTest {
converted[3] == 0xAAU.toUByte()
}
assertTrue {
val original = 123456U
val converted = original.toLittleEndianUByteArray()
converted[0] == 0x40U.toUByte() &&
converted[1] == 0xE2U.toUByte() &&
converted[2] == 0x01U.toUByte() &&
converted[3] == 0x00U.toUByte()
}
}
@Test