Added a bunch, also added xchacha20 ic and xor

This commit is contained in:
Ugljesa Jovanovic 2021-02-23 19:54:07 +01:00
parent 354c0c2fd6
commit 574377da3c
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
11 changed files with 473 additions and 81 deletions

View File

@ -9,13 +9,22 @@ const val crypto_stream_chacha20_KEYBYTES = 32
const val crypto_stream_chacha20_NONCEBYTES = 8 const val crypto_stream_chacha20_NONCEBYTES = 8
const val crypto_stream_chacha20_ietf_KEYBYTES = 32 const val crypto_stream_chacha20_ietf_KEYBYTES = 32
const val crypto_stream_chacha20_ietf_NONCEBYTES = 12 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 { 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 chacha20Keygen() : UByteArray
fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray) : UByteArray
fun chacha20Xor(message : UByteArray, 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 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
} }

View File

@ -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)
}
}
}
} }

View File

@ -232,6 +232,10 @@ interface JsSodiumInterface {
fun crypto_stream_chacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : 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 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 ---- // ---- Stream end ----
// ---- Scalar multiplication ---- // ---- Scalar multiplication ----

View File

@ -79,4 +79,42 @@ actual object Stream {
return result.toUByteArray() 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()
}
} }

View File

@ -78,6 +78,22 @@ interface JnaLibsodiumInterface : Library {
fun randombytes_buf(buffer: ByteArray, bufferSize: Int) 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); // void sodium_memzero(void * const pnt, const size_t len);
fun sodium_memzero(array: ByteArray, len: Int) fun sodium_memzero(array: ByteArray, len: Int)
@ -917,7 +933,8 @@ interface JnaLibsodiumInterface : Library {
message: ByteArray, message: ByteArray,
messageLength: Long, messageLength: Long,
secretKey: ByteArray secretKey: ByteArray
) : Int ): Int
// int crypto_sign_open( // int crypto_sign_open(
// unsigned char *m, unsigned long long *mlen_p, // unsigned char *m, unsigned long long *mlen_p,
// const unsigned char *sm, unsigned long long smlen, // const unsigned char *sm, unsigned long long smlen,
@ -928,7 +945,8 @@ interface JnaLibsodiumInterface : Library {
signedMessage: ByteArray, signedMessage: ByteArray,
signedMessageLength: Long, signedMessageLength: Long,
publicKey: ByteArray publicKey: ByteArray
) : Int ): Int
// int crypto_sign_detached( // int crypto_sign_detached(
// unsigned char *sig, unsigned long long *siglen_p, // unsigned char *sig, unsigned long long *siglen_p,
// const unsigned char *m, unsigned long long mlen, // const unsigned char *m, unsigned long long mlen,
@ -939,7 +957,8 @@ interface JnaLibsodiumInterface : Library {
message: ByteArray, message: ByteArray,
messageLength: Long, messageLength: Long,
secretKey: ByteArray secretKey: ByteArray
) : Int ): Int
// int crypto_sign_verify_detached( // int crypto_sign_verify_detached(
// const unsigned char *sig, // const unsigned char *sig,
// const unsigned char *m, // const unsigned char *m,
@ -950,33 +969,36 @@ interface JnaLibsodiumInterface : Library {
message: ByteArray, message: ByteArray,
messageLength: Long, messageLength: Long,
publicKey: ByteArray publicKey: ByteArray
) : Int ): Int
// int crypto_sign_ed25519_pk_to_curve25519( // int crypto_sign_ed25519_pk_to_curve25519(
// unsigned char *curve25519_pk, // unsigned char *curve25519_pk,
// const unsigned char *ed25519_pk) // const unsigned char *ed25519_pk)
fun crypto_sign_ed25519_pk_to_curve25519( fun crypto_sign_ed25519_pk_to_curve25519(
curve25519PublicKey: ByteArray, curve25519PublicKey: ByteArray,
ed25519PublicKey: ByteArray ed25519PublicKey: ByteArray
) : Int ): Int
// int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, // int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk,
// const unsigned char *ed25519_sk) // const unsigned char *ed25519_sk)
fun crypto_sign_ed25519_sk_to_curve25519( fun crypto_sign_ed25519_sk_to_curve25519(
curve25519SecretKey: ByteArray, curve25519SecretKey: ByteArray,
ed25519SecretKey: ByteArray ed25519SecretKey: ByteArray
) : Int ): Int
// int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk) // int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk)
fun crypto_sign_ed25519_sk_to_pk( fun crypto_sign_ed25519_sk_to_pk(
ed25519PublicKey: ByteArray, ed25519PublicKey: ByteArray,
ed25519SecretKey: ByteArray ed25519SecretKey: ByteArray
) : Int ): Int
// int crypto_sign_ed25519_sk_to_seed(unsigned char *seed, // int crypto_sign_ed25519_sk_to_seed(unsigned char *seed,
// const unsigned char *sk) // const unsigned char *sk)
fun crypto_sign_ed25519_sk_to_seed( fun crypto_sign_ed25519_sk_to_seed(
seed: ByteArray, seed: ByteArray,
ed25519SecretKey: ByteArray ed25519SecretKey: ByteArray
) : Int ): Int
// int crypto_sign_init(crypto_sign_state *state); // int crypto_sign_init(crypto_sign_state *state);
fun crypto_sign_init(state: Ed25519SignatureState) fun crypto_sign_init(state: Ed25519SignatureState)
@ -986,7 +1008,8 @@ interface JnaLibsodiumInterface : Library {
state: Ed25519SignatureState, state: Ed25519SignatureState,
message: ByteArray, message: ByteArray,
messageLength: Long messageLength: Long
) : Int ): Int
// int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, // int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig,
// unsigned long long *siglen_p, // unsigned long long *siglen_p,
// const unsigned char *sk) // const unsigned char *sk)
@ -995,78 +1018,261 @@ interface JnaLibsodiumInterface : Library {
signature: ByteArray, signature: ByteArray,
signatureLength: LongArray?, signatureLength: LongArray?,
secretKey: ByteArray secretKey: ByteArray
) : Int ): Int
// int crypto_sign_final_verify(crypto_sign_state *state, const unsigned char *sig, // int crypto_sign_final_verify(crypto_sign_state *state, const unsigned char *sig,
// const unsigned char *pk) // const unsigned char *pk)
fun crypto_sign_final_verify( fun crypto_sign_final_verify(
state: Ed25519SignatureState, state: Ed25519SignatureState,
signature: ByteArray, signature: ByteArray,
publicKey: ByteArray publicKey: ByteArray
) : Int ): Int
// int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) // int crypto_sign_keypair(unsigned char *pk, unsigned char *sk)
fun crypto_sign_keypair( fun crypto_sign_keypair(
publicKey: ByteArray, secretKey: ByteArray publicKey: ByteArray, secretKey: ByteArray
) )
// int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, // int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk,
// const unsigned char *seed) // const unsigned char *seed)
fun crypto_sign_seed_keypair( fun crypto_sign_seed_keypair(
publicKey: ByteArray, publicKey: ByteArray,
secretKey: ByteArray, secretKey: ByteArray,
seed: ByteArray seed: ByteArray
) : Int ): Int
//
//
// // ---- Sign end ---- // // ---- Sign end ----
// //
// //
// // ---- KDF ---- // // ---- 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 ----- // // ---- KDF end -----
// //
// // ---- Password hashing ----
//
// fun crypto_pwhash(keyLength : UInt, password : Uint8Array, salt: Uint8Array, opsLimit: UInt, memLimit: UInt, algorithm: UInt) : Uint8Array // // ---- Password hashing ----
// 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
// //
// 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 ---- // // ---- 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 ---- // // ---- 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 // int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
// fun crypto_kx_server_session_keys(serverPublicKey: Uint8Array, serverSecretKey: Uint8Array, clientPublicKey: Uint8Array) : dynamic // 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 ---- // // ---- Key exchange end ----
// //
// // -- Stream ---- // // -- 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 // int crypto_stream_chacha20(unsigned char *c, unsigned long long clen,
// fun crypto_stream_chacha20_ietf_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array // const unsigned char *n, const unsigned char *k)
// fun crypto_stream_chacha20_keygen() : Uint8Array fun crypto_stream_chacha20(
// fun crypto_stream_chacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array stream: ByteArray,
// fun crypto_stream_chacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array 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 ---- // // ---- Stream end ----
// //

View File

@ -1,13 +1,13 @@
package com.ionspin.kotlin.crypto.keyexchange package com.ionspin.kotlin.crypto.keyexchange
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object KeyExchange { actual object KeyExchange {
actual fun clientSessionKeys(clientPublicKey: UByteArray, clientSecretKey: UByteArray, serverPublicKey: UByteArray) : KeyExchangeSessionKeyPair { actual fun clientSessionKeys(clientPublicKey: UByteArray, clientSecretKey: UByteArray, serverPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES) val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES) val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
sodium.crypto_kx_client_session_keys( sodiumJna.crypto_kx_client_session_keys(
receiveKey.asByteArray(), receiveKey.asByteArray(),
sendKey.asByteArray(), sendKey.asByteArray(),
clientPublicKey.asByteArray(), clientPublicKey.asByteArray(),
@ -25,7 +25,7 @@ actual object KeyExchange {
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES) 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) return KeyExchangeKeyPair(publicKey, secretKey)
@ -35,7 +35,7 @@ actual object KeyExchange {
val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES) val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES)
val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES) 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) return KeyExchangeKeyPair(publicKey, secretKey)
} }
@ -44,7 +44,7 @@ actual object KeyExchange {
val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES) val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES) val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
sodium.crypto_kx_server_session_keys( sodiumJna.crypto_kx_server_session_keys(
receiveKey.asByteArray(), receiveKey.asByteArray(),
sendKey.asByteArray(), sendKey.asByteArray(),
serverPublicKey.asByteArray(), serverPublicKey.asByteArray(),

View File

@ -1,6 +1,6 @@
package com.ionspin.kotlin.crypto.pwhash 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 import com.sun.jna.NativeLong
actual object PasswordHash { 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 * 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. * 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( actual fun pwhash(
outputLength: Int, outputLength: Int,
@ -22,14 +22,14 @@ actual object PasswordHash {
): UByteArray { ): UByteArray {
val hashedPassword = UByteArray(outputLength) val hashedPassword = UByteArray(outputLength)
sodium.crypto_pwhash( sodiumJna.crypto_pwhash(
hashedPassword.asByteArray(), hashedPassword.asByteArray(),
outputLength.toLong(), outputLength.toLong(),
password.encodeToByteArray(), password,
password.length.toLong(), password.length.toLong(),
salt.asByteArray(), salt.asByteArray(),
opsLimit.toLong(), opsLimit.toLong(),
NativeLong(memLimit.toLong()), memLimit.toLong(),
algorithm algorithm
) )
@ -48,12 +48,12 @@ actual object PasswordHash {
*/ */
actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray {
val output = ByteArray(crypto_pwhash_STRBYTES) val output = ByteArray(crypto_pwhash_STRBYTES)
sodium.crypto_pwhash_str( sodiumJna.crypto_pwhash_str(
output, output,
password.encodeToByteArray(), password,
password.length.toLong(), password.length.toLong(),
opslimit.toLong(), opslimit.toLong(),
NativeLong(memlimit.toLong()) memlimit.toLong()
) )
return output.asUByteArray() return output.asUByteArray()
} }
@ -69,10 +69,10 @@ actual object PasswordHash {
opslimit: ULong, opslimit: ULong,
memlimit: Int memlimit: Int
): Int { ): Int {
return sodium.crypto_pwhash_str_needs_rehash( return sodiumJna.crypto_pwhash_str_needs_rehash(
passwordHash.asByteArray(), passwordHash.asByteArray(),
opslimit.toLong(), 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. * It returns 0 if the verification succeeds, and -1 on error.
*/ */
actual fun strVerify(passwordHash: UByteArray, password: String): Boolean { actual fun strVerify(passwordHash: UByteArray, password: String): Boolean {
val result = sodium.crypto_pwhash_str_verify( val result = sodiumJna.crypto_pwhash_str_verify(
passwordHash.asByteArray(), passwordHash.asByteArray(),
password.encodeToByteArray(), password,
password.length.toLong() password.length.toLong()
) )

View File

@ -1,12 +1,12 @@
package com.ionspin.kotlin.crypto.stream package com.ionspin.kotlin.crypto.stream
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
actual object Stream { actual object Stream {
actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray { actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
val result = UByteArray(clen) 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 return result
} }
@ -18,7 +18,7 @@ actual object Stream {
): UByteArray { ): UByteArray {
val result = UByteArray(message.size) val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_ietf_xor( sodiumJna.crypto_stream_chacha20_ietf_xor(
result.asByteArray(), result.asByteArray(),
message.asByteArray(), message.asByteArray(),
message.size.toLong(), message.size.toLong(),
@ -37,7 +37,7 @@ actual object Stream {
): UByteArray { ): UByteArray {
val result = UByteArray(message.size) val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_ietf_xor_ic( sodiumJna.crypto_stream_chacha20_ietf_xor_ic(
result.asByteArray(), result.asByteArray(),
message.asByteArray(), message.asByteArray(),
message.size.toLong(), message.size.toLong(),
@ -52,7 +52,7 @@ actual object Stream {
actual fun chacha20Keygen(): UByteArray { actual fun chacha20Keygen(): UByteArray {
val result = UByteArray(crypto_stream_chacha20_KEYBYTES) val result = UByteArray(crypto_stream_chacha20_KEYBYTES)
sodium.crypto_stream_chacha20_keygen(result.asByteArray()) sodiumJna.crypto_stream_chacha20_keygen(result.asByteArray())
return result return result
} }
@ -64,7 +64,7 @@ actual object Stream {
): UByteArray { ): UByteArray {
val result = UByteArray(message.size) val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_xor( sodiumJna.crypto_stream_chacha20_xor(
result.asByteArray(), result.asByteArray(),
message.asByteArray(), message.asByteArray(),
message.size.toLong(), message.size.toLong(),
@ -83,7 +83,7 @@ actual object Stream {
): UByteArray { ): UByteArray {
val result = UByteArray(message.size) val result = UByteArray(message.size)
sodium.crypto_stream_chacha20_xor_ic( sodiumJna.crypto_stream_chacha20_xor_ic(
result.asByteArray(), result.asByteArray(),
message.asByteArray(), message.asByteArray(),
message.size.toLong(), 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 return result
} }
} }

View File

@ -1,6 +1,5 @@
package com.ionspin.kotlin.crypto.util package com.ionspin.kotlin.crypto.util
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
/** /**
@ -28,7 +27,7 @@ actual object LibsodiumRandom {
*/ */
actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray {
val result = ByteArray(size) val result = ByteArray(size)
sodium.randombytes_buf_deterministic(result, size, seed.asByteArray()) sodiumJna.randombytes_buf_deterministic(result, size, seed.asByteArray())
return result.asUByteArray() return result.asUByteArray()
} }
@ -38,7 +37,7 @@ actual object LibsodiumRandom {
actual fun random(): UInt { actual fun random(): UInt {
//Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 //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 //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 * 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 { actual fun uniform(upperBound: UInt): UInt {
//Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 return sodiumJna.randombytes_uniform(upperBound.toLong()).toUInt()
//Using temporary fixed build until pull request is accepted
return sodium.randombytes_uniform(upperBound.toInt()).toUInt()
} }
} }

View File

@ -10,6 +10,9 @@ import libsodium.crypto_stream_chacha20_ietf_xor_ic
import libsodium.crypto_stream_chacha20_keygen import libsodium.crypto_stream_chacha20_keygen
import libsodium.crypto_stream_chacha20_xor import libsodium.crypto_stream_chacha20_xor
import libsodium.crypto_stream_chacha20_xor_ic 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 object Stream {
actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray { actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
@ -149,4 +152,71 @@ actual object Stream {
return result 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
}
} }

View File

@ -143,9 +143,9 @@ native libsodium library.
| crypto_stream_chacha20_xor | :heavy_check_mark: | | crypto_stream_chacha20_xor | :heavy_check_mark: |
| crypto_stream_chacha20_xor_ic | :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_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_keygen | :heavy_check_mark: |
| crypto_stream_xchacha20_xor | not present in LazySodium Android| | crypto_stream_xchacha20_xor | :heavy_check_mark: |
| crypto_stream_xchacha20_xor_ic | not present in LazySodium Android | | crypto_stream_xchacha20_xor_ic | :heavy_check_mark: |
| randombytes_buf | :heavy_check_mark: | | randombytes_buf | :heavy_check_mark: |
| randombytes_buf_deterministic | :heavy_check_mark: | | randombytes_buf_deterministic | :heavy_check_mark: |
| randombytes_close | not present in LazySodium | | randombytes_close | not present in LazySodium |