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_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
}

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_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 ----

View File

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

View File

@ -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 ----
//

View File

@ -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(),

View File

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

View File

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

View File

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

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_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
}
}

View File

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