Added _kx_ and nateive impl, updated libsodium submodule to latest commit
This commit is contained in:
		
							parent
							
								
									f4d6d941c9
								
							
						
					
					
						commit
						bd173f422f
					
				@ -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,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)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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