Added _kx_ and nateive impl, updated libsodium submodule to latest commit

This commit is contained in:
Ugljesa Jovanovic 2020-10-09 16:56:09 +02:00
parent f4d6d941c9
commit bd173f422f
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
5 changed files with 201 additions and 5 deletions

View File

@ -0,0 +1,23 @@
package com.ionspin.kotlin.crypto.keyexchange
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 09-Oct-2020
*/
const val crypto_kx_PUBLICKEYBYTES = 32
const val crypto_kx_SECRETKEYBYTES = 32
const val crypto_kx_SEEDBYTES = 32
const val crypto_kx_SESSIONKEYBYTES = 32
const val crypto_kx_PRIMITIVE = "x25519blake2b"
data class KeyExchangeKeyPair(val publicKey: UByteArray, val secretKey: UByteArray)
data class KeyExchangeSessionKeyPair(val receiveKey: UByteArray, val sendKey: UByteArray)
expect object KeyExchange {
fun clientSessionKeys(clientPublicKey: UByteArray, clientSecretKey: UByteArray, serverPublicKey: UByteArray) : KeyExchangeSessionKeyPair
fun keypair() : KeyExchangeKeyPair
fun seedKeypair(seed: UByteArray) : KeyExchangeKeyPair
fun serverSessionKeys(serverPublicKey: UByteArray, serverSecretKey: UByteArray, clientPublicKey: UByteArray) : KeyExchangeSessionKeyPair
}

View File

@ -0,0 +1,74 @@
package com.ionspin.kotlin.crypto.keyexchange
import com.ionspin.kotlin.crypto.util.LibsodiumRandom
import com.ionspin.kotlin.crypto.util.toHexString
import kotlin.test.Test
import kotlin.test.assertTrue
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 09-Oct-2020
*/
class KeyExchangeTest {
@Test
fun testKeyExchange() {
val keypairClient = KeyExchange.keypair()
val keypairServer = KeyExchange.keypair()
val clientSessionKeyPair = KeyExchange.clientSessionKeys(
keypairClient.publicKey,
keypairClient.secretKey,
keypairServer.publicKey
)
val serverSessionKeyPair = KeyExchange.serverSessionKeys(
keypairServer.publicKey,
keypairServer.secretKey,
keypairClient.publicKey
)
println(clientSessionKeyPair.receiveKey.toHexString())
println(clientSessionKeyPair.sendKey.toHexString())
println(serverSessionKeyPair.receiveKey.toHexString())
println(serverSessionKeyPair.sendKey.toHexString())
assertTrue {
clientSessionKeyPair.sendKey.contentEquals(serverSessionKeyPair.receiveKey)
}
assertTrue {
clientSessionKeyPair.receiveKey.contentEquals(serverSessionKeyPair.sendKey)
}
}
@Test
fun testKeyExchangeSeeded() {
val seed = UByteArray(crypto_kx_SEEDBYTES) { 7U }
val keypairClient = KeyExchange.seedKeypair(seed)
val keypairServer = KeyExchange.seedKeypair(seed)
println(keypairClient.publicKey.toHexString())
println(keypairClient.secretKey.toHexString())
println(keypairServer.publicKey.toHexString())
println(keypairServer.secretKey.toHexString())
assertTrue { keypairClient.secretKey.contentEquals(keypairServer.secretKey) }
assertTrue { keypairClient.secretKey.contentEquals(keypairServer.secretKey) }
val clientSessionKeyPair = KeyExchange.clientSessionKeys(
keypairClient.publicKey,
keypairClient.secretKey,
keypairServer.publicKey
)
val serverSessionKeyPair = KeyExchange.serverSessionKeys(
keypairServer.publicKey,
keypairServer.secretKey,
keypairClient.publicKey
)
println(clientSessionKeyPair.receiveKey.toHexString())
println(clientSessionKeyPair.sendKey.toHexString())
println(serverSessionKeyPair.receiveKey.toHexString())
println(serverSessionKeyPair.sendKey.toHexString())
assertTrue {
clientSessionKeyPair.sendKey.contentEquals(serverSessionKeyPair.receiveKey)
}
assertTrue {
clientSessionKeyPair.receiveKey.contentEquals(serverSessionKeyPair.sendKey)
}
}
}

View File

@ -0,0 +1,99 @@
package com.ionspin.kotlin.crypto.keyexchange
import com.ionspin.kotlin.crypto.util.toPtr
import kotlinx.cinterop.pin
import libsodium.crypto_kx_client_session_keys
import libsodium.crypto_kx_keypair
import libsodium.crypto_kx_seed_keypair
import libsodium.crypto_kx_server_session_keys
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 09-Oct-2020
*/
actual object KeyExchange {
actual fun clientSessionKeys(clientPublicKey: UByteArray, clientSecretKey: UByteArray, serverPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
val clientPublicKeyPinned = clientPublicKey.pin()
val clientSecretKeyPinned = clientSecretKey.pin()
val serverPublicKeyPinned = serverPublicKey.pin()
val receiveKeyPinned = receiveKey.pin()
val sendKeyPinned = sendKey.pin()
crypto_kx_client_session_keys(
receiveKeyPinned.toPtr(),
sendKeyPinned.toPtr(),
clientPublicKeyPinned.toPtr(),
clientSecretKeyPinned.toPtr(),
serverPublicKeyPinned.toPtr()
)
clientPublicKeyPinned.unpin()
clientSecretKeyPinned.unpin()
serverPublicKeyPinned.unpin()
receiveKeyPinned.unpin()
sendKeyPinned.unpin()
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
}
actual fun keypair() : KeyExchangeKeyPair {
val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES)
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
val publicKeyPinned = publicKey.pin()
val secretKeyPinned = secretKey.pin()
crypto_kx_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr())
publicKeyPinned.unpin()
secretKeyPinned.unpin()
return KeyExchangeKeyPair(publicKey, secretKey)
}
actual fun seedKeypair(seed: UByteArray) : KeyExchangeKeyPair {
val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES)
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
val seedPinned = seed.pin()
val publicKeyPinned = publicKey.pin()
val secretKeyPinned = secretKey.pin()
crypto_kx_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr())
publicKeyPinned.unpin()
secretKeyPinned.unpin()
seedPinned.unpin()
return KeyExchangeKeyPair(publicKey, secretKey)
}
actual fun serverSessionKeys(serverPublicKey: UByteArray, serverSecretKey: UByteArray, clientPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
val serverPublicKeyPinned = serverPublicKey.pin()
val serverSecretKeyPinned = serverSecretKey.pin()
val clientPublicKeyPinned = clientPublicKey.pin()
val receiveKeyPinned = receiveKey.pin()
val sendKeyPinned = sendKey.pin()
crypto_kx_server_session_keys(
receiveKeyPinned.toPtr(),
sendKeyPinned.toPtr(),
serverPublicKeyPinned.toPtr(),
serverSecretKeyPinned.toPtr(),
clientPublicKeyPinned.toPtr()
)
serverPublicKeyPinned.unpin()
serverSecretKeyPinned.unpin()
clientPublicKeyPinned.unpin()
receiveKeyPinned.unpin()
sendKeyPinned.unpin()
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
}
}

@ -1 +1 @@
Subproject commit b8e38c647aa45ced4554e2629dbf3f0d73b8d944
Subproject commit 23cb95e6326e5f8d796ee1f53fded769250e7626

View File

@ -254,10 +254,10 @@
| crypto_kdf_blake2b_BYTES_MIN | |
| crypto_kdf_blake2b_CONTEXTBYTES | |
| crypto_kdf_blake2b_KEYBYTES | |
| crypto_kx_PUBLICKEYBYTES | |
| crypto_kx_SECRETKEYBYTES | |
| crypto_kx_SEEDBYTES | |
| crypto_kx_SESSIONKEYBYTES | |
| crypto_kx_PUBLICKEYBYTES | :heavy_check_mark: |
| crypto_kx_SECRETKEYBYTES | :heavy_check_mark: |
| crypto_kx_SEEDBYTES | :heavy_check_mark: |
| crypto_kx_SESSIONKEYBYTES | :heavy_check_mark: |
| crypto_onetimeauth_BYTES | |
| crypto_onetimeauth_KEYBYTES | |
| crypto_onetimeauth_poly1305_BYTES | |