Added js _util functions

This commit is contained in:
Ugljesa Jovanovic 2020-09-26 23:58:45 +02:00
parent f113f7805d
commit 4af1477c90
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
5 changed files with 161 additions and 69 deletions

View File

@ -20,9 +20,8 @@ expect object LibsodiumUtil {
fun toBase64(data: UByteArray, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : String fun toBase64(data: UByteArray, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : String
fun toHex(data: UByteArray) : String fun toHex(data: UByteArray) : String
fun toString(data : UByteArray) : String
fun fromBase64(data: String, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : UByteArray fun fromBase64(data: String, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : UByteArray
fun fromHex(data: String) : UByteArray fun fromHex(data: String) : UByteArray
fun fromString(data: String) : UByteArray
} }

View File

@ -1,8 +1,10 @@
package com.ionspin.kotlin.crypto.util package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint
import com.ionspin.kotlin.crypto.LibsodiumInitializer
import kotlin.math.exp import kotlin.math.exp
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
/** /**
@ -12,8 +14,35 @@ import kotlin.test.assertTrue
*/ */
class LibsodiumUtilTest { class LibsodiumUtilTest {
@Test
fun testMemzero() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U)
LibsodiumUtil.memzero(input)
assertTrue {
input.contentEquals(UByteArray(9) { 0U })
}
}
}
@Test
fun testMemcmp() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U)
val input2 = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U)
val input3 = ubyteArrayOf(2U, 2U, 2U, 2U, 2U, 2U, 21U, 2U, 2U)
assertTrue {
LibsodiumUtil.memcmp(input, input2)
}
assertFalse {
LibsodiumUtil.memcmp(input, input3)
}
}
}
@Test @Test
fun testPadding() { fun testPadding() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U) val input = ubyteArrayOf(1U, 2U)
val blocksize = 16 val blocksize = 16
val padded = LibsodiumUtil.pad(input, blocksize) val padded = LibsodiumUtil.pad(input, blocksize)
@ -25,9 +54,11 @@ class LibsodiumUtilTest {
input.contentEquals(unpadded) input.contentEquals(unpadded)
} }
} }
}
@Test @Test
fun testPaddingAligned() { fun testPaddingAligned() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U) val input = ubyteArrayOf(1U, 2U)
val blocksize = 2 val blocksize = 2
val padded = LibsodiumUtil.pad(input, blocksize) val padded = LibsodiumUtil.pad(input, blocksize)
@ -39,9 +70,11 @@ class LibsodiumUtilTest {
input.contentEquals(unpadded) input.contentEquals(unpadded)
} }
} }
}
@Test @Test
fun testPaddingMultiblock() { fun testPaddingMultiblock() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U) val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U)
val blocksize = 4 val blocksize = 4
val padded = LibsodiumUtil.pad(input, blocksize) val padded = LibsodiumUtil.pad(input, blocksize)
@ -53,9 +86,11 @@ class LibsodiumUtilTest {
input.contentEquals(unpadded) input.contentEquals(unpadded)
} }
} }
}
@Test @Test
fun testToBase64() { fun testToBase64() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U)
val expected = "AQIDBAUgQID_" val expected = "AQIDBAUgQID_"
val output = LibsodiumUtil.toBase64(input) val output = LibsodiumUtil.toBase64(input)
@ -70,9 +105,11 @@ class LibsodiumUtilTest {
reconstructed.contentEquals(input) reconstructed.contentEquals(input)
} }
} }
}
@Test @Test
fun testToBase64Unaligned() { fun testToBase64Unaligned() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U)
val expected = "AQIDBAUgQID_gA" val expected = "AQIDBAUgQID_gA"
val output = LibsodiumUtil.toBase64(input) val output = LibsodiumUtil.toBase64(input)
@ -87,9 +124,11 @@ class LibsodiumUtilTest {
reconstructed.contentEquals(input) reconstructed.contentEquals(input)
} }
} }
}
@Test @Test
fun toHex() { fun toHex() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U)
val hex = LibsodiumUtil.toHex(input) val hex = LibsodiumUtil.toHex(input)
assertTrue { assertTrue {
@ -101,3 +140,4 @@ class LibsodiumUtilTest {
} }
} }
} }
}

View File

@ -194,9 +194,20 @@ interface JsSodiumInterface {
// ---- Password hashing end ---- // ---- Password hashing end ----
// ---- Utils ----
//util fun memcmp(first: Uint8Array, second: Uint8Array) : Boolean
fun memzero(array: Uint8Array) fun memzero(data: Uint8Array)
fun pad(data : Uint8Array, blocksize: Int) : Uint8Array
fun unpad(data: Uint8Array, blocksize: Int) : Uint8Array
fun to_base64(data: Uint8Array, variant: Int) : String
fun to_hex(data: Uint8Array) : String
fun to_string(data: Uint8Array) : String
fun from_base64(data: String, variant: Int): Uint8Array
fun from_hex(data : String): Uint8Array
fun from_string(data : String): Uint8Array
// ---- Utils end ----

View File

@ -0,0 +1,50 @@
package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object LibsodiumUtil {
actual fun memcmp(first: UByteArray, second: UByteArray): Boolean {
return getSodium().memcmp(first.toUInt8Array(), second.toUInt8Array())
}
actual fun memzero(target: UByteArray) {
// libsodium.js does this as well, and theres no clear way at the moment of casting ubytearray to uint8array
//although I feel like there should be a way to work around it
target.forEachIndexed {
index, _ -> target[index] = 0U
}
}
actual fun pad(unpaddedData: UByteArray, blocksize: Int): UByteArray {
return getSodium().pad(unpaddedData.toUInt8Array(), blocksize).toUByteArray()
}
actual fun unpad(paddedData: UByteArray, blocksize: Int): UByteArray {
return getSodium().unpad(paddedData.toUInt8Array(), blocksize).toUByteArray()
}
actual fun toBase64(
data: UByteArray,
variant: Base64Variants
): String {
return getSodium().to_base64(data.toUInt8Array(), variant.value)
}
actual fun toHex(data: UByteArray): String {
return getSodium().to_hex(data.toUInt8Array())
}
actual fun fromBase64(
data: String,
variant: Base64Variants
): UByteArray {
return getSodium().from_base64(data, variant.value).toUByteArray()
}
actual fun fromHex(data: String): UByteArray {
return getSodium().from_hex(data).toUByteArray()
}
}

View File

@ -113,10 +113,6 @@ actual object LibsodiumUtil {
return result.map { it.toChar() }.dropLast(1).joinToString("") return result.map { it.toChar() }.dropLast(1).joinToString("")
} }
actual fun toString(data: UByteArray): String {
TODO("not implemented yet")
}
actual fun fromBase64(data: String, variant : Base64Variants): UByteArray { actual fun fromBase64(data: String, variant : Base64Variants): UByteArray {
val maxLength = (data.length * 3) / 4 val maxLength = (data.length * 3) / 4
val intermediaryResult = UByteArray(maxLength) { 0U } val intermediaryResult = UByteArray(maxLength) { 0U }
@ -162,8 +158,4 @@ actual object LibsodiumUtil {
return result return result
} }
actual fun fromString(data: String): UByteArray {
TODO("not implemented yet")
}
} }