Added to hex and to base64 and from conversions
This commit is contained in:
parent
7e2b52a193
commit
f113f7805d
@ -5,6 +5,11 @@ package com.ionspin.kotlin.crypto.util
|
|||||||
* ugljesa.jovanovic@ionspin.com
|
* ugljesa.jovanovic@ionspin.com
|
||||||
* on 31-Aug-2020
|
* on 31-Aug-2020
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum class Base64Variants(val value: Int) {
|
||||||
|
ORIGINAL(1), ORIGINAL_NO_PADDING(3), URLSAFE(5), URLSAFE_NO_PADDING(7)
|
||||||
|
}
|
||||||
|
|
||||||
expect object LibsodiumUtil {
|
expect object LibsodiumUtil {
|
||||||
|
|
||||||
fun memcmp(first: UByteArray, second: UByteArray) : Boolean
|
fun memcmp(first: UByteArray, second: UByteArray) : Boolean
|
||||||
@ -13,11 +18,11 @@ expect object LibsodiumUtil {
|
|||||||
fun pad(unpaddedData : UByteArray, blocksize: Int) : UByteArray
|
fun pad(unpaddedData : UByteArray, blocksize: Int) : UByteArray
|
||||||
fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray
|
fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray
|
||||||
|
|
||||||
fun toBase64(data: UByteArray) : 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 toString(data : UByteArray) : String
|
||||||
|
|
||||||
fun fromBase64(data: String) : 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
|
fun fromString(data: String) : UByteArray
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
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 kotlin.math.exp
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
@ -52,4 +53,51 @@ class LibsodiumUtilTest {
|
|||||||
input.contentEquals(unpadded)
|
input.contentEquals(unpadded)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testToBase64() {
|
||||||
|
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U)
|
||||||
|
val expected = "AQIDBAUgQID_"
|
||||||
|
val output = LibsodiumUtil.toBase64(input)
|
||||||
|
println("Output: |$output|")
|
||||||
|
println("Expected|$expected| ")
|
||||||
|
assertTrue {
|
||||||
|
output == expected
|
||||||
|
}
|
||||||
|
val reconstructed = LibsodiumUtil.fromBase64(output)
|
||||||
|
println("Reconstructed: ${reconstructed.toHexString()}")
|
||||||
|
assertTrue {
|
||||||
|
reconstructed.contentEquals(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testToBase64Unaligned() {
|
||||||
|
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U)
|
||||||
|
val expected = "AQIDBAUgQID_gA"
|
||||||
|
val output = LibsodiumUtil.toBase64(input)
|
||||||
|
println("Output: |$output|")
|
||||||
|
println("Expected|$expected| ")
|
||||||
|
assertTrue {
|
||||||
|
output == expected
|
||||||
|
}
|
||||||
|
val reconstructed = LibsodiumUtil.fromBase64(output)
|
||||||
|
println("Reconstructed: ${reconstructed.toHexString()}")
|
||||||
|
assertTrue {
|
||||||
|
reconstructed.contentEquals(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun toHex() {
|
||||||
|
val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U)
|
||||||
|
val hex = LibsodiumUtil.toHex(input)
|
||||||
|
assertTrue {
|
||||||
|
hex == input.toHexString()
|
||||||
|
}
|
||||||
|
val reconstructed = LibsodiumUtil.fromHex(hex)
|
||||||
|
assertTrue {
|
||||||
|
reconstructed.contentEquals(input)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,27 @@
|
|||||||
package com.ionspin.kotlin.crypto.util
|
package com.ionspin.kotlin.crypto.util
|
||||||
|
|
||||||
import kotlinx.cinterop.StableRef
|
|
||||||
import kotlinx.cinterop.addressOf
|
import kotlinx.cinterop.addressOf
|
||||||
import kotlinx.cinterop.convert
|
import kotlinx.cinterop.convert
|
||||||
import kotlinx.cinterop.pin
|
import kotlinx.cinterop.pin
|
||||||
import kotlinx.cinterop.reinterpret
|
import libsodium.sodium_base642bin
|
||||||
|
import libsodium.sodium_base64_encoded_len
|
||||||
|
import libsodium.sodium_bin2base64
|
||||||
|
import libsodium.sodium_bin2hex
|
||||||
|
import libsodium.sodium_hex2bin
|
||||||
import libsodium.sodium_memcmp
|
import libsodium.sodium_memcmp
|
||||||
import libsodium.sodium_memzero
|
import libsodium.sodium_memzero
|
||||||
import libsodium.sodium_pad
|
import libsodium.sodium_pad
|
||||||
import libsodium.sodium_unpad
|
import libsodium.sodium_unpad
|
||||||
import platform.posix.size_t
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Ugljesa Jovanovic
|
* Created by Ugljesa Jovanovic
|
||||||
* ugljesa.jovanovic@ionspin.com
|
* ugljesa.jovanovic@ionspin.com
|
||||||
* on 31-Aug-2020
|
* on 31-Aug-2020
|
||||||
*/
|
*/
|
||||||
actual object LibsodiumUtil {
|
|
||||||
|
|
||||||
|
|
||||||
|
actual object LibsodiumUtil {
|
||||||
|
|
||||||
actual fun memcmp(first: UByteArray, second: UByteArray): Boolean {
|
actual fun memcmp(first: UByteArray, second: UByteArray): Boolean {
|
||||||
val firstPinned = first.pin()
|
val firstPinned = first.pin()
|
||||||
val secondPinned = second.pin()
|
val secondPinned = second.pin()
|
||||||
@ -37,7 +40,7 @@ actual object LibsodiumUtil {
|
|||||||
val resultingSize = if (unpaddedData.size % blocksize != 0 ) {
|
val resultingSize = if (unpaddedData.size % blocksize != 0 ) {
|
||||||
((unpaddedData.size / blocksize) + 1 ) * blocksize
|
((unpaddedData.size / blocksize) + 1 ) * blocksize
|
||||||
} else {
|
} else {
|
||||||
unpaddedData.size
|
unpaddedData.size + 1
|
||||||
}
|
}
|
||||||
val paddedData = UByteArray(resultingSize)
|
val paddedData = UByteArray(resultingSize)
|
||||||
unpaddedData.copyInto(paddedData, 0, 0)
|
unpaddedData.copyInto(paddedData, 0, 0)
|
||||||
@ -57,7 +60,7 @@ actual object LibsodiumUtil {
|
|||||||
actual fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray {
|
actual fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray {
|
||||||
val paddedDataCopy = paddedData.copyOf()
|
val paddedDataCopy = paddedData.copyOf()
|
||||||
val paddedDataCopyPinned = paddedDataCopy.pin()
|
val paddedDataCopyPinned = paddedDataCopy.pin()
|
||||||
var newSize = ULongArray(1) { 99UL }
|
var newSize = ULongArray(1) { 0UL }
|
||||||
val newSizePinned = newSize.pin()
|
val newSizePinned = newSize.pin()
|
||||||
sodium_unpad(
|
sodium_unpad(
|
||||||
newSizePinned.addressOf(0),
|
newSizePinned.addressOf(0),
|
||||||
@ -75,24 +78,88 @@ actual object LibsodiumUtil {
|
|||||||
return unpadded
|
return unpadded
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun toBase64(data: UByteArray): String {
|
actual fun toBase64(data: UByteArray, variant : Base64Variants): String {
|
||||||
TODO("not implemented yet")
|
val maxlen = sodium_base64_encoded_len(data.size.convert(), variant.value)
|
||||||
|
val dataPinned = data.pin()
|
||||||
|
val result = ByteArray(maxlen.toInt()) { 0 }
|
||||||
|
val resultPinned = result.pin()
|
||||||
|
sodium_bin2base64(
|
||||||
|
resultPinned.addressOf(0),
|
||||||
|
maxlen,
|
||||||
|
dataPinned.toPtr(),
|
||||||
|
data.size.convert(),
|
||||||
|
variant.value
|
||||||
|
)
|
||||||
|
dataPinned.unpin()
|
||||||
|
resultPinned.unpin()
|
||||||
|
//Drop '\0'
|
||||||
|
return result.map { it.toChar() }.dropLast(1).joinToString("")
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun toHex(data: UByteArray): String {
|
actual fun toHex(data: UByteArray): String {
|
||||||
TODO("not implemented yet")
|
val hexLen = (data.size * 2) + 1 // +1 for terminator char
|
||||||
|
val result = ByteArray(hexLen)
|
||||||
|
val resultPinned = result.pin()
|
||||||
|
val dataPinned = data.pin()
|
||||||
|
sodium_bin2hex(
|
||||||
|
resultPinned.addressOf(0),
|
||||||
|
hexLen.convert(),
|
||||||
|
dataPinned.toPtr(),
|
||||||
|
data.size.convert()
|
||||||
|
)
|
||||||
|
resultPinned.unpin()
|
||||||
|
dataPinned.unpin()
|
||||||
|
//Drop \0 termination
|
||||||
|
return result.map { it.toChar() }.dropLast(1).joinToString("")
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun toString(data: UByteArray): String {
|
actual fun toString(data: UByteArray): String {
|
||||||
TODO("not implemented yet")
|
TODO("not implemented yet")
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun fromBase64(data: String): UByteArray {
|
actual fun fromBase64(data: String, variant : Base64Variants): UByteArray {
|
||||||
TODO("not implemented yet")
|
val maxLength = (data.length * 3) / 4
|
||||||
|
val intermediaryResult = UByteArray(maxLength) { 0U }
|
||||||
|
|
||||||
|
val intermediaryResultPinned = intermediaryResult.pin()
|
||||||
|
var binLen = ULongArray(1) { 0UL }
|
||||||
|
var binLenPinned = binLen.pin()
|
||||||
|
sodium_base642bin(
|
||||||
|
intermediaryResultPinned.toPtr(),
|
||||||
|
maxLength.convert(),
|
||||||
|
data,
|
||||||
|
data.length.convert(),
|
||||||
|
null,
|
||||||
|
binLenPinned.addressOf(0),
|
||||||
|
null,
|
||||||
|
variant.value
|
||||||
|
|
||||||
|
)
|
||||||
|
binLenPinned.unpin()
|
||||||
|
intermediaryResultPinned.unpin()
|
||||||
|
|
||||||
|
return if (binLen[0].toInt() != maxLength) {
|
||||||
|
intermediaryResult.sliceArray(0 until binLen[0].toInt())
|
||||||
|
} else {
|
||||||
|
intermediaryResult
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun fromHex(data: String): UByteArray {
|
actual fun fromHex(data: String): UByteArray {
|
||||||
TODO("not implemented yet")
|
val expectedSize = (data.length + 1) / 2
|
||||||
|
val result = UByteArray(expectedSize)
|
||||||
|
val resultPinned = result.pin()
|
||||||
|
sodium_hex2bin(
|
||||||
|
resultPinned.toPtr(),
|
||||||
|
expectedSize.convert(),
|
||||||
|
data,
|
||||||
|
data.length.convert(),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
resultPinned.unpin()
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
actual fun fromString(data: String): UByteArray {
|
actual fun fromString(data: String): UByteArray {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user