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
/** /**
@ -13,91 +15,129 @@ import kotlin.test.assertTrue
class LibsodiumUtilTest { class LibsodiumUtilTest {
@Test @Test
fun testPadding() { fun testMemzero() {
val input = ubyteArrayOf(1U, 2U) LibsodiumInitializer.initializeWithCallback {
val blocksize = 16 val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U)
val padded = LibsodiumUtil.pad(input, blocksize) LibsodiumUtil.memzero(input)
println(padded.hexColumsPrint()) assertTrue {
val unpadded = LibsodiumUtil.unpad(padded, blocksize) input.contentEquals(UByteArray(9) { 0U })
println(unpadded.hexColumsPrint()) }
}
}
assertTrue { @Test
input.contentEquals(unpadded) 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
fun testPadding() {
LibsodiumInitializer.initializeWithCallback {
val input = ubyteArrayOf(1U, 2U)
val blocksize = 16
val padded = LibsodiumUtil.pad(input, blocksize)
println(padded.hexColumsPrint())
val unpadded = LibsodiumUtil.unpad(padded, blocksize)
println(unpadded.hexColumsPrint())
assertTrue {
input.contentEquals(unpadded)
}
} }
} }
@Test @Test
fun testPaddingAligned() { fun testPaddingAligned() {
val input = ubyteArrayOf(1U, 2U) LibsodiumInitializer.initializeWithCallback {
val blocksize = 2 val input = ubyteArrayOf(1U, 2U)
val padded = LibsodiumUtil.pad(input, blocksize) val blocksize = 2
println(padded.hexColumsPrint()) val padded = LibsodiumUtil.pad(input, blocksize)
val unpadded = LibsodiumUtil.unpad(padded, blocksize) println(padded.hexColumsPrint())
println(unpadded.hexColumsPrint()) val unpadded = LibsodiumUtil.unpad(padded, blocksize)
println(unpadded.hexColumsPrint())
assertTrue { assertTrue {
input.contentEquals(unpadded) input.contentEquals(unpadded)
}
} }
} }
@Test @Test
fun testPaddingMultiblock() { fun testPaddingMultiblock() {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U) LibsodiumInitializer.initializeWithCallback {
val blocksize = 4 val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U)
val padded = LibsodiumUtil.pad(input, blocksize) val blocksize = 4
println(padded.hexColumsPrint()) val padded = LibsodiumUtil.pad(input, blocksize)
val unpadded = LibsodiumUtil.unpad(padded, blocksize) println(padded.hexColumsPrint())
println(unpadded.hexColumsPrint()) val unpadded = LibsodiumUtil.unpad(padded, blocksize)
println(unpadded.hexColumsPrint())
assertTrue { assertTrue {
input.contentEquals(unpadded) input.contentEquals(unpadded)
}
} }
} }
@Test @Test
fun testToBase64() { fun testToBase64() {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) LibsodiumInitializer.initializeWithCallback {
val expected = "AQIDBAUgQID_" val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U)
val output = LibsodiumUtil.toBase64(input) val expected = "AQIDBAUgQID_"
println("Output: |$output|") val output = LibsodiumUtil.toBase64(input)
println("Expected|$expected| ") println("Output: |$output|")
assertTrue { println("Expected|$expected| ")
output == expected assertTrue {
} output == expected
val reconstructed = LibsodiumUtil.fromBase64(output) }
println("Reconstructed: ${reconstructed.toHexString()}") val reconstructed = LibsodiumUtil.fromBase64(output)
assertTrue { println("Reconstructed: ${reconstructed.toHexString()}")
reconstructed.contentEquals(input) assertTrue {
reconstructed.contentEquals(input)
}
} }
} }
@Test @Test
fun testToBase64Unaligned() { fun testToBase64Unaligned() {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) LibsodiumInitializer.initializeWithCallback {
val expected = "AQIDBAUgQID_gA" val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U)
val output = LibsodiumUtil.toBase64(input) val expected = "AQIDBAUgQID_gA"
println("Output: |$output|") val output = LibsodiumUtil.toBase64(input)
println("Expected|$expected| ") println("Output: |$output|")
assertTrue { println("Expected|$expected| ")
output == expected assertTrue {
} output == expected
val reconstructed = LibsodiumUtil.fromBase64(output) }
println("Reconstructed: ${reconstructed.toHexString()}") val reconstructed = LibsodiumUtil.fromBase64(output)
assertTrue { println("Reconstructed: ${reconstructed.toHexString()}")
reconstructed.contentEquals(input) assertTrue {
reconstructed.contentEquals(input)
}
} }
} }
@Test @Test
fun toHex() { fun toHex() {
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) LibsodiumInitializer.initializeWithCallback {
val hex = LibsodiumUtil.toHex(input) val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U)
assertTrue { val hex = LibsodiumUtil.toHex(input)
hex == input.toHexString() assertTrue {
} hex == input.toHexString()
val reconstructed = LibsodiumUtil.fromHex(hex) }
assertTrue { val reconstructed = LibsodiumUtil.fromHex(hex)
reconstructed.contentEquals(input) assertTrue {
reconstructed.contentEquals(input)
}
} }
} }
} }

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")
}
} }