Added _steam_ jvm and js implementations

This commit is contained in:
Ugljesa Jovanovic 2020-10-12 20:00:17 +02:00
parent a18355adae
commit 67d80beb34
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
4 changed files with 230 additions and 32 deletions

View File

@ -1,5 +1,6 @@
package com.ionspin.kotlin.crypto.stream package com.ionspin.kotlin.crypto.stream
import com.ionspin.kotlin.crypto.LibsodiumInitializer
import com.ionspin.kotlin.crypto.util.LibsodiumRandom import com.ionspin.kotlin.crypto.util.LibsodiumRandom
import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.encodeToUByteArray
import com.ionspin.kotlin.crypto.util.randombytes_SEEDBYTES import com.ionspin.kotlin.crypto.util.randombytes_SEEDBYTES
@ -20,43 +21,50 @@ class StreamTest {
@Test @Test
fun testChaCha20Stream() { fun testChaCha20Stream() {
val message = "This is a cha cha message".encodeToUByteArray() LibsodiumInitializer.initializeWithCallback {
val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_chacha20_NONCEBYTES, seed) val message = "This is a cha cha message".encodeToUByteArray()
val key = Stream.chacha20Keygen() val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_chacha20_NONCEBYTES, seed)
val stream = Stream.chacha20(message.size, nonce, key) val key = Stream.chacha20Keygen()
val encryptedManually = message.mapIndexed { index, it -> it xor stream[index] }.toUByteArray() val stream = Stream.chacha20(message.size, nonce, key)
val encryptedUsingLibsodium = Stream.chacha20Xor(message, nonce, key) val encryptedManually = message.mapIndexed { index, it -> it xor stream[index] }.toUByteArray()
val encryptedUsingLibsodiumWithInitialCounter = Stream.chacha20XorIc(message, nonce, 0U, key) val encryptedUsingLibsodium = Stream.chacha20Xor(message, nonce, key)
println(encryptedManually.toHexString()) val encryptedUsingLibsodiumWithInitialCounter = Stream.chacha20XorIc(message, nonce, 0U, key)
println(encryptedUsingLibsodium.toHexString()) println(encryptedManually.toHexString())
println(encryptedUsingLibsodiumWithInitialCounter.toHexString()) println(encryptedUsingLibsodium.toHexString())
assertTrue { println(encryptedUsingLibsodiumWithInitialCounter.toHexString())
encryptedManually.contentEquals(encryptedUsingLibsodium) println(seed.toHexString())
} assertTrue {
assertTrue { encryptedManually.contentEquals(encryptedUsingLibsodium)
encryptedManually.contentEquals(encryptedUsingLibsodiumWithInitialCounter) }
} assertTrue {
val decryptedUsingLibsodium = Stream.chacha20Xor(encryptedUsingLibsodium, nonce, key) encryptedManually.contentEquals(encryptedUsingLibsodiumWithInitialCounter)
assertTrue { }
decryptedUsingLibsodium.contentEquals(message) val decryptedUsingLibsodium = Stream.chacha20Xor(encryptedUsingLibsodium, nonce, key)
assertTrue {
decryptedUsingLibsodium.contentEquals(message)
}
} }
} }
@Test @Test
fun testChaCha20IetfStream() { fun testChaCha20IetfStream() {
val message = "This is a cha cha message".encodeToUByteArray() LibsodiumInitializer.initializeWithCallback {
val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_chacha20_NONCEBYTES, seed) val message = "This is a cha cha message".encodeToUByteArray()
val key = Stream.chacha20Keygen() val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_chacha20_ietf_NONCEBYTES, seed)
val encryptedUsingLibsodium = Stream.chacha20IetfXor(message, nonce, key) val key = Stream.chacha20Keygen()
val encryptedUsingLibsodiumWithInitialCounter = Stream.chacha20IetfXorIc(message, nonce, 0U, key) val encryptedUsingLibsodium = Stream.chacha20IetfXor(message, nonce, key)
println(encryptedUsingLibsodium.toHexString()) val encryptedUsingLibsodiumWithInitialCounter = Stream.chacha20IetfXorIc(message, nonce, 0U, key)
println(encryptedUsingLibsodiumWithInitialCounter.toHexString()) println(encryptedUsingLibsodium.toHexString())
assertTrue { println(encryptedUsingLibsodiumWithInitialCounter.toHexString())
encryptedUsingLibsodium.contentEquals(encryptedUsingLibsodiumWithInitialCounter) assertTrue {
} encryptedUsingLibsodium.contentEquals(encryptedUsingLibsodiumWithInitialCounter)
val decryptedUsingLibsodium = Stream.chacha20IetfXor(encryptedUsingLibsodium, nonce, key) }
assertTrue { val decryptedUsingLibsodium = Stream.chacha20IetfXor(encryptedUsingLibsodium, nonce, key)
decryptedUsingLibsodium.contentEquals(message) println(message.toHexString())
println(decryptedUsingLibsodium.toHexString())
assertTrue {
decryptedUsingLibsodium.contentEquals(message)
}
} }
} }
} }

View File

@ -222,6 +222,16 @@ interface JsSodiumInterface {
fun crypto_kx_seed_keypair(seed: Uint8Array) : dynamic fun crypto_kx_seed_keypair(seed: Uint8Array) : dynamic
fun crypto_kx_server_session_keys(serverPublicKey: Uint8Array, serverSecretKey: Uint8Array, clientPublicKey: Uint8Array) : dynamic fun crypto_kx_server_session_keys(serverPublicKey: Uint8Array, serverSecretKey: Uint8Array, clientPublicKey: Uint8Array) : dynamic
// ---- Key exchange end ----
// -- Stream ----
fun crypto_stream_chacha20(outLength: UInt, key: Uint8Array, nonce: Uint8Array) : Uint8Array
fun crypto_stream_chacha20_ietf_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
fun crypto_stream_chacha20_ietf_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array
fun crypto_stream_chacha20_keygen() : Uint8Array
fun crypto_stream_chacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
fun crypto_stream_chacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array

View File

@ -0,0 +1,82 @@
package com.ionspin.kotlin.crypto.stream
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
actual object Stream {
actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
//Note, unlike the other ones, here the positions of key and nonce are reversed.
val result = getSodium().crypto_stream_chacha20(clen.toUInt(), key.toUInt8Array(), nonce.toUInt8Array())
return result.toUByteArray()
}
actual fun chacha20IetfXor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_chacha20_ietf_xor(
message.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return result.toUByteArray()
}
actual fun chacha20IetfXorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_chacha20_ietf_xor_ic(
message.toUInt8Array(),
nonce.toUInt8Array(),
initialCounter.toUInt(),
key.toUInt8Array()
)
return result.toUByteArray()
}
actual fun chacha20Keygen(): UByteArray {
val result = getSodium().crypto_stream_chacha20_keygen()
return result.toUByteArray()
}
actual fun chacha20Xor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_chacha20_xor(
message.toUInt8Array(),
nonce.toUInt8Array(),
key.toUInt8Array()
)
return result.toUByteArray()
}
actual fun chacha20XorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
val result = getSodium().crypto_stream_chacha20_xor_ic(
message.toUInt8Array(),
nonce.toUInt8Array(),
initialCounter.toUInt(),
key.toUInt8Array()
)
return result.toUByteArray()
}
}

View File

@ -0,0 +1,98 @@
package com.ionspin.kotlin.crypto.stream
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
actual object Stream {
actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
val result = UByteArray(clen)
sodium.crypto_stream_chacha20(result.asByteArray(), clen.toLong(), nonce.asByteArray(), key.asByteArray())
return result
}
actual fun chacha20IetfXor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_ietf_xor(
result.asByteArray(),
message.asByteArray(),
message.size.toLong(),
nonce.asByteArray(),
key.asByteArray()
)
return result
}
actual fun chacha20IetfXorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_ietf_xor_ic(
result.asByteArray(),
message.asByteArray(),
message.size.toLong(),
nonce.asByteArray(),
initialCounter.toLong(),
key.asByteArray()
)
return result
}
actual fun chacha20Keygen(): UByteArray {
val result = UByteArray(crypto_stream_chacha20_KEYBYTES)
sodium.crypto_stream_chacha20_keygen(result.asByteArray())
return result
}
actual fun chacha20Xor(
message: UByteArray,
nonce: UByteArray,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_xor(
result.asByteArray(),
message.asByteArray(),
message.size.toLong(),
nonce.asByteArray(),
key.asByteArray()
)
return result
}
actual fun chacha20XorIc(
message: UByteArray,
nonce: UByteArray,
initialCounter: ULong,
key: UByteArray
): UByteArray {
val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_xor_ic(
result.asByteArray(),
message.asByteArray(),
message.size.toLong(),
nonce.asByteArray(),
initialCounter.toLong(),
key.asByteArray()
)
return result
}
}