diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/stream/Stream.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/stream/Stream.kt index 1f4ab72..f495685 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/stream/Stream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/stream/Stream.kt @@ -9,13 +9,22 @@ const val crypto_stream_chacha20_KEYBYTES = 32 const val crypto_stream_chacha20_NONCEBYTES = 8 const val crypto_stream_chacha20_ietf_KEYBYTES = 32 const val crypto_stream_chacha20_ietf_NONCEBYTES = 12 +const val crypto_stream_xchacha20_NONCEBYTES = 24 +const val crypto_stream_xchacha20_KEYBYTES = 32 expect object Stream { - fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray) : UByteArray - fun chacha20IetfXor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray - fun chacha20IetfXorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray fun chacha20Keygen() : UByteArray + + fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray) : UByteArray fun chacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray fun chacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray + + fun chacha20IetfXor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + fun chacha20IetfXorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray + + fun xChacha20Keygen() : UByteArray + + fun xChacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + fun xChacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/stream/StreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/stream/StreamTest.kt index 3003444..3d365fb 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/stream/StreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/stream/StreamTest.kt @@ -68,4 +68,26 @@ class StreamTest { } } } + + @Test + fun testXChaCha20IetfStream() = runTest { + LibsodiumInitializer.initializeWithCallback { + val message = "This is a cha cha message".encodeToUByteArray() + val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_xchacha20_NONCEBYTES, seed) + val key = Stream.xChacha20Keygen() + val encryptedUsingLibsodium = Stream.xChacha20Xor(message, nonce, key) + val encryptedUsingLibsodiumWithInitialCounter = Stream.xChacha20XorIc(message, nonce, 0U, key) + println(encryptedUsingLibsodium.toHexString()) + println(encryptedUsingLibsodiumWithInitialCounter.toHexString()) + assertTrue { + encryptedUsingLibsodium.contentEquals(encryptedUsingLibsodiumWithInitialCounter) + } + val decryptedUsingLibsodium = Stream.xChacha20Xor(encryptedUsingLibsodium, nonce, key) + println(message.toHexString()) + println(decryptedUsingLibsodium.toHexString()) + assertTrue { + decryptedUsingLibsodium.contentEquals(message) + } + } + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index a3aa2c5..3b4fe47 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -232,6 +232,10 @@ interface JsSodiumInterface { 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 + fun crypto_stream_xchacha20_keygen() : Uint8Array + fun crypto_stream_xchacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_stream_xchacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array + // ---- Stream end ---- // ---- Scalar multiplication ---- diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt index 4845654..5e84813 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt @@ -79,4 +79,42 @@ actual object Stream { return result.toUByteArray() } + + actual fun xChacha20Keygen(): UByteArray { + val result = getSodium().crypto_stream_xchacha20_keygen() + + return result.toUByteArray() + } + + actual fun xChacha20Xor( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val result = getSodium().crypto_stream_xchacha20_xor( + message.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + + return result.toUByteArray() + } + + actual fun xChacha20XorIc( + message: UByteArray, + nonce: UByteArray, + initialCounter: ULong, + key: UByteArray + ): UByteArray { + val result = getSodium().crypto_stream_xchacha20_xor_ic( + message.toUInt8Array(), + nonce.toUInt8Array(), + initialCounter.toUInt(), + key.toUInt8Array() + ) + + return result.toUByteArray() + } + + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/JnaLibsodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/JnaLibsodiumInterface.kt index f107f4a..4592ffc 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/JnaLibsodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/JnaLibsodiumInterface.kt @@ -78,6 +78,22 @@ interface JnaLibsodiumInterface : Library { fun randombytes_buf(buffer: ByteArray, bufferSize: Int) + // void randombytes_buf_deterministic(void * const buf, const size_t size, + // const unsigned char seed[randombytes_SEEDBYTES]) + fun randombytes_buf_deterministic( + buffer: ByteArray, + size: Int, + seed: ByteArray + ) + + // uint32_t randombytes_random(void) + fun randombytes_random() : Long + + // uint32_t randombytes_uniform(const uint32_t upper_bound); + fun randombytes_uniform( + upperBound: Long + ) : Long + // void sodium_memzero(void * const pnt, const size_t len); fun sodium_memzero(array: ByteArray, len: Int) @@ -917,7 +933,8 @@ interface JnaLibsodiumInterface : Library { message: ByteArray, messageLength: Long, secretKey: ByteArray - ) : Int + ): Int + // int crypto_sign_open( // unsigned char *m, unsigned long long *mlen_p, // const unsigned char *sm, unsigned long long smlen, @@ -928,7 +945,8 @@ interface JnaLibsodiumInterface : Library { signedMessage: ByteArray, signedMessageLength: Long, publicKey: ByteArray - ) : Int + ): Int + // int crypto_sign_detached( // unsigned char *sig, unsigned long long *siglen_p, // const unsigned char *m, unsigned long long mlen, @@ -939,7 +957,8 @@ interface JnaLibsodiumInterface : Library { message: ByteArray, messageLength: Long, secretKey: ByteArray - ) : Int + ): Int + // int crypto_sign_verify_detached( // const unsigned char *sig, // const unsigned char *m, @@ -950,33 +969,36 @@ interface JnaLibsodiumInterface : Library { message: ByteArray, messageLength: Long, publicKey: ByteArray - ) : Int + ): Int + // int crypto_sign_ed25519_pk_to_curve25519( // unsigned char *curve25519_pk, // const unsigned char *ed25519_pk) fun crypto_sign_ed25519_pk_to_curve25519( curve25519PublicKey: ByteArray, ed25519PublicKey: ByteArray - ) : Int + ): Int // int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, // const unsigned char *ed25519_sk) fun crypto_sign_ed25519_sk_to_curve25519( curve25519SecretKey: ByteArray, ed25519SecretKey: ByteArray - ) : Int + ): Int // int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk) fun crypto_sign_ed25519_sk_to_pk( ed25519PublicKey: ByteArray, ed25519SecretKey: ByteArray - ) : Int + ): Int + // int crypto_sign_ed25519_sk_to_seed(unsigned char *seed, // const unsigned char *sk) fun crypto_sign_ed25519_sk_to_seed( seed: ByteArray, ed25519SecretKey: ByteArray - ) : Int + ): Int + // int crypto_sign_init(crypto_sign_state *state); fun crypto_sign_init(state: Ed25519SignatureState) @@ -986,7 +1008,8 @@ interface JnaLibsodiumInterface : Library { state: Ed25519SignatureState, message: ByteArray, messageLength: Long - ) : Int + ): Int + // int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, // unsigned long long *siglen_p, // const unsigned char *sk) @@ -995,78 +1018,261 @@ interface JnaLibsodiumInterface : Library { signature: ByteArray, signatureLength: LongArray?, secretKey: ByteArray - ) : Int + ): Int + // int crypto_sign_final_verify(crypto_sign_state *state, const unsigned char *sig, // const unsigned char *pk) fun crypto_sign_final_verify( state: Ed25519SignatureState, signature: ByteArray, publicKey: ByteArray - ) : Int + ): Int + // int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) fun crypto_sign_keypair( publicKey: ByteArray, secretKey: ByteArray ) + // int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, // const unsigned char *seed) fun crypto_sign_seed_keypair( publicKey: ByteArray, secretKey: ByteArray, seed: ByteArray - ) : Int + ): Int - - - -// -// // // ---- Sign end ---- // // + + // // ---- KDF ---- // -// fun crypto_kdf_derive_from_key(subkey_len: UInt, subkeyId : UInt, ctx: String, key: Uint8Array) : Uint8Array -// fun crypto_kdf_keygen() : Uint8Array + + // int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, + // uint64_t subkey_id, + // const char ctx[crypto_kdf_CONTEXTBYTES], + // const unsigned char key[crypto_kdf_KEYBYTES]) + fun crypto_kdf_derive_from_key( + subkey: ByteArray, + subkeyLength: Int, + subkeyId: Long, + context: ByteArray, + key: ByteArray + ) + + // void crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]) + fun crypto_kdf_keygen( + key: ByteArray + ) // // // ---- KDF end ----- // -// // ---- Password hashing ---- -// -// fun crypto_pwhash(keyLength : UInt, password : Uint8Array, salt: Uint8Array, opsLimit: UInt, memLimit: UInt, algorithm: UInt) : Uint8Array -// fun crypto_pwhash_str(password: Uint8Array, opsLimit: UInt, memLimit: UInt) : String -// fun crypto_pwhash_str_needs_rehash(hashedPassword: String, opsLimit: UInt, memLimit: UInt) : Boolean -// fun crypto_pwhash_str_verify(hashedPassword: String, password: Uint8Array) : Boolean + + + // // ---- Password hashing ---- // + // int crypto_pwhash(unsigned char * const out, unsigned long long outlen, + // const char * const passwd, unsigned long long passwdlen, + // const unsigned char * const salt, + // unsigned long long opslimit, size_t memlimit, int alg) + fun crypto_pwhash( + output: ByteArray, + outputLength: Long, + password: String, + passwordLength: Long, + salt: ByteArray, + opslimit: Long, + memlimit: Long, + algorithm : Int + ) : Int + + // int crypto_pwhash_str(char out[crypto_pwhash_STRBYTES], + // const char * const passwd, unsigned long long passwdlen, + // unsigned long long opslimit, size_t memlimit) + fun crypto_pwhash_str( + output: ByteArray, + password: String, + passwordLength: Long, + opslimit: Long, + memlimit: Long + ) : Int + + // int crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES], + // unsigned long long opslimit, size_t memlimit) + fun crypto_pwhash_str_needs_rehash( + output: ByteArray, + opslimit: Long, + memlimit: Long + ) : Int + // int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], + // const char * const passwd, + // unsigned long long passwdlen) + fun crypto_pwhash_str_verify( + hash: ByteArray, + password: String, + passwordLength: Long + ) : Int + // // // ---- Password hashing end ---- // -// -// // ---- > ---- Random ---- < ----- -// -// fun randombytes_buf(length: UInt) : Uint8Array -// fun randombytes_buf_deterministic(length: UInt, seed : Uint8Array) : Uint8Array -// fun randombytes_random() : UInt -// fun randombytes_uniform(upper_bound: UInt) : UInt -// -// // ---- 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 + + + // int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + // unsigned char sk[crypto_kx_SECRETKEYBYTES]) + fun crypto_kx_keypair( + publicKey: ByteArray, + secretKey: ByteArray + ) + + + // int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + // unsigned char sk[crypto_kx_SECRETKEYBYTES], + // const unsigned char seed[crypto_kx_SEEDBYTES]) + fun crypto_kx_seed_keypair( + publicKey: ByteArray, + secretKey: ByteArray, + seed: ByteArray + ) + // int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + // unsigned char tx[crypto_kx_SESSIONKEYBYTES], + // const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], + // const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], + // const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) + fun crypto_kx_client_session_keys( + receiveKey : ByteArray, + sendKey: ByteArray, + clientPublicKey: ByteArray, + clientSecretKey: ByteArray, + serverPublicKey: ByteArray + ) + // int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + // unsigned char tx[crypto_kx_SESSIONKEYBYTES], + // const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], + // const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], + // const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) + fun crypto_kx_server_session_keys( + receiveKey: ByteArray, + sendKey: ByteArray, + serverPublicKey: ByteArray, + serverSecretKey: ByteArray, + clientPublicKey: ByteArray + ) + // // // ---- 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 + + // int crypto_stream_chacha20(unsigned char *c, unsigned long long clen, + // const unsigned char *n, const unsigned char *k) + fun crypto_stream_chacha20( + stream: ByteArray, + streamLength: Long, + nonce: ByteArray, + key: ByteArray + ) : Int + // int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, + // unsigned long long mlen, const unsigned char *n, + // const unsigned char *k) + fun crypto_stream_chacha20_xor( + ciphertext: ByteArray, + message: ByteArray, + messageLength: Long, + nonce: ByteArray, + key: ByteArray + ) : Int + // int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m, + // unsigned long long mlen, + // const unsigned char *n, uint64_t ic, + // const unsigned char *k) + fun crypto_stream_chacha20_xor_ic( + ciphertext: ByteArray, + message: ByteArray, + messageLength: Long, + nonce: ByteArray, + initialCounter : Long, + key: ByteArray + ) : Int + + // int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, + // const unsigned char *n, const unsigned char *k) + fun crypto_stream_chacha20_ietf( + stream: ByteArray, + streamLength: Long, + nonce: ByteArray, + key: ByteArray + ) : Int + + // int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, + // unsigned long long mlen, const unsigned char *n, + // const unsigned char *k) + fun crypto_stream_chacha20_ietf_xor( + ciphertext: ByteArray, + message: ByteArray, + messageLength: Long, + nonce: ByteArray, + key: ByteArray + ) : Int + + // int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, + // unsigned long long mlen, + // const unsigned char *n, uint32_t ic, + // const unsigned char *k) + fun crypto_stream_chacha20_ietf_xor_ic( + ciphertext: ByteArray, + message: ByteArray, + messageLength: Long, + nonce: ByteArray, + initialCounter : Long, + key: ByteArray + ) : Int + + // void crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES]) + fun crypto_stream_chacha20_keygen(key: ByteArray) + + // int crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, + // const unsigned char *n, const unsigned char *k) + fun crypto_stream_xchacha20( + stream: ByteArray, + streamLength: Long, + nonce: ByteArray, + key: ByteArray + ) : Int + + // int crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, + // unsigned long long mlen, const unsigned char *n, + // const unsigned char *k) + fun crypto_stream_xchacha20_xor( + ciphertext: ByteArray, + message: ByteArray, + messageLength: Long, + nonce: ByteArray, + key: ByteArray + ) : Int + + // int crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, + // unsigned long long mlen, + // const unsigned char *n, uint64_t ic, + // const unsigned char *k) + fun crypto_stream_xchacha20_xor_ic( + ciphertext: ByteArray, + message: ByteArray, + messageLength: Long, + nonce: ByteArray, + initialCounter : Long, + key: ByteArray + ) : Int + // void crypto_stream_xchacha20_keygen(unsigned char k[crypto_stream_xchacha20_KEYBYTES]) + fun crypto_stream_xchacha20_keygen(key: ByteArray) + + // // // ---- Stream end ---- // diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/keyexchange/KeyExchange.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/keyexchange/KeyExchange.kt index e140bc2..5bcc890 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/keyexchange/KeyExchange.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/keyexchange/KeyExchange.kt @@ -1,13 +1,13 @@ package com.ionspin.kotlin.crypto.keyexchange -import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna 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( + sodiumJna.crypto_kx_client_session_keys( receiveKey.asByteArray(), sendKey.asByteArray(), clientPublicKey.asByteArray(), @@ -25,7 +25,7 @@ actual object KeyExchange { val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES) - sodium.crypto_kx_keypair(publicKey.asByteArray(), secretKey.asByteArray()) + sodiumJna.crypto_kx_keypair(publicKey.asByteArray(), secretKey.asByteArray()) return KeyExchangeKeyPair(publicKey, secretKey) @@ -35,7 +35,7 @@ actual object KeyExchange { val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES) val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES) - sodium.crypto_kx_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray()) + sodiumJna.crypto_kx_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray()) return KeyExchangeKeyPair(publicKey, secretKey) } @@ -44,7 +44,7 @@ actual object KeyExchange { val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES) val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES) - sodium.crypto_kx_server_session_keys( + sodiumJna.crypto_kx_server_session_keys( receiveKey.asByteArray(), sendKey.asByteArray(), serverPublicKey.asByteArray(), diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt index 93999ca..36aabce 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -1,6 +1,6 @@ package com.ionspin.kotlin.crypto.pwhash -import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna import com.sun.jna.NativeLong actual object PasswordHash { @@ -10,7 +10,7 @@ actual object PasswordHash { * PASSWD_MIN and crypto_pwhash_PASSWD_MAX. outlen should be at least crypto_pwhash_BYTES_MIN = 16 (128 bits) and * at most crypto_pwhash_BYTES_MAX. * - * See https://libsodium.gitbook.io/doc/password_hashing/default_phf for more details + * See https://libsodiumJna.gitbook.io/doc/password_hashing/default_phf for more details */ actual fun pwhash( outputLength: Int, @@ -22,14 +22,14 @@ actual object PasswordHash { ): UByteArray { val hashedPassword = UByteArray(outputLength) - sodium.crypto_pwhash( + sodiumJna.crypto_pwhash( hashedPassword.asByteArray(), outputLength.toLong(), - password.encodeToByteArray(), + password, password.length.toLong(), salt.asByteArray(), opsLimit.toLong(), - NativeLong(memLimit.toLong()), + memLimit.toLong(), algorithm ) @@ -48,12 +48,12 @@ actual object PasswordHash { */ actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { val output = ByteArray(crypto_pwhash_STRBYTES) - sodium.crypto_pwhash_str( + sodiumJna.crypto_pwhash_str( output, - password.encodeToByteArray(), + password, password.length.toLong(), opslimit.toLong(), - NativeLong(memlimit.toLong()) + memlimit.toLong() ) return output.asUByteArray() } @@ -69,10 +69,10 @@ actual object PasswordHash { opslimit: ULong, memlimit: Int ): Int { - return sodium.crypto_pwhash_str_needs_rehash( + return sodiumJna.crypto_pwhash_str_needs_rehash( passwordHash.asByteArray(), opslimit.toLong(), - NativeLong(memlimit.toLong()) + memlimit.toLong() ) } @@ -82,9 +82,9 @@ actual object PasswordHash { * It returns 0 if the verification succeeds, and -1 on error. */ actual fun strVerify(passwordHash: UByteArray, password: String): Boolean { - val result = sodium.crypto_pwhash_str_verify( + val result = sodiumJna.crypto_pwhash_str_verify( passwordHash.asByteArray(), - password.encodeToByteArray(), + password, password.length.toLong() ) diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt index 32d17f6..a3fbc60 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt @@ -1,12 +1,12 @@ package com.ionspin.kotlin.crypto.stream -import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna 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()) + sodiumJna.crypto_stream_chacha20(result.asByteArray(), clen.toLong(), nonce.asByteArray(), key.asByteArray()) return result } @@ -18,7 +18,7 @@ actual object Stream { ): UByteArray { val result = UByteArray(message.size) - sodium.crypto_stream_chacha20_ietf_xor( + sodiumJna.crypto_stream_chacha20_ietf_xor( result.asByteArray(), message.asByteArray(), message.size.toLong(), @@ -37,7 +37,7 @@ actual object Stream { ): UByteArray { val result = UByteArray(message.size) - sodium.crypto_stream_chacha20_ietf_xor_ic( + sodiumJna.crypto_stream_chacha20_ietf_xor_ic( result.asByteArray(), message.asByteArray(), message.size.toLong(), @@ -52,7 +52,7 @@ actual object Stream { actual fun chacha20Keygen(): UByteArray { val result = UByteArray(crypto_stream_chacha20_KEYBYTES) - sodium.crypto_stream_chacha20_keygen(result.asByteArray()) + sodiumJna.crypto_stream_chacha20_keygen(result.asByteArray()) return result } @@ -64,7 +64,7 @@ actual object Stream { ): UByteArray { val result = UByteArray(message.size) - sodium.crypto_stream_chacha20_xor( + sodiumJna.crypto_stream_chacha20_xor( result.asByteArray(), message.asByteArray(), message.size.toLong(), @@ -83,7 +83,7 @@ actual object Stream { ): UByteArray { val result = UByteArray(message.size) - sodium.crypto_stream_chacha20_xor_ic( + sodiumJna.crypto_stream_chacha20_xor_ic( result.asByteArray(), message.asByteArray(), message.size.toLong(), @@ -93,6 +93,52 @@ actual object Stream { ) + return result + } + + actual fun xChacha20Keygen(): UByteArray { + val result = UByteArray(crypto_stream_chacha20_KEYBYTES) + + sodiumJna.crypto_stream_xchacha20_keygen(result.asByteArray()) + + return result + } + + actual fun xChacha20Xor( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val result = UByteArray(message.size) + + sodiumJna.crypto_stream_xchacha20_xor( + result.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + + return result + } + + actual fun xChacha20XorIc( + message: UByteArray, + nonce: UByteArray, + initialCounter: ULong, + key: UByteArray + ): UByteArray { + val result = UByteArray(message.size) + + sodiumJna.crypto_stream_xchacha20_xor_ic( + result.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + initialCounter.toLong(), + key.asByteArray() + ) + return result } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt index 627b0a9..1819324 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -1,6 +1,5 @@ package com.ionspin.kotlin.crypto.util -import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna /** @@ -28,7 +27,7 @@ actual object LibsodiumRandom { */ actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { val result = ByteArray(size) - sodium.randombytes_buf_deterministic(result, size, seed.asByteArray()) + sodiumJna.randombytes_buf_deterministic(result, size, seed.asByteArray()) return result.asUByteArray() } @@ -38,7 +37,7 @@ actual object LibsodiumRandom { actual fun random(): UInt { //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 //Using temporary forked and fixed build until pull request is accepted in original repo - return sodium.randombytes_random().toUInt() + return sodiumJna.randombytes_random().toUInt() } @@ -49,9 +48,7 @@ actual object LibsodiumRandom { * upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0 */ actual fun uniform(upperBound: UInt): UInt { - //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 - //Using temporary fixed build until pull request is accepted - return sodium.randombytes_uniform(upperBound.toInt()).toUInt() + return sodiumJna.randombytes_uniform(upperBound.toLong()).toUInt() } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt index ff37390..72d9c53 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/stream/Stream.kt @@ -10,6 +10,9 @@ import libsodium.crypto_stream_chacha20_ietf_xor_ic import libsodium.crypto_stream_chacha20_keygen import libsodium.crypto_stream_chacha20_xor import libsodium.crypto_stream_chacha20_xor_ic +import libsodium.crypto_stream_xchacha20_keygen +import libsodium.crypto_stream_xchacha20_xor +import libsodium.crypto_stream_xchacha20_xor_ic actual object Stream { actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray { @@ -149,4 +152,71 @@ actual object Stream { return result } + + actual fun xChacha20Keygen(): UByteArray { + val result = UByteArray(crypto_stream_xchacha20_KEYBYTES) + val resultPinned = result.pin() + + crypto_stream_xchacha20_keygen(resultPinned.toPtr()) + + resultPinned.unpin() + + return result + } + + actual fun xChacha20Xor( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val result = UByteArray(message.size) + val messagePinned = message.pin() + val resultPinned = result.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + crypto_stream_xchacha20_xor( + resultPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + resultPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return result + } + + actual fun xChacha20XorIc( + message: UByteArray, + nonce: UByteArray, + initialCounter: ULong, + key: UByteArray + ): UByteArray { + val result = UByteArray(message.size) + val messagePinned = message.pin() + val resultPinned = result.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + crypto_stream_xchacha20_xor_ic( + resultPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + initialCounter.convert(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + resultPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return result + } } diff --git a/supported_bindings_list.md b/supported_bindings_list.md index ca958d0..59a530f 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -143,9 +143,9 @@ native libsodium library. | crypto_stream_chacha20_xor | :heavy_check_mark: | | crypto_stream_chacha20_xor_ic | :heavy_check_mark: | | crypto_stream_keygen | Other XSalsa20 primitives are not available, so I'm leaving this out as well| -| crypto_stream_xchacha20_keygen | not present in LazySodium Android | -| crypto_stream_xchacha20_xor | not present in LazySodium Android| -| crypto_stream_xchacha20_xor_ic | not present in LazySodium Android | +| crypto_stream_xchacha20_keygen | :heavy_check_mark: | +| crypto_stream_xchacha20_xor | :heavy_check_mark: | +| crypto_stream_xchacha20_xor_ic | :heavy_check_mark: | | randombytes_buf | :heavy_check_mark: | | randombytes_buf_deterministic | :heavy_check_mark: | | randombytes_close | not present in LazySodium |