Merge pull request #20 from ionspin/sodium-update-kx-impl
Sodium update kx impl
This commit is contained in:
commit
8d782d2932
@ -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
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.ionspin.kotlin.crypto.keyexchange
|
||||
|
||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer
|
||||
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() {
|
||||
LibsodiumInitializer.initializeWithCallback {
|
||||
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() {
|
||||
LibsodiumInitializer.initializeWithCallback {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -40,6 +40,9 @@ class SignatureTest {
|
||||
assertFailsWith(InvalidSignatureException::class) {
|
||||
val tamperedSignature = signature.copyOf()
|
||||
tamperedSignature[crypto_sign_BYTES - 1] = 0U
|
||||
tamperedSignature[1] = 0U
|
||||
tamperedSignature[15] = 0U
|
||||
tamperedSignature[33] = 0U
|
||||
Signature.verifyDetached(tamperedSignature, message, keys.publicKey)
|
||||
}
|
||||
}
|
||||
@ -66,4 +69,4 @@ class SignatureTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,6 +216,12 @@ interface JsSodiumInterface {
|
||||
|
||||
// ---- Utils end ----
|
||||
|
||||
// ---- Key exchange ----
|
||||
fun crypto_kx_client_session_keys(clientPublicKey: Uint8Array, clientSecretKey: Uint8Array, serverPublicKey: Uint8Array) : dynamic
|
||||
fun crypto_kx_keypair() : dynamic
|
||||
fun crypto_kx_seed_keypair(seed: Uint8Array) : dynamic
|
||||
fun crypto_kx_server_session_keys(serverPublicKey: Uint8Array, serverSecretKey: Uint8Array, clientPublicKey: Uint8Array) : dynamic
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,57 @@
|
||||
package com.ionspin.kotlin.crypto.keyexchange
|
||||
|
||||
import com.ionspin.kotlin.crypto.getSodium
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
|
||||
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
|
||||
import org.khronos.webgl.Uint8Array
|
||||
|
||||
actual object KeyExchange {
|
||||
actual fun clientSessionKeys(clientPublicKey: UByteArray, clientSecretKey: UByteArray, serverPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
|
||||
|
||||
|
||||
val result = getSodium().crypto_kx_client_session_keys(
|
||||
clientPublicKey.toUInt8Array(),
|
||||
clientSecretKey.toUInt8Array(),
|
||||
serverPublicKey.toUInt8Array()
|
||||
)
|
||||
|
||||
val receiveKey = (result.sharedRx as Uint8Array).toUByteArray()
|
||||
val sendKey = (result.sharedTx as Uint8Array).toUByteArray()
|
||||
|
||||
|
||||
|
||||
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
|
||||
}
|
||||
|
||||
actual fun keypair() : KeyExchangeKeyPair {
|
||||
val result = getSodium().crypto_kx_keypair()
|
||||
|
||||
val publicKey = (result.publicKey as Uint8Array).toUByteArray()
|
||||
val secretKey = (result.privateKey as Uint8Array).toUByteArray()
|
||||
|
||||
return KeyExchangeKeyPair(publicKey, secretKey)
|
||||
}
|
||||
|
||||
actual fun seedKeypair(seed: UByteArray) : KeyExchangeKeyPair {
|
||||
val result = getSodium().crypto_kx_seed_keypair(seed.toUInt8Array())
|
||||
|
||||
val publicKey = (result.publicKey as Uint8Array).toUByteArray()
|
||||
val secretKey = (result.privateKey as Uint8Array).toUByteArray()
|
||||
|
||||
return KeyExchangeKeyPair(publicKey, secretKey)
|
||||
}
|
||||
|
||||
actual fun serverSessionKeys(serverPublicKey: UByteArray, serverSecretKey: UByteArray, clientPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
|
||||
|
||||
val result = getSodium().crypto_kx_server_session_keys(
|
||||
serverPublicKey.toUInt8Array(),
|
||||
serverSecretKey.toUInt8Array(),
|
||||
clientPublicKey.toUInt8Array()
|
||||
)
|
||||
|
||||
val receiveKey = (result.sharedRx as Uint8Array).toUByteArray()
|
||||
val sendKey = (result.sharedTx as Uint8Array).toUByteArray()
|
||||
|
||||
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.ionspin.kotlin.crypto.keyexchange
|
||||
|
||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
|
||||
|
||||
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)
|
||||
|
||||
sodium.crypto_kx_client_session_keys(
|
||||
receiveKey.asByteArray(),
|
||||
sendKey.asByteArray(),
|
||||
clientPublicKey.asByteArray(),
|
||||
clientSecretKey.asByteArray(),
|
||||
serverPublicKey.asByteArray()
|
||||
)
|
||||
|
||||
|
||||
|
||||
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
|
||||
}
|
||||
|
||||
actual fun keypair() : KeyExchangeKeyPair {
|
||||
val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES)
|
||||
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
|
||||
|
||||
|
||||
sodium.crypto_kx_keypair(publicKey.asByteArray(), secretKey.asByteArray())
|
||||
|
||||
|
||||
return KeyExchangeKeyPair(publicKey, secretKey)
|
||||
}
|
||||
|
||||
actual fun seedKeypair(seed: UByteArray) : KeyExchangeKeyPair {
|
||||
val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES)
|
||||
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
|
||||
|
||||
sodium.crypto_kx_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
|
||||
|
||||
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)
|
||||
|
||||
sodium.crypto_kx_server_session_keys(
|
||||
receiveKey.asByteArray(),
|
||||
sendKey.asByteArray(),
|
||||
serverPublicKey.asByteArray(),
|
||||
serverSecretKey.asByteArray(),
|
||||
clientPublicKey.asByteArray()
|
||||
)
|
||||
|
||||
return KeyExchangeSessionKeyPair(receiveKey, sendKey)
|
||||
}
|
||||
}
|
@ -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 b0ed382e71ff52e5ecef8691d62dfe7a04a803f7
|
@ -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 | |
|
||||
|
Loading…
x
Reference in New Issue
Block a user