Added sha2 hashes in common and native and test

This commit is contained in:
Ugljesa Jovanovic 2020-08-31 20:44:37 +02:00 committed by Ugljesa Jovanovic
parent 1878144b8f
commit 15be707114
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
7 changed files with 313 additions and 4 deletions

View File

@ -7,10 +7,18 @@ package com.ionspin.kotlin.crypto.generichash
*/ */
val crypto_generichash_BYTES = 32 val crypto_generichash_BYTES = 32
val crypto_generichash_blake2b_BYTES_MIN = 16
val crypto_generichash_blake2b_BYTES_MAX = 64
val crypto_generichash_blake2b_BYTES = 32
val crypto_generichash_blake2b_KEYBYTES_MIN = 16
val crypto_generichash_blake2b_KEYBYTES_MAX = 64
val crypto_generichash_blake2b_KEYBYTES = 32
val crypto_generichash_blake2b_SALTBYTES = 16
expect class GenericHashStateInternal
data class GenericHashState(val hashLength: Int, val internalState: GenericHashStateInternal) data class GenericHashState(val hashLength: Int, val internalState: GenericHashStateInternal)
expect class GenericHashStateInternal
expect object GenericHash { expect object GenericHash {
@ -21,6 +29,15 @@ expect object GenericHash {
fun genericHashFinal(state : GenericHashState) : UByteArray fun genericHashFinal(state : GenericHashState) : UByteArray
fun genericHashKeygen() : UByteArray fun genericHashKeygen() : UByteArray
// ---- Not present in LazySodium nor libsodium.js
// fun blake2b(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray
//
// fun blake2bInit(requestedHashLength: Int, key : UByteArray? = null) : Blake2bState
// fun blake2bUpdate(state: GenericHashState, messagePart : UByteArray)
// fun blake2bFinal(state : GenericHashState) : UByteArray
//
// fun blake2bKeygen() : UByteArray
} }

View File

@ -0,0 +1,31 @@
package com.ionspin.kotlin.crypto.hash
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 31-Aug-2020
*/
val crypto_hash_BYTES = 64
val crypto_hash_sha256_BYTES = 32
val crypto_hash_sha512_BYTES = 64
expect class Sha256State
expect class Sha512State
expect object Hash {
fun hash(data: UByteArray) : UByteArray
fun sha256(data: UByteArray) : UByteArray
fun sha256Init() : Sha256State
fun sha256Update(state: Sha256State, data : UByteArray)
fun sha256Final(state : Sha256State) : UByteArray
fun sha512(data: UByteArray) : UByteArray
fun sha512Init() : Sha512State
fun sha512Update(state: Sha512State, data : UByteArray)
fun sha512Final(state : Sha512State) : UByteArray
}

View File

@ -0,0 +1,77 @@
package com.ionspin.kotlin.crypto.hash
import com.ionspin.kotlin.crypto.LibsodiumInitializer
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.hexStringToUByteArray
import com.ionspin.kotlin.crypto.util.toHexString
import kotlin.test.Test
import kotlin.test.assertTrue
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 31-Aug-2020
*/
class HashTest {
@Test
fun hashTest() {
LibsodiumInitializer.initializeWithCallback {
val input = ("Input for various hash functions").encodeToUByteArray()
val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" +
"838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray()
val result = Hash.hash(input)
assertTrue {
result.contentEquals(expected)
}
}
}
@Test
fun hashTestSha256() {
LibsodiumInitializer.initializeWithCallback {
val input = ("Input for various hash functions").encodeToUByteArray()
val expected = ("2bb078ec5993b5428355ba49bf030b1ac7" +
"1519e635aebc2f28124fac2aef9264").hexStringToUByteArray()
val result = Hash.sha256(input)
assertTrue {
result.contentEquals(expected)
}
val sha256State = Hash.sha256Init()
Hash.sha256Update(sha256State, input)
val multipartResult = Hash.sha256Final(sha256State)
assertTrue {
multipartResult.contentEquals(expected)
}
}
}
@Test
fun hashTestSha512() {
LibsodiumInitializer.initializeWithCallback {
val input = ("Input for various hash functions").encodeToUByteArray()
val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" +
"838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray()
val result = Hash.sha512(input)
assertTrue {
result.contentEquals(expected)
}
val sha512State = Hash.sha512Init()
Hash.sha512Update(sha512State, input)
val multipartResult = Hash.sha512Final(sha512State)
assertTrue {
multipartResult.contentEquals(expected)
}
}
}
}

View File

@ -18,7 +18,7 @@ interface JsSodiumInterface {
fun crypto_hash_sha512(message: Uint8Array): Uint8Array fun crypto_hash_sha512(message: Uint8Array): Uint8Array
//Updateable // ---- Generic hash ---- // Updateable
fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic
@ -28,11 +28,27 @@ interface JsSodiumInterface {
fun crypto_generichash_keygen() : Uint8Array fun crypto_generichash_keygen() : Uint8Array
//Short hash // ---- Generic hash end ---- // Updateable
// ---- Blake2b ----
fun crypto_generichash_blake2b(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array): Uint8Array
fun crypto_generichash_blake2b_init(key : Uint8Array, hashLength: Int) : dynamic
fun crypto_generichash_blake2b_update(state: dynamic, inputMessage: Uint8Array)
fun crypto_generichash_blake2b_final(state: dynamic, hashLength: Int) : Uint8Array
fun crypto_generichash_blake2b_keygen() : Uint8Array
// ---- Blake2b end ----
// ---- Short hash ----
fun crypto_shorthash(data : Uint8Array, key: Uint8Array) : Uint8Array fun crypto_shorthash(data : Uint8Array, key: Uint8Array) : Uint8Array
fun crypto_shorthash_keygen() : Uint8Array fun crypto_shorthash_keygen() : Uint8Array
// ---- Short hash end ----
fun crypto_hash_sha256_init() : dynamic fun crypto_hash_sha256_init() : dynamic

View File

@ -48,4 +48,35 @@ actual object GenericHash {
actual fun genericHashKeygen(): UByteArray { actual fun genericHashKeygen(): UByteArray {
return getSodium().crypto_generichash_keygen().toUByteArray() return getSodium().crypto_generichash_keygen().toUByteArray()
} }
// -- Not present in LazySodium nor libsodium.js
// actual fun blake2b(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray {
// return getSodium().crypto_generichash_blake2b(
// requestedHashLength,
// message.toUInt8Array(),
// key?.toUInt8Array() ?: Uint8Array(0)
// ).toUByteArray()
// }
//
// actual fun blake2bInit(
// requestedHashLength: Int,
// key: UByteArray?
// ): Blake2bState {
// val state = getSodium().crypto_generichash_blake2b_init(key?.toUInt8Array() ?: Uint8Array(0), requestedHashLength)
// return Blake2bState(requestedHashLength, state)
// }
//
// actual fun blake2bUpdate(
// state: GenericHashState,
// messagePart: UByteArray
// ) {
// getSodium().crypto_generichash_blake2b_update(state.internalState, messagePart.toUInt8Array())
// }
//
// actual fun blake2bFinal(state: GenericHashState): UByteArray {
// return getSodium().crypto_generichash_blake2b_final(state.internalState, state.hashLength).toUByteArray()
// }
//
// actual fun blake2bKeygen(): UByteArray {
// return getSodium().crypto_generichash_blake2b_keygen().toUByteArray()
// }
} }

View File

@ -0,0 +1,39 @@
package com.ionspin.kotlin.crypto.hash
actual object Hash {
actual fun hash(data: UByteArray): UByteArray {
TODO("not implemented yet")
}
actual fun sha256(data: UByteArray): UByteArray {
TODO("not implemented yet")
}
actual fun sha256Init(): Sha256State {
TODO("not implemented yet")
}
actual fun sha256Update(state: Sha256State, data: UByteArray) {
}
actual fun sha256Final(state: Sha256State): UByteArray {
TODO("not implemented yet")
}
actual fun sha512(data: UByteArray): UByteArray {
TODO("not implemented yet")
}
actual fun sha512Init(): Sha512State {
TODO("not implemented yet")
}
actual fun sha512Update(state: Sha512State, data: UByteArray) {
}
actual fun sha512Final(state: Sha512State): UByteArray {
TODO("not implemented yet")
}
}

View File

@ -0,0 +1,98 @@
package com.ionspin.kotlin.crypto.hash
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
import kotlinx.cinterop.pointed
import kotlinx.cinterop.ptr
import kotlinx.cinterop.reinterpret
import libsodium.crypto_hash
import libsodium.crypto_hash_sha256
import libsodium.crypto_hash_sha256_final
import libsodium.crypto_hash_sha256_init
import libsodium.crypto_hash_sha256_state
import libsodium.crypto_hash_sha256_update
import libsodium.crypto_hash_sha512
import libsodium.crypto_hash_sha512_final
import libsodium.crypto_hash_sha512_init
import libsodium.crypto_hash_sha512_state
import libsodium.crypto_hash_sha512_update
import platform.posix.malloc
actual typealias Sha256State = crypto_hash_sha256_state
actual typealias Sha512State = crypto_hash_sha512_state
actual object Hash {
actual fun hash(data: UByteArray): UByteArray {
val hashResult = UByteArray(crypto_hash_BYTES)
val hashResultPinned = hashResult.pin()
val dataPinned = data.pin()
crypto_hash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert())
hashResultPinned.unpin()
dataPinned.unpin()
return hashResult
}
actual fun sha256(data: UByteArray): UByteArray {
val hashResult = UByteArray(crypto_hash_sha256_BYTES)
val hashResultPinned = hashResult.pin()
val dataPinned = data.pin()
crypto_hash_sha256(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert())
hashResultPinned.unpin()
dataPinned.unpin()
return hashResult
}
actual fun sha256Init(): Sha256State {
val stateAllocated = malloc(Sha256State.size.convert())
val statePointed = stateAllocated!!.reinterpret<Sha256State>().pointed
crypto_hash_sha256_init(statePointed.ptr)
return statePointed
}
actual fun sha256Update(state: Sha256State, data: UByteArray) {
val dataPinned = data.pin()
crypto_hash_sha256_update(state.ptr, dataPinned.toPtr(), data.size.convert())
}
actual fun sha256Final(state: Sha256State): UByteArray {
val hashResult = UByteArray(crypto_hash_sha256_BYTES)
val hashResultPinned = hashResult.pin()
crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr())
return hashResult
}
actual fun sha512(data: UByteArray): UByteArray {
val hashResult = UByteArray(crypto_hash_sha512_BYTES)
val hashResultPinned = hashResult.pin()
val dataPinned = data.pin()
crypto_hash_sha512(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert())
hashResultPinned.unpin()
dataPinned.unpin()
return hashResult
}
actual fun sha512Init(): Sha512State {
val stateAllocated = malloc(Sha512State.size.convert())
val statePointed = stateAllocated!!.reinterpret<Sha512State>().pointed
crypto_hash_sha512_init(statePointed.ptr)
return statePointed
}
actual fun sha512Update(state: Sha512State, data: UByteArray) {
val dataPinned = data.pin()
crypto_hash_sha512_update(state.ptr, dataPinned.toPtr(), data.size.convert())
}
actual fun sha512Final(state: Sha512State): UByteArray {
val hashResult = UByteArray(crypto_hash_sha512_BYTES)
val hashResultPinned = hashResult.pin()
crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr())
return hashResult
}
}