diff --git a/README.md b/README.md index d0a8635..ebf10c3 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,117 @@ [![Build Status](https://travis-ci.com/ionspin/kotlin-multiplatform-crypto.svg?branch=master)](https://travis-ci.com/ionspin/kotlin-multiplatform-crypto) -![Maven Central](https://img.shields.io/maven-central/v/com.ionspin.kotlin/multiplatform-crypto.svg) # Kotlin Multiplatform Crypto Library -#Note: -### Next stable release will be published after public release of Kotlin 1.4, until then API will change significantly +This repository contains two cryptography related projects: -Kotlin Multiplatform Crypto is a library for various cryptographic applications. +1. Libsodium bindings for Kotiln Multiplatform +2. Pure/Delegated kotlin multiplatform crypto library written from scratch in pure form. [Link to project readme](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/multiplatform-crypto-api/README.md) -The library comes in two flavors `multiplatform-crypto` and `multiplatform-crypto-delegated`. This project also provides -direct libsodium bindings under `multiplatform-crypto-libsodium-bindings`. +This readme represents the libsodium bindings project -* `multiplatform-crypto` contains pure kotlin implementations, is not reviewed, should be considered unsafe and only -for prototyping or experimentation purposes. +# Libsodium bindings for Kotiln Multiplatform -* `multiplatform-crypto-delegated` relies on platform specific implementations, mostly libsodium, but care should still be taken that the kotlin code is not reviewed or proven safe. +Libsodium bindings project uses libsodium c sources, libsodium.js as well as LazySodium Java and Android to provide a kotlin multiplatform wrapper library for libsodium. -APIs of both variants are identical. +## Installation -* `multiplatform-crypto-libsodium-bindings` is a generated bindings library using `kotlin-multiplatform-libsodium-generator` - * Under HEAVY development at the moment +The libsodium binding library is not published yet as it is still missing several features, you can track the +[progress here](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/supported_bindings_list.md) +## Usage -### Table of contents -1. [Supported platforms](#supported-platforms-by-variant) -2. [API](#api) -3. TODO +Before using the wrapper you need to initialize the underlying libsodium library. You can use either a callback or coroutines approach + +``` + LibsodiumInitializer.initializeWithCallback { + // Libsodium initialized + } +``` + +``` + suspend fun initalizeProject() { + ... + LibsodiumInitializer.intialize() + ... + } +``` + +After intiailization you can call libsodium functions directly + +The API is very close to libsodium but still adapted to kotlin standards, as an example here is the usage of authenticated +encryption api: + +**libsodium:** + +``` + #define MESSAGE ((const unsigned char *) "test") + #define MESSAGE_LEN 4 + #define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN) + + unsigned char key[crypto_secretbox_KEYBYTES]; + unsigned char nonce[crypto_secretbox_NONCEBYTES]; + unsigned char ciphertext[CIPHERTEXT_LEN]; + + crypto_secretbox_keygen(key); + randombytes_buf(nonce, sizeof nonce); + crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key); + + unsigned char decrypted[MESSAGE_LEN]; + if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key) != 0) { + /* message forged! */ + } +``` + +**kotlin:** +``` + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val key = LibsodiumRandom.buf(32) + + val nonce = LibsodiumRandom.buf(24) + + val encrypted = SecretBox.easy(message, nonce, key) + val decrypted = SecretBox.openEasy(encrypted, nonce, key) +``` +If message cannot be verified, `openEasy` function will throw a `SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey` + +In some cases libsodium C api returns two values, usually encrypted data and a autogenerated nonce. In situations like +those, kotlin API returns a data class wrapping both objects. An example of this behavior is initializing the secret stream, where initialization funciton returns both the header and state: + +**libsodium:** +``` + crypto_secretstream_xchacha20poly1305_state state; + unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + + /* Set up a new stream: initialize the state and create the header */ + crypto_secretstream_xchacha20poly1305_init_push(&state, header, key); +``` + +**kotlin:** +This is what the response data class definition looks like: +``` + data class SecretStreamStateAndHeader(val state: SecretStreamState, val header : UByteArray) +``` +And here is the usage sample +``` + val key = LibsodiumRandom.buf(crypto_secretstream_xchacha20poly1305_KEYBYTES) + val stateAndHeader = SecretStream.xChaCha20Poly1305InitPush(key) + val state = stateAndHeader.state + val header = stateAndHeader.header +``` + +The functions are mapped from libsodium to kotiln objects, so `crypto_secretstream_xchacha20poly1305_init_push` becomes +`SecretStream.xChaCha20Poly1305InitPush` + +At the moment you should refer to original libsodium documentation for instructions on how to use the library + +## Supported native platforms + +Currently supported native platforms: -## Supported platforms by variant |Platform|Pure variant| Delegated variant| |--------|------------|------------------| |Linux X86 64| :heavy_check_mark: | :heavy_check_mark: | @@ -46,235 +129,17 @@ APIs of both variants are identical. |minGW X86 64| :heavy_check_mark: | :heavy_check_mark: | |minGW X86 32| :x: | :x: | -## Sample project -The library includes sample project that shows usage on different platforms -- NOTE: Currently only linux, macOs and windows are included. -## Notes & Roadmap +### TODO: +- Copy/adapt code documentation, currently only some functions have documentation that is a copy-paste from libsodium website +- Complete the bindings list +- Samples +- Android testing -**The API will move fast and break often until v1.0** -Next steps: -- Expand API (ECC, Signing ...) -## Should I use this in production? -**NO.** -The library is under HEAVY development. -## Why? -This is an experimental implementation, mostly for expanding personal understanding of cryptography. -It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure. - -## API for Pure and Delegated flavourd - -### Hashing functions -* Blake2b -* SHA512 -* SHA256 - -### Key Derivation - -* Argon2 - -### Authenticated symmetric encryption (AEAD) - -* XChaCha20-Poly1305 - - -### Delegated flavor dependancy table -The following table describes which library is used for particular cryptographic primitive - -| Primitive | JVM | JS | Native | -| ----------|-----|----|--------| -| Blake2b | LazySodium | libsodium.js | libsodium | -| SHA256 | LazySodium | libsodium.js | libsodium | -| SHA512 | LazySodium | libsodium.js | libsodium | -| XChaCha20-Poly1305 | LazySodium | libsodium.js | libsodium | - - - -## Integration - -NOTE: Latest version of the library is built with Kotlin 1.4-M2 and therefore only SNAPSHOT variant is available. Next -stable version will be released when Kotlin 1.4. is released - -#### Gradle -Kotlin -```kotlin -implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0") - -or - -implementation("com.ionspin.kotlin:multiplatform-crypto-delegated:0.1.0") -``` - -#### Snapshot builds -```kotlin -repositories { - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - } -} -implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0-SNAPSHOT") - -``` - -## Usage - -### Helper functions - -All API take `UByteArray` as message/key/nonce/etc parameter. For convenience when working with strings we provide -`String.enocdeToUbyteArray()` extensions function, and `UByteArray.toHexString` extension function. - -More convenience functions will be added. - -### Hashes - -Hashes are provided in two versions, "stateless", usually the companion object of the hash, -which takes the data to be hashed in one go, and "updatable" which can be fed data in chunks. - - -#### Blake2b - -You can use Blake 2b in two modes - -##### Stateless version -You need to deliver the complete data that is to be hashed in one go - -```kotlin -val input = "abc" -val result = Crypto.Blake2b.stateless(input.encodeToUByteArray()) -``` - -Result is returned as a `UByteArray` - -##### Updatable instance version -You can create an instance and feed the data by using `update(input : UByteArray)` call. Once all data is supplied, -you should call `digest()`. - -If you want to use Blake2b with a key, you should supply it when creating the `Blake2b` instance. - -```kotlin -val test = "abc" -val key = "key" -val blake2b = Crypto.Blake2b.updateable(key.encodeToUByteArray()) -blake2b.update(test.encodeToUByteArray()) -val result = blake2b.digest().toHexString() -``` - -After digest is called, the instance is reset and can be reused (Keep in mind key stays the same for the particular instance). -#### SHA2 (SHA256 and SHA512) - -##### Stateless version - -You need to deliver the complete data that is to be hashed in one go. You can either provide the `UByteArray` as input -or `String`. Result is always returned as `UByteArray` (At least in verision 0.0.1) - -```kotlin -val input = "abc" -val result = Crypto.Sha256.stateless(input.encodeToUByteArray()) -``` - -```kotlin -val input ="abc" -val result = Crypto.Sha512.stateless(input.encodeToUByteArray()) -``` - -Result is returned as a `UByteArray` - -##### Updateable version - -Or you can use the updatable instance version - -```kotlin -val sha256 = Crypto.Sha256.updateable() -sha256.update("abc".encodeToUByteArray()) -val result = sha256.digest() -``` - -```kotlin -val sha512 = Crypto.Sha512.updateable() -sha512.update("abc".encodeToUByteArray()) -val result = sha512.digest() -``` - -### Key derivation - -#### Argon2 - -NOTE: This implementation is tested against KAT generated by reference Argon2 implementation, which does not follow -specification completely. See this issue https://github.com/P-H-C/phc-winner-argon2/issues/183 - -```kotlin -val argon2Instance = Argon2( - password = "Password", - salt = "RandomSalt", - parallelism = 8, - tagLength = 64U, - requestedMemorySize = 256U, //4GB - numberOfIterations = 4U, - key = "", - associatedData = "", - argonType = ArgonType.Argon2id - ) -val tag = argon2Instance.derive() -val tagString = tag.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") -val expectedTagString = "c255e3e94305817d5e09a7c771e574e3a81cc78fef5da4a9644b6df0" + - "0ba1c9b424e3dd0ce7e600b1269b14c84430708186a8a60403e1bfbda935991592b9ff37" -println("Tag: ${tagString}") -assertEquals(tagString, expectedTagString) -``` - -### Symmetric encryption (OUTDATED, won't be exposed in next release, no counterpart in delegated flavor - 0.1.1) - -#### AES - -Aes is available with CBC and CTR mode through `AesCbc` and `AesCtr` classes/objects. -Similarly to hashes you can either use stateless or updateable version. - -Initialization vector, or counter states are chosen by the SDK automaticaly, and returned alongside encrypted data - -##### Stateless AesCbc and AesCtr - -AesCtr - -```kotlin -val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" -val key = AesKey.Aes128Key(keyString) -val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" - -val encryptedDataAndInitializationVector = AesCtr.encrypt(key, plainText.hexStringToUByteArray()) -val decrypted = AesCtr.decrypt( - key, - encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initialCounter -) -plainText == decrypted.toHexString() -``` - -AesCbc - -```kotlin - -val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" -val key = AesKey.Aes128Key(keyString) - -val plainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" - -val encryptedDataAndInitializationVector = AesCbc.encrypt(key, plainText.hexStringToUByteArray()) -val decrypted = AesCbc.decrypt( - key, - encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initilizationVector -) -plainText == decrypted.toHexString() - -``` - -## Libsodium bindings - -* Under development diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6b9af03..2658b0f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -25,10 +25,12 @@ repositories { maven ("https://dl.bintray.com/kotlin/kotlin-eap") maven("https://dl.bintray.com/kotlin/kotlin-dev") jcenter() + google() } dependencies { implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0-rc") + implementation("com.android.tools.build:gradle:4.0.1") } System.setProperty("PROJECT_PATH", project.projectDir.parentFile.toString()) diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index a4617e6..2d0fb60 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -15,17 +15,17 @@ */ object Versions { - val kotlinCoroutines = "1.3.8-1.4.0-rc" - val kotlin = "1.4.0-rc" - val kotlinSerialization = "1.0-M1-1.4.0-rc" + val kotlinCoroutines = "1.3.9" + val kotlin = "1.4.0" + val kotlinSerialization = "1.0.0-RC" val atomicfu = "0.14.3-M2-2-SNAPSHOT" //NOTE: my linux arm32 and arm64 build val nodePlugin = "1.3.0" - val dokkaPlugin = "1.4.0-M3-dev-92" + val dokkaPlugin = "1.4.0-rc" val taskTreePlugin = "1.5" val kotlinBigNumVersion = "0.1.6-1.4.0-rc-SNAPSHOT" - val lazySodium = "4.2.6" + val lazySodium = "4.3.1-SNAPSHOT" val jna = "5.5.0" val kotlinPoet = "1.6.0" @@ -61,8 +61,9 @@ object Deps { val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.kotlinSerialization}" object Npm { - val libsodium = Pair("libsodium-wrappers-sumo", "0.7.6") - val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "file:${getProjectPath()}/multiplatform-crypto-delegated/libsodium-wrappers-sumo-0.7.6.tgz") + val libsodium = Pair("libsodium-wrappers-sumo", "0.7.8") + //val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "file:${getProjectPath()}/multiplatform-crypto-delegated/libsodium-wrappers-sumo-0.7.6.tgz") + val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "0.7.8") } } @@ -80,7 +81,10 @@ object Deps { val kotlinPoet = "com.squareup:kotlinpoet:${Versions.kotlinPoet}" object Delegated { - val lazysodium = "com.goterl.lazycode:lazysodium-java:${Versions.lazySodium}" + // Temporary until reported lazysodium issues are fixed. My snapshot build with + // And cause I registered com.ionspin.kotlin as maven central package root now I have to use + // that even though this is pure java library. :) + val lazysodium = "com.ionspin.kotlin:lazysodium-java:${Versions.lazySodium}" val jna = "net.java.dev.jna:jna:${Versions.jna}" } } @@ -107,5 +111,7 @@ object PluginsDeps { val signing = "signing" val dokka = "org.jetbrains.dokka" val taskTree = "com.dorongold.task-tree" + val androidLibrary = "com.android.library" + val kotlinAndroidExtensions = "kotlin-android-extensions" } diff --git a/gradle.properties b/gradle.properties index 9296ffa..51da301 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,3 +23,5 @@ kotlin.js.compiler=ir kotlin.native.disableCompilerDaemon=true org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=4096m + +android.useAndroidX=true diff --git a/kotlin-multiplatform-libsodium-generator/build.gradle.kts b/kotlin-multiplatform-libsodium-generator/build.gradle.kts deleted file mode 100644 index 934c736..0000000 --- a/kotlin-multiplatform-libsodium-generator/build.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -plugins { - kotlin -} - -group = "com.ionspin.kotlin.crypto" -version = "0.0.1" - -repositories { - mavenCentral() - google() - maven ("https://kotlin.bintray.com/kotlinx") - maven ("https://dl.bintray.com/kotlin/kotlin-eap") - maven ("https://dl.bintray.com/kotlin/kotlin-dev") - jcenter() - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - } -} - -dependencies { - implementation (kotlin(Deps.Jvm.stdLib)) - implementation("com.squareup:kotlinpoet:1.6.0") - testImplementation(kotlin(Deps.Jvm.test)) - testImplementation(kotlin(Deps.Jvm.testJUnit)) -} - -tasks.withType().all { - kotlinOptions.freeCompilerArgs += listOf( - "-Xuse-experimental=kotlin.ExperimentalUnsignedTypes" - ) -} - - - - - diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index 6287381..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,26 +0,0 @@ -package debug.test - -import kotlin.Int -import kotlin.UByteArray - -expect class Sha256State - -expect class Sha512State - -expect class GenericHashState - -expect class Crypto internal constructor() { - fun crypto_hash_sha256_init(): Sha256State - - fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) - - fun crypto_hash_sha256_final(state: Sha256State): UByteArray - - fun crypto_hash_sha512_init(): Sha512State - - fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) - - fun crypto_hash_sha512_final(state: Sha512State): UByteArray - - fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index 727d9c7..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -package debug.test - -import com.ionspin.kotlin.crypto.getSodium -import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray -import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array -import kotlin.Any -import kotlin.Int -import kotlin.UByteArray - -actual typealias Sha256State = Any - -actual typealias Sha512State = Any - -actual typealias GenericHashState = Any - -actual class Crypto internal actual constructor() { - actual fun crypto_hash_sha256_init(): dynamic { - println("Debug crypto_hash_sha256_init") - val result = js("getSodium().crypto_hash_sha256_init()") - return result - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - println("Debug crypto_hash_sha256_final") - return getSodium().crypto_hash_sha256_final(state).toUByteArray() - } - - actual fun crypto_hash_sha512_init(): dynamic { - println("Debug crypto_hash_sha512_init") - val result = js("getSodium().crypto_hash_sha512_init()") - return result - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - println("Debug crypto_hash_sha512_final") - return getSodium().crypto_hash_sha512_final(state).toUByteArray() - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { - println("Debug crypto_generichash_init") - return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) - } -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index 1213842..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,62 +0,0 @@ -package debug.test - -import com.goterl.lazycode.lazysodium.SodiumJava -import com.goterl.lazycode.lazysodium.interfaces.Hash -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray - -val sodium: SodiumJava = SodiumJava() - -actual typealias Sha256State = Hash.State256 - -actual typealias Sha512State = Hash.State512 - -actual typealias GenericHashState = ByteArray - -actual class Crypto internal actual constructor() { - actual fun crypto_hash_sha256_init(): Sha256State { - val state = debug.test.Sha256State() - println("Debug crypto_hash_sha256_init") - sodium.crypto_hash_sha256_init(state) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - sodium.crypto_hash_sha256_final(state, out.asByteArray()) - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val state = debug.test.Sha512State() - println("Debug crypto_hash_sha512_init") - sodium.crypto_hash_sha512_init(state) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - sodium.crypto_hash_sha512_final(state, out.asByteArray()) - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) - println("Debug crypto_generichash_init") - sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) - return state - } -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index 5224235..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,88 +0,0 @@ -package debug.test - -import kotlin.Byte -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray -import kotlinx.cinterop.addressOf -import kotlinx.cinterop.convert -import kotlinx.cinterop.pin -import kotlinx.cinterop.pointed -import kotlinx.cinterop.ptr -import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.toCValues -import libsodium.crypto_generichash_blake2b_state -import libsodium.crypto_hash_sha256_state -import libsodium.crypto_hash_sha512_state -import libsodium.sodium_malloc - -actual typealias Sha256State = crypto_hash_sha256_state - -actual typealias Sha512State = crypto_hash_sha512_state - -actual typealias GenericHashState = crypto_generichash_blake2b_state - -actual class Crypto internal actual constructor() { - val _emitByte: Byte = 0 - - val _emitByteArray: ByteArray = ByteArray(0) - - actual fun crypto_hash_sha256_init(): Sha256State { - val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha256_init") - libsodium.crypto_hash_sha256_init(state.ptr) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha512_init") - libsodium.crypto_hash_sha512_init(state.ptr) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_generichash_init") - val pinnedKey = key.pin() - libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), - outlen.convert()) - pinnedKey.unpin() - return state - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt deleted file mode 100644 index f20abfc..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.ionspin.kotlin.crypto.generator - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 18-Jul-2020 - */ -object Launcher { - @JvmStatic - fun main(args : Array) { - println("Ok") - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt deleted file mode 100644 index 9bcf7ff..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 18-Jul-2020 - */ -class CInteropParser { - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt deleted file mode 100644 index dfd1175..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ /dev/null @@ -1,174 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.TypeName -import com.squareup.kotlinpoet.asTypeName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 28-Jul-2020 - */ - -val packageName = "debug.test" - -fun withPackageName(name: String) = ClassName(packageName, name) - -class KotlinFileDefinition( - val name: String, - val commonClassList: MutableList = mutableListOf() -) { - operator fun ClassDefinition.unaryPlus() { - commonClassList.add(this) - } -} - -class ClassDefinition( - val name: String, - val innerClasses: MutableList = mutableListOf(), - val methods: MutableList = mutableListOf() -) { - operator fun InnerClassDefinition.unaryPlus() { - innerClasses.add(this) - } - - operator fun FunctionDefinition.unaryPlus() { - methods.add(this) - } - - operator fun List.unaryPlus() { - methods.addAll(this) - } -} - -class InnerClassDefinition( - val name: String, - val javaName: String, - val jsName: String, - val nativeName: String, - val functions: MutableList = mutableListOf() -) - -class FunctionDefinition( - val name: String, - val javaName: String, - val jsName: String, - val nativeName: String, - val parameterList: MutableList = mutableListOf(), - val returnType: GeneralTypeDefinition, - val dynamicJsReturn: Boolean = false, - val isStateCreationFunction: Boolean = false, - val outputLengthWhenArray: Int = -1 -) { - operator fun ParameterDefinition.unaryPlus() { - parameterList.add(this) - } -} - -class ParameterDefinition( - val parameterName: String, - val parameterType: GeneralTypeDefinition, - val modifiesReturn: Boolean = false, - val isActuallyAnOutputParam: Boolean = false, - val isStateType: Boolean = false, - val dropParameterFromDefinition: Boolean = false, - val specificJvmInitializer: String? = null, -) - -interface GeneralTypeDefinition { - val typeName: TypeName -} - -data class CustomTypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition - -enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition { - ARRAY_OF_UBYTES(UByteArray::class.asTypeName()), - ARRAY_OF_UBYTES_LONG_SIZE(UByteArray::class.asTypeName()), - ARRAY_OF_UBYTES_NO_SIZE(UByteArray::class.asTypeName()), - LONG(Long::class.asTypeName()), - INT(Int::class.asTypeName()), - STRING(String::class.asTypeName()), - UNIT(Unit::class.asTypeName()) -} - -fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefinition { - val commonKotlinFileInstance = KotlinFileDefinition(name) - commonKotlinFileInstance.body() - return commonKotlinFileInstance -} - - -fun classDef(name: String, body: ClassDefinition.() -> Unit): ClassDefinition { - val commonClass = ClassDefinition(name) - commonClass.body() - return commonClass -} - -fun innerClassDef( - name: String, - javaName: String, - jsName: String, - nativeName: String, - specificConstructor : String? = null, - body: InnerClassDefinition.() -> Unit = {} -): InnerClassDefinition { - val genClass = InnerClassDefinition( - name, - javaName, - jsName, - nativeName - ) - genClass.body() - return genClass -} - -fun funcDef( - name: String, - javaName: String, - jsName: String, - nativeName: String, - returnType: GeneralTypeDefinition, - dynamicJsReturn: Boolean = false, - isStateCreationFunction: Boolean = false, - outputLengthWhenArray: Int = -1, - body: FunctionDefinition.() -> Unit -): FunctionDefinition { - val function = FunctionDefinition( - name, - javaName, - jsName, - nativeName, - returnType = returnType, - dynamicJsReturn = dynamicJsReturn, - isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray - ) - function.body() - return function -} - -fun funcDef( - name: String, - returnType: GeneralTypeDefinition, - dynamicJsReturn: Boolean = false, - isStateCreationFunction: Boolean = false, - outputLengthWhenArray: Int = -1, - body: FunctionDefinition.() -> Unit -): FunctionDefinition { - val function = - FunctionDefinition( - name, - name, - name, - name, - returnType = returnType, - dynamicJsReturn = dynamicJsReturn, - isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray - ) - function.body() - return function -} - - - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt deleted file mode 100644 index 61cacf0..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 01-Aug-2020 - */ -object LibSodiumDefinitions { - val testKotlinFile = fileDef("DebugTest") { - +classDef("Crypto") { - defineHashFunctions() - defineGenericHashFunctions() - } - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt deleted file mode 100644 index d6d47fd..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -import com.squareup.kotlinpoet.ClassName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 04-Aug-2020 - */ -fun ClassDefinition.defineGenericHashFunctions() { - /* - * ------------- GENERIC HASH (BLAKE2B) - */ - - +innerClassDef( - "GenericHashState", - "kotlin.ByteArray", - "Uint8Array", - "crypto_generichash_blake2b_state" - ) - - +funcDef( - "crypto_generichash_init", - CustomTypeDefinition(ClassName(packageName, "GenericHashState")), - true, - isStateCreationFunction = true - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("GenericHashState"))), - isStateType = true, - dropParameterFromDefinition = true, - specificJvmInitializer = "sodium.crypto_generichash_statebytes()" - ) - +ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES) - +ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true) - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt deleted file mode 100644 index b196ecf..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt +++ /dev/null @@ -1,80 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -import com.squareup.kotlinpoet.ClassName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 04-Aug-2020 - */ -fun ClassDefinition.defineHashFunctions() { - /* - --------------- SHA256 - */ - +innerClassDef( - "Sha256State", - "com.goterl.lazycode.lazysodium.interfaces.Hash.State256", - "Sha256State", - "crypto_hash_sha256_state" - ) - +funcDef( - "crypto_hash_sha256_init", - CustomTypeDefinition(ClassName(packageName, "Sha256State")), - dynamicJsReturn = true, - isStateCreationFunction = true - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("Sha256State"))), - dropParameterFromDefinition = true, - isStateType = true - ) - } - - +funcDef("crypto_hash_sha256_update", TypeDefinition.UNIT) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("Sha256State"))), - isStateType = true - ) - +ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE) - } - - +funcDef("crypto_hash_sha256_final", TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 32) { - +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State")))) - +ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true) - } - - /* - --------------- SHA512 - */ - +innerClassDef( - "Sha512State", - "com.goterl.lazycode.lazysodium.interfaces.Hash.State512", - "Sha512State", - "crypto_hash_sha512_state" - ) - +funcDef( - "crypto_hash_sha512_init", - CustomTypeDefinition(ClassName(packageName, "Sha512State")), - true, - isStateCreationFunction = true - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("Sha512State"))), - dropParameterFromDefinition = true, - isStateType = true - ) - } - - +funcDef("crypto_hash_sha512_update", TypeDefinition.UNIT) { - +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State")))) - +ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE) - } - - +funcDef("crypto_hash_sha512_final", TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 64) { - +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State")))) - +ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true) - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretstreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretstreamDefinitions.kt deleted file mode 100644 index 9854763..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretstreamDefinitions.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -/** - * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Aug/2020 - */ -fun ClassDefinition.defineSecretStreamFunctions() { - - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt deleted file mode 100644 index 1ff5af6..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt +++ /dev/null @@ -1,89 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.squareup.kotlinpoet.* - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ - -enum class MultiplatformModifier(val modifierList: List) { - EXPECT(listOf(KModifier.EXPECT)), - ACTUAL(listOf(KModifier.ACTUAL)), - NONE(listOf()) -} - -object CommonLibsodiumGenerator { - - fun createCommonFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create expected inner classes that will be represented by type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addType(createCommonInnerClassSpec(it, MultiplatformModifier.EXPECT)) - } - val commonClassSpec = - createClass( - commonClassDefinition, - MultiplatformModifier.EXPECT, - ::createCommonMethodSpec - ) - fileBuilder.addType(commonClassSpec.build()) - } - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - fun createCommonInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeSpec { - val innerClassBuilder = TypeSpec.classBuilder(innerClassDefinition.name) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createCommonMethodSpec(methodDefinition: FunctionDefinition): FunSpec { - val methodBuilder = FunSpec.builder(methodDefinition.name) - var actualReturnType : TypeName = Any::class.asTypeName() - var actualReturnTypeFound : Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.dropParameterFromDefinition.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnTypeFound = true - actualReturnType = paramDefinition.parameterType.typeName - } - } - if (actualReturnTypeFound) { - methodBuilder.returns(actualReturnType) - } else { - methodBuilder.returns(methodDefinition.returnType.typeName) - } - return methodBuilder.build() - } - -} - - - - - - - - - - - - - - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt deleted file mode 100644 index c347f7c..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefinitions -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.packageName -import java.io.File - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object Coordinator { - - fun run() { - - val commonFileSpec = CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile) - val jvmFileSpec = JvmLibsodiumGenerator.createJvmFile(packageName, LibSodiumDefinitions.testKotlinFile) - val nativeFileSpec = NativeLibsodiumGenerator.createNativeFile(packageName, LibSodiumDefinitions.testKotlinFile) - val jsFileSpec = JsLibsodiumGenerator.createJsFile(packageName, LibSodiumDefinitions.testKotlinFile) - - val commonFile = File("multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/") - commonFileSpec.writeTo(commonFile) - val jvmFile = File("multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/") - jvmFileSpec.writeTo(jvmFile) - val nativeFile = File("multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/") - nativeFileSpec.writeTo(nativeFile) - val jsFile = File("multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/") - jsFileSpec.writeTo(jsFile) - - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt deleted file mode 100644 index 03f11b6..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ /dev/null @@ -1,170 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* -import com.squareup.kotlinpoet.* - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object JsLibsodiumGenerator { - - val jsInterfaceFunctionDefinitions : MutableList = mutableListOf() - - - fun createJsFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUInt8Array") - fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUByteArray") - fileBuilder.addImport("com.ionspin.kotlin.crypto", "getSodium") - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addTypeAlias(createJsInnerClassSpec(it, MultiplatformModifier.ACTUAL)) - } - - val commonClassSpec = createClass( - commonClassDefinition, - MultiplatformModifier.ACTUAL, - ::createJsFunctionImplementation - ) - fileBuilder.addType(commonClassSpec.build()) - } - createJsInterfaceFile() - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - // This helps with static typing in js target - fun createJsInterfaceFile() { - val fileBuilder = FileSpec.builder(packageName, "JsSodiumInterfaceDebug") - val jsInterface = TypeSpec.interfaceBuilder("JsSodiumInterfaceDebug") - jsInterface.addFunctions(jsInterfaceFunctionDefinitions) - fileBuilder.addType(jsInterface.build()) - val file = fileBuilder.build() - file.writeTo(System.out) - } - - fun createJsInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeAliasSpec { - val innerClassBuilder = TypeAliasSpec.builder(innerClassDefinition.name, Any::class.asTypeName()) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createJsFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec { - val methodBuilder = FunSpec.builder(methodDefinition.name) - - var returnModifierFound = false - var returnModifierName = "" - var actualReturnType: TypeName = DYNAMIC - var actualReturnTypeFound: Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - if (paramDefinition.modifiesReturn) { - if (returnModifierFound == true) { - throw RuntimeException("Return modifier already found") - } - returnModifierFound = true - returnModifierName = paramDefinition.parameterName - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnTypeFound = true - actualReturnType = paramDefinition.parameterType.typeName - } - } - if (actualReturnTypeFound) { - methodBuilder.returns(actualReturnType) - } else if (methodDefinition.dynamicJsReturn) { - methodBuilder.returns(Dynamic) - } else { - methodBuilder.returns(methodDefinition.returnType.typeName) - } - //Create a spec for interface - methodBuilder.addModifiers(KModifier.ABSTRACT) - jsInterfaceFunctionDefinitions.add(methodBuilder.build()) - //continue with normal func spec for implementation - methodBuilder.modifiers.clear() - methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList - methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") - val constructJsCall = StringBuilder() - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()") - } - TypeDefinition.INT -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - TypeDefinition.UNIT -> { - constructJsCall.append("getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - is CustomTypeDefinition -> { - if (methodDefinition.parameterList.filter { it.isStateType.not() }.size > 0) { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } else { - constructJsCall.append("val result = js(\"getSodium().${methodDefinition.jsName}()\")") - constructJsCall.append("\nreturn result") - } - } - } - methodBuilder.addStatement(constructJsCall.toString()) - return methodBuilder.build() - } - - fun paramsToString(methodDefinition: FunctionDefinition): String { - val paramsBuilder = StringBuilder() - paramsBuilder.append("(") - val jsParams = methodDefinition.parameterList.filter { it.dropParameterFromDefinition.not() } - jsParams.forEachIndexed { index, paramDefinition -> - val separator = if (index == jsParams.size - 1) { - "" - } else { - ", " - } - if (paramDefinition.parameterType is CustomTypeDefinition) { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array(), " + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) - } - TypeDefinition.LONG -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.INT -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.STRING -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - } - } - - - } - paramsBuilder.append(')') - return paramsBuilder.toString() - } - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt deleted file mode 100644 index e303c2f..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ /dev/null @@ -1,215 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.CodeBlock -import com.squareup.kotlinpoet.FileSpec -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.ParameterSpec -import com.squareup.kotlinpoet.PropertySpec -import com.squareup.kotlinpoet.TypeAliasSpec - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object JvmLibsodiumGenerator { - - - fun createJvmFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - val sodiumProperty = PropertySpec.builder("sodium", ClassName.bestGuess("com.goterl.lazycode.lazysodium.SodiumJava")) - sodiumProperty.initializer(CodeBlock.of("SodiumJava()")) - fileBuilder.addProperty(sodiumProperty.build()) - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addTypeAlias(createJvmInnerClassSpec(it, MultiplatformModifier.ACTUAL)) - } - - val commonClassSpec = createClass( - commonClassDefinition, - MultiplatformModifier.ACTUAL, - ::createJvmFunctionImplementation - ) - fileBuilder.addType(commonClassSpec.build()) - } - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - fun createJvmInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeAliasSpec { - val innerClassBuilder = TypeAliasSpec.builder(innerClassDefinition.name, ClassName.bestGuess(innerClassDefinition.javaName)) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createJvmFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec { - val methodBuilder = FunSpec.builder(methodDefinition.name) - methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList - var returnModifierFound = false - var returnModifierName = "" - lateinit var actualReturnParameterDefinition: ParameterDefinition - var actualReturnTypeFound: Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) { - createStateParam(paramDefinition, methodBuilder) - } - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - if (paramDefinition.modifiesReturn) { - if (returnModifierFound == true) { - throw RuntimeException("Return modifier already found") - } - returnModifierFound = true - returnModifierName = paramDefinition.parameterName - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnParameterDefinition = paramDefinition - actualReturnTypeFound = true - } - } - if (actualReturnTypeFound) { - if (returnModifierFound) { - createOutputParam( - actualReturnParameterDefinition, - returnModifierName, - methodBuilder - ) - } else { - if (methodDefinition.outputLengthWhenArray == -1) { - throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") - } - createOutputParam( - actualReturnParameterDefinition, - methodDefinition.outputLengthWhenArray.toString(), - methodBuilder - ) - } - } - methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") - val constructJvmCall = StringBuilder() - if (methodDefinition.isStateCreationFunction) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return out") - } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - } - is CustomTypeDefinition -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - } - } - methodBuilder.returns(methodDefinition.returnType.typeName) - return methodBuilder.build() - } - - fun createOutputParam(outputParam: ParameterDefinition, length: String?, methodBuilder: FunSpec.Builder) { - /* - val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES) - sodium.crypto_hash_sha256_final(state, hashed) - return hashed.asUByteArray() - */ - when (outputParam.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val out = UByteArray($length)") - } - else -> { - throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") - } - - - } - } - - fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) { - /* - val state = Hash.State256() - */ - val specificInitializer = stateParameterDefinition.specificJvmInitializer ?: "" - methodBuilder.addStatement("val state = ${stateParameterDefinition.parameterType.typeName}($specificInitializer)") - } - - fun paramsToString(methodDefinition: FunctionDefinition) : String { - val paramsBuilder = StringBuilder() - paramsBuilder.append("(") - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - val separator = if (index == methodDefinition.parameterList.size - 1) { - "" - } else { - ", " - } - if (paramDefinition.parameterType is CustomTypeDefinition) { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - if (paramDefinition.parameterType is TypeDefinition) { - when(paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size.toLong()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".asByteArray()" + separator) - } - TypeDefinition.LONG -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.INT -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.STRING -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - } - } - - } - paramsBuilder.append(')') - return paramsBuilder.toString() - } - - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt deleted file mode 100644 index 46bcea0..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ /dev/null @@ -1,291 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.CodeBlock -import com.squareup.kotlinpoet.FileSpec -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.ParameterSpec -import com.squareup.kotlinpoet.PropertySpec -import com.squareup.kotlinpoet.TypeAliasSpec -import com.squareup.kotlinpoet.asTypeName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object NativeLibsodiumGenerator { - - - fun createNativeFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - fileBuilder.addImport("kotlinx.cinterop", "toCValues") - fileBuilder.addImport("kotlinx.cinterop", "convert") - fileBuilder.addImport("kotlinx.cinterop", "ptr") - fileBuilder.addImport("kotlinx.cinterop", "pin") - fileBuilder.addImport("kotlinx.cinterop", "addressOf") - fileBuilder.addImport("kotlinx.cinterop", "reinterpret") - fileBuilder.addImport("kotlinx.cinterop", "pointed") - fileBuilder.addImport("libsodium", "sodium_malloc") - - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addTypeAlias(createNativeInnerClassSpec(it, MultiplatformModifier.ACTUAL)) - } - - val commonClassSpec = createClass( - commonClassDefinition, - MultiplatformModifier.ACTUAL, - ::createNativeFunctionImplementation - ) - //Workarounds for native not emitting types - val byteEmitter = PropertySpec.builder("_emitByte", Byte::class.asTypeName()) - byteEmitter.initializer(CodeBlock.of("0")) - val byteArrayEmitter = PropertySpec.builder("_emitByteArray", ByteArray::class.asTypeName()) - byteArrayEmitter.initializer(CodeBlock.of("ByteArray(0)")) - commonClassSpec.addProperty(byteEmitter.build()) - commonClassSpec.addProperty(byteArrayEmitter.build()) - fileBuilder.addType(commonClassSpec.build()) - } - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - fun createNativeInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeAliasSpec { - val innerClassBuilder = - TypeAliasSpec.builder(innerClassDefinition.name, ClassName("libsodium", innerClassDefinition.nativeName)) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createNativeFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec { - val methodBuilder = FunSpec.builder(methodDefinition.name) - methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList - var returnModifierFound = false - var returnModifierName = "" - lateinit var actualReturnParameterDefinition: ParameterDefinition - var actualReturnTypeFound: Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) { - createStateParam(paramDefinition, methodBuilder) - } - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - if (paramDefinition.modifiesReturn) { - if (returnModifierFound == true) { - throw RuntimeException("Return modifier already found") - } - returnModifierFound = true - returnModifierName = paramDefinition.parameterName - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnParameterDefinition = paramDefinition - actualReturnTypeFound = true - } - } - if (actualReturnTypeFound) { - if (returnModifierFound) { - createOutputParam(actualReturnParameterDefinition, returnModifierName, methodBuilder) - } else { - if (methodDefinition.outputLengthWhenArray == -1) { - throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") - } - createOutputParam(actualReturnParameterDefinition, methodDefinition.outputLengthWhenArray.toString(), methodBuilder) - } - } - methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") - pinParams(methodDefinition, methodBuilder) - val constructNativeCall = StringBuilder() - if (methodDefinition.isStateCreationFunction) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return out") - } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - } - is CustomTypeDefinition -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - } - - - } - - methodBuilder.returns(methodDefinition.returnType.typeName) - - return methodBuilder.build() - } - - fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) { - /* - val allocated = sodium_malloc(crypto_hash_sha256_state.size.convert())!! - state = allocated.reinterpret().pointed - */ - methodBuilder.addStatement("val allocated = sodium_malloc(${stateParameterDefinition.parameterType.typeName}.size.convert())!!") - methodBuilder.addStatement("val state = allocated.reinterpret<${stateParameterDefinition.parameterType.typeName}>().pointed") - } - - fun createOutputParam(outputParam: ParameterDefinition, length: String?, methodBuilder: FunSpec.Builder) { - /* - val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES) - val hashResultPinned = hashResult.pin() - crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0)) - sodium_free(state.ptr) - return hashResult - */ - when (outputParam.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val out = UByteArray($length)") - } - else -> { - throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") - } - - - } - } - - fun pinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) { - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") - } - TypeDefinition.LONG -> { - - } - TypeDefinition.INT -> { - - } - TypeDefinition.STRING -> { - - } - } - } - - } - } - - fun unpinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) { - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") - } - TypeDefinition.LONG -> { - - } - TypeDefinition.INT -> { - - } - TypeDefinition.STRING -> { - - } - } - } - - } - } - - fun paramsToString(methodDefinition: FunctionDefinition): String { - val paramsBuilder = StringBuilder() - paramsBuilder.append("(") - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - val separator = if (index == methodDefinition.parameterList.size - 1) { - "" - } else { - ", " - } - if (paramDefinition.parameterType is CustomTypeDefinition) { - paramsBuilder.append(paramDefinition.parameterName + ".ptr" + separator) - } - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), " + paramDefinition.parameterName + ".size.convert()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), " + paramDefinition.parameterName + ".size.convert()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0)" + separator) - } - TypeDefinition.LONG -> { - paramsBuilder.append(paramDefinition.parameterName + ".convert()" + separator) - } - TypeDefinition.INT -> { - paramsBuilder.append(paramDefinition.parameterName + ".convert()" + separator) - } - TypeDefinition.STRING -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - } - } - - } - paramsBuilder.append(')') - return paramsBuilder.toString() - } - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt deleted file mode 100644 index 189561b..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.KModifier -import com.squareup.kotlinpoet.TypeSpec - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -fun createClass( - classDefinition: ClassDefinition, - multiplatformModifier: MultiplatformModifier, - methodCreator: (FunctionDefinition) -> FunSpec -): TypeSpec.Builder { - val commonClassBuilder = TypeSpec.classBuilder(classDefinition.name) - // Ugly - val primaryConstructor = FunSpec.constructorBuilder() - if (multiplatformModifier == MultiplatformModifier.EXPECT) { - primaryConstructor.addModifiers(KModifier.INTERNAL) - } else { - primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL) - } - - commonClassBuilder.primaryConstructor(primaryConstructor.build()) - commonClassBuilder.modifiers += multiplatformModifier.modifierList - for (methodDefinition in classDefinition.methods) { - commonClassBuilder.addFunction(methodCreator(methodDefinition)) - } - return commonClassBuilder -} - - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm deleted file mode 100644 index 74f517f..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm +++ /dev/null @@ -1,101 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CStruct public final class crypto_aead_aes256gcm_state_ public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val opaque: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_hash_sha512_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val buf: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val count: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val state: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_auth_hmacsha512_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val ictx: libsodium.crypto_hash_sha512_state /* compiled code */ - - public final val octx: libsodium.crypto_hash_sha512_state /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_hash_sha256_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val buf: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final var count: platform.posix.uint64_t /* = kotlin.ULong */ /* compiled code */ - - public final val state: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_auth_hmacsha256_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val ictx: libsodium.crypto_hash_sha256_state /* compiled code */ - - public final val octx: libsodium.crypto_hash_sha256_state /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_generichash_blake2b_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val opaque: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_onetimeauth_poly1305_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val opaque: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_secretstream_xchacha20poly1305_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val _pad: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val k: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val nonce: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_sign_ed25519ph_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val hs: libsodium.crypto_hash_sha512_state /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class randombytes_implementation public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final var buf: kotlinx.cinterop.CPointer? */, platform.posix.size_t /* = kotlin.ULong */) -> kotlin.Unit>>? /* compiled code */ - - public final var close: kotlinx.cinterop.CPointer kotlin.Int>>? /* compiled code */ - - public final var implementation_name: kotlinx.cinterop.CPointer kotlinx.cinterop.CPointer */>?>>? /* compiled code */ - - public final var random: kotlinx.cinterop.CPointer platform.posix.uint32_t /* = kotlin.UInt */>>? /* compiled code */ - - public final var stir: kotlinx.cinterop.CPointer kotlin.Unit>>? /* compiled code */ - - public final var uniform: kotlinx.cinterop.CPointer platform.posix.uint32_t /* = kotlin.UInt */>>? /* compiled code */ -} - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm deleted file mode 100644 index d9073d2..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_is_available(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_is_available(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_beforenm(ctx_: kotlinx.cinterop.CValuesRef?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt_afternm(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt_detached_afternm(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt_afternm(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt_detached_afternm(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_is_available(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_init(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_library_minimal(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_library_version_major(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_library_version_minor(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_misuse(): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_set_misuse_handler(handler: kotlinx.cinterop.CPointer kotlin.Unit>>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_version_string(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm deleted file mode 100644 index 55096ca..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun crypto_box(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_beforenm(k: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_beforenmbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_beforenm(k: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_beforenmbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_open_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_detached_afternm(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_easy_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_detached_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_easy_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seal(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seal_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_sealbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash(out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b(out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_init_salt_personal(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, outlen: platform.posix.size_t /* = kotlin.ULong */, salt: kotlinx.cinterop.CValuesRef */>?, personal: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keybytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keybytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_personalbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_salt_personal(out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, salt: kotlinx.cinterop.CValuesRef */>?, personal: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keybytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keybytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_contextbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_derive_from_key(subkey: kotlinx.cinterop.CValuesRef */>?, subkey_len: platform.posix.size_t /* = kotlin.ULong */, subkey_id: platform.posix.uint64_t /* = kotlin.ULong */, ctx: kotlinx.cinterop.CValuesRef */>?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_contextbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_derive_from_key(subkey: kotlinx.cinterop.CValuesRef */>?, subkey_len: platform.posix.size_t /* = kotlin.ULong */, subkey_id: platform.posix.uint64_t /* = kotlin.ULong */, ctx: kotlinx.cinterop.CValuesRef */>?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_client_session_keys(rx: kotlinx.cinterop.CValuesRef */>?, tx: kotlinx.cinterop.CValuesRef */>?, client_pk: kotlinx.cinterop.CValuesRef */>?, client_sk: kotlinx.cinterop.CValuesRef */>?, server_pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_server_session_keys(rx: kotlinx.cinterop.CValuesRef */>?, tx: kotlinx.cinterop.CValuesRef */>?, server_pk: kotlinx.cinterop.CValuesRef */>?, server_sk: kotlinx.cinterop.CValuesRef */>?, client_pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_sessionkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm deleted file mode 100644 index 926379c..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_alg_argon2i13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_alg_argon2id13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_alg_default(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_alg_argon2i13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_alg_argon2id13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str_alg(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint32_t /* = kotlin.UInt */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm deleted file mode 100644 index 2d912db..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun _sodium_runtime_get_cpu_features(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_headerbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_init_pull(state: kotlinx.cinterop.CValuesRef?, header: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_init_push(state: kotlinx.cinterop.CValuesRef?, header: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_pull(state: kotlinx.cinterop.CValuesRef?, m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, tag_p: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_push(state: kotlinx.cinterop.CValuesRef?, c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, tag: kotlin.UByte): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_rekey(state: kotlinx.cinterop.CValuesRef?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_final(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_message(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_push(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_rekey(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphash24(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphash24_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphash24_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphashx24(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphashx24_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphashx24_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign(sm: kotlinx.cinterop.CValuesRef */>?, smlen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_detached(sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519(sm: kotlinx.cinterop.CValuesRef */>?, smlen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_detached(sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_open(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, sm: kotlinx.cinterop.CValuesRef */>?, smlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_pk_to_curve25519(curve25519_pk: kotlinx.cinterop.CValuesRef */>?, ed25519_pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_sk_to_curve25519(curve25519_sk: kotlinx.cinterop.CValuesRef */>?, ed25519_sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_sk_to_pk(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_sk_to_seed(seed: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_verify_detached(sig: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_final_create(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_final_verify(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_update(state: kotlinx.cinterop.CValuesRef?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_final_create(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_final_verify(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_open(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, sm: kotlinx.cinterop.CValuesRef */>?, smlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_update(state: kotlinx.cinterop.CValuesRef?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_verify_detached(sig: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_16(x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_16_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_32(x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_32_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_64(x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_64_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes(buf: kotlinx.cinterop.CValuesRef */>?, buf_len: kotlin.ULong): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_buf(buf: kotlinx.cinterop.CValuesRef<*>?, size: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_buf_deterministic(buf: kotlinx.cinterop.CValuesRef<*>?, size: platform.posix.size_t /* = kotlin.ULong */, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_close(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_implementation_name(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_random(): platform.posix.uint32_t /* = kotlin.UInt */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_set_implementation(impl: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_stir(): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_uniform(upper_bound: platform.posix.uint32_t /* = kotlin.UInt */): platform.posix.uint32_t /* = kotlin.UInt */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_add(a: kotlinx.cinterop.CValuesRef */>?, b: kotlinx.cinterop.CValuesRef */>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_allocarray(count: platform.posix.size_t /* = kotlin.ULong */, size: platform.posix.size_t /* = kotlin.ULong */): kotlinx.cinterop.COpaquePointer? /* = kotlinx.cinterop.CPointer? */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_base642bin(bin: kotlinx.cinterop.CValuesRef */>?, bin_maxlen: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString b64: kotlin.String?, b64_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ignore: kotlin.String?, bin_len: kotlinx.cinterop.CValuesRef */>?, b64_end: kotlinx.cinterop.CValuesRef */> /* = kotlinx.cinterop.CPointerVarOf */>> */>?, variant: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_base64_encoded_len(bin_len: platform.posix.size_t /* = kotlin.ULong */, variant: kotlin.Int): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_bin2base64(b64: kotlinx.cinterop.CValuesRef */>?, b64_maxlen: platform.posix.size_t /* = kotlin.ULong */, bin: kotlinx.cinterop.CValuesRef */>?, bin_len: platform.posix.size_t /* = kotlin.ULong */, variant: kotlin.Int): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_bin2hex(hex: kotlinx.cinterop.CValuesRef */>?, hex_maxlen: platform.posix.size_t /* = kotlin.ULong */, bin: kotlinx.cinterop.CValuesRef */>?, bin_len: platform.posix.size_t /* = kotlin.ULong */): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_compare(b1_: kotlinx.cinterop.CValuesRef */>?, b2_: kotlinx.cinterop.CValuesRef */>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_free(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_hex2bin(bin: kotlinx.cinterop.CValuesRef */>?, bin_maxlen: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString hex: kotlin.String?, hex_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ignore: kotlin.String?, bin_len: kotlinx.cinterop.CValuesRef */>?, hex_end: kotlinx.cinterop.CValuesRef */> /* = kotlinx.cinterop.CPointerVarOf */>> */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_increment(n: kotlinx.cinterop.CValuesRef */>?, nlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_is_zero(n: kotlinx.cinterop.CValuesRef */>?, nlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_malloc(size: platform.posix.size_t /* = kotlin.ULong */): kotlinx.cinterop.COpaquePointer? /* = kotlinx.cinterop.CPointer? */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_memcmp(b1_: kotlinx.cinterop.CValuesRef<*>?, b2_: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_memzero(pnt: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mlock(addr: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mprotect_noaccess(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mprotect_readonly(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mprotect_readwrite(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_munlock(addr: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_aesni(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_armcrypto(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_avx(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_avx2(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_avx512f(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_neon(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_pclmul(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_rdrand(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_sse2(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_sse3(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_sse41(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_ssse3(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_stackzero(len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_sub(a: kotlinx.cinterop.CValuesRef */>?, b: kotlinx.cinterop.CValuesRef */>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm deleted file mode 100644 index dbcc66b..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun _sodium_alloc_init(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_beforenm(k: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_beforenmbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_detached_afternm(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_easy_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_detached_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_easy_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seal(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seal_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_sealbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_add(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_from_string(p: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, msg: kotlinx.cinterop.CValuesRef */>?, msg_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_from_string_ro(p: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, msg: kotlinx.cinterop.CValuesRef */>?, msg_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_from_uniform(p: kotlinx.cinterop.CValuesRef */>?, r: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_hashbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_is_valid_point(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_nonreducedscalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_random(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_add(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_complement(comp: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_invert(recip: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_is_canonical(s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_mul(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_negate(neg: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_random(r: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_reduce(r: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_sub(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_sub(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_uniformbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_add(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_from_hash(p: kotlinx.cinterop.CValuesRef */>?, r: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_hashbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_is_valid_point(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_nonreducedscalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_random(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_add(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_complement(comp: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_invert(recip: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_is_canonical(s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_mul(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_negate(neg: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_random(r: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_reduce(r: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_sub(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_sub(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_expand(out: kotlinx.cinterop.CValuesRef */>?, out_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, ctx_len: platform.posix.size_t /* = kotlin.ULong */, prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_extract(prk: kotlinx.cinterop.CValuesRef */>?, salt: kotlinx.cinterop.CValuesRef */>?, salt_len: platform.posix.size_t /* = kotlin.ULong */, ikm: kotlinx.cinterop.CValuesRef */>?, ikm_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_keygen(prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_expand(out: kotlinx.cinterop.CValuesRef */>?, out_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, ctx_len: platform.posix.size_t /* = kotlin.ULong */, prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_extract(prk: kotlinx.cinterop.CValuesRef */>?, salt: kotlinx.cinterop.CValuesRef */>?, salt_len: platform.posix.size_t /* = kotlin.ULong */, ikm: kotlinx.cinterop.CValuesRef */>?, ikm_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_keygen(prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_ll(passwd: kotlinx.cinterop.CValuesRef */>?, passwdlen: platform.posix.size_t /* = kotlin.ULong */, salt: kotlinx.cinterop.CValuesRef */>?, saltlen: platform.posix.size_t /* = kotlin.ULong */, N: platform.posix.uint64_t /* = kotlin.ULong */, r: platform.posix.uint32_t /* = kotlin.UInt */, p: platform.posix.uint32_t /* = kotlin.UInt */, buf: kotlinx.cinterop.CValuesRef */>?, buflen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_base_noclamp(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_noclamp(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_pad(padded_buflen_p: kotlinx.cinterop.CValuesRef */>?, buf: kotlinx.cinterop.CValuesRef */>?, unpadded_buflen: platform.posix.size_t /* = kotlin.ULong */, blocksize: platform.posix.size_t /* = kotlin.ULong */, max_buflen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_unpad(unpadded_buflen_p: kotlinx.cinterop.CValuesRef */>?, buf: kotlinx.cinterop.CValuesRef */>?, padded_buflen: platform.posix.size_t /* = kotlin.ULong */, blocksize: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm deleted file mode 100644 index 7a15690..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -public const val SODIUM_LIBRARY_VERSION_MAJOR: kotlin.Int /* compiled code */ - -public const val SODIUM_LIBRARY_VERSION_MINOR: kotlin.Int /* compiled code */ - -public const val SODIUM_SIZE_MAX: kotlin.ULong /* compiled code */ - -public const val SODIUM_VERSION_STRING: kotlin.String /* compiled code */ - -public const val crypto_aead_aegis128l_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis128l_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis128l_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_aegis128l_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis128l_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_aegis256_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_aes256gcm_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_chacha20poly1305_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_auth_hmacsha256_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512256_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_BEFORENMBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_box_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_box_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_SEALBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_KEYBYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_KEYBYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_generichash_blake2b_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_KEYBYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_KEYBYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_PERSONALBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_hash_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_hash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_hash_sha256_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_hash_sha512_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_blake2b_BYTES_MAX: kotlin.Int /* compiled code */ - -public const val crypto_kdf_blake2b_BYTES_MIN: kotlin.Int /* compiled code */ - -public const val crypto_stream_xsalsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_xsalsa20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_xsalsa20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public val randombytes_internal_implementation: libsodium.randombytes_implementation /* compiled code */ - -public val randombytes_sysrandom_implementation: libsodium.randombytes_implementation /* compiled code */ - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -public typealias crypto_aead_aes256gcm_state = libsodium.crypto_aead_aes256gcm_state_ - -public typealias crypto_auth_hmacsha512256_state = libsodium.crypto_auth_hmacsha512_state - -public typealias crypto_generichash_state = libsodium.crypto_generichash_blake2b_state - -public typealias crypto_onetimeauth_state = libsodium.crypto_onetimeauth_poly1305_state - -public typealias crypto_sign_state = libsodium.crypto_sign_ed25519ph_state - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm deleted file mode 100644 index eb6a78a..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -public const val crypto_kdf_BYTES_MAX: kotlin.Int /* compiled code */ - -public const val crypto_kdf_BYTES_MIN: kotlin.Int /* compiled code */ - -public const val crypto_kdf_CONTEXTBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_KEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_kdf_blake2b_CONTEXTBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_blake2b_KEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_kx_PUBLICKEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_SECRETKEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_SEEDBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_SESSIONKEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_onetimeauth_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_onetimeauth_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_onetimeauth_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_onetimeauth_poly1305_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_onetimeauth_poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_ALG_ARGON2I13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_ALG_ARGON2ID13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_ALG_DEFAULT: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_PASSWD_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_pwhash_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_pwhash_argon2i_ALG_ARGON2I13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_argon2i_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2i_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_PASSWD_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_pwhash_argon2id_ALG_ARGON2ID13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_argon2id_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2id_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_PASSWD_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_scalarmult_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_scalarmult_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_curve25519_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_curve25519_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretbox_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_secretbox_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_HEADERBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_FINAL: kotlin.Int /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_MESSAGE: kotlin.Int /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_PUSH: kotlin.Int /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_REKEY: kotlin.Int /* compiled code */ - -public const val crypto_shorthash_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_shorthash_siphash24_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_siphash24_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_siphashx24_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_siphashx24_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_sign_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_sign_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_sign_ed25519_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_IETF_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_chacha20_IETF_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_chacha20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_ietf_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_chacha20_ietf_NONCEBYTES: kotlin.UInt /* compiled code */ - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm deleted file mode 100644 index 60ee5dc..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm +++ /dev/null @@ -1,145 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -public const val crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_SEALBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_ed25519_BYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_HASHBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_NONREDUCEDSCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_SCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_UNIFORMBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_BYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_HASHBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_NONREDUCEDSCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_SCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_hkdf_sha256_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha256_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha512_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha512_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha512_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_scalarmult_ed25519_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_ed25519_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_ristretto255_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_ristretto255_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_stream_salsa2012_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa2012_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_salsa2012_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa208_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa208_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_salsa208_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_salsa20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_xchacha20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_xchacha20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_xchacha20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_verify_16_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_verify_32_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_verify_64_BYTES: kotlin.UInt /* compiled code */ - -public const val randombytes_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val randombytes_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val sodium_base64_VARIANT_ORIGINAL: kotlin.Int /* compiled code */ - -public const val sodium_base64_VARIANT_ORIGINAL_NO_PADDING: kotlin.Int /* compiled code */ - -public const val sodium_base64_VARIANT_URLSAFE: kotlin.Int /* compiled code */ - -public const val sodium_base64_VARIANT_URLSAFE_NO_PADDING: kotlin.Int /* compiled code */ - diff --git a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt deleted file mode 100644 index 32aa3b2..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.ionspin.kotlin.crypto.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.generator.CommonLibsodiumGenerator -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefinitions -import com.ionspin.kotlin.crypto.generator.libsodium.generator.Coordinator -import org.junit.Test - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -class DebugTest { - @Test - fun debugTest() { - Coordinator.run() - } -} diff --git a/libsodium_js_debug_list.txt b/libsodium_js_debug_list.txt new file mode 100644 index 0000000..01d4ff7 --- /dev/null +++ b/libsodium_js_debug_list.txt @@ -0,0 +1,395 @@ +add = function(e,t){if(!(e instanceof Uint8Array&&t instanceof Uint8Array))throw new TypeError("Only Uint8Array instances can added");var r=e.length,a=0,_=0;if(t.length!=e.length)throw new TypeError("Arguments must have the same length");for(_=0;_>=8,a+=e[_]+t[_],e[_]=255&a} +base64_variants = Object {ORIGINAL: 1, +ORIGINAL_NO_PADDING: 3, +URLSAFE: 5, +URLSAFE_NO_PADDING: 7} +compare = function(e,t){if(!(e instanceof Uint8Array&&t instanceof Uint8Array))throw new TypeError("Only Uint8Array instances can be compared");if(e.length!==t.length)throw new TypeError("Only instances of identical length can be compared");for(var r=0,a=1,_=e.length;_-- >0;)r|=t[_]-e[_]>>8&a,a&=(t[_]^e[_])-1>>8;return r+r+a-1} +from_base64 = function(e,t){t=o(t);var a,_=[],n=new l(3*(e=m(_,e,"input")).length/4),s=u(e),c=d(4),h=d(4);return _.push(s),_.push(n.address),_.push(n.result_bin_len_p),_.push(n.b64_end_p),0!==r._sodium_base642bin(n.address,n.length,s,e.length,0,c,h,t)&&g(_,"invalid input"),r.getValue(h,"i32")-s!==e.length&&g(_,"incomplete input"),n.length=r.getValue(c,"i32"),a=n.to_Uint8Array(),v(_),a} +from_hex = function(e){var t,a=[],_=new l((e=m(a,e,"input")).length/2),n=u(e),s=d(4);return a.push(n),a.push(_.address),a.push(_.hex_end_p),0!==r._sodium_hex2bin(_.address,_.length,n,e.length,0,0,s)&&g(a,"invalid input"),r.getValue(s,"i32")-n!==e.length&&g(a,"incomplete input"),t=_.to_Uint8Array(),v(a),t} +from_string = function _(e){if("function"==typeof TextEncoder)return(new TextEncoder).encode(e);e=unescape(encodeURIComponent(e));for(var t=new Uint8Array(e.length),r=0,a=e.length;r>=8,t+=e[r],e[r]=255&t} +is_zero = function(e){if(!(e instanceof Uint8Array))throw new TypeError("Only Uint8Array instances can be checked");for(var t=0,r=0,a=e.length;r 0");var a,_=[],n=d(4),s=1,c=0,o=0|e.length,h=new l(o+t);_.push(n),_.push(h.address);for(var p=h.address,y=h.address+o+t;p>>48|o>>>32|o>>>16|o))-1>>16);return 0!==r._sodium_pad(n,h.address,e.length,t,h.length)&&g(_,"internal error"),h.length=r.getValue(n,"i32"),a=h.to_Uint8Array(),v(_),a} +unpad = function(e,t){if(!(e instanceof Uint8Array))throw new TypeError("buffer must be a Uint8Array");if((t|=0)<=0)throw new Error("block size must be > 0");var a=[],_=u(e),n=d(4);return a.push(_),a.push(n),0!==r._sodium_unpad(n,_,e.length,t)&&g(a,"unsupported/invalid padding"),e=(e=new Uint8Array(e)).subarray(0,r.getValue(n,"i32")),v(a),e} +ready = Promise {[[PromiseStatus]]: "resolved", +[[PromiseValue]]: undefined} +symbols = function(){return Object.keys(e).sort()} +to_base64 = function h(e,t){t=o(t),e=m(_,e,"input");var a,_=[],s=0|Math.floor(e.length/3),c=e.length-3*s,h=4*s+(0!==c?0==(2&t)?4:2+(c>>>1):0),p=new l(h+1),y=u(e);return _.push(y),_.push(p.address),0===r._sodium_bin2base64(p.address,p.length,y,e.length,t)&&g(_,"conversion failed"),p.length=h,a=n(p.to_Uint8Array()),v(_),a} +to_hex = function s(e){e=m(null,e,"input");for(var t,r,a,_="",n=0;n>8&-39)<<8|87+(t=e[n]>>>4)+(t-10>>8&-39),_+=String.fromCharCode(255&a)+String.fromCharCode(a>>>8);return _} +to_string = function n(e){if("function"==typeof TextDecoder)return new TextDecoder("utf-8",{fatal:!0}).decode(e);var t=Math.ceil(e.length/8192);if(t<=1)try{return decodeURIComponent(escape(String.fromCharCode.apply(null,e)))}catch(e){throw new TypeError("The encoded data was not valid.")}for(var r="",a=0,_=0;_=240?(h=4,c=!0):p>=224?(h=3,c=!0):p>=192?(h=2,c=!0):p<128&&(h=1,c=!0)}while(!c);for(var y=h-(s.length-o),i=0;i>>24>>>8,o,y);var x=p(g,s);return v(c),x} +crypto_kdf_keygen = function Le(e){var t=[];i(e);var a=new l(0|r._crypto_kdf_keybytes()),_=a.address;t.push(_),r._crypto_kdf_keygen(_);var n=p(a,e);return v(t),n} +crypto_kx_client_session_keys = function Ue(e,t,a,_){var n=[];i(_),e=m(n,e,"clientPublicKey");var s,c=0|r._crypto_kx_publickeybytes();e.length!==c&&b(n,"invalid clientPublicKey length"),s=u(e),n.push(s),t=m(n,t,"clientSecretKey");var o,h=0|r._crypto_kx_secretkeybytes();t.length!==h&&b(n,"invalid clientSecretKey length"),o=u(t),n.push(o),a=m(n,a,"serverPublicKey");var y,d=0|r._crypto_kx_publickeybytes();a.length!==d&&b(n,"invalid serverPublicKey length"),y=u(a),n.push(y);var f=new l(0|r._crypto_kx_sessionkeybytes()),E=f.address;n.push(E);var x=new l(0|r._crypto_kx_sessionkeybytes()),k=x.address;if(n.push(k),0==(0|r._crypto_kx_client_session_keys(E,k,s,o,y))){var S=p({sharedRx:f,sharedTx:x},_);return v(n),S}g(n,"invalid usage")} +crypto_kx_keypair = function Oe(e){var t=[];i(e);var a=new l(0|r._crypto_kx_publickeybytes()),_=a.address;t.push(_);var n=new l(0|r._crypto_kx_secretkeybytes()),s=n.address;if(t.push(s),0==(0|r._crypto_kx_keypair(_,s))){var c={publicKey:p(a,e),privateKey:p(n,e),keyType:"x25519"};return v(t),c}g(t,"internal error")} +crypto_kx_seed_keypair = function Ce(e,t){var a=[];i(t),e=m(a,e,"seed");var _,n=0|r._crypto_kx_seedbytes();e.length!==n&&b(a,"invalid seed length"),_=u(e),a.push(_);var s=new l(0|r._crypto_kx_publickeybytes()),c=s.address;a.push(c);var o=new l(0|r._crypto_kx_secretkeybytes()),h=o.address;if(a.push(h),0==(0|r._crypto_kx_seed_keypair(c,h,_))){var y={publicKey:p(s,t),privateKey:p(o,t),keyType:"x25519"};return v(a),y}g(a,"internal error")} +crypto_kx_server_session_keys = function Re(e,t,a,_){var n=[];i(_),e=m(n,e,"serverPublicKey");var s,c=0|r._crypto_kx_publickeybytes();e.length!==c&&b(n,"invalid serverPublicKey length"),s=u(e),n.push(s),t=m(n,t,"serverSecretKey");var o,h=0|r._crypto_kx_secretkeybytes();t.length!==h&&b(n,"invalid serverSecretKey length"),o=u(t),n.push(o),a=m(n,a,"clientPublicKey");var y,d=0|r._crypto_kx_publickeybytes();a.length!==d&&b(n,"invalid clientPublicKey length"),y=u(a),n.push(y);var f=new l(0|r._crypto_kx_sessionkeybytes()),E=f.address;n.push(E);var x=new l(0|r._crypto_kx_sessionkeybytes()),k=x.address;if(n.push(k),0==(0|r._crypto_kx_server_session_keys(E,k,s,o,y))){var S=p({sharedRx:f,sharedTx:x},_);return v(n),S}g(n,"invalid usage")} +crypto_onetimeauth = function Pe(e,t,a){var _=[];i(a);var n=u(e=m(_,e,"message")),s=e.length;_.push(n),t=m(_,t,"key");var c,o=0|r._crypto_onetimeauth_keybytes();t.length!==o&&b(_,"invalid key length"),c=u(t),_.push(c);var h=new l(0|r._crypto_onetimeauth_bytes()),y=h.address;if(_.push(y),0==(0|r._crypto_onetimeauth(y,n,s,0,c))){var d=p(h,a);return v(_),d}g(_,"invalid usage")} +crypto_onetimeauth_final = function Ge(e,t){var a=[];i(t),f(a,e,"state_address");var _=new l(0|r._crypto_onetimeauth_bytes()),n=_.address;if(a.push(n),0==(0|r._crypto_onetimeauth_final(e,n))){var s=(r._free(e),p(_,t));return v(a),s}g(a,"invalid usage")} +crypto_onetimeauth_init = function Xe(e,t){var a=[];i(t);var _=null;null!=e&&(_=u(e=m(a,e,"key")),e.length,a.push(_));var n=new l(144).address;if(0==(0|r._crypto_onetimeauth_init(n,_))){var s=n;return v(a),s}g(a,"invalid usage")} +crypto_onetimeauth_keygen = function De(e){var t=[];i(e);var a=new l(0|r._crypto_onetimeauth_keybytes()),_=a.address;t.push(_),r._crypto_onetimeauth_keygen(_);var n=p(a,e);return v(t),n} +crypto_onetimeauth_update = function Fe(e,t,a){var _=[];i(a),f(_,e,"state_address");var n=u(t=m(_,t,"message_chunk")),s=t.length;_.push(n),0!=(0|r._crypto_onetimeauth_update(e,n,s))&&g(_,"invalid usage"),v(_)} +crypto_onetimeauth_verify = function Ve(e,t,a){var _=[];e=m(_,e,"hash");var n,s=0|r._crypto_onetimeauth_bytes();e.length!==s&&b(_,"invalid hash length"),n=u(e),_.push(n);var c=u(t=m(_,t,"message")),o=t.length;_.push(c),a=m(_,a,"key");var h,p=0|r._crypto_onetimeauth_keybytes();a.length!==p&&b(_,"invalid key length"),h=u(a),_.push(h);var y=0==(0|r._crypto_onetimeauth_verify(n,c,o,0,h));return v(_),y} +crypto_pwhash = function He(e,t,a,_,n,s,c){var o=[];i(c),f(o,e,"keyLength"),("number"!=typeof e||(0|e)!==e||e<0)&&b(o,"keyLength must be an unsigned integer");var h=u(t=m(o,t,"password")),y=t.length;o.push(h),a=m(o,a,"salt");var d,E=0|r._crypto_pwhash_saltbytes();a.length!==E&&b(o,"invalid salt length"),d=u(a),o.push(d),f(o,_,"opsLimit"),("number"!=typeof _||(0|_)!==_||_<0)&&b(o,"opsLimit must be an unsigned integer"),f(o,n,"memLimit"),("number"!=typeof n||(0|n)!==n||n<0)&&b(o,"memLimit must be an unsigned integer"),f(o,s,"algorithm"),("number"!=typeof s||(0|s)!==s||s<0)&&b(o,"algorithm must be an unsigned integer");var x=new l(0|e),k=x.address;if(o.push(k),0==(0|r._crypto_pwhash(k,e,0,h,y,0,d,_,0,n,s))){var S=p(x,c);return v(o),S}g(o,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256 = function ze(e,t,a,_,n,s){var c=[];i(s),f(c,e,"keyLength"),("number"!=typeof e||(0|e)!==e||e<0)&&b(c,"keyLength must be an unsigned integer");var o=u(t=m(c,t,"password")),h=t.length;c.push(o),a=m(c,a,"salt");var y,d=0|r._crypto_pwhash_scryptsalsa208sha256_saltbytes();a.length!==d&&b(c,"invalid salt length"),y=u(a),c.push(y),f(c,_,"opsLimit"),("number"!=typeof _||(0|_)!==_||_<0)&&b(c,"opsLimit must be an unsigned integer"),f(c,n,"memLimit"),("number"!=typeof n||(0|n)!==n||n<0)&&b(c,"memLimit must be an unsigned integer");var E=new l(0|e),x=E.address;if(c.push(x),0==(0|r._crypto_pwhash_scryptsalsa208sha256(x,e,0,o,h,0,y,_,0,n))){var k=p(E,s);return v(c),k}g(c,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256_ll = function je(e,t,a,_,n,s,c){var o=[];i(c);var h=u(e=m(o,e,"password")),y=e.length;o.push(h);var d=u(t=m(o,t,"salt")),E=t.length;o.push(d),f(o,a,"opsLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(o,"opsLimit must be an unsigned integer"),f(o,_,"r"),("number"!=typeof _||(0|_)!==_||_<0)&&b(o,"r must be an unsigned integer"),f(o,n,"p"),("number"!=typeof n||(0|n)!==n||n<0)&&b(o,"p must be an unsigned integer"),f(o,s,"keyLength"),("number"!=typeof s||(0|s)!==s||s<0)&&b(o,"keyLength must be an unsigned integer");var x=new l(0|s),k=x.address;if(o.push(k),0==(0|r._crypto_pwhash_scryptsalsa208sha256_ll(h,y,d,E,a,0,_,n,k,s))){var S=p(x,c);return v(o),S}g(o,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256_str = function qe(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"password")),c=e.length;n.push(s),f(n,t,"opsLimit"),("number"!=typeof t||(0|t)!==t||t<0)&&b(n,"opsLimit must be an unsigned integer"),f(n,a,"memLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(n,"memLimit must be an unsigned integer");var o=new l(0|r._crypto_pwhash_scryptsalsa208sha256_strbytes()).address;if(n.push(o),0==(0|r._crypto_pwhash_scryptsalsa208sha256_str(o,s,c,0,t,0,a))){var h=r.UTF8ToString(o);return v(n),h}g(n,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256_str_verify = function We(e,t,a){var n=[];i(a),"string"!=typeof e&&b(n,"hashed_password must be a string"),e=_(e+"\0"),null!=c&&e.length-1!==c&&b(n,"invalid hashed_password length");var s=u(e),c=e.length-1;n.push(s);var o=u(t=m(n,t,"password")),h=t.length;n.push(o);var p=0==(0|r._crypto_pwhash_scryptsalsa208sha256_str_verify(s,o,h,0));return v(n),p} +crypto_pwhash_str = function Je(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"password")),c=e.length;n.push(s),f(n,t,"opsLimit"),("number"!=typeof t||(0|t)!==t||t<0)&&b(n,"opsLimit must be an unsigned integer"),f(n,a,"memLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(n,"memLimit must be an unsigned integer");var o=new l(0|r._crypto_pwhash_strbytes()).address;if(n.push(o),0==(0|r._crypto_pwhash_str(o,s,c,0,t,0,a))){var h=r.UTF8ToString(o);return v(n),h}g(n,"invalid usage")} +crypto_pwhash_str_needs_rehash = function Qe(e,t,a,n){var s=[];i(n),"string"!=typeof e&&b(s,"hashed_password must be a string"),e=_(e+"\0"),null!=o&&e.length-1!==o&&b(s,"invalid hashed_password length");var c=u(e),o=e.length-1;s.push(c),f(s,t,"opsLimit"),("number"!=typeof t||(0|t)!==t||t<0)&&b(s,"opsLimit must be an unsigned integer"),f(s,a,"memLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(s,"memLimit must be an unsigned integer");var h=0!=(0|r._crypto_pwhash_str_needs_rehash(c,t,0,a));return v(s),h} +crypto_pwhash_str_verify = function Ze(e,t,a){var n=[];i(a),"string"!=typeof e&&b(n,"hashed_password must be a string"),e=_(e+"\0"),null!=c&&e.length-1!==c&&b(n,"invalid hashed_password length");var s=u(e),c=e.length-1;n.push(s);var o=u(t=m(n,t,"password")),h=t.length;n.push(o);var p=0==(0|r._crypto_pwhash_str_verify(s,o,h,0));return v(n),p} +crypto_scalarmult = function $e(e,t,a){var _=[];i(a),e=m(_,e,"privateKey");var n,s=0|r._crypto_scalarmult_scalarbytes();e.length!==s&&b(_,"invalid privateKey length"),n=u(e),_.push(n),t=m(_,t,"publicKey");var c,o=0|r._crypto_scalarmult_scalarbytes();t.length!==o&&b(_,"invalid publicKey length"),c=u(t),_.push(c);var h=new l(0|r._crypto_scalarmult_bytes()),y=h.address;if(_.push(y),0==(0|r._crypto_scalarmult(y,n,c))){var d=p(h,a);return v(_),d}g(_,"weak public key")} +crypto_scalarmult_base = function et(e,t){var a=[];i(t),e=m(a,e,"privateKey");var _,n=0|r._crypto_scalarmult_scalarbytes();e.length!==n&&b(a,"invalid privateKey length"),_=u(e),a.push(_);var s=new l(0|r._crypto_scalarmult_scalarbytes()),c=s.address;if(a.push(c),0==(0|r._crypto_scalarmult_base(c,_))){var o=p(s,t);return v(a),o}g(a,"insecure scalar")} +crypto_scalarmult_ristretto255 = function tt(e,t,a){var _=[];i(a),e=m(_,e,"scalar");var n,s=0|r._crypto_scalarmult_ristretto255_scalarbytes();e.length!==s&&b(_,"invalid scalar length"),n=u(e),_.push(n),t=m(_,t,"privateKey");var c,o=0|r._crypto_scalarmult_ristretto255_bytes();t.length!==o&&b(_,"invalid privateKey length"),c=u(t),_.push(c);var h=new l(0|r._crypto_scalarmult_ristretto255_bytes()),y=h.address;if(_.push(y),0==(0|r._crypto_scalarmult_ristretto255(y,n,c))){var d=p(h,a);return v(_),d}g(_,"input is zero element")} +crypto_scalarmult_ristretto255_base = function rt(e,t){var a=[];i(t);var _=u(e=m(a,e,"scalar"));e.length,a.push(_);var n=new l(0|r._crypto_core_ristretto255_bytes()),s=n.address;if(a.push(s),0==(0|r._crypto_scalarmult_ristretto255_base(s,_))){var c=p(n,t);return v(a),c}g(a,"scalar is 0")} +crypto_secretbox_detached = function at(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"message")),c=e.length;n.push(s),t=m(n,t,"nonce");var o,h=0|r._crypto_secretbox_noncebytes();t.length!==h&&b(n,"invalid nonce length"),o=u(t),n.push(o),a=m(n,a,"key");var y,d=0|r._crypto_secretbox_keybytes();a.length!==d&&b(n,"invalid key length"),y=u(a),n.push(y);var f=new l(0|c),E=f.address;n.push(E);var x=new l(0|r._crypto_secretbox_macbytes()),k=x.address;if(n.push(k),0==(0|r._crypto_secretbox_detached(E,k,s,c,0,o,y))){var S=p({mac:x,cipher:f},_);return v(n),S}g(n,"invalid usage")} +crypto_secretbox_easy = function _t(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"message")),c=e.length;n.push(s),t=m(n,t,"nonce");var o,h=0|r._crypto_secretbox_noncebytes();t.length!==h&&b(n,"invalid nonce length"),o=u(t),n.push(o),a=m(n,a,"key");var y,d=0|r._crypto_secretbox_keybytes();a.length!==d&&b(n,"invalid key length"),y=u(a),n.push(y);var f=new l(c+r._crypto_secretbox_macbytes()|0),E=f.address;if(n.push(E),0==(0|r._crypto_secretbox_easy(E,s,c,0,o,y))){var x=p(f,_);return v(n),x}g(n,"invalid usage")} +crypto_secretbox_keygen = function nt(e){var t=[];i(e);var a=new l(0|r._crypto_secretbox_keybytes()),_=a.address;t.push(_),r._crypto_secretbox_keygen(_);var n=p(a,e);return v(t),n} +crypto_secretbox_open_detached = function st(e,t,a,_,n){var s=[];i(n);var c=u(e=m(s,e,"ciphertext")),o=e.length;s.push(c),t=m(s,t,"mac");var h,y=0|r._crypto_secretbox_macbytes();t.length!==y&&b(s,"invalid mac length"),h=u(t),s.push(h),a=m(s,a,"nonce");var d,f=0|r._crypto_secretbox_noncebytes();a.length!==f&&b(s,"invalid nonce length"),d=u(a),s.push(d),_=m(s,_,"key");var E,x=0|r._crypto_secretbox_keybytes();_.length!==x&&b(s,"invalid key length"),E=u(_),s.push(E);var k=new l(0|o),S=k.address;if(s.push(S),0==(0|r._crypto_secretbox_open_detached(S,c,h,o,0,d,E))){var T=p(k,n);return v(s),T}g(s,"wrong secret key for the given ciphertext")} +crypto_secretbox_open_easy = function ct(e,t,a,_){var n=[];i(_),e=m(n,e,"ciphertext");var s,c=r._crypto_secretbox_macbytes(),o=e.length;o>>0;return v([]),t} +randombytes_stir = function zt(e){i(e),r._randombytes_stir()} +randombytes_uniform = function jt(e,t){var a=[];i(t),f(a,e,"upper_bound"),("number"!=typeof e||(0|e)!==e||e<0)&&b(a,"upper_bound must be an unsigned integer");var _=r._randombytes_uniform(e)>>>0;return v(a),_} +sodium_version_string = function qt(){var e=r._sodium_version_string(),t=r.UTF8ToString(e);return v([]),t} +SODIUM_LIBRARY_VERSION_MAJOR = 10 +SODIUM_LIBRARY_VERSION_MINOR = 3 +crypto_aead_chacha20poly1305_ABYTES = 16 +crypto_aead_chacha20poly1305_IETF_ABYTES = 16 +crypto_aead_chacha20poly1305_IETF_KEYBYTES = 32 +crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX = -17 +crypto_aead_chacha20poly1305_IETF_NPUBBYTES = 12 +crypto_aead_chacha20poly1305_IETF_NSECBYTES = 0 +crypto_aead_chacha20poly1305_KEYBYTES = 32 +crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX = -17 +crypto_aead_chacha20poly1305_NPUBBYTES = 8 +crypto_aead_chacha20poly1305_NSECBYTES = 0 +crypto_aead_chacha20poly1305_ietf_ABYTES = 16 +crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32 +crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX = -17 +crypto_aead_chacha20poly1305_ietf_NPUBBYTES = 12 +crypto_aead_chacha20poly1305_ietf_NSECBYTES = 0 +crypto_aead_xchacha20poly1305_IETF_ABYTES = 16 +crypto_aead_xchacha20poly1305_IETF_KEYBYTES = 32 +crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX = -17 +crypto_aead_xchacha20poly1305_IETF_NPUBBYTES = 24 +crypto_aead_xchacha20poly1305_IETF_NSECBYTES = 0 +crypto_aead_xchacha20poly1305_ietf_ABYTES = 16 +crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32 +crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX = -17 +crypto_aead_xchacha20poly1305_ietf_NPUBBYTES = 24 +crypto_aead_xchacha20poly1305_ietf_NSECBYTES = 0 +crypto_auth_BYTES = 32 +crypto_auth_KEYBYTES = 32 +crypto_auth_hmacsha256_BYTES = 32 +crypto_auth_hmacsha256_KEYBYTES = 32 +crypto_auth_hmacsha512256_BYTES = 32 +crypto_auth_hmacsha512256_KEYBYTES = 32 +crypto_auth_hmacsha512_BYTES = 64 +crypto_auth_hmacsha512_KEYBYTES = 32 +crypto_box_BEFORENMBYTES = 32 +crypto_box_MACBYTES = 16 +crypto_box_MESSAGEBYTES_MAX = -17 +crypto_box_NONCEBYTES = 24 +crypto_box_PUBLICKEYBYTES = 32 +crypto_box_SEALBYTES = 48 +crypto_box_SECRETKEYBYTES = 32 +crypto_box_SEEDBYTES = 32 +crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES = 32 +crypto_box_curve25519xchacha20poly1305_MACBYTES = 16 +crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX = -17 +crypto_box_curve25519xchacha20poly1305_NONCEBYTES = 24 +crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES = 32 +crypto_box_curve25519xchacha20poly1305_SEALBYTES = 48 +crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES = 32 +crypto_box_curve25519xchacha20poly1305_SEEDBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_MACBYTES = 16 +crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX = -17 +crypto_box_curve25519xsalsa20poly1305_NONCEBYTES = 24 +crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_SEEDBYTES = 32 +crypto_core_ed25519_BYTES = 32 +crypto_core_ed25519_HASHBYTES = 64 +crypto_core_ed25519_NONREDUCEDSCALARBYTES = 64 +crypto_core_ed25519_SCALARBYTES = 32 +crypto_core_ed25519_UNIFORMBYTES = 32 +crypto_core_hchacha20_CONSTBYTES = 16 +crypto_core_hchacha20_INPUTBYTES = 16 +crypto_core_hchacha20_KEYBYTES = 32 +crypto_core_hchacha20_OUTPUTBYTES = 32 +crypto_core_hsalsa20_CONSTBYTES = 16 +crypto_core_hsalsa20_INPUTBYTES = 16 +crypto_core_hsalsa20_KEYBYTES = 32 +crypto_core_hsalsa20_OUTPUTBYTES = 32 +crypto_core_ristretto255_BYTES = 32 +crypto_core_ristretto255_HASHBYTES = 64 +crypto_core_ristretto255_NONREDUCEDSCALARBYTES = 64 +crypto_core_ristretto255_SCALARBYTES = 32 +crypto_core_salsa2012_CONSTBYTES = 16 +crypto_core_salsa2012_INPUTBYTES = 16 +crypto_core_salsa2012_KEYBYTES = 32 +crypto_core_salsa2012_OUTPUTBYTES = 64 +crypto_core_salsa20_CONSTBYTES = 16 +crypto_core_salsa20_INPUTBYTES = 16 +crypto_core_salsa20_KEYBYTES = 32 +crypto_core_salsa20_OUTPUTBYTES = 64 +crypto_generichash_BYTES = 32 +crypto_generichash_BYTES_MAX = 64 +crypto_generichash_BYTES_MIN = 16 +crypto_generichash_KEYBYTES = 32 +crypto_generichash_KEYBYTES_MAX = 64 +crypto_generichash_KEYBYTES_MIN = 16 +crypto_generichash_blake2b_BYTES = 32 +crypto_generichash_blake2b_BYTES_MAX = 64 +crypto_generichash_blake2b_BYTES_MIN = 16 +crypto_generichash_blake2b_KEYBYTES = 32 +crypto_generichash_blake2b_KEYBYTES_MAX = 64 +crypto_generichash_blake2b_KEYBYTES_MIN = 16 +crypto_generichash_blake2b_PERSONALBYTES = 16 +crypto_generichash_blake2b_SALTBYTES = 16 +crypto_hash_BYTES = 64 +crypto_hash_sha256_BYTES = 32 +crypto_hash_sha512_BYTES = 64 +crypto_kdf_BYTES_MAX = 64 +crypto_kdf_BYTES_MIN = 16 +crypto_kdf_CONTEXTBYTES = 8 +crypto_kdf_KEYBYTES = 32 +crypto_kdf_blake2b_BYTES_MAX = 64 +crypto_kdf_blake2b_BYTES_MIN = 16 +crypto_kdf_blake2b_CONTEXTBYTES = 8 +crypto_kdf_blake2b_KEYBYTES = 32 +crypto_kx_PUBLICKEYBYTES = 32 +crypto_kx_SECRETKEYBYTES = 32 +crypto_kx_SEEDBYTES = 32 +crypto_kx_SESSIONKEYBYTES = 32 +crypto_onetimeauth_BYTES = 16 +crypto_onetimeauth_KEYBYTES = 32 +crypto_onetimeauth_poly1305_BYTES = 16 +crypto_onetimeauth_poly1305_KEYBYTES = 32 +crypto_pwhash_ALG_ARGON2I13 = 1 +crypto_pwhash_ALG_ARGON2ID13 = 2 +crypto_pwhash_ALG_DEFAULT = 2 +crypto_pwhash_BYTES_MAX = -1 +crypto_pwhash_BYTES_MIN = 16 +crypto_pwhash_MEMLIMIT_INTERACTIVE = 67108864 +crypto_pwhash_MEMLIMIT_MAX = -2147483648 +crypto_pwhash_MEMLIMIT_MIN = 8192 +crypto_pwhash_MEMLIMIT_MODERATE = 268435456 +crypto_pwhash_MEMLIMIT_SENSITIVE = 1073741824 +crypto_pwhash_OPSLIMIT_INTERACTIVE = 2 +crypto_pwhash_OPSLIMIT_MAX = -1 +crypto_pwhash_OPSLIMIT_MIN = 1 +crypto_pwhash_OPSLIMIT_MODERATE = 3 +crypto_pwhash_OPSLIMIT_SENSITIVE = 4 +crypto_pwhash_PASSWD_MAX = -1 +crypto_pwhash_PASSWD_MIN = 0 +crypto_pwhash_SALTBYTES = 16 +crypto_pwhash_STRBYTES = 128 +crypto_pwhash_argon2i_BYTES_MAX = -1 +crypto_pwhash_argon2i_BYTES_MIN = 16 +crypto_pwhash_argon2i_SALTBYTES = 16 +crypto_pwhash_argon2i_STRBYTES = 128 +crypto_pwhash_argon2id_BYTES_MAX = -1 +crypto_pwhash_argon2id_BYTES_MIN = 16 +crypto_pwhash_argon2id_SALTBYTES = 16 +crypto_pwhash_argon2id_STRBYTES = 128 +crypto_pwhash_scryptsalsa208sha256_BYTES_MAX = -1 +crypto_pwhash_scryptsalsa208sha256_BYTES_MIN = 16 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE = 16777216 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX = -1 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN = 16777216 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE = 1073741824 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE = 524288 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX = -1 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN = 32768 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE = 33554432 +crypto_pwhash_scryptsalsa208sha256_SALTBYTES = 32 +crypto_pwhash_scryptsalsa208sha256_STRBYTES = 102 +crypto_scalarmult_BYTES = 32 +crypto_scalarmult_SCALARBYTES = 32 +crypto_scalarmult_curve25519_BYTES = 32 +crypto_scalarmult_curve25519_SCALARBYTES = 32 +crypto_scalarmult_ed25519_BYTES = 32 +crypto_scalarmult_ed25519_SCALARBYTES = 32 +crypto_scalarmult_ristretto255_BYTES = 32 +crypto_scalarmult_ristretto255_SCALARBYTES = 32 +crypto_secretbox_KEYBYTES = 32 +crypto_secretbox_MACBYTES = 16 +crypto_secretbox_MESSAGEBYTES_MAX = -17 +crypto_secretbox_NONCEBYTES = 24 +crypto_secretbox_xchacha20poly1305_KEYBYTES = 32 +crypto_secretbox_xchacha20poly1305_MACBYTES = 16 +crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX = -17 +crypto_secretbox_xchacha20poly1305_NONCEBYTES = 24 +crypto_secretbox_xsalsa20poly1305_KEYBYTES = 32 +crypto_secretbox_xsalsa20poly1305_MACBYTES = 16 +crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX = -17 +crypto_secretbox_xsalsa20poly1305_NONCEBYTES = 24 +crypto_secretstream_xchacha20poly1305_ABYTES = 17 +crypto_secretstream_xchacha20poly1305_HEADERBYTES = 24 +crypto_secretstream_xchacha20poly1305_KEYBYTES = 32 +crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = -18 +crypto_secretstream_xchacha20poly1305_TAG_FINAL = 3 +crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = 0 +crypto_secretstream_xchacha20poly1305_TAG_PUSH = 1 +crypto_secretstream_xchacha20poly1305_TAG_REKEY = 2 +crypto_shorthash_BYTES = 8 +crypto_shorthash_KEYBYTES = 16 +crypto_shorthash_siphash24_BYTES = 8 +crypto_shorthash_siphash24_KEYBYTES = 16 +crypto_shorthash_siphashx24_BYTES = 16 +crypto_shorthash_siphashx24_KEYBYTES = 16 +crypto_sign_BYTES = 64 +crypto_sign_MESSAGEBYTES_MAX = -65 +crypto_sign_PUBLICKEYBYTES = 32 +crypto_sign_SECRETKEYBYTES = 64 +crypto_sign_SEEDBYTES = 32 +crypto_sign_ed25519_BYTES = 64 +crypto_sign_ed25519_MESSAGEBYTES_MAX = -65 +crypto_sign_ed25519_PUBLICKEYBYTES = 32 +crypto_sign_ed25519_SECRETKEYBYTES = 64 +crypto_sign_ed25519_SEEDBYTES = 32 +crypto_stream_KEYBYTES = 32 +crypto_stream_MESSAGEBYTES_MAX = -1 +crypto_stream_NONCEBYTES = 24 +crypto_stream_chacha20_IETF_KEYBYTES = 32 +crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX = -1 +crypto_stream_chacha20_IETF_NONCEBYTES = 12 +crypto_stream_chacha20_KEYBYTES = 32 +crypto_stream_chacha20_MESSAGEBYTES_MAX = -1 +crypto_stream_chacha20_NONCEBYTES = 8 +crypto_stream_chacha20_ietf_KEYBYTES = 32 +crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX = -1 +crypto_stream_chacha20_ietf_NONCEBYTES = 12 +crypto_stream_salsa2012_KEYBYTES = 32 +crypto_stream_salsa2012_MESSAGEBYTES_MAX = -1 +crypto_stream_salsa2012_NONCEBYTES = 8 +crypto_stream_salsa208_KEYBYTES = 32 +crypto_stream_salsa208_MESSAGEBYTES_MAX = -1 +crypto_stream_salsa208_NONCEBYTES = 8 +crypto_stream_salsa20_KEYBYTES = 32 +crypto_stream_salsa20_MESSAGEBYTES_MAX = -1 +crypto_stream_salsa20_NONCEBYTES = 8 +crypto_stream_xchacha20_KEYBYTES = 32 +crypto_stream_xchacha20_MESSAGEBYTES_MAX = -1 +crypto_stream_xchacha20_NONCEBYTES = 24 +crypto_stream_xsalsa20_KEYBYTES = 32 +crypto_stream_xsalsa20_MESSAGEBYTES_MAX = -1 +crypto_stream_xsalsa20_NONCEBYTES = 24 +crypto_verify_16_BYTES = 16 +crypto_verify_32_BYTES = 32 +crypto_verify_64_BYTES = 64 +SODIUM_VERSION_STRING = "1.0.18" +crypto_pwhash_STRPREFIX = "$argon2id$" +crypto_pwhash_scryptsalsa208sha256_STRPREFIX = "$7$" diff --git a/multiplatform-crypto-api/README.md b/multiplatform-crypto-api/README.md new file mode 100644 index 0000000..d65ec6a --- /dev/null +++ b/multiplatform-crypto-api/README.md @@ -0,0 +1,288 @@ +[![Build Status](https://travis-ci.com/ionspin/kotlin-multiplatform-crypto.svg?branch=master)](https://travis-ci.com/ionspin/kotlin-multiplatform-crypto) +![Maven Central](https://img.shields.io/maven-central/v/com.ionspin.kotlin/multiplatform-crypto.svg) + +# Kotlin Multiplatform Crypto Library + + +Kotlin Multiplatform Crypto is a library for various cryptographic applications. + +The library comes in two flavors `multiplatform-crypto` and `multiplatform-crypto-delegated`. + +* `multiplatform-crypto` contains pure kotlin implementations, is not reviewed, should be considered unsafe and only +for prototyping or experimentation purposes. + +* `multiplatform-crypto-delegated` relies on platform specific implementations, mostly libsodium, but care should still be taken that the kotlin code is not reviewed or proven safe. + +APIs of both variants are identical. + + +### Table of contents +1. [Supported platforms](#supported-platforms-by-variant) +2. [API](#api) +3. TODO + +## Supported platforms by variant +|Platform|Pure variant| Delegated variant| +|--------|------------|------------------| +|Linux X86 64| :heavy_check_mark: | :heavy_check_mark: | +|Linux Arm 64| :heavy_check_mark: | :heavy_check_mark: | +|Linux Arm 32| :heavy_check_mark: | :x: | +|macOS X86 64| :heavy_check_mark: | :heavy_check_mark: | +|iOS x86 64 | :heavy_check_mark: | :heavy_check_mark: | +|iOS Arm 64 | :heavy_check_mark: | :heavy_check_mark: | +|iOS Arm 32 | :heavy_check_mark: | :heavy_check_mark: | +|watchOS X86 32 | :heavy_check_mark: | :heavy_check_mark: | +|watchOS Arm 64(_32) | :heavy_check_mark: | :heavy_check_mark: | +|watchos Arm 32 | :heavy_check_mark: | :heavy_check_mark: | +|tvOS X86 64 | :heavy_check_mark: | :heavy_check_mark: | +|tvOS Arm 64 | :heavy_check_mark: | :heavy_check_mark: | +|minGW X86 64| :heavy_check_mark: | :heavy_check_mark: | +|minGW X86 32| :x: | :x: | + +## Sample project +The library includes sample project that shows usage on different platforms +- NOTE: Currently only linux, macOs and windows are included. + +## Notes & Roadmap + +**The API will move fast and break often until v1.0** + +Next steps: +- Expand API (ECC, Signing ...) + +## Should I use this in production? +**NO.** +The library is under HEAVY development. Until development is done it will not be reviewed and therefore it shouldn't be used. +Contributions are still welcome! + +## Why? + +This is an experimental implementation, mostly for expanding personal understanding of cryptography. +It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure. + +## API for Pure and Delegated flavours + +### Hashing functions +* Blake2b +* SHA512 +* SHA256 + +### Key Derivation + +* Argon2 + +### Authenticated symmetric encryption (AEAD) + +* XChaCha20-Poly1305 + + +### Delegated flavor dependancy table +The following table describes which library is used for particular cryptographic primitive + +| Primitive | JVM | JS | Native | +| ----------|-----|----|--------| +| Blake2b | LazySodium | libsodium.js | libsodium | +| SHA256 | LazySodium | libsodium.js | libsodium | +| SHA512 | LazySodium | libsodium.js | libsodium | +| XChaCha20-Poly1305 | LazySodium | libsodium.js | libsodium | + + + +## Integration + +NOTE: Latest version of the library is built with Kotlin 1.4-M2 and therefore only SNAPSHOT variant is available. Next +stable version will be released when Kotlin 1.4. is released + +#### Gradle +Kotlin +```kotlin +implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0") + +or + +implementation("com.ionspin.kotlin:multiplatform-crypto-delegated:0.1.0") +``` + +#### Snapshot builds +```kotlin +repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + } +} +implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0-SNAPSHOT") + +``` + +## Usage + +### Helper functions + +All API take `UByteArray` as message/key/nonce/etc parameter. For convenience when working with strings we provide +`String.enocdeToUbyteArray()` extensions function, and `UByteArray.toHexString` extension function. + +More convenience functions will be added. + +### Hashes + +Hashes are provided in two versions, "stateless", usually the companion object of the hash, +which takes the data to be hashed in one go, and "updatable" which can be fed data in chunks. + + +#### Blake2b + +You can use Blake 2b in two modes + +##### Stateless version +You need to deliver the complete data that is to be hashed in one go + +```kotlin +val input = "abc" +val result = Crypto.Blake2b.stateless(input.encodeToUByteArray()) +``` + +Result is returned as a `UByteArray` + +##### Updatable instance version +You can create an instance and feed the data by using `update(input : UByteArray)` call. Once all data is supplied, +you should call `digest()`. + +If you want to use Blake2b with a key, you should supply it when creating the `Blake2b` instance. + +```kotlin +val test = "abc" +val key = "key" +val blake2b = Crypto.Blake2b.updateable(key.encodeToUByteArray()) +blake2b.update(test.encodeToUByteArray()) +val result = blake2b.digest().toHexString() +``` + +After digest is called, the instance is reset and can be reused (Keep in mind key stays the same for the particular instance). +#### SHA2 (SHA256 and SHA512) + +##### Stateless version + +You need to deliver the complete data that is to be hashed in one go. You can either provide the `UByteArray` as input +or `String`. Result is always returned as `UByteArray` (At least in verision 0.0.1) + +```kotlin +val input = "abc" +val result = Crypto.Sha256.stateless(input.encodeToUByteArray()) +``` + +```kotlin +val input ="abc" +val result = Crypto.Sha512.stateless(input.encodeToUByteArray()) +``` + +Result is returned as a `UByteArray` + +##### Updateable version + +Or you can use the updatable instance version + +```kotlin +val sha256 = Crypto.Sha256.updateable() +sha256.update("abc".encodeToUByteArray()) +val result = sha256.digest() +``` + +```kotlin +val sha512 = Crypto.Sha512.updateable() +sha512.update("abc".encodeToUByteArray()) +val result = sha512.digest() +``` + +### Key derivation + +#### Argon2 + +NOTE: This implementation is tested against KAT generated by reference Argon2 implementation, which does not follow +specification completely. See this issue https://github.com/P-H-C/phc-winner-argon2/issues/183 + +```kotlin +val argon2Instance = Argon2( + password = "Password", + salt = "RandomSalt", + parallelism = 8, + tagLength = 64U, + requestedMemorySize = 256U, //4GB + numberOfIterations = 4U, + key = "", + associatedData = "", + argonType = ArgonType.Argon2id + ) +val tag = argon2Instance.derive() +val tagString = tag.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") +val expectedTagString = "c255e3e94305817d5e09a7c771e574e3a81cc78fef5da4a9644b6df0" + + "0ba1c9b424e3dd0ce7e600b1269b14c84430708186a8a60403e1bfbda935991592b9ff37" +println("Tag: ${tagString}") +assertEquals(tagString, expectedTagString) +``` + +### Symmetric encryption (OUTDATED, won't be exposed in next release, no counterpart in delegated flavor - 0.1.1) + +#### AES + +Aes is available with CBC and CTR mode through `AesCbc` and `AesCtr` classes/objects. +Similarly to hashes you can either use stateless or updateable version. + +Initialization vector, or counter states are chosen by the SDK automaticaly, and returned alongside encrypted data + +##### Stateless AesCbc and AesCtr + +AesCtr + +```kotlin +val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" +val key = AesKey.Aes128Key(keyString) +val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" + +val encryptedDataAndInitializationVector = AesCtr.encrypt(key, plainText.hexStringToUByteArray()) +val decrypted = AesCtr.decrypt( + key, + encryptedDataAndInitializationVector.encryptedData, + encryptedDataAndInitializationVector.initialCounter +) +plainText == decrypted.toHexString() +``` + +AesCbc + +```kotlin + +val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" +val key = AesKey.Aes128Key(keyString) + +val plainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" + +val encryptedDataAndInitializationVector = AesCbc.encrypt(key, plainText.hexStringToUByteArray()) +val decrypted = AesCbc.decrypt( + key, + encryptedDataAndInitializationVector.encryptedData, + encryptedDataAndInitializationVector.initilizationVector +) +plainText == decrypted.toHexString() + +``` + +## Libsodium bindings + +* Under development + + + + + + + + + + + + + + + + + diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt index 427ffd4..376ea57 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt @@ -54,16 +54,16 @@ interface HashApi { } interface EncryptionApi { - fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData - fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T + fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData + fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T fun createMultipartEncryptor(key: SymmetricKey) : MultipartAuthenticatedEncryption fun createMultipartDecryptor(key: SymmetricKey, header: MultipartEncryptionHeader) : MultipartAuthenticatedDecryption } interface AuthenticatedEncryption { - fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray - fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray + fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray } @@ -75,12 +75,12 @@ data class MultipartEncryptionHeader(val nonce: UByteArray) class InvalidTagException : RuntimeException("Tag mismatch! Encrypted data is corrupted or tampered with.") interface MultipartAuthenticatedDecryption { - fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray = ubyteArrayOf()) : DecryptedDataPart + fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray = ubyteArrayOf()) : DecryptedDataPart fun cleanup() } interface MultipartAuthenticatedEncryption { - fun encryptPartialData(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : EncryptedDataPart + fun encryptPartialData(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : EncryptedDataPart fun startEncryption() : MultipartEncryptionHeader fun cleanup() diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt index 5d3d87a..4507c00 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt @@ -145,17 +145,17 @@ object Crypto { } object Encryption : EncryptionApi { - override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData { if (key.value.size != 32) { throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}") } val nonce = SRNG.getRandomBytes(24) - return EncryptedData(XChaCha20Poly1305Delegated.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce) + return EncryptedData(XChaCha20Poly1305Delegated.encrypt(key.value, nonce, data.toEncryptableForm(), associatedData), nonce) } - override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { - return byteArrayDeserializer(XChaCha20Poly1305Delegated.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData)) + override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { + return byteArrayDeserializer(XChaCha20Poly1305Delegated.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, associatedData)) } @@ -185,8 +185,8 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe return header } - override fun encryptPartialData(data: UByteArray, additionalData: UByteArray): EncryptedDataPart { - return EncryptedDataPart(primitive.encrypt(data, additionalData)) + override fun encryptPartialData(data: UByteArray, associatedData: UByteArray): EncryptedDataPart { + return EncryptedDataPart(primitive.encrypt(data, associatedData)) } override fun cleanup() { @@ -196,8 +196,8 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Delegated) : MultipartAuthenticatedDecryption { - override fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray): DecryptedDataPart { - return DecryptedDataPart(decryptor.decrypt(data.data, additionalData)) + override fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray): DecryptedDataPart { + return DecryptedDataPart(decryptor.decrypt(data.data, associatedData)) } override fun cleanup() { diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt index 7166932..5f92fc8 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt @@ -9,13 +9,13 @@ package com.ionspin.kotlin.crypto.authenticated expect class XChaCha20Poly1305Delegated internal constructor() { internal constructor(key: UByteArray, testState : UByteArray, testHeader: UByteArray, isDecryptor: Boolean) companion object { - fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray - fun decrypt(key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, additionalData: UByteArray) : UByteArray + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray + fun decrypt(key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, associatedData: UByteArray) : UByteArray } fun initializeForEncryption(key: UByteArray) : UByteArray fun initializeForDecryption(key: UByteArray, header: UByteArray) - fun encrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray - fun decrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray + fun encrypt(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray + fun decrypt(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray fun cleanup() diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt index 6b8eb10..b24e406 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt @@ -213,4 +213,4 @@ fun Collection.flattenToUByteArray(): UByteArray { } } return result -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt index f553169..6ed851c 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt @@ -26,7 +26,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -61,9 +61,9 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) - val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, additionalData) + val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, associatedData) encrypted.hexColumsPrint() - val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData) + val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, associatedData) println("Decrypted") decrypted.hexColumsPrint() println("----------") @@ -74,7 +74,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -93,8 +93,8 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) - val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, additionalData) - val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData) + val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, associatedData) + val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, associatedData) encrypted.contentEquals(expected) && decrypted.contentEquals(message) } @@ -109,7 +109,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -144,7 +144,7 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) -// val xChaChaPoly = XChaCha20Poly1305Delegated(key, additionalData) +// val xChaChaPoly = XChaCha20Poly1305Delegated(key, associatedData) // val firstChunk = xChaChaPoly.encrypt(message) // val finalChunk = xChaChaPoly.finishEncryption().first // val result = firstChunk + finalChunk @@ -157,7 +157,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -176,7 +176,7 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) -// val xChaChaPoly = XChaCha20Poly1305Delegated(key, additionalData) +// val xChaChaPoly = XChaCha20Poly1305Delegated(key, associatedData) // val firstChunk = xChaChaPoly.encrypt(message) // val finalChunk = xChaChaPoly.finishEncryption().first // val result = firstChunk + finalChunk diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt index c85fad2..9573fcc 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt @@ -22,17 +22,17 @@ class EncryptionTest { val plaintext = ("pUoR4JVXJUeMKNkt6ZGGzEdTo33ajNGXwXpivBKA0XKs8toGRYI9Eul4bELRDkaQDNhd4vZseEFU" + "ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" + "EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray() - val additionalData = "Additional data 1".encodeToUByteArray() + val associatedData = "Additional data 1".encodeToUByteArray() val keyValue = UByteArray(32) { it.toUByte() } val key = SymmetricKey(keyValue) val encryptor = Crypto.Encryption.createMultipartEncryptor(key) val header = encryptor.startEncryption() - val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), additionalData) + val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), associatedData) val ciphertext2 = encryptor.encryptPartialData(plaintext.sliceArray(100 until 200)) val ciphertext3 = encryptor.encryptPartialData(plaintext.sliceArray(200 until 250)) //decrypt val decryptor = Crypto.Encryption.createMultipartDecryptor(key, header) - val plaintext1 = decryptor.decryptPartialData(ciphertext1, additionalData) + val plaintext1 = decryptor.decryptPartialData(ciphertext1, associatedData) val plaintext2 = decryptor.decryptPartialData(ciphertext2) val plaintext3 = decryptor.decryptPartialData(ciphertext3) diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 1934eb9..b917faf 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -40,17 +40,17 @@ interface JsSodiumInterface { fun crypto_hash_sha512_final(state: dynamic): Uint8Array //XChaCha20Poly1305 - fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, additionalData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array - fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, additionalData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array //XChaCha20Poly1305 //encrypt fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: Uint8Array, tag: UByte) : Uint8Array + fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, associatedData: Uint8Array, tag: UByte) : Uint8Array //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, associatedData: Uint8Array) : dynamic //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt index 2ab0433..faeea44 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -24,11 +24,11 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, message: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val encrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt( message.toUInt8Array(), - additionalData.toUInt8Array(), + associatedData.toUInt8Array(), Uint8Array(0), nonce.toUInt8Array(), key.toUInt8Array() @@ -40,12 +40,12 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val decrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt( Uint8Array(0), ciphertext.toUInt8Array(), - additionalData.toUInt8Array(), + associatedData.toUInt8Array(), nonce.toUInt8Array(), key.toUInt8Array() ) @@ -92,25 +92,25 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { isEncryptor = !isDecryptor } - actual fun encrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } if (!isEncryptor) { throw RuntimeException("Initialized as decryptor, attempted to use as encryptor") } - val encrypted = getSodium().crypto_secretstream_xchacha20poly1305_push(state, data.toUInt8Array(), additionalData.toUInt8Array(), 0U) + val encrypted = getSodium().crypto_secretstream_xchacha20poly1305_push(state, data.toUInt8Array(), associatedData.toUInt8Array(), 0U) return encrypted.toUByteArray() } - actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } if (isEncryptor) { throw RuntimeException("Initialized as encryptor, attempted to use as decryptor") } - val decryptedWithTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(state, data.toUInt8Array(), additionalData.toUInt8Array()) + val decryptedWithTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(state, data.toUInt8Array(), associatedData.toUInt8Array()) val decrypted = decryptedWithTag.message as Uint8Array val validTag = decryptedWithTag.tag diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt index 4edc35b..cb2cdfe 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -16,7 +16,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, message: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val ciphertext = ByteArray(message.size + 16) SodiumJava().crypto_aead_xchacha20poly1305_ietf_encrypt( @@ -24,8 +24,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { longArrayOf(ciphertext.size.toLong()), message.toByteArray(), message.size.toLong(), - additionalData.toByteArray(), - additionalData.size.toLong(), + associatedData.toByteArray(), + associatedData.size.toLong(), null, nonce.toByteArray(), key.toByteArray() @@ -38,7 +38,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val message = ByteArray(ciphertext.size - 16) SodiumJava().crypto_aead_xchacha20poly1305_ietf_decrypt( @@ -47,8 +47,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { null, ciphertext.toByteArray(), ciphertext.size.toLong(), - additionalData.toByteArray(), - additionalData.size.toLong(), + associatedData.toByteArray(), + associatedData.size.toLong(), nonce.toByteArray(), key.toByteArray() @@ -89,7 +89,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { isEncryptor = false } - actual fun encrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } @@ -100,13 +100,13 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { sodium.crypto_secretstream_xchacha20poly1305_push( state, ciphertext, null, data.asByteArray(), data.size.toLong(), - additionalData.asByteArray(), additionalData.size.toLong(), + associatedData.asByteArray(), associatedData.size.toLong(), 0 ) return ciphertext.asUByteArray() } - actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } @@ -120,8 +120,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { null, data.asByteArray(), (data.size).toLong(), - additionalData.asByteArray(), - additionalData.size.toLong() + associatedData.asByteArray(), + associatedData.size.toLong() ) if (validTag != 0) { println("Tag validation failed") diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt index 0d60110..eb7f836 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.authenticated import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint import com.ionspin.kotlin.crypto.InvalidTagException +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* @@ -16,18 +17,18 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, message: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val ciphertextLength = message.size + crypto_aead_xchacha20poly1305_IETF_ABYTES.toInt() val ciphertext = UByteArray(ciphertextLength) val ciphertextPinned = ciphertext.pin() crypto_aead_xchacha20poly1305_ietf_encrypt( - ciphertextPinned.addressOf(0), + ciphertextPinned.toPtr(), ulongArrayOf(ciphertextLength.convert()).toCValues(), message.toCValues(), message.size.convert(), - additionalData.toCValues(), - additionalData.size.convert(), + associatedData.toCValues(), + associatedData.size.convert(), null, nonce.toCValues(), key.toCValues() @@ -40,19 +41,19 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val messageLength = ciphertext.size - crypto_aead_xchacha20poly1305_IETF_ABYTES.toInt() val message = UByteArray(messageLength) val messagePinned = message.pin() crypto_aead_xchacha20poly1305_ietf_decrypt( - messagePinned.addressOf(0), + messagePinned.toPtr(), ulongArrayOf(messageLength.convert()).toCValues(), null, ciphertext.toCValues(), ciphertext.size.convert(), - additionalData.toCValues(), - additionalData.size.convert(), + associatedData.toCValues(), + associatedData.size.convert(), nonce.toCValues(), key.toCValues() ) @@ -95,7 +96,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { actual fun initializeForEncryption(key: UByteArray) : UByteArray { val pinnedHeader = header.pin() - crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues()) + crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.toPtr(), key.toCValues()) println("state-----------") state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).asUByteArray().hexColumsPrint() println("state-----------") @@ -111,17 +112,17 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { } - actual fun encrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray { val ciphertextWithTag = UByteArray(data.size + crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) val ciphertextWithTagPinned = ciphertextWithTag.pin() crypto_secretstream_xchacha20poly1305_push( state.ptr, - ciphertextWithTagPinned.addressOf(0), + ciphertextWithTagPinned.toPtr(), null, data.toCValues(), data.size.convert(), - additionalData.toCValues(), - additionalData.size.convert(), + associatedData.toCValues(), + associatedData.size.convert(), 0U, ) println("Encrypt partial") @@ -131,18 +132,18 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { return ciphertextWithTag } - actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray { val plaintext = UByteArray(data.size - crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) val plaintextPinned = plaintext.pin() val validTag = crypto_secretstream_xchacha20poly1305_pull( state.ptr, - plaintextPinned.addressOf(0), + plaintextPinned.toPtr(), null, null, data.toCValues(), data.size.convert(), - additionalData.toCValues(), - additionalData.size.convert() + associatedData.toCValues(), + associatedData.size.convert() ) plaintextPinned.unpin() println("tag: $validTag") diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index a72383b..d819606 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.crypto.util.toHexString +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -30,7 +31,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I override fun digest(): UByteArray { val hashResult = UByteArray(requestedHashLength) val hashResultPinned = hashResult.pin() - crypto_generichash_final(state.ptr, hashResultPinned.addressOf(0), requestedHashLength.convert()) + crypto_generichash_final(state.ptr, hashResultPinned.toPtr(), requestedHashLength.convert()) free(state.ptr) return hashResult } @@ -44,7 +45,7 @@ actual object Blake2bDelegatedStateless : Blake2b { val hashResult = UByteArray(MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() crypto_generichash( - hashResultPinned.addressOf(0), + hashResultPinned.toPtr(), hashLength.convert(), inputMessage.toCValues(), inputMessage.size.convert(), diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt index 0663629..32c1e5d 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt @@ -1,6 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -32,7 +33,7 @@ actual class Sha256Delegated : Sha256 { override fun digest(): UByteArray { val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0)) + crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr()) sodium_free(state.ptr) return hashResult } @@ -46,7 +47,7 @@ actual object Sha256StatelessDelegated : StatelessSha256 { override fun digest(inputMessage: UByteArray): UByteArray { val hashResult = UByteArray(MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha256(hashResultPinned.addressOf(0), inputMessage.toCValues(), inputMessage.size.convert()) + crypto_hash_sha256(hashResultPinned.toPtr(), inputMessage.toCValues(), inputMessage.size.convert()) hashResultPinned.unpin() return hashResult } diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index f4b80a6..a700b04 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.hash.sha +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -30,7 +31,7 @@ actual class Sha512Delegated : Sha512Multipart { override fun digest(): UByteArray { val hashResult = UByteArray(Sha512Properties.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha512_final(state.ptr, hashResultPinned.addressOf(0)) + crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr()) free(state.ptr) return hashResult } @@ -42,7 +43,7 @@ actual object Sha512StatelessDelegated : Sha512 { override fun digest(inputMessage: UByteArray): UByteArray { val hashResult = UByteArray(Sha512StatelessDelegated.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha512(hashResultPinned.addressOf(0), inputMessage.toCValues(), inputMessage.size.convert()) + crypto_hash_sha512(hashResultPinned.toPtr(), inputMessage.toCValues(), inputMessage.size.convert()) hashResultPinned.unpin() return hashResult } diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt new file mode 100644 index 0000000..7a0d892 --- /dev/null +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt @@ -0,0 +1,13 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.Pinned +import kotlinx.cinterop.UByteVar +import kotlinx.cinterop.addressOf + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Aug-2020 + */ +fun Pinned.toPtr() : CPointer = addressOf(0) diff --git a/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt b/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt index fd6827e..4bc8bcd 100644 --- a/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt +++ b/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt @@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.toHexString +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -39,7 +40,7 @@ class HelperTest { } val result = UByteArray(32) val resultPinned = result.pin() - crypto_hash_sha256_final(state, resultPinned.addressOf(0)) + crypto_hash_sha256_final(state, resultPinned.toPtr()) println("$target to \"${result.toHexString()}\",") free(state) } @@ -69,7 +70,7 @@ class HelperTest { } val result = UByteArray(32) val resultPinned = result.pin() - crypto_hash_sha512_final(state, resultPinned.addressOf(0)) + crypto_hash_sha512_final(state, resultPinned.toPtr()) println("$target to \"${result.toHexString()}\",") free(state) } diff --git a/multiplatform-crypto-libsodium-bindings/build.gradle.kts b/multiplatform-crypto-libsodium-bindings/build.gradle.kts index fbd9577..57c3ca5 100644 --- a/multiplatform-crypto-libsodium-bindings/build.gradle.kts +++ b/multiplatform-crypto-libsodium-bindings/build.gradle.kts @@ -28,6 +28,9 @@ plugins { id(PluginsDeps.node) version Versions.nodePlugin id(PluginsDeps.dokka) id(PluginsDeps.taskTree) version Versions.taskTreePlugin + id(PluginsDeps.androidLibrary) + id(PluginsDeps.kotlinAndroidExtensions) + } val sonatypeStaging = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" @@ -43,6 +46,10 @@ val sonatypeUsernameEnv: String? = System.getenv()["SONATYPE_USERNAME"] repositories { mavenCentral() jcenter() + maven("https://dl.bintray.com/terl/lazysodium-maven") + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + } } group = ReleaseInfo.group @@ -51,6 +58,21 @@ version = ReleaseInfo.version val ideaActive = isInIdea() println("Idea active: $ideaActive") +android { + compileSdkVersion(29) + defaultConfig { + minSdkVersion(24) + targetSdkVersion(29) + versionCode = 1 + versionName = "1.0" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + getByName("release") { + isMinifyEnabled = false + } + } +} kotlin { @@ -58,6 +80,7 @@ kotlin { runningOnLinuxx86_64 { println("Configuring Linux X86-64 targets") jvm() + android() js { browser { testTask { @@ -111,26 +134,8 @@ kotlin { // >>> referenced by randombytes_sysrandom.c // >>> libsodium_la-randombytes_sysrandom.o:(_randombytes_linux_getrandom) in archive /tmp/included11051337748775083797/libsodium.a -// linuxArm32Hfp() { -// binaries { -// staticLib { -// } -// } -// compilations.getByName("main") { -// val libsodiumCinterop by cinterops.creating { -// defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) -// compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-arm32/include/") -// } -// kotlinOptions.freeCompilerArgs = listOf( -// "-include-binary", "${project.rootDir}/sodiumWrapper/static-arm32/lib/libsodium.a" -// ) -// } -// } - - } - runningOnLinuxArm64 { println("Configuring Linux Arm 64 targets") @@ -249,7 +254,6 @@ kotlin { implementation(kotlin(Deps.Common.stdLib)) implementation(kotlin(Deps.Common.test)) implementation(Deps.Common.kotlinBigNum) - api(project(Deps.Common.apiProject)) } } val commonTest by getting { @@ -412,6 +416,7 @@ kotlin { runningOnLinuxx86_64 { println("Configuring Linux 64 Bit source sets") val jvmMain by getting { + kotlin.srcDirs("src/jvmSpecific", "src/jvmMain/kotlin") dependencies { implementation(kotlin(Deps.Jvm.stdLib)) implementation(kotlin(Deps.Jvm.test)) @@ -429,6 +434,28 @@ kotlin { implementation(kotlin(Deps.Jvm.reflection)) } } + val androidMain by getting { + isNotRunningInIdea { + kotlin.srcDirs("src/androidSpecific", "src/jvmMain/kotlin") + } + isRunningInIdea { + kotlin.srcDirs("src/androidSpecific") + } + dependencies { + implementation("com.goterl.lazycode:lazysodium-android:4.2.0@aar") + implementation("net.java.dev.jna:jna:5.5.0@aar") + } + } + + val androidTest by getting { + dependencies { + implementation(kotlin(Deps.Jvm.test)) + implementation(kotlin(Deps.Jvm.testJUnit)) + implementation("androidx.test:runner:1.2.0") + implementation("androidx.test:rules:1.2.0") + } + } + val jsMain by getting { dependencies { implementation(kotlin(Deps.Js.stdLib)) @@ -522,7 +549,11 @@ kotlin { } - +tasks.whenTaskAdded { + if("DebugUnitTest" in name || "ReleaseUnitTest" in name) { + enabled = false // https://youtrack.jetbrains.com/issue/KT-34662 otherwise common tests fail, because we require native android libs to be loaded + } +} tasks { @@ -566,6 +597,8 @@ tasks { } } + + // val legacyjsNodeTest by getting(KotlinJsTest::class) { // // testLogging { diff --git a/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt b/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt new file mode 100644 index 0000000..b537c33 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt @@ -0,0 +1,12 @@ +package com.ionspin.kotlin.crypto + +import com.goterl.lazycode.lazysodium.LazySodiumAndroid +import com.goterl.lazycode.lazysodium.SodiumAndroid + + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 22-Aug-2020 + */ +typealias SodiumWrapper = SodiumAndroid diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt similarity index 85% rename from multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt index 2ea2e2f..9313ca7 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/Initializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt @@ -3,10 +3,10 @@ package com.ionspin.kotlin.crypto /** * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020 */ -expect object Initializer { +expect object LibsodiumInitializer { fun isInitialized() : Boolean suspend fun initialize() fun initializeWithCallback(done: () -> (Unit)) -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..6388806 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,128 @@ +package com.ionspin.kotlin.crypto.aead + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ + +//X - Ietf +val crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32 +val crypto_aead_xchacha20poly1305_ietf_NPUBBYTES = 24 +val crypto_aead_xchacha20poly1305_ietf_ABYTES = 16 + +// Ietf +val crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32 +val crypto_aead_chacha20poly1305_ietf_NPUBBYTES = 12 +val crypto_aead_chacha20poly1305_ietf_ABYTES = 16 + +// original chacha20poly1305 + +val crypto_aead_chacha20poly1305_KEYBYTES = 32 +val crypto_aead_chacha20poly1305_NPUBBYTES = 8 +val crypto_aead_chacha20poly1305_ABYTES = 16 + + +data class AeadEncryptedDataAndTag(val data: UByteArray, val tag: UByteArray) + +class AeadCorrupedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + +expect object AuthenticatedEncryptionWithAssociatedData { + // X - Ietf + fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag + + fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + // Ietf + + fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag + + fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + // Original chacha20poly1305 + + fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag + + fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + + fun xChaCha20Poly1305IetfKeygen() : UByteArray + fun chaCha20Poly1305IetfKeygen() : UByteArray + fun chaCha20Poly1305Keygen() : UByteArray + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt new file mode 100644 index 0000000..2b0d120 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt @@ -0,0 +1,36 @@ +package com.ionspin.kotlin.crypto.auth + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ + +val crypto_auth_BYTES = 32 +val crypto_auth_KEYBYTES = 32 + +// do the 512 hmac and the deliver just 32 bytes of result +val crypto_auth_hmacsha512256_BYTES = 32 +val crypto_auth_hmacsha512256_KEYBYTES = 32 + +val crypto_auth_hmacsha256_KEYBYTES = 32 +val crypto_auth_hmacsha256_BYTES = 32 + +val crypto_auth_hmacsha512_KEYBYTES = 32 +val crypto_auth_hmacsha512_BYTES = 64 + +expect object Auth { + + fun authKeygen() : UByteArray + fun auth(message: UByteArray, key: UByteArray) : UByteArray + fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean + + fun authHmacSha256Keygen() : UByteArray + fun authHmacSha256(message: UByteArray, key: UByteArray) : UByteArray + fun authHmacSha256Verify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean + + fun authHmacSha512Keygen() : UByteArray + fun authHmacSha512(message: UByteArray, key: UByteArray) : UByteArray + fun authHmacSha512Verify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt new file mode 100644 index 0000000..fdbc907 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt @@ -0,0 +1,90 @@ +package com.ionspin.kotlin.crypto.box + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ + +val crypto_box_PUBLICKEYBYTES = 32 +val crypto_box_SECRETKEYBYTES = 32 +val crypto_box_MACBYTES = 16 +val crypto_box_SEEDBYTES = 32 +val crypto_box_NONCEBYTES = 24 +val crypto_box_SEALBYTES = 48 +val crypto_box_BEFORENMBYTES = 32 + +data class BoxKeyPair(val publicKey : UByteArray, val secretKey: UByteArray) +data class BoxEncryptedDataAndTag(val ciphertext: UByteArray, val tag: UByteArray) + +class BoxCorruptedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + +expect object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + fun keypair() : BoxKeyPair + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + fun seedKeypair(seed: UByteArray) : BoxKeyPair + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + fun easy(message : UByteArray, nonce : UByteArray, recipientsPublicKey: UByteArray, sendersSecretKey: UByteArray) : UByteArray + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + fun openEasy(ciphertext : UByteArray, nonce: UByteArray, sendersPublicKey: UByteArray, recipientsSecretKey: UByteArray) : UByteArray + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + fun beforeNM(publicKey: UByteArray, secretKey: UByteArray) : UByteArray + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + fun easyAfterNM(message : UByteArray, nonce: UByteArray, precomputedKey: UByteArray) : UByteArray + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + fun openEasyAfterNM(ciphertext: UByteArray, nonce: UByteArray, precomputedKey: UByteArray) : UByteArray + + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + fun detached(message: UByteArray, nonce: UByteArray, recipientsPublicKey: UByteArray, sendersSecretKey: UByteArray) : BoxEncryptedDataAndTag + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + fun openDetached(ciphertext: UByteArray, tag: UByteArray, nonce: UByteArray, sendersPublicKey: UByteArray, recipientsSecretKey: UByteArray) : UByteArray + + + fun seal(message: UByteArray, recipientsPublicKey: UByteArray) : UByteArray + + fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray) : UByteArray + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt new file mode 100644 index 0000000..c778647 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt @@ -0,0 +1,44 @@ +package com.ionspin.kotlin.crypto.generichash + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ + +val crypto_generichash_BYTES = 32 +val crypto_generichash_blake2b_BYTES_MIN = 16 +val crypto_generichash_blake2b_BYTES_MAX = 64 +val crypto_generichash_blake2b_BYTES = 32 +val crypto_generichash_blake2b_KEYBYTES_MIN = 16 +val crypto_generichash_blake2b_KEYBYTES_MAX = 64 +val crypto_generichash_blake2b_KEYBYTES = 32 +val crypto_generichash_blake2b_SALTBYTES = 16 + +expect class GenericHashStateInternal + +data class GenericHashState(val hashLength: Int, val internalState: GenericHashStateInternal) + + +expect object GenericHash { + + fun genericHash(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray + + fun genericHashInit(requestedHashLength: Int, key : UByteArray? = null) : GenericHashState + fun genericHashUpdate(state: GenericHashState, messagePart : UByteArray) + fun genericHashFinal(state : GenericHashState) : UByteArray + + fun genericHashKeygen() : UByteArray +// ---- Not present in LazySodium nor libsodium.js +// fun blake2b(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray +// +// fun blake2bInit(requestedHashLength: Int, key : UByteArray? = null) : Blake2bState +// fun blake2bUpdate(state: GenericHashState, messagePart : UByteArray) +// fun blake2bFinal(state : GenericHashState) : UByteArray +// +// fun blake2bKeygen() : UByteArray + + +} + + diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt new file mode 100644 index 0000000..f0fb7eb --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt @@ -0,0 +1,32 @@ +package com.ionspin.kotlin.crypto.hash + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ + +val crypto_hash_BYTES = 64 +val crypto_hash_sha256_BYTES = 32 +val crypto_hash_sha512_BYTES = 64 + +expect class Sha256State +expect class Sha512State + +expect object Hash { + + //Not present in LazySodium + //fun hash(data: UByteArray) : UByteArray + + fun sha256(data: UByteArray) : UByteArray + fun sha256Init() : Sha256State + fun sha256Update(state: Sha256State, data : UByteArray) + fun sha256Final(state : Sha256State) : UByteArray + + fun sha512(data: UByteArray) : UByteArray + fun sha512Init() : Sha512State + fun sha512Update(state: Sha512State, data : UByteArray) + fun sha512Final(state : Sha512State) : UByteArray + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/kdf/Kdf.kt new file mode 100644 index 0000000..4c64812 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/kdf/Kdf.kt @@ -0,0 +1,33 @@ +package com.ionspin.kotlin.crypto.kdf + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 16/Sep/2020 + */ +const val crypto_kdf_PRIMITIVE = "blake2b" +const val crypto_kdf_BYTES_MIN = 16 +const val crypto_kdf_BYTES_MAX = 64 +const val crypto_kdf_CONTEXTBYTES = 8 +const val crypto_kdf_KEYBYTES = 32 + +expect object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + fun deriveFromKey(subkeyId: Int, subkeyLength: Int, context: String, masterKey: UByteArray) : UByteArray + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + fun keygen() : UByteArray +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt new file mode 100644 index 0000000..75f5ab8 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt @@ -0,0 +1,75 @@ +package com.ionspin.kotlin.crypto.pwhash + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 17/Sep/2020 + */ + + +const val crypto_pwhash_BYTES_MIN = 16U +const val crypto_pwhash_MEMLIMIT_INTERACTIVE = 67108864U +const val crypto_pwhash_MEMLIMIT_MIN = 8192 +const val crypto_pwhash_MEMLIMIT_MODERATE = 268435456 +const val crypto_pwhash_MEMLIMIT_SENSITIVE = 1073741824 +const val crypto_pwhash_OPSLIMIT_INTERACTIVE = 2 +const val crypto_pwhash_OPSLIMIT_MAX = 4294967295UL +const val crypto_pwhash_OPSLIMIT_MIN = 1UL +const val crypto_pwhash_OPSLIMIT_MODERATE = 3UL +const val crypto_pwhash_OPSLIMIT_SENSITIVE = 4UL +const val crypto_pwhash_PASSWD_MAX = 4294967295 +const val crypto_pwhash_PASSWD_MIN = 0 +const val crypto_pwhash_SALTBYTES = 16 +const val crypto_pwhash_STRBYTES = 128 +const val crypto_pwhash_STRPREFIX = "\$argon2id$" + +val crypto_pwhash_argon2id_ALG_ARGON2ID13 = 2 +val crypto_pwhash_argon2i_ALG_ARGON2I13 = 1 +val crypto_pwhash_ALG_DEFAULT = crypto_pwhash_argon2id_ALG_ARGON2ID13 + +class PasswordHashingFailed() : RuntimeException("Password hashing failed") + +expect object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * 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 + */ + fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ): UByteArray + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + fun strNeedsRehash(passwordHash: UByteArray, opslimit: ULong, memlimit: Int): Int + + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * It returns 0 if the verification succeeds, and -1 on error. + */ + fun strVerify(passwordHash: UByteArray, password: String): Boolean + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..94abe7a --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt @@ -0,0 +1,28 @@ +package com.ionspin.kotlin.crypto.secretbox + +import kotlin.js.JsName + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 29-Aug-2020 + */ + +val crypto_secretbox_KEYBYTES = 32 +val crypto_secretbox_MACBYTES = 16 +val crypto_secretbox_NONCEBYTES = 24 + +class SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + +data class SecretBoxEncryptedDataAndTag(val data: UByteArray, val tag: UByteArray) + +expect object SecretBox { + + fun easy(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + fun openEasy(ciphertext: UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + + fun detached(message: UByteArray, nonce: UByteArray, key: UByteArray) : SecretBoxEncryptedDataAndTag + fun openDetached(ciphertext: UByteArray, tag: UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + + fun keygen() : UByteArray +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt new file mode 100644 index 0000000..2aaeb2c --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt @@ -0,0 +1,36 @@ +package com.ionspin.kotlin.crypto.secretstream + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 26-Aug-2020 + * + * This file is named with Jvm suffix because of https://youtrack.jetbrains.com/issue/KT-21186 + */ +expect class SecretStreamState + +data class SecretStreamStateAndHeader(val state: SecretStreamState, val header : UByteArray) + +data class DecryptedDataAndTag(val decryptedData : UByteArray, val tag : UByte) + +val crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = 0 +val crypto_secretstream_xchacha20poly1305_TAG_PUSH = 1 +val crypto_secretstream_xchacha20poly1305_TAG_REKEY = 2 +val crypto_secretstream_xchacha20poly1305_TAG_FINAL = 3 + +val crypto_secretstream_xchacha20poly1305_HEADERBYTES = 24 +val crypto_secretstream_xchacha20poly1305_KEYBYTES = 32 +val crypto_secretstream_xchacha20poly1305_ABYTES = 17 + +class SecretStreamCorruptedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + +expect object SecretStream { + + fun xChaCha20Poly1305InitPush(key: UByteArray) : SecretStreamStateAndHeader + fun xChaCha20Poly1305Push(state : SecretStreamState, message: UByteArray, associatedData : UByteArray = ubyteArrayOf(), tag: UByte) : UByteArray + fun xChaCha20Poly1305InitPull(key: UByteArray, header: UByteArray) : SecretStreamStateAndHeader + fun xChaCha20Poly1305Pull(state : SecretStreamState, ciphertext: UByteArray, associatedData : UByteArray = ubyteArrayOf()) : DecryptedDataAndTag + fun xChaCha20Poly1305Keygen() : UByteArray + fun xChaCha20Poly1305Rekey(state: SecretStreamState) + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..cc9b927 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,15 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +const val crypto_shorthash_KEYBYTES = 16 +const val crypto_shorthash_BYTES = 8 + +expect object ShortHash { + + fun shortHash(data : UByteArray, key: UByteArray) : UByteArray + fun shortHashKeygen() : UByteArray +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt new file mode 100644 index 0000000..4f7a22a --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt @@ -0,0 +1,81 @@ +package com.ionspin.kotlin.crypto.signature + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 13/Sep/2020 + */ +expect class SignatureState + +data class SignatureKeyPair(val publicKey: UByteArray, val secretKey: UByteArray) + +const val crypto_sign_BYTES = 64 +const val crypto_sign_SEEDBYTES = 32 +const val crypto_sign_PUBLICKEYBYTES = 32 +const val crypto_sign_SECRETKEYBYTES = 64 +const val crypto_scalarmult_curve25519_BYTES = 32 + +class InvalidSignatureException() : RuntimeException("Signature validation failed") + +expect object Signature { + fun init(): SignatureState + fun update(state: SignatureState, data: UByteArray) + fun finalCreate(state: SignatureState, secretKey: UByteArray): UByteArray + fun finalVerify(state: SignatureState, signature: UByteArray, publicKey: UByteArray) + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + fun keypair(): SignatureKeyPair + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + fun seedKeypair(seed: UByteArray): SignatureKeyPair + + /** + * The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is crypto_sign_BYTES + mlen bytes long. + */ + fun sign(message : UByteArray, secretKey : UByteArray) : UByteArray + + /** + * The crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + fun open(signedMessage: UByteArray, publicKey: UByteArray) : UByteArray + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to crypto_sign_BYTES bytes long. + */ + fun detached(message: UByteArray, secretKey: UByteArray): UByteArray + + /** + * The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + fun verifyDetached(signature: UByteArray, message: UByteArray, publicKey: UByteArray) + /** + * The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray + + /** + * The crypto_sign_ed25519_sk_to_curve25519() function converts an Ed25519 secret key ed25519_sk to an X25519 secret key and stores it into x25519_sk. + */ + fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + fun ed25519SkToSeed(secretKey : UByteArray) : UByteArray + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + fun ed25519SkToPk(secretKey: UByteArray) : UByteArray +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt new file mode 100644 index 0000000..83aa113 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt @@ -0,0 +1,38 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +val randombytes_SEEDBYTES = 32 + +expect object LibsodiumRandom { + + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + fun buf(size: Int) : UByteArray + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + fun bufDeterministic(size: Int, seed: UByteArray) : UByteArray + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + fun random() : UInt + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0 + */ + fun uniform(upperBound : UInt) : UInt +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..d8360f0 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt @@ -0,0 +1,27 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ + +enum class Base64Variants(val value: Int) { + ORIGINAL(1), ORIGINAL_NO_PADDING(3), URLSAFE(5), URLSAFE_NO_PADDING(7) +} + +expect object LibsodiumUtil { + + fun memcmp(first: UByteArray, second: UByteArray) : Boolean + fun memzero(target: UByteArray) + + fun pad(unpaddedData : UByteArray, blocksize: Int) : UByteArray + fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray + + fun toBase64(data: UByteArray, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : String + fun toHex(data: UByteArray) : String + + fun fromBase64(data: String, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : UByteArray + fun fromHex(data: String) : UByteArray + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/Util.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/Util.kt new file mode 100644 index 0000000..b3034e7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/Util.kt @@ -0,0 +1,24 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 28-Aug-2020 + */ +fun String.hexStringToUByteArray() : UByteArray { + return this.chunked(2).map { it.toUByte(16) }.toUByteArray() +} + +fun String.encodeToUByteArray() : UByteArray{ + return encodeToByteArray().asUByteArray() +} + +fun UByteArray.toHexString() : String { + return this.joinToString(separator = "") { + if (it <= 0x0FU) { + "0${it.toString(16)}" + } else { + it.toString(16) + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 6287381..5d4c83c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -1,26 +1,79 @@ -package debug.test - -import kotlin.Int -import kotlin.UByteArray - -expect class Sha256State - -expect class Sha512State - -expect class GenericHashState - -expect class Crypto internal constructor() { - fun crypto_hash_sha256_init(): Sha256State - - fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) - - fun crypto_hash_sha256_final(state: Sha256State): UByteArray - - fun crypto_hash_sha512_init(): Sha512State - - fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) - - fun crypto_hash_sha512_final(state: Sha512State): UByteArray - - fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState -} +//package debug.test +// +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +//import kotlin.js.JsName +// +//expect class Sha256State +// +//expect class Sha512State +// +//expect class GenericHashState +// +//expect class SecretStreamState +// +//data class SecretStreamStateAndHeader( +// @JsName("state") +// val state: SecretStreamState, +// @JsName("header") +// val header: UByteArray +//) +// +//data class DecryptedDataAndTag( +// @JsName("decrypted") +// val decrypted: UByteArray, +// @JsName("tag") +// val tag: UByte +//) +// +//expect class Crypto internal constructor() { +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// fun crypto_hash_sha256_init(): Sha256State +// +// fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) +// +// fun crypto_hash_sha256_final(state: Sha256State): UByteArray +// +// fun crypto_hash_sha512_init(): Sha512State +// +// fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) +// +// fun crypto_hash_sha512_final(state: Sha512State): UByteArray +// +// fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// SecretStreamState +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt index 905a71c..28c1665 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -1,10 +1,9 @@ package com.ionspin.kotlin.crypto -import com.ionspin.kotlin.bignum.integer.BigInteger -import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.generichash.GenericHash +import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.toHexString -import debug.test.Crypto import kotlin.test.Test import kotlin.test.assertTrue @@ -18,19 +17,15 @@ class SmokeTest { @Test fun testIfLibraryIsNotOnFire() { testBlocking { - Initializer.initialize() - val crypto = Crypto() - //TODO seems to be a bug in JS compiler, if we have the same method name in crypto an in JsSodiumInterface, method tries to call wrong method name (unneeded suffix _0) - //I've worked around this by making state functions with 1 parameter execute call with js("") wrap, but still might sail somewhere else - val state256 = crypto.crypto_hash_sha256_init() - crypto.crypto_hash_sha256_update(state256, "Hello".encodeToUByteArray()) - val result = crypto.crypto_hash_sha256_final(state256) - val resultString = result.toHexString() - println("Result: $resultString") + LibsodiumInitializer.initialize() + val hashResult = GenericHash.genericHash("Hello".encodeToUByteArray(), 64) + println("Smoke test: ${hashResult.toHexString()}") assertTrue { - "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969" == resultString + "EF15EAF92D5E335345A3E1D977BC7D8797C3D275717CC1B10AF79C93CDA01AEB2A0C59BC02E2BDF9380FD1B54EB9E1669026930CCC24BD49748E65F9A6B2EE68".toLowerCase() == hashResult.toHexString() } + } } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedDataTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedDataTest.kt new file mode 100644 index 0000000..c6de2bf --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedDataTest.kt @@ -0,0 +1,320 @@ +package com.ionspin.kotlin.crypto.aead + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ +class AuthenticatedEncryptionWithAssociatedDataTest { + @Test + fun testXChaCha20Poly1305Ieft() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfEncrypt( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecrypt( + encrypted, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecrypt( + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testXChaCha20Poly1305IeftDetached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfEncryptDetached( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecryptDetached( + encrypted.data, + encrypted.tag, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecryptDetached( + encrypted.data, + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305Ieft() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfEncrypt( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecrypt( + encrypted, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecrypt( + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305IeftDetached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfEncryptDetached( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecryptDetached( + encrypted.data, + encrypted.tag, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecryptDetached( + encrypted.data, + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305Encrypt( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305Decrypt( + encrypted, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305Decrypt( + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305Detached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305EncryptDetached( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305DecryptDetached( + encrypted.data, + encrypted.tag, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305DecryptDetached( + encrypted.data, + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt new file mode 100644 index 0000000..9650457 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt @@ -0,0 +1,108 @@ +package com.ionspin.kotlin.crypto.auth + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ +class AuthTest { + @Test + fun testAuth() { + LibsodiumInitializer.initializeWithCallback { + val message = ("I wonder if it would be possible" + + " to get some lyrics in these tests").encodeToUByteArray() + + val key = "We'll see1We'll see1We'll see123".encodeToUByteArray() + + val expected = "702beb4494a1d80795512668df016807ec052dc848a4c958eb1544ec1c8d6314".hexStringToUByteArray() + + val hashed = Auth.auth(message, key) + println(hashed.toHexString()) + assertTrue { + hashed.contentEquals(expected) + } + assertTrue { Auth.authVerify(hashed, message, key) } + + assertFalse { + val tampered = hashed.copyOf() + tampered[5] = 0U + Auth.authVerify(tampered, message, key) + } + } + + } + + @Test + fun testAuthHmacSha256() { + LibsodiumInitializer.initializeWithCallback { + val message = ("I wonder if it would be possible" + + " to get some lyrics in these tests").encodeToUByteArray() + + val key = "We'll see1We'll see1We'll see123".encodeToUByteArray() + + val expected = "b1b3cf73089e04106a135629ba586b6c94b81b87162302f3f32b4fb797f82e8a".hexStringToUByteArray() + + val hashed = Auth.authHmacSha256(message, key) + println(hashed.toHexString()) + assertTrue { + hashed.contentEquals(expected) + } + assertTrue { Auth.authHmacSha256Verify(hashed, message, key) } + + assertFalse { + val tampered = hashed.copyOf() + tampered[5] = 0U + Auth.authHmacSha256Verify(tampered, message, key) + } + } + } + + @Test + fun testAuthHmacSha512() { + LibsodiumInitializer.initializeWithCallback { + val message = ("I wonder if it would be possible" + + " to get some lyrics in these tests").encodeToUByteArray() + + val key = "We'll see1We'll see1We'll see123".encodeToUByteArray() + + val expected = ("702beb4494a1d80795512668df016807ec052dc848a4c958eb1544ec1c8d63145fd11513c2d" + + "aecb03780e2b8b121e87f0a171033489de92665d9a218f4ed9589").hexStringToUByteArray() + + val hashed = Auth.authHmacSha512(message, key) + println(hashed.toHexString()) + assertTrue { + hashed.contentEquals(expected) + } + println(hashed.toHexString()) + assertTrue { Auth.authHmacSha512Verify(hashed, message, key) } + + assertFalse { + val tampered = hashed.copyOf() + tampered[5] = 0U + Auth.authHmacSha512Verify(tampered, message, key) + } + } + } + + @Test + fun simpleKeygenTest() { + LibsodiumInitializer.initializeWithCallback { + val authKey = Auth.authKeygen() + assertTrue { authKey.size == crypto_auth_KEYBYTES } + val auth256Key = Auth.authHmacSha256Keygen() + assertTrue { auth256Key.size == crypto_auth_hmacsha256_KEYBYTES } + val auth512Key = Auth.authHmacSha512Keygen() + assertTrue { auth512Key.size == crypto_auth_hmacsha512_KEYBYTES } + } + + + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt new file mode 100644 index 0000000..e1ebb59 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt @@ -0,0 +1,132 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import kotlin.random.Random +import kotlin.random.nextUBytes +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 01-Sep-2020 + */ +class BoxTest { + @Test + fun keypairTest() { + LibsodiumInitializer.initializeWithCallback { + val keypair = Box.keypair() + assertTrue { + keypair.publicKey.size == crypto_box_PUBLICKEYBYTES + } + assertTrue { + keypair.secretKey.size == crypto_box_SECRETKEYBYTES + } + } + } + + @Test + fun testBoxEasy() { + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) + val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + assertTrue { + decrypted.contentEquals(message) + } + + assertFailsWith() { + val tampered = encrypted.copyOf() + tampered[1] = 0U + Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + } + } + } + + @Test + fun testBoxEasyDetached() { + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val encrypted = Box.detached(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) + val decrypted = Box.openDetached( + encrypted.ciphertext, + encrypted.tag, + messageNonce, + senderKeypair.publicKey, + recipientKeypair.secretKey + ) + assertTrue { + decrypted.contentEquals(message) + } + + assertFailsWith() { + val tampered = encrypted.ciphertext.copyOf() + tampered[1] = 0U + Box.openDetached( + tampered, + encrypted.tag, + messageNonce, + senderKeypair.publicKey, + recipientKeypair.secretKey + ) + } + } + } + + @Test + fun testBeforeNonceAndMessage() { + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val senderComputedSessionKey = Box.beforeNM(recipientKeypair.publicKey, senderKeypair.secretKey) + val recipientComputedSessionKey = Box.beforeNM(senderKeypair.publicKey, recipientKeypair.secretKey) + + assertTrue { + senderComputedSessionKey.contentEquals(recipientComputedSessionKey) + } + val encrypted = Box.easyAfterNM(message, messageNonce, senderComputedSessionKey) + val decrypted = Box.openEasyAfterNM(encrypted, messageNonce, recipientComputedSessionKey) + assertTrue { + decrypted.contentEquals(message) + } + + assertFailsWith() { + val tampered = encrypted.copyOf() + tampered[1] = 0U + Box.openEasyAfterNM(tampered, messageNonce, recipientComputedSessionKey) + } + } + } + + @Test + fun testSeal() { + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val recipientKeypair = Box.keypair() + val sealed = Box.seal(message, recipientKeypair.publicKey) + val unsealed = Box.sealOpen(sealed, recipientKeypair.publicKey, recipientKeypair.secretKey) + + assertTrue { + unsealed.contentEquals(message) + } + + assertFailsWith() { + val tampered = sealed.copyOf() + tampered[1] = 0U + Box.sealOpen(tampered, recipientKeypair.publicKey, recipientKeypair.secretKey) + } + } + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashTest.kt new file mode 100644 index 0000000..d39c387 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashTest.kt @@ -0,0 +1,74 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.testBlocking +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 26-Aug-2020 + */ +class GenericHashTest { + + + @Test + fun testGenericHash() { + LibsodiumInitializer.initializeWithCallback { + val inputString = "1234567890" + val inputStringBuilder = StringBuilder() + for (i in 0 until 14) { + inputStringBuilder.append(inputString) + } + val input = inputStringBuilder.toString().encodeToUByteArray() + val expectedResult = ubyteArrayOf( + //@formatter:off + 0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, + 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU, + 0x2fU, 0x0dU, 0x2fU, 0xb4U, 0xc0U, 0x7dU, 0x7eU, 0x4aU, 0x72U, 0x40U, 0x46U, 0x12U, 0xd9U, 0x28U, 0x99U, + 0xafU, 0x8aU, 0x32U, 0x8fU, 0x3bU, 0x61U, 0x4eU, 0xd7U, 0x72U, 0x44U, 0xb4U, 0x81U, 0x15U, 0x1dU, 0x40U, + 0xb1U, 0x1eU, 0x32U, 0xa4U + //@formatter:on + ) + + + val result = GenericHash.genericHash(input, 64) + println("GenericHash result: ${result.toHexString()}") + assertTrue { + result.contentEquals(expectedResult) + } + } + + } + + @Test + fun testGenericHashMultipart() { + LibsodiumInitializer.initializeWithCallback { + val updates = 14 + val input = "1234567890" + val expectedResult = ubyteArrayOf( + //@formatter:off + 0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, + 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU, + 0x2fU, 0x0dU, 0x2fU, 0xb4U, 0xc0U, 0x7dU, 0x7eU, 0x4aU, 0x72U, 0x40U, 0x46U, 0x12U, 0xd9U, 0x28U, 0x99U, + 0xafU, 0x8aU, 0x32U, 0x8fU, 0x3bU, 0x61U, 0x4eU, 0xd7U, 0x72U, 0x44U, 0xb4U, 0x81U, 0x15U, 0x1dU, 0x40U, + 0xb1U, 0x1eU, 0x32U, 0xa4U + //@formatter:on + ) + + val genericHashState = GenericHash.genericHashInit(64) + for (i in 0 until updates) { + GenericHash.genericHashUpdate(genericHashState, input.encodeToUByteArray()) + } + val result = GenericHash.genericHashFinal(genericHashState) + println("GenericHash result: ${result.toHexString()}") + assertTrue { + result.contentEquals(expectedResult) + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt new file mode 100644 index 0000000..70800e3 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt @@ -0,0 +1,78 @@ +package com.ionspin.kotlin.crypto.hash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ +class HashTest { + //Not present in Lazy sodium +// @Test +// fun hashTest() { +// LibsodiumInitializer.initializeWithCallback { +// val input = ("Input for various hash functions").encodeToUByteArray() +// val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" + +// "838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray() +// +// val result = Hash.hash(input) +// assertTrue { +// result.contentEquals(expected) +// } +// } +// +// } + + + @Test + fun hashTestSha256() { + LibsodiumInitializer.initializeWithCallback { + val input = ("Input for various hash functions").encodeToUByteArray() + val expected = ("2bb078ec5993b5428355ba49bf030b1ac7" + + "1519e635aebc2f28124fac2aef9264").hexStringToUByteArray() + + val result = Hash.sha256(input) + assertTrue { + result.contentEquals(expected) + } + + val sha256State = Hash.sha256Init() + Hash.sha256Update(sha256State, input) + val multipartResult = Hash.sha256Final(sha256State) + assertTrue { + multipartResult.contentEquals(expected) + } + } + + } + + @Test + fun hashTestSha512() { + LibsodiumInitializer.initializeWithCallback { + val input = ("Input for various hash functions").encodeToUByteArray() + val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" + + "838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray() + + val result = Hash.sha512(input) + assertTrue { + result.contentEquals(expected) + } + + val sha512State = Hash.sha512Init() + Hash.sha512Update(sha512State, input) + val multipartResult = Hash.sha512Final(sha512State) + assertTrue { + multipartResult.contentEquals(expected) + } + } + + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/kdf/KdfTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/kdf/KdfTest.kt new file mode 100644 index 0000000..06c4f99 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/kdf/KdfTest.kt @@ -0,0 +1,34 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import kotlin.test.Test +import kotlin.test.assertFails +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 16/Sep/2020 + */ +class KdfTest { + @Test + fun testKdf() { + LibsodiumInitializer.initializeWithCallback { + val masterKey = Kdf.keygen() + val subkey1 = Kdf.deriveFromKey(1, crypto_kdf_BYTES_MAX, "test1234", masterKey) + val subkey2 = Kdf.deriveFromKey(2, crypto_kdf_BYTES_MAX, "test1234", masterKey) + + assertTrue { + subkey1.size == crypto_kdf_BYTES_MAX && + subkey2.size == crypto_kdf_BYTES_MAX + } + + val repeatSubkey1 = Kdf.deriveFromKey(1, crypto_kdf_BYTES_MAX, "test1234", masterKey) + assertTrue { + subkey1.contentEquals(repeatSubkey1) + } + assertFalse { + subkey1.contentEquals(subkey2) + } + } + } +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt new file mode 100644 index 0000000..942ac78 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt @@ -0,0 +1,67 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.random.Random +import kotlin.random.nextUBytes +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Sep-2020 + */ +class PasswordHashTest { + @Test + fun testPasswordHash() { + LibsodiumInitializer.initializeWithCallback { + val randomBytes = Random(0).nextUBytes(crypto_pwhash_SALTBYTES) + val password = "correct horse battery staple" + val hashedPassword = PasswordHash.pwhash( + 64, + password, + randomBytes, + crypto_pwhash_OPSLIMIT_MIN, + crypto_pwhash_MEMLIMIT_MIN, + crypto_pwhash_ALG_DEFAULT + ) + println("Hashed password: ${hashedPassword.toHexString()}") + assertTrue { + hashedPassword.toHexString().equals("e762ee529e90e3bbc242c23e8e2f963ab9a17ed9e79f89a00c71261a979207b2213cc" + + "0330c53f410a9c8933c46e8642dc542efc0660c69e255b601c7244ef6b0") + } + } + } + + @Test + fun testPasswordHashForStorage() { + + LibsodiumInitializer.initializeWithCallback { + val password = "correct horse battery staple" + val hashedPassword = PasswordHash.str( + password, + crypto_pwhash_OPSLIMIT_MIN, + crypto_pwhash_MEMLIMIT_MIN + ) + println("Hashed password for storage: ${hashedPassword.toHexString()}") + + assertTrue { + PasswordHash.strVerify( + hashedPassword, + password + ) + } + + assertTrue { + PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_MIN) == 0 + } + + assertTrue { + PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_SENSITIVE) == 1 + } + + //TODO strNeedsRehash -1 case? + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt new file mode 100644 index 0000000..caf19a5 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt @@ -0,0 +1,82 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 29-Aug-2020 + */ +class SecretBoxTest { + + @Test + fun secretBoxTestEasy() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val encrypted = SecretBox.easy(message, nonce, key) + val decrypted = SecretBox.openEasy(encrypted, nonce, key) + assertTrue { decrypted.contentEquals(message) } + assertFailsWith(SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[2] = 0U + SecretBox.openEasy(tamperedTag, nonce, key) + } + } + + + } + + @Test + fun secretBoxTestDetached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val encrypted = SecretBox.detached(message, nonce, key) + val decrypted = SecretBox.openDetached(encrypted.data, encrypted.tag, nonce, key) + assertTrue { decrypted.contentEquals(message) } + assertFailsWith(SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[2] = 0U + SecretBox.openDetached(encrypted.data, tamperedTag, nonce, key) + } + } + + + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt new file mode 100644 index 0000000..574891f --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -0,0 +1,93 @@ +package com.ionspin.kotlin.crypto.secretstream + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.testBlocking +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 15-Aug-2020 + */ +class SecretStreamTest { + + + @Test + fun testSecretStream() = testBlocking { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val expected = ubyteArrayOf( + 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, + 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, + 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, + 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, + 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, + 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, + 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, + 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, + 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, + 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, + 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, + 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, + 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, + 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, + 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, + 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, + 0xcfU, 0x49U + ) + message.hexColumsPrint() + println("---- init enc ----") + val stateAndHeader = SecretStream.xChaCha20Poly1305InitPush(key) + println("---- encrypt ----") + val encrypted = + SecretStream.xChaCha20Poly1305Push(stateAndHeader.state, message, ubyteArrayOf(), 0U) + encrypted.hexColumsPrint() + println("---- init dec ----") + val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header) + println("---- decrypt ----") + val decrypted = + SecretStream.xChaCha20Poly1305Pull(decryptState.state, encrypted, ubyteArrayOf()) + decrypted.decryptedData.hexColumsPrint() + assertTrue { + decrypted.decryptedData.contentEquals(message) + } + assertFailsWith(SecretStreamCorruptedOrTamperedDataException::class) { + encrypted[encrypted.size - 5] = 0U + val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header) + val decrypted = + SecretStream.xChaCha20Poly1305Pull(decryptState.state, encrypted, ubyteArrayOf()) + } + + + } + } + + +} +// TODO modify nonce in state so we can have reproducible tests, theres already a similar way of doing this +// in crypto delegated project XChaCha20Poly1305 test +expect fun modifyState(state: SecretStreamState, forceNonce: UByteArray) + + diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/shorthash/ShortHashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/shorthash/ShortHashTest.kt new file mode 100644 index 0000000..cae34ca --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/shorthash/ShortHashTest.kt @@ -0,0 +1,41 @@ +package com.ionspin.kotlin.crypto.shorthash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.shortinputhash.ShortHash +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 28-Aug-2020 + */ +class ShortHashTest { + + @Test + fun testShortHash() { + LibsodiumInitializer.initializeWithCallback { + val expected = "00e5d509c14e81bb".hexStringToUByteArray() + val input = "Libsodium test" + val key = "key1key1key1key1" + val hash = ShortHash.shortHash(input.encodeToUByteArray(), key.encodeToUByteArray()) + println(hash.toHexString()) + assertTrue { + expected.contentEquals(hash) + } + } + } + + @Test + fun testKeygen() { + LibsodiumInitializer.initializeWithCallback { + assertTrue { + val key = ShortHash.shortHashKeygen() + key.size == 16 + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt new file mode 100644 index 0000000..17f22e6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt @@ -0,0 +1,69 @@ +package com.ionspin.kotlin.crypto.signature + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Sep/2020 + */ +class SignatureTest { + + @Test + fun testSignAndVerify() { + LibsodiumInitializer.initializeWithCallback { + val keys = Signature.keypair() + val message = "Some text that will be signed".encodeToUByteArray() + val signedMessage = Signature.sign(message, keys.secretKey) + val verifiedMessage = Signature.open(signedMessage, keys.publicKey) + assertTrue { + verifiedMessage.contentEquals(message) + } + assertFailsWith(InvalidSignatureException::class) { + val tamperedMessage = signedMessage.copyOf() + tamperedMessage[crypto_sign_BYTES + 1] = 0U + Signature.open(tamperedMessage, keys.publicKey) + } + } + + } + + @Test + fun testDetachedSignAndVerify() { + LibsodiumInitializer.initializeWithCallback { + val keys = Signature.keypair() + val message = "Some text that will be signed".encodeToUByteArray() + val signature = Signature.detached(message, keys.secretKey) + val verifiedMessage = Signature.verifyDetached(signature, message, keys.publicKey) + assertFailsWith(InvalidSignatureException::class) { + val tamperedSignature = signature.copyOf() + tamperedSignature[crypto_sign_BYTES - 1] = 0U + Signature.verifyDetached(tamperedSignature, message, keys.publicKey) + } + } + } + + @Test + fun testMultipart() { + LibsodiumInitializer.initializeWithCallback { + val keys = Signature.keypair() + val message1 = "Some text that ".encodeToUByteArray() + val message2 = "will be signed".encodeToUByteArray() + val state = Signature.init() + Signature.update(state, message1) + Signature.update(state, message2) + val signature = Signature.finalCreate(state, keys.secretKey) + val verificationState = Signature.init() + Signature.update(verificationState, message1) + Signature.update(verificationState, message2) + Signature.finalVerify(verificationState, signature, keys.publicKey) + assertFailsWith(InvalidSignatureException::class) { + val tamperedSignature = signature.copyOf() + tamperedSignature[crypto_sign_BYTES - 1] = 0U + Signature.finalVerify(verificationState, tamperedSignature, keys.publicKey) + } + } + } +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandomTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandomTest.kt new file mode 100644 index 0000000..a515a32 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandomTest.kt @@ -0,0 +1,56 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 03-Oct-2020 + */ +class LibsodiumRandomTest { + + @Test + fun testRandom() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^32 + LibsodiumInitializer.initializeWithCallback { + val random = LibsodiumRandom.random() + assertTrue { random != 0U } + } + + } + + @Test + fun testRandomUniform() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^31 + LibsodiumInitializer.initializeWithCallback { + val random = LibsodiumRandom.uniform(UInt.MAX_VALUE / 2U) + assertTrue { random != 0U && random < (UInt.MAX_VALUE / 2U)} + } + } + + @Test + fun testRandomBuffer() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^52 + LibsodiumInitializer.initializeWithCallback { + val result = LibsodiumRandom.buf(20) + val lowProbability = UByteArray(20) { 0U } + assertFalse { result.contentEquals(lowProbability) } + } + } + + @Test + fun testRandomBufferDeterministic() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^52 + LibsodiumInitializer.initializeWithCallback { + val seed = UByteArray(randombytes_SEEDBYTES) { 1U } + val result = LibsodiumRandom.bufDeterministic(20, seed) + val lowProbability = UByteArray(20) { 0U } + assertFalse { result.contentEquals(lowProbability) } + val secondResult = LibsodiumRandom.bufDeterministic(20, seed) + assertTrue { result.contentEquals(secondResult) } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt new file mode 100644 index 0000000..52b97f9 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt @@ -0,0 +1,159 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import kotlin.math.exp +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 25-Sep-2020 + */ + +class LibsodiumUtilTest { + @Test + fun testMemzero() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + LibsodiumUtil.memzero(input) + assertTrue { + input.contentEquals(UByteArray(9) { 0U }) + } + } + } + + @Test + fun testMemcmp() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + val input2 = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + val input3 = ubyteArrayOf(2U, 2U, 2U, 2U, 2U, 2U, 21U, 2U, 2U) + assertTrue { + LibsodiumUtil.memcmp(input, input2) + } + assertFalse { + LibsodiumUtil.memcmp(input, input3) + } + } + } + + @Test + fun testPadding() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U) + val blocksize = 16 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } + } + + @Test + fun testPaddingChars() { + LibsodiumInitializer.initializeWithCallback { + val input = charArrayOf('a', 'b', 'c', 'd').map { it.toByte().toUByte() }.toUByteArray() + val blocksize = 4 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } + } + + @Test + fun testPaddingAligned() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U) + val blocksize = 2 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } + } + + @Test + fun testPaddingMultiblock() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U) + val blocksize = 4 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } + } + + @Test + fun testToBase64() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + val expected = "AQIDBAUgQID_" + val output = LibsodiumUtil.toBase64(input) + println("Output: |$output|") + println("Expected|$expected| ") + assertTrue { + output == expected + } + val reconstructed = LibsodiumUtil.fromBase64(output) + println("Reconstructed: ${reconstructed.toHexString()}") + assertTrue { + reconstructed.contentEquals(input) + } + } + } + + @Test + fun testToBase64Unaligned() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) + val expected = "AQIDBAUgQID_gA" + val output = LibsodiumUtil.toBase64(input) + println("Output: |$output|") + println("Expected|$expected| ") + assertTrue { + output == expected + } + val reconstructed = LibsodiumUtil.fromBase64(output) + println("Reconstructed: ${reconstructed.toHexString()}") + assertTrue { + reconstructed.contentEquals(input) + } + } + } + + @Test + fun toHex() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) + val hex = LibsodiumUtil.toHex(input) + assertTrue { + hex == input.toHexString() + } + val reconstructed = LibsodiumUtil.fromHex(hex) + assertTrue { + reconstructed.contentEquals(input) + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt index 3cb5304..6358a90 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt @@ -34,3 +34,5 @@ fun testBlocking(block : suspend () -> Unit) { } block.startCoroutine(continuation) } + + 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 1934eb9..f216f00 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 @@ -1,6 +1,7 @@ package ext.libsodium.com.ionspin.kotlin.crypto +import com.ionspin.kotlin.crypto.box.BoxKeyPair import org.khronos.webgl.Uint8Array /** @@ -12,13 +13,13 @@ interface JsSodiumInterface { fun randombytes_buf(numberOfBytes: Int): Uint8Array - fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array,): Uint8Array + fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array): Uint8Array fun crypto_hash_sha256(message: Uint8Array): Uint8Array fun crypto_hash_sha512(message: Uint8Array): Uint8Array - //Updateable + // ---- Generic hash ---- // Updateable fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic @@ -26,6 +27,29 @@ interface JsSodiumInterface { fun crypto_generichash_final(state: dynamic, hashLength: Int) : Uint8Array + fun crypto_generichash_keygen() : Uint8Array + + // ---- Generic hash end ---- // Updateable + + // ---- Blake2b ---- + + fun crypto_generichash_blake2b(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array): Uint8Array + + fun crypto_generichash_blake2b_init(key : Uint8Array, hashLength: Int) : dynamic + + fun crypto_generichash_blake2b_update(state: dynamic, inputMessage: Uint8Array) + + fun crypto_generichash_blake2b_final(state: dynamic, hashLength: Int) : Uint8Array + + fun crypto_generichash_blake2b_keygen() : Uint8Array + + // ---- Blake2b end ---- + + // ---- Short hash ---- + fun crypto_shorthash(data : Uint8Array, key: Uint8Array) : Uint8Array + + fun crypto_shorthash_keygen() : Uint8Array + // ---- Short hash end ---- fun crypto_hash_sha256_init() : dynamic @@ -39,21 +63,161 @@ interface JsSodiumInterface { fun crypto_hash_sha512_final(state: dynamic): Uint8Array - //XChaCha20Poly1305 - fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, additionalData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array - fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, additionalData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + //XChaCha20Poly1305 - also in bindings + //fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + //fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array //XChaCha20Poly1305 //encrypt - fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: Uint8Array, tag: UByte) : Uint8Array + fun crypto_secretstream_xchacha20poly1305_init_push(key: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, associatedData: Uint8Array, tag: UByte) : Uint8Array //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, associatedData: Uint8Array) : dynamic + + //keygen and rekey + fun crypto_secretstream_xchacha20poly1305_keygen() : Uint8Array + fun crypto_secretstream_xchacha20poly1305_rekey(state: dynamic) + + // ---- SecretBox ---- + fun crypto_secretbox_detached(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic + fun crypto_secretbox_easy(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_secretbox_keygen() : Uint8Array + fun crypto_secretbox_open_detached(ciphertext : Uint8Array, tag : Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic + fun crypto_secretbox_open_easy(ciphertext : Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic + + + // ---- SecretBox End ---- + + + // ---- AEAD ---- + fun crypto_aead_chacha20poly1305_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array + fun crypto_aead_chacha20poly1305_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic + fun crypto_aead_chacha20poly1305_ietf_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_ietf_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array + fun crypto_aead_chacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_ietf_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic + fun crypto_aead_chacha20poly1305_ietf_keygen() : Uint8Array + fun crypto_aead_chacha20poly1305_keygen() : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic + fun crypto_aead_xchacha20poly1305_ietf_keygen(): Uint8Array + + // ---- AEAD end ---- + + // ---- Auth ---- + + fun crypto_auth(message: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_auth_keygen() : Uint8Array + fun crypto_auth_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean + fun crypto_auth_hmacsha256(message: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_auth_hmacsha256_keygen() : Uint8Array + fun crypto_auth_hmacsha256_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean + fun crypto_auth_hmacsha512(message: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_auth_hmacsha512_keygen() : Uint8Array + fun crypto_auth_hmacsha512_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean + + // ---- Auth end ---- + + // ---- Box ---- + + fun crypto_box_keypair() : dynamic + fun crypto_box_seed_keypair(seed : Uint8Array) : dynamic + fun crypto_box_easy(message: Uint8Array, + nonce: Uint8Array, + recipientsPublicKey: Uint8Array, + sendersSecretKey: Uint8Array) : Uint8Array + fun crypto_box_open_easy(ciphertext: Uint8Array, + nonce: Uint8Array, + sendersPublicKey: Uint8Array, + recipientsSecretKey: Uint8Array) : Uint8Array + fun crypto_box_detached(message: Uint8Array, + nonce: Uint8Array, + recipientsPublicKey: Uint8Array, + sendersSecretKey: Uint8Array) : dynamic + fun crypto_box_open_detached(ciphertext: Uint8Array, + tag: Uint8Array, + nonce: Uint8Array, + sendersPublicKey: Uint8Array, + recipientsSecretKey: Uint8Array) : Uint8Array + fun crypto_box_beforenm(publicKey: Uint8Array, secretKey: Uint8Array) : Uint8Array + fun crypto_box_easy_afternm(message: Uint8Array, + nonce: Uint8Array, + precomputedKey: Uint8Array) : Uint8Array + fun crypto_box_open_easy_afternm(ciphertext: Uint8Array, + nonce: Uint8Array, + precomputedKey: Uint8Array) : Uint8Array + fun crypto_box_seal(message: Uint8Array, recipientsPublicKey: Uint8Array) : Uint8Array + fun crypto_box_seal_open(ciphertext: Uint8Array, recipientsPublicKey: Uint8Array, recipientsSecretKey: Uint8Array) : Uint8Array + + // ---- Box end ---- + + // ---- Sign start ---- + fun crypto_sign(message: Uint8Array, secretKey: Uint8Array) : Uint8Array + fun crypto_sign_detached(message: Uint8Array, secretKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_pk_to_curve25519(ed25519PublicKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_sk_to_curve25519(ed25519SecretKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_sk_to_pk(ed25519SecretKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_sk_to_seed(ed25519SecretKey: Uint8Array) : Uint8Array + fun crypto_sign_final_create(state: dynamic, secretKey: Uint8Array) : Uint8Array + fun crypto_sign_final_verify(state: dynamic, signature: Uint8Array, publicKey: Uint8Array) : Boolean + fun crypto_sign_init() : dynamic + fun crypto_sign_keypair() : dynamic + fun crypto_sign_open(signedMessage: Uint8Array, publicKey: Uint8Array) : Uint8Array + fun crypto_sign_seed_keypair(seed: Uint8Array) : dynamic + fun crypto_sign_update(state: dynamic, message: Uint8Array) + fun crypto_sign_verify_detached(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array) : Boolean + + + // ---- Sign end ---- + + + // ---- KDF ---- + + fun crypto_kdf_derive_from_key(subkey_len: UInt, subkeyId : UInt, ctx: String, key: Uint8Array) : Uint8Array + fun crypto_kdf_keygen() : Uint8Array + + // ---- 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 end ---- + + // ---- Utils ---- + + fun memcmp(first: Uint8Array, second: Uint8Array) : Boolean + fun memzero(data: Uint8Array) + fun pad(data : Uint8Array, blocksize: Int) : Uint8Array + fun unpad(data: Uint8Array, blocksize: Int) : Uint8Array + fun to_base64(data: Uint8Array, variant: Int) : String + fun to_hex(data: Uint8Array) : String + fun to_string(data: Uint8Array) : String + fun from_base64(data: String, variant: Int): Uint8Array + fun from_hex(data : String): Uint8Array + fun from_string(data : String): Uint8Array + + // ---- > ---- 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 ---- + + - //util - fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt index 9cecbbd..ec40078 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt @@ -15,6 +15,9 @@ fun UByteArray.toUInt8Array() : Uint8Array { fun Uint8Array.toUByteArray() : UByteArray { + if (length.asDynamic() == undefined) { + println("Error") + } val result = UByteArray(length) for (i in 0 until length) { result[i] = get(i).toUByte() diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt similarity index 96% rename from multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt index 9567243..437304a 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt @@ -20,7 +20,7 @@ fun setSodiumLoaded(loaded: Boolean) { js("sodiumLoaded = loaded") } -actual object Initializer { +actual object LibsodiumInitializer { private var isPlatformInitialized = false actual suspend fun initialize() { @@ -40,4 +40,4 @@ actual object Initializer { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..846ccb7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,247 @@ +package com.ionspin.kotlin.crypto.aead + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual object AuthenticatedEncryptionWithAssociatedData { + + // Ietf + + // Original chacha20poly1305 + actual fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + return getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ).toUByteArray() + } + + actual fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + return getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt( + null, + ciphertext.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } + } + + actual fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val result = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt_detached( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ) + return AeadEncryptedDataAndTag( + (result.ciphertext as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) + } + + actual fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + return getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt_detached( + null, + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } + } + + actual fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + return getSodium().crypto_aead_chacha20poly1305_ietf_encrypt( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ).toUByteArray() + } + + actual fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + return getSodium().crypto_aead_chacha20poly1305_ietf_decrypt( + null, + ciphertext.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } + } + + actual fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val result = getSodium().crypto_aead_chacha20poly1305_ietf_encrypt_detached( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ) + return AeadEncryptedDataAndTag( + (result.ciphertext as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) + } + + actual fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + return getSodium().crypto_aead_chacha20poly1305_ietf_decrypt_detached( + null, + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } + } + + actual fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + return getSodium().crypto_aead_chacha20poly1305_encrypt( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ).toUByteArray() + } + + actual fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + return getSodium().crypto_aead_chacha20poly1305_decrypt( + null, + ciphertext.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } + } + + actual fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val result = getSodium().crypto_aead_chacha20poly1305_encrypt_detached( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ) + return AeadEncryptedDataAndTag( + (result.ciphertext as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) + } + + actual fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + return getSodium().crypto_aead_chacha20poly1305_decrypt_detached( + null, + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } + } + + actual fun xChaCha20Poly1305IetfKeygen(): UByteArray { + return getSodium().crypto_aead_xchacha20poly1305_ietf_keygen().toUByteArray() + } + + actual fun chaCha20Poly1305IetfKeygen(): UByteArray { + return getSodium().crypto_aead_chacha20poly1305_ietf_keygen().toUByteArray() + } + + actual fun chaCha20Poly1305Keygen(): UByteArray { + return getSodium().crypto_aead_chacha20poly1305_keygen().toUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt new file mode 100644 index 0000000..50cf35a --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -0,0 +1,75 @@ +package com.ionspin.kotlin.crypto.auth + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual object Auth { + actual fun authKeygen(): UByteArray { + return getSodium().crypto_auth_keygen().toUByteArray() + } + + actual fun auth(message: UByteArray, key: UByteArray): UByteArray { + return getSodium().crypto_auth( + message.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + + } + + actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { + return getSodium().crypto_auth_verify( + mac.toUInt8Array(), + message.toUInt8Array(), + key.toUInt8Array() + ) + } + + actual fun authHmacSha256Keygen(): UByteArray { + return getSodium().crypto_auth_hmacsha256_keygen().toUByteArray() + } + + actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { + return getSodium().crypto_auth_hmacsha256( + message.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } + + actual fun authHmacSha256Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + return getSodium().crypto_auth_hmacsha256_verify( + mac.toUInt8Array(), + message.toUInt8Array(), + key.toUInt8Array() + ) + } + + actual fun authHmacSha512Keygen(): UByteArray { + return getSodium().crypto_auth_hmacsha512_keygen().toUByteArray() + } + + actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { + return getSodium().crypto_auth_hmacsha512( + message.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } + + actual fun authHmacSha512Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + return getSodium().crypto_auth_hmacsha512_verify( + mac.toUInt8Array(), + message.toUInt8Array(), + key.toUInt8Array() + ) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt new file mode 100644 index 0000000..376f4a6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -0,0 +1,200 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + actual fun keypair(): BoxKeyPair { + val keypair = getSodium().crypto_box_keypair() + return BoxKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): BoxKeyPair { + val keypair = getSodium().crypto_box_seed_keypair(seed.toUInt8Array()) + return BoxKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + actual fun easy( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): UByteArray { + return getSodium().crypto_box_easy( + message.toUInt8Array(), + nonce.toUInt8Array(), + recipientsPublicKey.toUInt8Array(), + sendersSecretKey.toUInt8Array(), + ).toUByteArray() + + } + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_open_easy( + ciphertext.toUInt8Array(), + nonce.toUInt8Array(), + sendersPublicKey.toUInt8Array(), + recipientsSecretKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + + } + + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray { + return getSodium().crypto_box_beforenm( + publicKey.toUInt8Array(), + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun easyAfterNM( + message: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + return getSodium().crypto_box_easy_afternm( + message.toUInt8Array(), + nonce.toUInt8Array(), + precomputedKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun openEasyAfterNM( + ciphertext: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_open_easy_afternm( + ciphertext.toUInt8Array(), + nonce.toUInt8Array(), + precomputedKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + } + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + actual fun detached( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): BoxEncryptedDataAndTag { + val detached = getSodium().crypto_box_detached( + message.toUInt8Array(), + nonce.toUInt8Array(), + recipientsPublicKey.toUInt8Array(), + sendersSecretKey.toUInt8Array(), + ) + return BoxEncryptedDataAndTag( + (detached.ciphertext as Uint8Array).toUByteArray(), + (detached.mac as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_open_detached( + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + nonce.toUInt8Array(), + sendersPublicKey.toUInt8Array(), + recipientsSecretKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + } + + actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray { + return getSodium().crypto_box_seal( + message.toUInt8Array(), + recipientsPublicKey.toUInt8Array() + ).toUByteArray() + } + + actual fun sealOpen( + ciphertext: UByteArray, + recipientsPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_seal_open( + ciphertext.toUInt8Array(), + recipientsPublicKey.toUInt8Array(), + recipientsSecretKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + } + + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt new file mode 100644 index 0000000..3ea5001 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -0,0 +1,82 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ + +actual typealias GenericHashStateInternal = Any + +actual object GenericHash { + actual fun genericHash( + message: UByteArray, + requestedHashLength: Int, + key: UByteArray? + ): UByteArray { + return getSodium().crypto_generichash( + requestedHashLength, + message.toUInt8Array(), + key?.toUInt8Array() ?: Uint8Array(0) + ).toUByteArray() + } + + actual fun genericHashInit( + requestedHashLength: Int, + key: UByteArray? + ): GenericHashState { + val state = getSodium().crypto_generichash_init(key?.toUInt8Array() ?: Uint8Array(0), requestedHashLength) + return GenericHashState(requestedHashLength, state) + } + + actual fun genericHashUpdate( + state: GenericHashState, + messagePart: UByteArray + ) { + getSodium().crypto_generichash_update(state.internalState, messagePart.toUInt8Array()) + } + + actual fun genericHashFinal(state: GenericHashState): UByteArray { + return getSodium().crypto_generichash_final(state.internalState, state.hashLength).toUByteArray() + } + + actual fun genericHashKeygen(): UByteArray { + return getSodium().crypto_generichash_keygen().toUByteArray() + } +// -- Not present in LazySodium nor libsodium.js +// actual fun blake2b(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray { +// return getSodium().crypto_generichash_blake2b( +// requestedHashLength, +// message.toUInt8Array(), +// key?.toUInt8Array() ?: Uint8Array(0) +// ).toUByteArray() +// } +// +// actual fun blake2bInit( +// requestedHashLength: Int, +// key: UByteArray? +// ): Blake2bState { +// val state = getSodium().crypto_generichash_blake2b_init(key?.toUInt8Array() ?: Uint8Array(0), requestedHashLength) +// return Blake2bState(requestedHashLength, state) +// } +// +// actual fun blake2bUpdate( +// state: GenericHashState, +// messagePart: UByteArray +// ) { +// getSodium().crypto_generichash_blake2b_update(state.internalState, messagePart.toUInt8Array()) +// } +// +// actual fun blake2bFinal(state: GenericHashState): UByteArray { +// return getSodium().crypto_generichash_blake2b_final(state.internalState, state.hashLength).toUByteArray() +// } +// +// actual fun blake2bKeygen(): UByteArray { +// return getSodium().crypto_generichash_blake2b_keygen().toUByteArray() +// } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt new file mode 100644 index 0000000..13fe9bd --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -0,0 +1,47 @@ +package com.ionspin.kotlin.crypto.hash + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual typealias Sha256State = Any +actual typealias Sha512State = Any + +actual object Hash { + + //Not present in LazySodium + //fun hash(data: UByteArray) : UByteArray + actual fun sha256(data: UByteArray): UByteArray { + return getSodium().crypto_hash_sha256(data.toUInt8Array()).toUByteArray() + } + + actual fun sha256Init(): Sha256State { + return getSodium().crypto_hash_sha256_init() + } + + actual fun sha256Update(state: Sha256State, data: UByteArray) { + getSodium().crypto_hash_sha256_update(state, data.toUInt8Array()) + } + + actual fun sha256Final(state: Sha256State): UByteArray { + return getSodium().crypto_hash_sha256_final(state).toUByteArray() + } + + actual fun sha512(data: UByteArray): UByteArray { + return getSodium().crypto_hash_sha512(data.toUInt8Array()).toUByteArray() + } + + actual fun sha512Init(): Sha512State { + return getSodium().crypto_hash_sha512_init() + } + + actual fun sha512Update(state: Sha512State, data: UByteArray) { + getSodium().crypto_hash_sha512_update(state, data.toUInt8Array()) + } + + actual fun sha512Final(state: Sha512State): UByteArray { + return getSodium().crypto_hash_sha512_final(state).toUByteArray() + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt new file mode 100644 index 0000000..1866909 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt @@ -0,0 +1,43 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + actual fun deriveFromKey( + subkeyId: Int, + subkeyLength: Int, + context: String, + masterKey: UByteArray + ): UByteArray { + return getSodium().crypto_kdf_derive_from_key( + subkeyLength.toUInt(), + subkeyId.toUInt(), + context, + masterKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + actual fun keygen(): UByteArray { + return getSodium().crypto_kdf_keygen().toUByteArray() + } + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt new file mode 100644 index 0000000..9cc13b7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -0,0 +1,89 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.getSodium +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * 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 + */ + actual fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ): UByteArray { + return getSodium().crypto_pwhash( + outputLength.toUInt(), + password.encodeToUByteArray().toUInt8Array(), + salt.toUInt8Array(), + opsLimit.toUInt(), + memLimit.toUInt(), + algorithm.toUInt() + ).toUByteArray() + } + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { + return getSodium().crypto_pwhash_str( + password.encodeToUByteArray().toUInt8Array(), + opslimit.toUInt(), + memlimit.toUInt() + ).encodeToUByteArray() + } + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + actual fun strNeedsRehash( + passwordHash: UByteArray, + opslimit: ULong, + memlimit: Int + ): Int { + return if ( + getSodium().crypto_pwhash_str_needs_rehash( + passwordHash.asByteArray().decodeToString(), + opslimit.toUInt(), + memlimit.toUInt() + ) + ) { + 1 + } else { + 0 + } + } + + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * It returns 0 if the verification succeeds, and -1 on error. + */ + actual fun strVerify(passwordHash: UByteArray, password: String): Boolean { + return getSodium().crypto_pwhash_str_verify( + passwordHash.asByteArray().decodeToString(), + password.encodeToUByteArray().toUInt8Array() + ) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..4ff9188 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt @@ -0,0 +1,74 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual object SecretBox { + actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray { + return getSodium().crypto_secretbox_easy( + message.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } + + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + val decryptionResult = getSodium().crypto_secretbox_open_easy( + ciphertext.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return (decryptionResult as Uint8Array).toUByteArray() + } catch (error: Throwable) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + } + + actual fun detached( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): SecretBoxEncryptedDataAndTag { + val result = getSodium().crypto_secretbox_detached( + message.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return SecretBoxEncryptedDataAndTag( + (result.cipher as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) + } + + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + val decryptionResult = getSodium().crypto_secretbox_open_detached( + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return (decryptionResult as Uint8Array).toUByteArray() + } catch (error: Throwable) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + + } + + actual fun keygen(): UByteArray { + return getSodium().crypto_secretbox_keygen().toUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt new file mode 100644 index 0000000..27856e8 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -0,0 +1,58 @@ +package com.ionspin.kotlin.crypto.secretstream + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual typealias SecretStreamState = Any + +actual object SecretStream { + actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { + val state = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) + return SecretStreamStateAndHeader(state.state, (state.header as Uint8Array).toUByteArray()) + } + + actual fun xChaCha20Poly1305Push( + state: SecretStreamState, + message: UByteArray, + associatedData: UByteArray, + tag: UByte + ): UByteArray { + return getSodium().crypto_secretstream_xchacha20poly1305_push( + state, message.toUInt8Array(), associatedData.toUInt8Array(), tag + ).toUByteArray() + } + + actual fun xChaCha20Poly1305InitPull( + key: UByteArray, + header: UByteArray + ): SecretStreamStateAndHeader { + val state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), key.toUInt8Array()) + return SecretStreamStateAndHeader(state, header) + } + + actual fun xChaCha20Poly1305Pull( + state: SecretStreamState, + ciphertext: UByteArray, + associatedData: UByteArray + ): DecryptedDataAndTag { + val dataAndTag = getSodium().crypto_secretstream_xchacha20poly1305_pull( + state, ciphertext.toUInt8Array(), associatedData.toUInt8Array() + ) + if (dataAndTag == false) { + throw SecretStreamCorruptedOrTamperedDataException() + } + return DecryptedDataAndTag((dataAndTag.message as Uint8Array).toUByteArray(), dataAndTag.tag) + + } + + actual fun xChaCha20Poly1305Keygen(): UByteArray { + return getSodium().crypto_shorthash_keygen().toUByteArray() + } + + actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) { + getSodium().crypto_secretstream_xchacha20poly1305_rekey(state) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..df47ed7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,21 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual object ShortHash { + actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray { + return getSodium().crypto_shorthash(data.toUInt8Array(), key.toUInt8Array()).toUByteArray() + } + + actual fun shortHashKeygen(): UByteArray { + return getSodium().crypto_shorthash_keygen().toUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt new file mode 100644 index 0000000..6b6fb3b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt @@ -0,0 +1,161 @@ +package com.ionspin.kotlin.crypto.signature + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual typealias SignatureState = Any + +actual object Signature { + actual fun init(): SignatureState { + return getSodium().crypto_sign_init() + } + + actual fun update(state: SignatureState, data: UByteArray) { + getSodium().crypto_sign_update(state, data.toUInt8Array()) + } + + actual fun finalCreate( + state: SignatureState, + secretKey: UByteArray + ): UByteArray { + return getSodium().crypto_sign_final_create( + state, + secretKey.toUInt8Array() + ).toUByteArray() + } + + actual fun finalVerify( + state: SignatureState, + signature: UByteArray, + publicKey: UByteArray + ) { + val verificationResult = getSodium().crypto_sign_final_verify( + state, + signature.toUInt8Array(), + publicKey.toUInt8Array() + ) + if (verificationResult == false) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + actual fun keypair(): SignatureKeyPair { + val keypair = getSodium().crypto_sign_keypair() + return SignatureKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): SignatureKeyPair { + val keypair = getSodium().crypto_sign_seed_keypair(seed.toUInt8Array()) + return SignatureKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is crypto_sign_BYTES + mlen bytes long. + */ + actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign( + message.toUInt8Array(), + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray { + try { + return getSodium().crypto_sign_open( + signedMessage.toUInt8Array(), + publicKey.toUInt8Array() + ).toUByteArray() + } catch (error : Throwable) { + throw InvalidSignatureException() + } + } + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to crypto_sign_BYTES bytes long. + */ + actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_detached( + message.toUInt8Array(), + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + actual fun verifyDetached(signature: UByteArray, message: UByteArray, publicKey: UByteArray) { + val verificationResult = getSodium().crypto_sign_verify_detached( + signature.toUInt8Array(), + message.toUInt8Array(), + publicKey.toUInt8Array() + ) + + if (verificationResult == false) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_pk_to_curve25519( + ed25519PublicKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_sign_ed25519_sk_to_curve25519() function converts an Ed25519 secret key ed25519_sk to an X25519 secret key and stores it into x25519_sk. + */ + actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_sk_to_curve25519( + ed25519SecretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_sk_to_seed( + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_sk_to_pk( + secretKey.toUInt8Array() + ).toUByteArray() + } + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt new file mode 100644 index 0000000..1854710 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -0,0 +1,48 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +actual object LibsodiumRandom { + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + actual fun buf(size: Int): UByteArray { + return getSodium().randombytes_buf(size).toUByteArray() + } + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { + return getSodium().randombytes_buf_deterministic(size.toUInt(), seed.toUInt8Array()).toUByteArray() + } + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + actual fun random(): UInt { + return getSodium().randombytes_random() + } + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * 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 { + return getSodium().randombytes_uniform(upperBound) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..e9c83fd --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -0,0 +1,50 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual object LibsodiumUtil { + actual fun memcmp(first: UByteArray, second: UByteArray): Boolean { + return getSodium().memcmp(first.toUInt8Array(), second.toUInt8Array()) + } + + actual fun memzero(target: UByteArray) { + // libsodium.js does this as well, and theres no clear way at the moment of casting ubytearray to uint8array + // although I feel like there should be a way to work around it + (target.indices).forEach { + index -> target[index] = 0U + } + } + + actual fun pad(unpaddedData: UByteArray, blocksize: Int): UByteArray { + return getSodium().pad(unpaddedData.toUInt8Array(), blocksize).toUByteArray() + } + + actual fun unpad(paddedData: UByteArray, blocksize: Int): UByteArray { + return getSodium().unpad(paddedData.toUInt8Array(), blocksize).toUByteArray() + } + + actual fun toBase64( + data: UByteArray, + variant: Base64Variants + ): String { + return getSodium().to_base64(data.toUInt8Array(), variant.value) + } + + actual fun toHex(data: UByteArray): String { + return getSodium().to_hex(data.toUInt8Array()) + } + + actual fun fromBase64( + data: String, + variant: Base64Variants + ): UByteArray { + return getSodium().from_base64(data, variant.value).toUByteArray() + } + + actual fun fromHex(data: String): UByteArray { + return getSodium().from_hex(data).toUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index 727d9c7..43b49bc 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -1,53 +1,113 @@ -package debug.test - -import com.ionspin.kotlin.crypto.getSodium -import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray -import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array -import kotlin.Any -import kotlin.Int -import kotlin.UByteArray - -actual typealias Sha256State = Any - -actual typealias Sha512State = Any - -actual typealias GenericHashState = Any - -actual class Crypto internal actual constructor() { - actual fun crypto_hash_sha256_init(): dynamic { - println("Debug crypto_hash_sha256_init") - val result = js("getSodium().crypto_hash_sha256_init()") - return result - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - println("Debug crypto_hash_sha256_final") - return getSodium().crypto_hash_sha256_final(state).toUByteArray() - } - - actual fun crypto_hash_sha512_init(): dynamic { - println("Debug crypto_hash_sha512_init") - val result = js("getSodium().crypto_hash_sha512_init()") - return result - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - println("Debug crypto_hash_sha512_final") - return getSodium().crypto_hash_sha512_final(state).toUByteArray() - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { - println("Debug crypto_generichash_init") - return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) - } -} +//package debug.test +// +//import com.ionspin.kotlin.crypto.getSodium +//import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +//import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +//import kotlin.Any +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +//import org.khronos.webgl.Uint8Array +// +//actual typealias Sha256State = Any +// +//actual typealias Sha512State = Any +// +//actual typealias GenericHashState = Any +// +//actual typealias SecretStreamState = Any +// +//actual class Crypto internal actual constructor() { +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// actual fun crypto_hash_sha256_init(): dynamic { +// println("Debug crypto_hash_sha256_init") +// val result = js("getSodium().crypto_hash_sha256_init()") +// return result +// } +// +// actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { +// println("Debug crypto_hash_sha256_update") +// getSodium().crypto_hash_sha256_update(state, input.toUInt8Array()) +// } +// +// actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { +// println("Debug crypto_hash_sha256_final") +// return getSodium().crypto_hash_sha256_final(state).toUByteArray() +// } +// +// actual fun crypto_hash_sha512_init(): dynamic { +// println("Debug crypto_hash_sha512_init") +// val result = js("getSodium().crypto_hash_sha512_init()") +// return result +// } +// +// actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { +// println("Debug crypto_hash_sha512_update") +// getSodium().crypto_hash_sha512_update(state, input.toUInt8Array()) +// } +// +// actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { +// println("Debug crypto_hash_sha512_final") +// return getSodium().crypto_hash_sha512_final(state).toUByteArray() +// } +// +// actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { +// println("Debug crypto_generichash_init") +// return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) +// } +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): +// SecretStreamStateAndHeader { +// println("Debug crypto_secretstream_xchacha20poly1305_init_push") +// val stateAndHeader = +// getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) +// val state = stateAndHeader.state +// val header = (stateAndHeader.header as Uint8Array).toUByteArray() +// return SecretStreamStateAndHeader(state, header) +// } +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// dynamic { +// println("Debug crypto_secretstream_xchacha20poly1305_init_pull") +// return getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), +// key.toUInt8Array()) +// } +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray { +// println("Debug crypto_secretstream_xchacha20poly1305_push") +// return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(), +// ad.toUInt8Array(), tag).toUByteArray() +// } +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag { +// println("Debug crypto_secretstream_xchacha20poly1305_pull") +//// return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(), +//// ad.toUInt8Array()) +// return DecryptedDataAndTag(ubyteArrayOf(), 0U) +// } +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt b/multiplatform-crypto-libsodium-bindings/src/jsTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt new file mode 100644 index 0000000..27130e3 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt @@ -0,0 +1,4 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual fun modifyState(state: SecretStreamState, forceNonce: UByteArray) { +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt similarity index 71% rename from multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt index 2af22a3..0f72b4b 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt @@ -1,21 +1,19 @@ package com.ionspin.kotlin.crypto -import com.goterl.lazycode.lazysodium.SodiumJava - /** * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020 */ -actual object Initializer { +actual object LibsodiumInitializer { private var isPlatformInitialized = false - lateinit var sodium : SodiumJava + lateinit var sodium : SodiumWrapper actual suspend fun initialize() { - sodium = SodiumJava() + sodium = SodiumWrapper() isPlatformInitialized = true } actual fun initializeWithCallback(done: () -> Unit) { - sodium = SodiumJava() + sodium = SodiumWrapper() isPlatformInitialized = true done() } @@ -24,4 +22,4 @@ actual object Initializer { return isPlatformInitialized } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..8fa92fd --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,307 @@ +package com.ionspin.kotlin.crypto.aead + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object AuthenticatedEncryptionWithAssociatedData { + + // Ietf + + // Original chacha20poly1305 + actual fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_aead_xchacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_xchacha20poly1305_ietf_encrypt( + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return ciphertext + } + + actual fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_aead_xchacha20poly1305_ietf_ABYTES) + val validationResult = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt( + message.asByteArray(), + null, + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message + } + + actual fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_aead_xchacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_xchacha20poly1305_ietf_encrypt_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt_detached( + message.asByteArray(), + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + tag.asByteArray(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message + } + + actual fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_chacha20poly1305_ietf_encrypt( + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return ciphertext + } + + actual fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ietf_ABYTES) + val validationResult = sodium.crypto_aead_chacha20poly1305_ietf_decrypt( + message.asByteArray(), + null, + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message + } + + actual fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached( + message.asByteArray(), + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + tag.asByteArray(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message + } + + actual fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ABYTES) + sodium.crypto_aead_chacha20poly1305_encrypt( + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return ciphertext + } + + actual fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ABYTES) + val validationResult = sodium.crypto_aead_chacha20poly1305_decrypt( + message.asByteArray(), + null, + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message + } + + actual fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ABYTES) + sodium.crypto_aead_chacha20poly1305_encrypt_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_aead_chacha20poly1305_decrypt_detached( + message.asByteArray(), + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + tag.asByteArray(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message + } + + actual fun xChaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_xchacha20poly1305_ietf_KEYBYTES) + sodium.crypto_aead_xchacha20poly1305_ietf_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun chaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_ietf_KEYBYTES) + sodium.crypto_aead_chacha20poly1305_ietf_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun chaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_KEYBYTES) + sodium.crypto_aead_chacha20poly1305_keygen(generatedKey.asByteArray()) + return generatedKey + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt new file mode 100644 index 0000000..afaec45 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -0,0 +1,92 @@ +package com.ionspin.kotlin.crypto.auth + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object Auth { + actual fun authKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_KEYBYTES) + sodium.crypto_auth_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun auth(message: UByteArray, key: UByteArray): UByteArray { + val mac = UByteArray(crypto_auth_BYTES) + sodium.crypto_auth( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) + return mac + } + + actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { + return sodium.crypto_auth_verify( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) == 0 + } + + actual fun authHmacSha256Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_hmacsha256_KEYBYTES) + sodium.crypto_auth_hmacsha256_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { + val mac = UByteArray(crypto_auth_hmacsha256_BYTES) + sodium.crypto_auth_hmacsha256( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) + return mac + } + + actual fun authHmacSha256Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + return sodium.crypto_auth_hmacsha256_verify( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) == 0 + } + + actual fun authHmacSha512Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_hmacsha512_KEYBYTES) + sodium.crypto_auth_hmacsha512_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { + val mac = UByteArray(crypto_auth_hmacsha512_BYTES) + sodium.crypto_auth_hmacsha512( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) + return mac + } + + actual fun authHmacSha512Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + return sodium.crypto_auth_hmacsha512_verify( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) == 0 + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt new file mode 100644 index 0000000..27b8be7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -0,0 +1,226 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + actual fun keypair(): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + sodium.crypto_box_keypair(publicKey.asByteArray(), secretKey.asByteArray()) + return BoxKeyPair(publicKey, secretKey) + } + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + sodium.crypto_box_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray()) + return BoxKeyPair(publicKey, secretKey) + } + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + actual fun easy( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) + sodium.crypto_box_easy( + ciphertext.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + recipientsPublicKey.asByteArray(), + sendersSecretKey.asByteArray() + ) + return ciphertext + } + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) + val validationResult = sodium.crypto_box_open_easy( + message.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + sendersPublicKey.asByteArray(), + recipientsSecretKey.asByteArray() + ) + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray { + val sessionKey = UByteArray(crypto_box_BEFORENMBYTES) + sodium.crypto_box_beforenm(sessionKey.asByteArray(), publicKey.asByteArray(), secretKey.asByteArray()) + return sessionKey + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun easyAfterNM( + message: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) + + sodium.crypto_box_easy_afternm( + ciphertext.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + precomputedKey.asByteArray() + ) + + return ciphertext + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun openEasyAfterNM( + ciphertext: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) + val validationResult = sodium.crypto_box_open_easy_afternm( + message.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + precomputedKey.asByteArray() + ) + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + actual fun detached( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): BoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val tag = UByteArray(crypto_box_MACBYTES) + + sodium.crypto_box_detached( + ciphertext.asByteArray(), + tag.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + recipientsPublicKey.asByteArray(), + sendersSecretKey.asByteArray() + ) + + return BoxEncryptedDataAndTag(ciphertext, tag) + } + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + + val validationResult = sodium.crypto_box_open_detached( + message.asByteArray(), + ciphertext.asByteArray(), + tag.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + sendersPublicKey.asByteArray(), + recipientsSecretKey.asByteArray() + ) + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray { + val ciphertextWithPublicKey = UByteArray(message.size + crypto_box_SEALBYTES) + sodium.crypto_box_seal( + ciphertextWithPublicKey.asByteArray(), + message.asByteArray(), + message.size.toLong(), + recipientsPublicKey.asByteArray() + ) + return ciphertextWithPublicKey + } + + actual fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES) + val validationResult = sodium.crypto_box_seal_open( + message.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + recipientsPublicKey.asByteArray(), + recipientsSecretKey.asByteArray() + ) + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt new file mode 100644 index 0000000..f674d82 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -0,0 +1,59 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual class GenericHashStateInternal(internal val data: ByteArray) + +actual object GenericHash { + actual fun genericHash( + message: UByteArray, + requestedHashLength: Int, + key: UByteArray? + ): UByteArray { + val hash = UByteArray(requestedHashLength) + sodium.crypto_generichash( + hash.asByteArray(), + requestedHashLength, + message.asByteArray(), + message.size.toLong(), + key?.asByteArray(), + (key?.size ?: 0) + ) + return hash + } + + actual fun genericHashInit( + requestedHashLength: Int, + key: UByteArray? + ): GenericHashState { + val state = GenericHashStateInternal(ByteArray(sodium.crypto_generichash_statebytes())) + sodium.crypto_generichash_init(state.data, key?.asByteArray(), key?.size ?: 0, requestedHashLength) + return GenericHashState(requestedHashLength, state) + } + + actual fun genericHashUpdate( + state: GenericHashState, + messagePart: UByteArray + ) { + sodium.crypto_generichash_update(state.internalState.data, messagePart.asByteArray(), messagePart.size.toLong()) + } + + actual fun genericHashFinal(state: GenericHashState): UByteArray { + val hashResult = ByteArray(state.hashLength) + sodium.crypto_generichash_final(state.internalState.data, hashResult, state.hashLength) + return hashResult.asUByteArray() + } + + actual fun genericHashKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_generichash_BYTES) + sodium.crypto_generichash_keygen(generatedKey.asByteArray()) + return generatedKey + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/HashJvm.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/HashJvm.kt new file mode 100644 index 0000000..cdaf573 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/HashJvm.kt @@ -0,0 +1,56 @@ +package com.ionspin.kotlin.crypto.hash + +import com.goterl.lazycode.lazysodium.interfaces.Hash +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual typealias Sha256State = Hash.State256 +actual typealias Sha512State = Hash.State512 + +actual object Hash { + + actual fun sha256(data: UByteArray): UByteArray { + val resultHash = UByteArray(crypto_hash_sha256_BYTES) + sodium.crypto_hash_sha256(resultHash.asByteArray(), data.asByteArray(), data.size.toLong()) + return resultHash + } + + actual fun sha256Init(): Sha256State { + val state = Hash.State256() + sodium.crypto_hash_sha256_init(state) + return state + } + + actual fun sha256Update(state: Sha256State, data: UByteArray) { + sodium.crypto_hash_sha256_update(state, data.asByteArray(), data.size.toLong()) + } + + actual fun sha256Final(state: Sha256State): UByteArray { + val resultHash = UByteArray(crypto_hash_sha256_BYTES) + sodium.crypto_hash_sha256_final(state, resultHash.asByteArray()) + return resultHash + } + + actual fun sha512(data: UByteArray): UByteArray { + val resultHash = UByteArray(crypto_hash_sha512_BYTES) + sodium.crypto_hash_sha512(resultHash.asByteArray(), data.asByteArray(), data.size.toLong()) + return resultHash + } + + actual fun sha512Init(): Sha512State { + val state = Hash.State512() + sodium.crypto_hash_sha512_init(state) + return state + } + + actual fun sha512Update(state: Sha512State, data: UByteArray) { + sodium.crypto_hash_sha512_update(state, data.asByteArray(), data.size.toLong()) + } + + actual fun sha512Final(state: Sha512State): UByteArray { + val resultHash = UByteArray(crypto_hash_sha512_BYTES) + sodium.crypto_hash_sha512_final(state, resultHash.asByteArray()) + return resultHash + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt new file mode 100644 index 0000000..7df70a6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt @@ -0,0 +1,49 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + actual fun deriveFromKey( + subkeyId: Int, + subkeyLength: Int, + context: String, + masterKey: UByteArray + ): UByteArray { + val subkey = UByteArray(subkeyLength) + val contextEncoded = context.encodeToByteArray() + + sodium.crypto_kdf_derive_from_key( + subkey.asByteArray(), + subkeyLength, + subkeyId.toLong(), + contextEncoded, + masterKey.asByteArray() + ) + + return subkey + } + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + actual fun keygen(): UByteArray { + val masterKey = UByteArray(crypto_kdf_KEYBYTES) + sodium.crypto_kdf_keygen(masterKey.asByteArray()) + return masterKey + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000..93999ca --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -0,0 +1,94 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium +import com.sun.jna.NativeLong + +actual object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * 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 + */ + actual fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ): UByteArray { + val hashedPassword = UByteArray(outputLength) + + sodium.crypto_pwhash( + hashedPassword.asByteArray(), + outputLength.toLong(), + password.encodeToByteArray(), + password.length.toLong(), + salt.asByteArray(), + opsLimit.toLong(), + NativeLong(memLimit.toLong()), + algorithm + ) + + return hashedPassword + } + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { + val output = ByteArray(crypto_pwhash_STRBYTES) + sodium.crypto_pwhash_str( + output, + password.encodeToByteArray(), + password.length.toLong(), + opslimit.toLong(), + NativeLong(memlimit.toLong()) + ) + return output.asUByteArray() + } + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + actual fun strNeedsRehash( + passwordHash: UByteArray, + opslimit: ULong, + memlimit: Int + ): Int { + return sodium.crypto_pwhash_str_needs_rehash( + passwordHash.asByteArray(), + opslimit.toLong(), + NativeLong(memlimit.toLong()) + ) + } + + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * 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( + passwordHash.asByteArray(), + password.encodeToByteArray(), + password.length.toLong() + ) + + return result == 0 + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..8f113e6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt @@ -0,0 +1,82 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object SecretBox { + actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray { + val ciphertext = UByteArray(message.size + crypto_secretbox_MACBYTES) + sodium.crypto_secretbox_easy( + ciphertext.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + return ciphertext + } + + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val decrypted = UByteArray(ciphertext.size - crypto_secretbox_MACBYTES) + val validationResult = sodium.crypto_secretbox_open_easy( + decrypted.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + if (validationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return decrypted + } + + actual fun detached( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): SecretBoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_secretbox_MACBYTES) + sodium.crypto_secretbox_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + return SecretBoxEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_secretbox_open_detached( + message.asByteArray(), + ciphertext.asByteArray(), + tag.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + if (validationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return message + } + + actual fun keygen() : UByteArray { + val generatedKey = UByteArray(crypto_secretbox_KEYBYTES) + sodium.crypto_secretbox_keygen(generatedKey.asByteArray()) + return generatedKey + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt new file mode 100644 index 0000000..ca6470c --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt @@ -0,0 +1,78 @@ +package com.ionspin.kotlin.crypto.secretstream + +import com.goterl.lazycode.lazysodium.interfaces.SecretStream +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual typealias SecretStreamState = SecretStream.State + +actual object SecretStream { + actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { + val state = SecretStreamState() + val header = UByteArray(sodium.crypto_secretstream_xchacha20poly1305_headerbytes()) + sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) + return SecretStreamStateAndHeader(state, header) + } + + actual fun xChaCha20Poly1305Push( + state: SecretStreamState, + message: UByteArray, + associatedData: UByteArray, + tag: UByte + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_secretstream_xchacha20poly1305_ABYTES) + sodium.crypto_secretstream_xchacha20poly1305_push( + state, + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + tag.toByte() + ) + return ciphertext + } + + actual fun xChaCha20Poly1305InitPull( + key: UByteArray, + header: UByteArray + ): SecretStreamStateAndHeader { + val state = SecretStreamState() + sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray()) + return SecretStreamStateAndHeader(state, header) + } + + actual fun xChaCha20Poly1305Pull( + state: SecretStreamState, + ciphertext: UByteArray, + associatedData: UByteArray + ): DecryptedDataAndTag { + val result = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES) + val tagArray = UByteArray(1) { 0U } + val validationResult = sodium.crypto_secretstream_xchacha20poly1305_pull( + state, + result.asByteArray(), + null, + tagArray.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong() + ) + if (validationResult != 0) { + throw SecretStreamCorruptedOrTamperedDataException() + } + return DecryptedDataAndTag(result, tagArray[0]) + } + + actual fun xChaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_secretstream_xchacha20poly1305_KEYBYTES) + sodium.crypto_secretstream_xchacha20poly1305_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) { + sodium.crypto_secretstream_xchacha20poly1305_rekey(state) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..f915ef7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,25 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ + + +actual object ShortHash { + actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_shorthash_BYTES) + sodium.crypto_shorthash(hashResult.asByteArray(), data.asByteArray(), data.size.toLong(), key.asByteArray()) + return hashResult + } + + actual fun shortHashKeygen(): UByteArray { + val key = UByteArray(crypto_shorthash_KEYBYTES) + sodium.crypto_shorthash_keygen(key.asByteArray()) + return key + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/signature/SignatureJvm.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/signature/SignatureJvm.kt new file mode 100644 index 0000000..56f022b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/signature/SignatureJvm.kt @@ -0,0 +1,209 @@ +package com.ionspin.kotlin.crypto.signature + +import com.goterl.lazycode.lazysodium.interfaces.Sign +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual typealias SignatureState = Sign.StateCryptoSign + +actual object Signature { + actual fun init(): SignatureState { + return SignatureState() + } + + actual fun update(state: SignatureState, data: UByteArray) { + sodium.crypto_sign_update(state, data.asByteArray(), data.size.toLong()) + } + + actual fun finalCreate( + state: SignatureState, + secretKey: UByteArray + ): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + sodium.crypto_sign_final_create( + state, + signature.asByteArray(), + null, + secretKey.asByteArray() + ) + return signature + } + + actual fun finalVerify( + state: SignatureState, + signature: UByteArray, + publicKey: UByteArray + ) { + val verificationResult = sodium.crypto_sign_final_verify( + state, + signature.asByteArray(), + publicKey.asByteArray() + ) + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + actual fun keypair(): SignatureKeyPair { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + sodium.crypto_sign_keypair( + publicKey.asByteArray(), + secretKey.asByteArray(), + ) + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): SignatureKeyPair { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + + + sodium.crypto_sign_seed_keypair( + publicKey.asByteArray(), + secretKey.asByteArray(), + seed.asByteArray() + ) + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The sodium.crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is sodium.crypto_sign_BYTES + mlen bytes long. + */ + actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray { + val signedMessage = UByteArray(message.size + crypto_sign_BYTES) + + sodium.crypto_sign( + signedMessage.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + secretKey.asByteArray() + ) + + return signedMessage + } + + /** + * The sodium.crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray { + val message = UByteArray(signedMessage.size - crypto_sign_BYTES) + + val verificationResult = sodium.crypto_sign_open( + message.asByteArray(), + null, + signedMessage.asByteArray(), + signedMessage.size.toLong(), + publicKey.asByteArray() + ) + if (verificationResult == -1) { + throw InvalidSignatureException() + } + return message + } + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The sodium.crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to sodium.crypto_sign_BYTES bytes long. + */ + actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + + sodium.crypto_sign_detached( + signature.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + secretKey.asByteArray() + ) + + return signature + } + + /** + * The sodium.crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + actual fun verifyDetached( + signature: UByteArray, + message: UByteArray, + publicKey: UByteArray + ) { + + val verificationResult = sodium.crypto_sign_verify_detached( + signature.asByteArray(), + message.asByteArray(), + message.size.toLong(), + publicKey.asByteArray() + ) + + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The sodium.crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray { + val x25519PublicKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + sodium.crypto_sign_ed25519_sk_to_curve25519( + x25519PublicKey.asByteArray(), + ed25519PublicKey.asByteArray() + ) + return x25519PublicKey + } + + actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray { + val x25519SecretKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + sodium.crypto_sign_ed25519_sk_to_curve25519( + x25519SecretKey.asByteArray(), + ed25519SecretKey.asByteArray() + ) + return x25519SecretKey + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray { + val seed = UByteArray(crypto_sign_SEEDBYTES) + + sodium.crypto_sign_ed25519_sk_to_seed( + seed.asByteArray(), + secretKey.asByteArray() + ) + + return seed + + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + + sodium.crypto_sign_ed25519_sk_to_pk( + publicKey.asByteArray(), + secretKey.asByteArray() + ) + + return publicKey + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000..fbbcae3 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -0,0 +1,56 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +actual object LibsodiumRandom { + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + actual fun buf(size: Int): UByteArray { + val result = ByteArray(size) + sodium.randombytes_buf(result, size) + return result.asUByteArray() + } + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { + val result = ByteArray(size) + sodium.randombytes_buf_deterministic(result, size, seed.asByteArray()) + return result.asUByteArray() + } + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + 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() + } + + + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * 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() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..a88bf78 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -0,0 +1,164 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium +import java.lang.RuntimeException +import java.util.* + +actual object LibsodiumUtil { + actual fun memcmp(first: UByteArray, second: UByteArray): Boolean { + if (first.size != second.size) { + throw RuntimeException("Sodium memcmp() only supports comparing same length arrays") + } + return sodium.sodium_memcmp(first.asByteArray(), second.asByteArray(), first.size) == 0 + } + + actual fun memzero(target: UByteArray) { + sodium.sodium_memzero(target.asByteArray(), target.size) + } + + actual fun pad(unpaddedData: UByteArray, blocksize: Int): UByteArray { + + // Pad is invalid in lazysodium-java because it uses char arrays, which are 2 bytes in java + // while libsodium expects 1 byte char array + // See https://github.com/terl/lazysodium-java/issues/85 + + //This is temporary solution until lazysodium is fixed + if (blocksize == 0) { + throw RuntimeException("Invalid block size: $blocksize") + } + val padAmount = blocksize - (unpaddedData.size % blocksize) + val result = if (padAmount == blocksize) { + unpaddedData + UByteArray(blocksize) { + when (it) { + 0 -> 0x80U + else -> 0x00U + } + } + } else { + unpaddedData + UByteArray(padAmount) { + when (it) { + 0 -> 0x80U + else -> 0x00U + } + } + } + + return result + +// val newPadSizeReference = IntByReference(0) +// val newSize = ((unpaddedData.size / blocksize) + 1) * blocksize +// val charArray = CharArray(newSize) { +// if (it < unpaddedData.size) { +// unpaddedData[it].toByte().toChar() +// } else { +// '\u0000' +// } +// } +// sodium.sodium_pad( +// newPadSizeReference.pointer, +// charArray, +// unpaddedData.size + 1, +// blocksize, +// newSize +// ) +// +// return charArray.slice(0 until newPadSizeReference.value).map { it.toByte().toUByte()}.toUByteArray() + + } + + actual fun unpad(paddedData: UByteArray, blocksize: Int): UByteArray { + + // Pad is invalid in lazysodium-java because it uses char arrays, which are 2 bytes in java + // while libsodium expects 1 byte char array + // See https://github.com/terl/lazysodium-java/issues/85 + + //This is temporary solution until lazysodium is fixed + + val unpaddedData = paddedData.dropLastWhile { it == 0U.toUByte() } + if (unpaddedData.last() != 0x80U.toUByte()) { + throw RuntimeException("Invalid padding!") + } + return unpaddedData.dropLast(1).toUByteArray() + + +// val paddedDataCopy = paddedData.copyOf().asByteArray().map { it.toChar() }.toCharArray() +// var unpaddedSize = IntByReference(0) +// +// sodium.sodium_unpad( +// unpaddedSize.pointer, +// paddedDataCopy, +// paddedData.size, +// blocksize +// ) +// +// val unpadded = paddedDataCopy.sliceArray(0 until unpaddedSize.value).map { it.toByte().toUByte() }.toUByteArray() +// +// return unpadded + } + + actual fun toBase64( + data: UByteArray, + variant: Base64Variants + ): String { + val maxlen = sodium.sodium_base64_encoded_len(data.size, variant.value) + val result = ByteArray(maxlen) { 0 } + sodium.sodium_bin2base64( + result, + maxlen, + data.asByteArray(), + data.size, + variant.value + ) + //Drop terminating char \0 + return String(result.sliceArray(0 until result.size - 1)) + } + + actual fun toHex(data: UByteArray): String { + val hexLen = (data.size * 2) + 1 // +1 for terminator char + val result = ByteArray(hexLen) + sodium.sodium_bin2hex( + result, + hexLen, + data.asByteArray(), + data.size + ) + //Drop terminating char \0 + return String(result.sliceArray(0 until result.size - 1)) + } + + actual fun fromBase64( + data: String, + variant: Base64Variants + ): UByteArray { + // from base64 is currently broken in lazysodium-java + // see https://github.com/terl/lazysodium-java/issues/83 +// val maxLength = (data.length * 3) / 4 +// val intermediaryResult = UByteArray(maxLength) { 0U } +// +// sodium.sodium_base642bin( +// intermediaryResult.asByteArray(), +// maxLength, +// data.encodeToByteArray(), +// data.length, +// null, +// binLenPinned.addressOf(0), +// null, +// variant.value +// +// ) + val decoder = when(variant) { + Base64Variants.ORIGINAL -> Base64.getDecoder() + Base64Variants.ORIGINAL_NO_PADDING -> Base64.getDecoder() + Base64Variants.URLSAFE -> Base64.getUrlDecoder() + Base64Variants.URLSAFE_NO_PADDING -> Base64.getUrlDecoder() + } + return decoder.decode(data).asUByteArray() + } + + actual fun fromHex(data: String): UByteArray { + // from hex is currently broken in lazysodium-java + // see https://github.com/terl/lazysodium-java/issues/83 + return data.hexStringToUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index 1213842..178c9c3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -1,62 +1,128 @@ -package debug.test - -import com.goterl.lazycode.lazysodium.SodiumJava -import com.goterl.lazycode.lazysodium.interfaces.Hash -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray - -val sodium: SodiumJava = SodiumJava() - -actual typealias Sha256State = Hash.State256 - -actual typealias Sha512State = Hash.State512 - -actual typealias GenericHashState = ByteArray - -actual class Crypto internal actual constructor() { - actual fun crypto_hash_sha256_init(): Sha256State { - val state = debug.test.Sha256State() - println("Debug crypto_hash_sha256_init") - sodium.crypto_hash_sha256_init(state) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - sodium.crypto_hash_sha256_final(state, out.asByteArray()) - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val state = debug.test.Sha512State() - println("Debug crypto_hash_sha512_init") - sodium.crypto_hash_sha512_init(state) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - sodium.crypto_hash_sha512_final(state, out.asByteArray()) - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) - println("Debug crypto_generichash_init") - sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) - return state - } -} +//package debug.test +// +//import com.goterl.lazycode.lazysodium.SodiumJava +//import com.goterl.lazycode.lazysodium.interfaces.Hash +//import com.goterl.lazycode.lazysodium.interfaces.SecretStream +//import kotlin.ByteArray +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +// +//val sodium: SodiumJava = SodiumJava() +// +//actual typealias Sha256State = Hash.State256 +// +//actual typealias Sha512State = Hash.State512 +// +//actual typealias GenericHashState = ByteArray +// +//actual typealias SecretStreamState = SecretStream.State +// +//actual class Crypto internal actual constructor() { +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// actual fun crypto_hash_sha256_init(): Sha256State { +// val state = debug.test.Sha256State() +// println("Debug crypto_hash_sha256_init") +// sodium.crypto_hash_sha256_init(state) +// return state +// } +// +// actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { +// println("Debug crypto_hash_sha256_update") +// sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) +// } +// +// actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { +// val out = UByteArray(32) +// println("Debug crypto_hash_sha256_final") +// sodium.crypto_hash_sha256_final(state, out.asByteArray()) +// return out +// } +// +// actual fun crypto_hash_sha512_init(): Sha512State { +// val state = debug.test.Sha512State() +// println("Debug crypto_hash_sha512_init") +// sodium.crypto_hash_sha512_init(state) +// return state +// } +// +// actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { +// println("Debug crypto_hash_sha512_update") +// sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) +// } +// +// actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { +// val out = UByteArray(64) +// println("Debug crypto_hash_sha512_final") +// sodium.crypto_hash_sha512_final(state, out.asByteArray()) +// return out +// } +// +// actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { +// val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) +// println("Debug crypto_generichash_init") +// sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) +// return state +// } +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): +// SecretStreamStateAndHeader { +// println("Debug crypto_secretstream_xchacha20poly1305_init_push") +// val header = UByteArray(24) +// val state = SecretStream.State() +// sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), +// key.asByteArray()) +// return SecretStreamStateAndHeader(state, header) +// } +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// SecretStreamState { +// val state = debug.test.SecretStreamState() +// println("Debug crypto_secretstream_xchacha20poly1305_init_pull") +// sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), +// key.asByteArray()) +// return state +// } +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray { +// val c = UByteArray(m.size + 17) +// println("Debug crypto_secretstream_xchacha20poly1305_push") +// sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(), +// m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte()) +// return c +// } +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag { +// val m = UByteArray(c.size - 17) +// var tag_p : UByte = 0U +// println("Debug crypto_secretstream_xchacha20poly1305_pull") +// sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, byteArrayOf(), +// c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) +// return debug.test.DecryptedDataAndTag(m, tag_p) +// } +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt b/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt new file mode 100644 index 0000000..eb62fc6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt @@ -0,0 +1,11 @@ +package com.ionspin.kotlin.crypto + +import com.goterl.lazycode.lazysodium.LazySodiumJava +import com.goterl.lazycode.lazysodium.SodiumJava + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 22-Aug-2020 + */ +typealias SodiumWrapper = SodiumJava diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt b/multiplatform-crypto-libsodium-bindings/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt new file mode 100644 index 0000000..46ec50b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt @@ -0,0 +1,6 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual fun modifyState(state: SecretStreamState, forceNonce: UByteArray) { + state.nonce = forceNonce.sliceArray(12 until 24).asByteArray() + println("Nonce modified ${state.nonce}") +} diff --git a/multiplatform-crypto-libsodium-bindings/src/main/AndroidManifest.xml b/multiplatform-crypto-libsodium-bindings/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0b4b599 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt similarity index 94% rename from multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt index 944c199..5f6ae73 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt @@ -5,7 +5,7 @@ package com.ionspin.kotlin.crypto import libsodium.sodium_init import kotlin.native.concurrent.AtomicInt -actual object Initializer { +actual object LibsodiumInitializer { private var isPlatformInitialized : AtomicInt = AtomicInt(0) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..6d0531d --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,534 @@ +package com.ionspin.kotlin.crypto.aead + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_aead_chacha20poly1305_decrypt +import libsodium.crypto_aead_chacha20poly1305_decrypt_detached +import libsodium.crypto_aead_chacha20poly1305_encrypt +import libsodium.crypto_aead_chacha20poly1305_encrypt_detached +import libsodium.crypto_aead_chacha20poly1305_ietf_decrypt +import libsodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached +import libsodium.crypto_aead_chacha20poly1305_ietf_encrypt +import libsodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached +import libsodium.crypto_aead_chacha20poly1305_ietf_keygen +import libsodium.crypto_aead_chacha20poly1305_keygen +import libsodium.crypto_aead_xchacha20poly1305_ietf_decrypt +import libsodium.crypto_aead_xchacha20poly1305_ietf_decrypt_detached +import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt +import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt_detached +import libsodium.crypto_aead_xchacha20poly1305_ietf_keygen + +actual object AuthenticatedEncryptionWithAssociatedData { + + // Ietf + + // Original chacha20poly1305 + actual fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size + crypto_aead_xchacha20poly1305_ietf_ABYTES) + val ciphertextPinned = ciphertext.pin() + + crypto_aead_xchacha20poly1305_ietf_encrypt( + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return ciphertext + } + + actual fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertextPinned = ciphertext.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_xchacha20poly1305_ietf_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_xchacha20poly1305_ietf_decrypt( + messagePinned.toPtr(), + null, + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message + } + + actual fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size) + val ciphertextPinned = ciphertext.pin() + + val authenticationTag = UByteArray(crypto_aead_xchacha20poly1305_ietf_ABYTES) + val authenticationTagPinned = authenticationTag.pin() + + crypto_aead_xchacha20poly1305_ietf_encrypt_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size) + val messagePinned = message.pin() + + val validationResult = crypto_aead_xchacha20poly1305_ietf_decrypt_detached( + messagePinned.toPtr(), + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + tagPinned.toPtr(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + tagPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message + } + + actual fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ietf_ABYTES) + val ciphertextPinned = ciphertext.pin() + + crypto_aead_chacha20poly1305_ietf_encrypt( + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return ciphertext + } + + actual fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertextPinned = ciphertext.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ietf_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_ietf_decrypt( + messagePinned.toPtr(), + null, + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message + } + + actual fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size) + val ciphertextPinned = ciphertext.pin() + + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ietf_ABYTES) + val authenticationTagPinned = authenticationTag.pin() + + crypto_aead_chacha20poly1305_ietf_encrypt_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_ietf_decrypt_detached( + messagePinned.toPtr(), + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + tagPinned.toPtr(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + tagPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message + } + + actual fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ABYTES) + val ciphertextPinned = ciphertext.pin() + + crypto_aead_chacha20poly1305_encrypt( + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return ciphertext + } + + actual fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertextPinned = ciphertext.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_decrypt( + messagePinned.toPtr(), + null, + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message + } + + actual fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size) + val ciphertextPinned = ciphertext.pin() + + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ABYTES) + val authenticationTagPinned = authenticationTag.pin() + + crypto_aead_chacha20poly1305_encrypt_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_decrypt_detached( + messagePinned.toPtr(), + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + tagPinned.toPtr(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + tagPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message + } + + actual fun xChaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_xchacha20poly1305_ietf_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_aead_xchacha20poly1305_ietf_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun chaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_ietf_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_aead_chacha20poly1305_ietf_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun chaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_aead_chacha20poly1305_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt new file mode 100644 index 0000000..1964240 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -0,0 +1,165 @@ +package com.ionspin.kotlin.crypto.auth + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_auth +import libsodium.crypto_auth_hmacsha256 +import libsodium.crypto_auth_hmacsha256_keygen +import libsodium.crypto_auth_hmacsha256_verify +import libsodium.crypto_auth_hmacsha512 +import libsodium.crypto_auth_hmacsha512_keygen +import libsodium.crypto_auth_hmacsha512_verify +import libsodium.crypto_auth_keygen +import libsodium.crypto_auth_verify + +actual object Auth { + actual fun authKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_auth_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun auth(message: UByteArray, key: UByteArray): UByteArray { + val messagePinned = message.pin() + val keyPinned = key.pin() + + val mac = UByteArray(crypto_auth_BYTES) + val macPinned = mac.pin() + + crypto_auth( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr() + ) + + macPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + + return mac + } + + actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { + val macPinned = mac.pin() + val messagePinned = message.pin() + val keyPinned = key.pin() + val verify = crypto_auth_verify( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr(), + ) + + keyPinned.unpin() + messagePinned.unpin() + macPinned.unpin() + return verify == 0 + } + + actual fun authHmacSha256Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_hmacsha256_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_auth_hmacsha256_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { + val messagePinned = message.pin() + val keyPinned = key.pin() + + val mac = UByteArray(crypto_auth_hmacsha256_BYTES) + val macPinned = mac.pin() + + crypto_auth_hmacsha256( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr() + ) + + macPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + + return mac + } + + actual fun authHmacSha256Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + val macPinned = mac.pin() + val messagePinned = message.pin() + val keyPinned = key.pin() + + val verify = crypto_auth_hmacsha256_verify( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr(), + ) + + keyPinned.unpin() + messagePinned.unpin() + macPinned.unpin() + return verify == 0 + } + + actual fun authHmacSha512Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_hmacsha512_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_auth_hmacsha512_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { + val messagePinned = message.pin() + val keyPinned = key.pin() + + val mac = UByteArray(crypto_auth_hmacsha512_BYTES) + val macPinned = mac.pin() + + crypto_auth_hmacsha512( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr() + ) + + macPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + + return mac + } + + actual fun authHmacSha512Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + val macPinned = mac.pin() + val messagePinned = message.pin() + val keyPinned = key.pin() + + val verify = crypto_auth_hmacsha512_verify( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr(), + ) + + keyPinned.unpin() + messagePinned.unpin() + macPinned.unpin() + return verify == 0 + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt new file mode 100644 index 0000000..48f64c9 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -0,0 +1,361 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_box_beforenm +import libsodium.crypto_box_detached +import libsodium.crypto_box_easy +import libsodium.crypto_box_easy_afternm +import libsodium.crypto_box_keypair +import libsodium.crypto_box_open_detached +import libsodium.crypto_box_open_easy +import libsodium.crypto_box_open_easy_afternm +import libsodium.crypto_box_seal +import libsodium.crypto_box_seal_open +import libsodium.crypto_box_seed_keypair + +actual object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + actual fun keypair(): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + crypto_box_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr()) + publicKeyPinned.unpin() + secretKeyPinned.unpin() + return BoxKeyPair(publicKey, secretKey) + } + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + val seedPinned = seed.pin() + crypto_box_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr()) + publicKeyPinned.unpin() + secretKeyPinned.unpin() + seedPinned.unpin() + return BoxKeyPair(publicKey, secretKey) + } + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + actual fun easy( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) + val ciphertextPinned = ciphertext.pin() + + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val recipientsPublicKeyPinned = recipientsPublicKey.pin() + val sendersSecretKeyPinned = sendersSecretKey.pin() + + crypto_box_easy( + ciphertextPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + recipientsPublicKeyPinned.toPtr(), + sendersSecretKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + recipientsPublicKeyPinned.unpin() + sendersSecretKeyPinned.unpin() + + return ciphertext + } + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) + val messagePinned = message.pin() + + val ciphertextPinned = ciphertext.pin() + val noncePinned = nonce.pin() + val sendersPublicKeyPinned = sendersPublicKey.pin() + val recipientsSecretKeyPinned = recipientsSecretKey.pin() + + val validationResult = crypto_box_open_easy( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + sendersPublicKeyPinned.toPtr(), + recipientsSecretKeyPinned.toPtr() + ) + + messagePinned.unpin() + ciphertextPinned.unpin() + noncePinned.unpin() + sendersPublicKeyPinned.unpin() + recipientsSecretKeyPinned.unpin() + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray { + val sessionKey = UByteArray(crypto_box_BEFORENMBYTES) + + val sessionKeyPinned = sessionKey.pin() + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + + crypto_box_beforenm(sessionKeyPinned.toPtr(), publicKeyPinned.toPtr(), secretKeyPinned.toPtr()) + + sessionKeyPinned.unpin() + publicKeyPinned.unpin() + secretKeyPinned.unpin() + + return sessionKey + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun easyAfterNM( + message: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) + + val ciphertextPinned = ciphertext.pin() + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val precomputedKeyPinned = precomputedKey.pin() + + crypto_box_easy_afternm( + ciphertextPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + precomputedKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + precomputedKeyPinned.unpin() + + + + return ciphertext + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun openEasyAfterNM( + ciphertext: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) + + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val noncePinned = nonce.pin() + val precomputedKeyPinned = precomputedKey.pin() + + val validationResult = crypto_box_open_easy_afternm( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + precomputedKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + precomputedKeyPinned.unpin() + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + actual fun detached( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): BoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val tag = UByteArray(crypto_box_MACBYTES) + + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val recipientsPublicKeyPinned = recipientsPublicKey.pin() + val sendersSecretKeyPinned = sendersSecretKey.pin() + + crypto_box_detached( + ciphertextPinned.toPtr(), + tagPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + recipientsPublicKeyPinned.toPtr(), + sendersSecretKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + tagPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + recipientsPublicKeyPinned.unpin() + sendersSecretKeyPinned.unpin() + return BoxEncryptedDataAndTag(ciphertext, tag) + } + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val noncePinned = nonce.pin() + val recipientsSecretKeyPinned = recipientsSecretKey.pin() + val sendersPublicKeyPinned = sendersPublicKey.pin() + + + val validationResult = crypto_box_open_detached( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + tagPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + sendersPublicKeyPinned.toPtr(), + recipientsSecretKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + tagPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + recipientsSecretKeyPinned.unpin() + sendersPublicKeyPinned.unpin() + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray { + val ciphertextWithPublicKey = UByteArray(message.size + crypto_box_SEALBYTES) + + val ciphertextWithPublicKeyPinned = ciphertextWithPublicKey.pin() + val messagePinned = message.pin() + val recipientsPublicKeyPinned = recipientsPublicKey.pin() + + crypto_box_seal( + ciphertextWithPublicKeyPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + recipientsPublicKeyPinned.toPtr() + ) + + ciphertextWithPublicKeyPinned.unpin() + messagePinned.unpin() + recipientsPublicKeyPinned.unpin() + + return ciphertextWithPublicKey + + } + + actual fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES) + + val recipientsPublicKeyPinned = recipientsPublicKey.pin() + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val recipientsSecretKeyPinned = recipientsSecretKey.pin() + + val validationResult = crypto_box_seal_open( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + recipientsPublicKeyPinned.toPtr(), + recipientsSecretKeyPinned.toPtr() + ) + + messagePinned.unpin() + ciphertextPinned.unpin() + recipientsPublicKeyPinned.unpin() + recipientsSecretKeyPinned.unpin() + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt new file mode 100644 index 0000000..2f765d4 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -0,0 +1,101 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.pointed +import kotlinx.cinterop.ptr +import kotlinx.cinterop.reinterpret +import libsodium.crypto_generichash +import libsodium.crypto_generichash_final +import libsodium.crypto_generichash_init +import libsodium.crypto_generichash_keygen +import libsodium.crypto_generichash_update +import platform.posix.malloc + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ + +actual typealias GenericHashStateInternal = libsodium.crypto_generichash_blake2b_state + +actual object GenericHash { + val _emitByte: Byte = 0 + val _emitByteArray: ByteArray = ByteArray(0) + + + + actual fun genericHash(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray { + val hash = UByteArray(requestedHashLength) + val pinnedHash = hash.pin() + val pinnedKey = key?.pin() + val pinnedMessage = message.pin() + crypto_generichash( + pinnedHash.toPtr(), + requestedHashLength.convert(), + pinnedMessage.toPtr(), + message.size.convert(), + pinnedKey?.toPtr(), + (key?.size ?: 0).convert() + ) + pinnedHash.unpin() + pinnedKey?.unpin() + pinnedMessage.unpin() + return hash + } + + actual fun genericHashInit( + requestedHashLength: Int, + key: UByteArray? + ): GenericHashState { + val stateAllocated = malloc(GenericHashStateInternal.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + val pinnedKey = key?.pin() + crypto_generichash_init( + statePointed.ptr, + pinnedKey?.toPtr(), + (key?.size ?: 0).convert(), + requestedHashLength.convert() + ) + pinnedKey?.unpin() + return GenericHashState(requestedHashLength, statePointed) + } + + actual fun genericHashUpdate( + state: GenericHashState, + messagePart: UByteArray + ) { + val pinnedMessage = messagePart.pin() + crypto_generichash_update( + state.internalState.ptr, + pinnedMessage.toPtr(), + messagePart.size.convert() + ) + pinnedMessage.unpin() + } + + actual fun genericHashFinal(state: GenericHashState): UByteArray { + val hashResult = UByteArray(state.hashLength) + val hashResultPinned = hashResult.pin() + crypto_generichash_final( + state.internalState.ptr, + hashResultPinned.toPtr(), + state.hashLength.convert() + ) + hashResultPinned.unpin() + return hashResult + } + + actual fun genericHashKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_generichash_BYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_generichash_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt new file mode 100644 index 0000000..25d9458 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -0,0 +1,99 @@ +package com.ionspin.kotlin.crypto.hash + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.pointed +import kotlinx.cinterop.ptr +import kotlinx.cinterop.reinterpret +import libsodium.crypto_hash +import libsodium.crypto_hash_sha256 +import libsodium.crypto_hash_sha256_final +import libsodium.crypto_hash_sha256_init +import libsodium.crypto_hash_sha256_state +import libsodium.crypto_hash_sha256_update +import libsodium.crypto_hash_sha512 +import libsodium.crypto_hash_sha512_final +import libsodium.crypto_hash_sha512_init +import libsodium.crypto_hash_sha512_state +import libsodium.crypto_hash_sha512_update +import platform.posix.malloc + +actual typealias Sha256State = crypto_hash_sha256_state +actual typealias Sha512State = crypto_hash_sha512_state + +actual object Hash { + //Not present in Lazy Sodium +// actual fun hash(data: UByteArray): UByteArray { +// val hashResult = UByteArray(crypto_hash_BYTES) +// val hashResultPinned = hashResult.pin() +// val dataPinned = data.pin() +// crypto_hash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) +// hashResultPinned.unpin() +// dataPinned.unpin() +// +// return hashResult +// } + + actual fun sha256(data: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_hash_sha256_BYTES) + val hashResultPinned = hashResult.pin() + val dataPinned = data.pin() + crypto_hash_sha256(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) + hashResultPinned.unpin() + dataPinned.unpin() + + return hashResult + } + + actual fun sha256Init(): Sha256State { + val stateAllocated = malloc(Sha256State.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + crypto_hash_sha256_init(statePointed.ptr) + return statePointed + } + + actual fun sha256Update(state: Sha256State, data: UByteArray) { + val dataPinned = data.pin() + crypto_hash_sha256_update(state.ptr, dataPinned.toPtr(), data.size.convert()) + } + + actual fun sha256Final(state: Sha256State): UByteArray { + val hashResult = UByteArray(crypto_hash_sha256_BYTES) + val hashResultPinned = hashResult.pin() + crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr()) + return hashResult + } + + actual fun sha512(data: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_hash_sha512_BYTES) + val hashResultPinned = hashResult.pin() + val dataPinned = data.pin() + crypto_hash_sha512(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) + hashResultPinned.unpin() + dataPinned.unpin() + + return hashResult + } + + actual fun sha512Init(): Sha512State { + val stateAllocated = malloc(Sha512State.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + crypto_hash_sha512_init(statePointed.ptr) + return statePointed + } + + actual fun sha512Update(state: Sha512State, data: UByteArray) { + val dataPinned = data.pin() + crypto_hash_sha512_update(state.ptr, dataPinned.toPtr(), data.size.convert()) + } + + actual fun sha512Final(state: Sha512State): UByteArray { + val hashResult = UByteArray(crypto_hash_sha512_BYTES) + val hashResultPinned = hashResult.pin() + crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr()) + return hashResult + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt new file mode 100644 index 0000000..972ce15 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt @@ -0,0 +1,66 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_kdf_derive_from_key +import libsodium.crypto_kdf_keygen + +actual object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + actual fun deriveFromKey( + subkeyId: Int, + subkeyLength: Int, + context: String, + masterKey: UByteArray + ): UByteArray { + val subkey = UByteArray(subkeyLength) + val contextEncoded = context.encodeToByteArray() + + val contextEncodedAndPinned = contextEncoded.pin() + val masterKeyPinned = masterKey.pin() + val subkeyPinned = subkey.pin() + crypto_kdf_derive_from_key( + subkeyPinned.toPtr(), + subkeyLength.convert(), + subkeyId.convert(), + contextEncodedAndPinned.addressOf(0), + masterKeyPinned.toPtr() + ) + + contextEncodedAndPinned.unpin() + masterKeyPinned.unpin() + subkeyPinned.unpin() + + return subkey + + + } + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + actual fun keygen(): UByteArray { + val masterKey = UByteArray(crypto_kdf_KEYBYTES) + val masterKeyPinned = masterKey.pin() + crypto_kdf_keygen(masterKeyPinned.toPtr()) + masterKeyPinned.unpin() + return masterKey + } + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt new file mode 100644 index 0000000..20a4381 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -0,0 +1,114 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.toCValues +import libsodium.crypto_pwhash +import libsodium.crypto_pwhash_str +import libsodium.crypto_pwhash_str_needs_rehash +import libsodium.crypto_pwhash_str_verify + +actual object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * 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 + */ + actual fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ) : UByteArray { + val hashedPassword = UByteArray(outputLength) + + val hashedPasswordPinned = hashedPassword.pin() + val saltPinned = salt.pin() + + val hashingResult = crypto_pwhash( + hashedPasswordPinned.toPtr(), + outputLength.convert(), + password, + password.length.convert(), + saltPinned.toPtr(), + opsLimit, + memLimit.convert(), + algorithm + ) + saltPinned.unpin() + hashedPasswordPinned.unpin() + if (hashingResult != 0) { + throw PasswordHashingFailed() + } + + return hashedPassword + } + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { + val output = ByteArray(crypto_pwhash_STRBYTES) + val outputPinned = output.pin() + crypto_pwhash_str( + outputPinned.addressOf(0), + password, + password.length.convert(), + opslimit, + memlimit.convert() + ) + outputPinned.unpin() + + return output.asUByteArray() + } + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + actual fun strNeedsRehash( + passwordHash: UByteArray, + opslimit: ULong, + memlimit: Int + ): Int { + val result = crypto_pwhash_str_needs_rehash( + passwordHash.asByteArray().toCValues(), + opslimit, + memlimit.convert() + ) + return result + + + } + + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * It returns 0 if the verification succeeds, and -1 on error. + */ + actual fun strVerify(passwordHash: UByteArray, password: String): Boolean { + val result = crypto_pwhash_str_verify( + passwordHash.asByteArray().toCValues(), + password, + password.length.convert() + ) + return result == 0 + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..b0da444 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt @@ -0,0 +1,126 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_secretbox_detached +import libsodium.crypto_secretbox_easy +import libsodium.crypto_secretbox_keygen +import libsodium.crypto_secretbox_open_detached +import libsodium.crypto_secretbox_open_easy + +actual object SecretBox { + actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray { + val ciphertext = UByteArray(message.size + crypto_secretbox_MACBYTES) + val ciphertextPinned = ciphertext.pin() + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + crypto_secretbox_easy( + ciphertextPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + return ciphertext + } + + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_secretbox_MACBYTES) + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + val verificationResult = crypto_secretbox_open_easy( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + if (verificationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return message + } + + actual fun detached( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): SecretBoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_secretbox_MACBYTES) + val ciphertextPinned = ciphertext.pin() + val authenticationTagPinned = authenticationTag.pin() + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + crypto_secretbox_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + authenticationTagPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + return SecretBoxEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + val verificationResult = crypto_secretbox_open_detached( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + tagPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + if (verificationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return message + } + + actual fun keygen() :UByteArray { + val generatedKey = UByteArray(crypto_secretbox_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_secretbox_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt new file mode 100644 index 0000000..ce04cf0 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -0,0 +1,136 @@ +package com.ionspin.kotlin.crypto.secretstream + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.pointed +import kotlinx.cinterop.ptr +import kotlinx.cinterop.reinterpret +import libsodium.crypto_secretstream_xchacha20poly1305_ABYTES +import libsodium.crypto_secretstream_xchacha20poly1305_headerbytes +import libsodium.crypto_secretstream_xchacha20poly1305_init_pull +import libsodium.crypto_secretstream_xchacha20poly1305_init_push +import libsodium.crypto_secretstream_xchacha20poly1305_keygen +import libsodium.crypto_secretstream_xchacha20poly1305_pull +import libsodium.crypto_secretstream_xchacha20poly1305_push +import libsodium.crypto_secretstream_xchacha20poly1305_rekey +import platform.posix.malloc + +actual typealias SecretStreamState = libsodium.crypto_secretstream_xchacha20poly1305_state + +actual object SecretStream { + actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { + val stateAllocated = malloc(SecretStreamState.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + + val header = UByteArray(crypto_secretstream_xchacha20poly1305_headerbytes().convert()) { 0U } + val headerPinned = header.pin() + val keyPinned = key.pin() + crypto_secretstream_xchacha20poly1305_init_push( + statePointed.ptr, + headerPinned.toPtr(), + keyPinned.toPtr() + ) + headerPinned.unpin() + keyPinned.unpin() + return SecretStreamStateAndHeader(statePointed, header) + + } + + actual fun xChaCha20Poly1305Push( + state: SecretStreamState, + message: UByteArray, + associatedData: UByteArray, + tag: UByte + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) { 0U } + val ciphertextPinned = ciphertext.pin() + val messagePinned = message.pin() + val associatedDataPinned = if (associatedData.isNotEmpty()) { + associatedData.pin() + } else { + null + } + crypto_secretstream_xchacha20poly1305_push( + state.ptr, + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned?.toPtr(), + associatedData.size.convert(), + tag + ) + + ciphertextPinned.unpin() + messagePinned.unpin() + associatedDataPinned?.unpin() + return ciphertext + } + + actual fun xChaCha20Poly1305InitPull( + key: UByteArray, + header: UByteArray + ): SecretStreamStateAndHeader { + val stateAllocated = malloc(SecretStreamState.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + val keyPinned = key.pin() + val headerPinned = header.pin() + crypto_secretstream_xchacha20poly1305_init_pull( + statePointed.ptr, + headerPinned.toPtr(), + keyPinned.toPtr() + ) + headerPinned.unpin() + keyPinned.unpin() + return SecretStreamStateAndHeader(statePointed, header) + } + + actual fun xChaCha20Poly1305Pull( + state: SecretStreamState, + ciphertext: UByteArray, + associatedData: UByteArray + ): DecryptedDataAndTag { + val message = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val associatedDataPinned = if (associatedData.isNotEmpty()) { + associatedData.pin() + } else { + null + } + val tag = UByteArray(1) { 0U } + val tagPinned = tag.pin() + val validationResult = crypto_secretstream_xchacha20poly1305_pull( + state.ptr, + messagePinned.toPtr(), + null, + tagPinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + associatedDataPinned?.toPtr(), + associatedData.size.convert() + ) + ciphertextPinned.unpin() + messagePinned.unpin() + associatedDataPinned?.unpin() + tagPinned.unpin() + if (validationResult != 0) { + throw SecretStreamCorruptedOrTamperedDataException() + } + return DecryptedDataAndTag(message, tag[0]) + } + + actual fun xChaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_secretstream_xchacha20poly1305_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_secretstream_xchacha20poly1305_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) { + crypto_secretstream_xchacha20poly1305_rekey(state.ptr) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..852f043 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,35 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_shorthash +import libsodium.crypto_shorthash_keygen + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual object ShortHash { + actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_shorthash_BYTES) + val hashResultPinned = hashResult.pin() + val dataPinned = data.pin() + val keyPinned = key.pin() + crypto_shorthash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert(), keyPinned.toPtr()) + hashResultPinned.unpin() + dataPinned.unpin() + keyPinned.unpin() + return hashResult + } + + actual fun shortHashKeygen(): UByteArray { + val keyResult = UByteArray(crypto_shorthash_KEYBYTES) + val keyResultPinned = keyResult.pin() + crypto_shorthash_keygen(keyResultPinned.toPtr()) + keyResultPinned.unpin() + return keyResult + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt new file mode 100644 index 0000000..722ec37 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt @@ -0,0 +1,275 @@ +package com.ionspin.kotlin.crypto.signature + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.* +import libsodium.* +import platform.posix.malloc + +actual typealias SignatureState = crypto_sign_ed25519ph_state + +actual object Signature { + actual fun init(): SignatureState { + val stateAllocated = malloc(SignatureState.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + crypto_sign_init(statePointed.ptr) + return statePointed + } + + actual fun update(state: SignatureState, data: UByteArray) { + val dataPinned = data.pin() + crypto_sign_update(state.ptr, dataPinned.toPtr(), data.size.convert()) + dataPinned.unpin() + } + + actual fun finalCreate( + state: SignatureState, + secretKey: UByteArray + ): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + val secretKeyPinned = secretKey.pin() + val signaturePinned = signature.pin() + crypto_sign_final_create( + state.ptr, + signaturePinned.toPtr(), + null, + secretKeyPinned.toPtr() + ) + secretKeyPinned.unpin() + signaturePinned.unpin() + return signature + } + + actual fun finalVerify( + state: SignatureState, + signature: UByteArray, + publicKey: UByteArray + ) { + val signaturePinned = signature.pin() + val publicKeyPinned = publicKey.pin() + val verificationResult = crypto_sign_final_verify( + state.ptr, + signaturePinned.toPtr(), + publicKeyPinned.toPtr() + ) + + signaturePinned.unpin() + publicKeyPinned.unpin() + + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + actual fun keypair(): SignatureKeyPair { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign_keypair( + publicKeyPinned.toPtr(), + secretKeyPinned.toPtr(), + ) + publicKeyPinned.unpin() + secretKeyPinned.unpin() + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): SignatureKeyPair { + val seedPinned = seed.pin() + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign_seed_keypair( + publicKeyPinned.toPtr(), + secretKeyPinned.toPtr(), + seedPinned.toPtr() + ) + seedPinned.unpin() + publicKeyPinned.unpin() + secretKeyPinned.unpin() + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is crypto_sign_BYTES + mlen bytes long. + */ + actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray { + val signedMessage = UByteArray(message.size + crypto_sign_BYTES) + val signedMessagePinned = signedMessage.pin() + val messagePinned = message.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign( + signedMessagePinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + secretKeyPinned.toPtr() + ) + signedMessagePinned.unpin() + messagePinned.unpin() + secretKeyPinned.unpin() + + return signedMessage + } + + /** + * The crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray { + val message = UByteArray(signedMessage.size - crypto_sign_BYTES) + val messagePinned = message.pin() + val signedMessagePinned = signedMessage.pin() + val publicKeyPinned = publicKey.pin() + + val verificationResult = crypto_sign_open( + messagePinned.toPtr(), + null, + signedMessagePinned.toPtr(), + signedMessage.size.convert(), + publicKeyPinned.toPtr() + ) + messagePinned.unpin() + signedMessagePinned.unpin() + publicKeyPinned.unpin() + if (verificationResult == -1) { + throw InvalidSignatureException() + } + return message + } + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to crypto_sign_BYTES bytes long. + */ + actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + val signaturePinned = signature.pin() + val messagePinned = message.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign_detached( + signaturePinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + secretKeyPinned.toPtr() + ) + signaturePinned.unpin() + messagePinned.unpin() + secretKeyPinned.unpin() + + return signature + } + + /** + * The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + actual fun verifyDetached( + signature: UByteArray, + message: UByteArray, + publicKey: UByteArray + ) { + val signaturePinned = signature.pin() + val messagePinned = message.pin() + val publicKeyPinned = publicKey.pin() + val verificationResult = crypto_sign_verify_detached( + signaturePinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + publicKeyPinned.toPtr() + ) + signaturePinned.unpin() + messagePinned.unpin() + publicKeyPinned.unpin() + + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray { + val x25519PublicKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + val x25519PublicKeyPinned = x25519PublicKey.pin() + val ed25519PublicKeyPinned = ed25519PublicKey.pin() + crypto_sign_ed25519_sk_to_curve25519( + x25519PublicKeyPinned.toPtr(), + ed25519PublicKeyPinned.toPtr() + ) + x25519PublicKeyPinned.unpin() + ed25519PublicKeyPinned.unpin() + return x25519PublicKey + } + + actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray { + val x25519SecretKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + val x25519SecretKeyPinned = x25519SecretKey.pin() + val ed25519SecretKeyPinned = ed25519SecretKey.pin() + crypto_sign_ed25519_sk_to_curve25519( + x25519SecretKeyPinned.toPtr(), + ed25519SecretKeyPinned.toPtr() + ) + x25519SecretKeyPinned.unpin() + ed25519SecretKeyPinned.unpin() + return x25519SecretKey + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray { + val seed = UByteArray(crypto_sign_SEEDBYTES) + + val secretKeyPinned = secretKey.pin() + val seedPinned = seed.pin() + + crypto_sign_ed25519_sk_to_seed( + seedPinned.toPtr(), + secretKeyPinned.toPtr() + ) + + secretKeyPinned.unpin() + seedPinned.unpin() + + return seed + + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + + val secretKeyPinned = secretKey.pin() + val publicKeyPinned = publicKey.pin() + + crypto_sign_ed25519_sk_to_pk( + publicKeyPinned.toPtr(), + secretKeyPinned.toPtr() + ) + + secretKeyPinned.unpin() + publicKeyPinned.unpin() + + return publicKey + } + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt new file mode 100644 index 0000000..8964c2b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt @@ -0,0 +1,14 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.Pinned +import kotlinx.cinterop.UByteVar +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.toCPointer + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Aug-2020 + */ +fun Pinned.toPtr() : CPointer? = addressOf(0) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt new file mode 100644 index 0000000..8ea76d6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -0,0 +1,63 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.randombytes_buf +import libsodium.randombytes_buf_deterministic +import libsodium.randombytes_close +import libsodium.randombytes_random +import libsodium.randombytes_stir +import libsodium.randombytes_uniform + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +actual object LibsodiumRandom { + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + actual fun buf(size: Int): UByteArray { + val result = UByteArray(size) + val resultPinned = result.pin() + randombytes_buf(resultPinned.toPtr(), size.convert()) + resultPinned.unpin() + return result + } + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { + val result = UByteArray(size) + val resultPinned = result.pin() + val seedPinned = seed.pin() + randombytes_buf_deterministic(resultPinned.toPtr(), size.convert(), seedPinned.toPtr()) + resultPinned.unpin() + seedPinned.unpin() + return result + } + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + actual fun random(): UInt { + return randombytes_random() + } + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * 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 { + return randombytes_uniform(upperBound) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..81577aa --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -0,0 +1,161 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.sodium_base642bin +import libsodium.sodium_base64_encoded_len +import libsodium.sodium_bin2base64 +import libsodium.sodium_bin2hex +import libsodium.sodium_hex2bin +import libsodium.sodium_memcmp +import libsodium.sodium_memzero +import libsodium.sodium_pad +import libsodium.sodium_unpad + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ + + +actual object LibsodiumUtil { + + actual fun memcmp(first: UByteArray, second: UByteArray): Boolean { + val firstPinned = first.pin() + val secondPinned = second.pin() + val result = sodium_memcmp(firstPinned.toPtr(), secondPinned.toPtr(), first.size.convert()) + firstPinned.unpin() + secondPinned.unpin() + return result == 0 + } + + actual fun memzero(target: UByteArray) { + val targetPinned = target.pin() + sodium_memzero(targetPinned.toPtr(), target.size.convert()) + } + + actual fun pad(unpaddedData : UByteArray, blocksize: Int) : UByteArray { + val resultingSize = if (unpaddedData.size % blocksize != 0 ) { + ((unpaddedData.size / blocksize) + 1 ) * blocksize + } else { + unpaddedData.size + blocksize + } + val paddedData = UByteArray(resultingSize) + unpaddedData.copyInto(paddedData, 0, 0) + val paddedDataPinned = paddedData.pin() + + sodium_pad( + null, + paddedDataPinned.toPtr(), + unpaddedData.size.convert(), + blocksize.convert(), + resultingSize.convert() + ) + paddedDataPinned.unpin() + return paddedData + } + + actual fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray { + val paddedDataCopy = paddedData.copyOf() + val paddedDataCopyPinned = paddedDataCopy.pin() + var newSize = ULongArray(1) { 0UL } + val newSizePinned = newSize.pin() + sodium_unpad( + newSizePinned.addressOf(0), + paddedDataCopyPinned.toPtr(), + paddedData.size.convert(), + blocksize.convert() + ) + val unpaddedSize = newSize[0] + if (unpaddedSize > Int.MAX_VALUE.toULong()) { + throw RuntimeException("Unsupported array size (larger than Integer max value) $unpaddedSize") + } + val unpadded = paddedDataCopy.sliceArray(0 until unpaddedSize.toInt()) + paddedDataCopyPinned.unpin() + newSizePinned.unpin() + return unpadded + } + + actual fun toBase64(data: UByteArray, variant : Base64Variants): String { + val maxlen = sodium_base64_encoded_len(data.size.convert(), variant.value) + val dataPinned = data.pin() + val result = ByteArray(maxlen.toInt()) { 0 } + val resultPinned = result.pin() + sodium_bin2base64( + resultPinned.addressOf(0), + maxlen, + dataPinned.toPtr(), + data.size.convert(), + variant.value + ) + dataPinned.unpin() + resultPinned.unpin() + //Drop '\0' + return result.map { it.toChar() }.dropLast(1).joinToString("") + } + + actual fun toHex(data: UByteArray): String { + val hexLen = (data.size * 2) + 1 // +1 for terminator char + val result = ByteArray(hexLen) + val resultPinned = result.pin() + val dataPinned = data.pin() + sodium_bin2hex( + resultPinned.addressOf(0), + hexLen.convert(), + dataPinned.toPtr(), + data.size.convert() + ) + resultPinned.unpin() + dataPinned.unpin() + //Drop \0 termination + return result.map { it.toChar() }.dropLast(1).joinToString("") + } + + actual fun fromBase64(data: String, variant : Base64Variants): UByteArray { + val maxLength = (data.length * 3) / 4 + val intermediaryResult = UByteArray(maxLength) { 0U } + + val intermediaryResultPinned = intermediaryResult.pin() + var binLen = ULongArray(1) { 0UL } + var binLenPinned = binLen.pin() + sodium_base642bin( + intermediaryResultPinned.toPtr(), + maxLength.convert(), + data, + data.length.convert(), + null, + binLenPinned.addressOf(0), + null, + variant.value + + ) + binLenPinned.unpin() + intermediaryResultPinned.unpin() + + return if (binLen[0].toInt() != maxLength) { + intermediaryResult.sliceArray(0 until binLen[0].toInt()) + } else { + intermediaryResult + } + } + + actual fun fromHex(data: String): UByteArray { + val expectedSize = (data.length + 1) / 2 + val result = UByteArray(expectedSize) + val resultPinned = result.pin() + sodium_hex2bin( + resultPinned.toPtr(), + expectedSize.convert(), + data, + data.length.convert(), + null, + null, + null + ) + resultPinned.unpin() + return result + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/SodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/SodiumUtil.kt new file mode 100644 index 0000000..d30db27 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/SodiumUtil.kt @@ -0,0 +1,8 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 29-Aug-2020 + */ +//fun randomBytesBuf() diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 5224235..7496ed9 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -1,88 +1,179 @@ -package debug.test - -import kotlin.Byte -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray -import kotlinx.cinterop.addressOf -import kotlinx.cinterop.convert -import kotlinx.cinterop.pin -import kotlinx.cinterop.pointed -import kotlinx.cinterop.ptr -import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.toCValues -import libsodium.crypto_generichash_blake2b_state -import libsodium.crypto_hash_sha256_state -import libsodium.crypto_hash_sha512_state -import libsodium.sodium_malloc - -actual typealias Sha256State = crypto_hash_sha256_state - -actual typealias Sha512State = crypto_hash_sha512_state - -actual typealias GenericHashState = crypto_generichash_blake2b_state - -actual class Crypto internal actual constructor() { - val _emitByte: Byte = 0 - - val _emitByteArray: ByteArray = ByteArray(0) - - actual fun crypto_hash_sha256_init(): Sha256State { - val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha256_init") - libsodium.crypto_hash_sha256_init(state.ptr) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha512_init") - libsodium.crypto_hash_sha512_init(state.ptr) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_generichash_init") - val pinnedKey = key.pin() - libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), - outlen.convert()) - pinnedKey.unpin() - return state - } -} +//package debug.test +// +//import kotlin.Byte +//import kotlin.ByteArray +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +//import kotlinx.cinterop.addressOf +//import kotlinx.cinterop.convert +//import kotlinx.cinterop.pin +//import kotlinx.cinterop.pointed +//import kotlinx.cinterop.ptr +//import kotlinx.cinterop.reinterpret +//import kotlinx.cinterop.toCValues +//import libsodium.crypto_generichash_blake2b_state +//import libsodium.crypto_hash_sha256_state +//import libsodium.crypto_hash_sha512_state +//import libsodium.crypto_secretstream_xchacha20poly1305_state +//import libsodium.sodium_malloc +// +//actual typealias Sha256State = crypto_hash_sha256_state +// +//actual typealias Sha512State = crypto_hash_sha512_state +// +//actual typealias GenericHashState = crypto_generichash_blake2b_state +// +//actual typealias SecretStreamState = crypto_secretstream_xchacha20poly1305_state +// +//actual class Crypto internal actual constructor() { +// val _emitByte: Byte = 0 +// +// val _emitByteArray: ByteArray = ByteArray(0) +// +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// actual fun crypto_hash_sha256_init(): Sha256State { +// val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_hash_sha256_init") +// libsodium.crypto_hash_sha256_init(state.ptr) +// return state +// } +// +// actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { +// println("Debug crypto_hash_sha256_update") +// val pinnedInput = input.pin() +// libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) +// pinnedInput.unpin() +// } +// +// actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { +// val out = UByteArray(32) +// println("Debug crypto_hash_sha256_final") +// val pinnedOut = out.pin() +// libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) +// pinnedOut.unpin() +// return out +// } +// +// actual fun crypto_hash_sha512_init(): Sha512State { +// val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_hash_sha512_init") +// libsodium.crypto_hash_sha512_init(state.ptr) +// return state +// } +// +// actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { +// println("Debug crypto_hash_sha512_update") +// val pinnedInput = input.pin() +// libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) +// pinnedInput.unpin() +// } +// +// actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { +// val out = UByteArray(64) +// println("Debug crypto_hash_sha512_final") +// val pinnedOut = out.pin() +// libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) +// pinnedOut.unpin() +// return out +// } +// +// actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { +// val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_generichash_init") +// val pinnedKey = key.pin() +// libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), +// outlen.convert()) +// pinnedKey.unpin() +// return state +// } +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): +// SecretStreamStateAndHeader { +// println("Debug crypto_secretstream_xchacha20poly1305_init_push") +// val pinnedKey = key.pin() +// val state = +// sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! +// .reinterpret() +// .pointed +// val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) +// { 0U } +// val pinnedHeader = header.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, +// pinnedHeader.addressOf(0), pinnedKey.addressOf(0)) +// pinnedHeader.unpin() +// pinnedKey.unpin() +// return SecretStreamStateAndHeader(state, header) +// } +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// SecretStreamState { +// val allocated = sodium_malloc(debug.test.SecretStreamState.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_secretstream_xchacha20poly1305_init_pull") +// val pinnedHeader = header.pin() +// val pinnedKey = key.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_init_pull(state.ptr, pinnedHeader.addressOf(0), +// pinnedKey.addressOf(0)) +// pinnedHeader.unpin() +// pinnedKey.unpin() +// return state +// } +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray { +// val c = UByteArray(m.size + 17) +// println("Debug crypto_secretstream_xchacha20poly1305_push") +// val pinnedC = c.pin() +// val pinnedM = m.pin() +// val pinnedAd = ad.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_push(state.ptr, pinnedC.addressOf(0), null, +// pinnedM.addressOf(0), m.size.convert(), pinnedAd.addressOf(0), ad.size.convert(), tag) +// pinnedC.unpin() +// pinnedM.unpin() +// pinnedAd.unpin() +// return c +// } +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag { +// val m = UByteArray(c.size - 17) +// var tag_p : UByte = 0U +// println("Debug crypto_secretstream_xchacha20poly1305_pull") +// val pinnedM = m.pin() +// val pinnedC = c.pin() +// val pinnedAd = ad.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_pull(state.ptr, pinnedM.addressOf(0), null, +// ubyteArrayOf().toCValues(), pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) +// pinnedM.unpin() +// pinnedC.unpin() +// pinnedAd.unpin() +// return debug.test.DecryptedDataAndTag(m, tag_p) +// } +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt b/multiplatform-crypto-libsodium-bindings/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt new file mode 100644 index 0000000..27130e3 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt @@ -0,0 +1,4 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual fun modifyState(state: SecretStreamState, forceNonce: UByteArray) { +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt index 385aaec..d13f8ca 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt @@ -102,17 +102,17 @@ object Crypto { } object Encryption : EncryptionApi { - override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData { if (key.value.size != 32) { throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}") } val nonce = SRNG.getRandomBytes(24) - return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce) + return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), associatedData), nonce) } - override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { - return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData)) + override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { + return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, associatedData)) } @@ -130,8 +130,8 @@ object Crypto { class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey) : MultipartAuthenticatedEncryption { val header = MultipartEncryptionHeader(SRNG.getRandomBytes(24)) val primitive = XChaCha20Poly1305Pure(key.value, header.nonce) - override fun encryptPartialData(data: UByteArray, additionalData: UByteArray): EncryptedDataPart { - return EncryptedDataPart(primitive.streamEncrypt(data, additionalData, 0U)) + override fun encryptPartialData(data: UByteArray, associatedData: UByteArray): EncryptedDataPart { + return EncryptedDataPart(primitive.streamEncrypt(data, associatedData, 0U)) } override fun startEncryption(): MultipartEncryptionHeader { @@ -144,8 +144,8 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe } class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption { - override fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray): DecryptedDataPart { - return DecryptedDataPart(decryptor.streamDecrypt(data.data, additionalData, 0U)) + override fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray): DecryptedDataPart { + return DecryptedDataPart(decryptor.streamDecrypt(data.data, associatedData, 0U)) } override fun cleanup() { diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt index 3c6d6ef..1c35fd9 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt @@ -13,7 +13,7 @@ import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray internal class ChaCha20Poly1305Pure { companion object { - fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray { val state = UIntArray(16) { when (it) { 0 -> ChaCha20Pure.sigma0_32 @@ -37,11 +37,11 @@ internal class ChaCha20Poly1305Pure { } val oneTimeKey = ChaCha20Pure.hash(state).sliceArray(0 until 32) val cipherText = ChaCha20Pure.xorWithKeystream(key, nonce, message, 1U) - val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U } + val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U } val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U } - val macData = additionalData + additionalDataPad + + val macData = associatedData + associatedDataPad + cipherText + cipherTextPad + - additionalData.size.toULong().toLittleEndianUByteArray() + + associatedData.size.toULong().toLittleEndianUByteArray() + cipherText.size.toULong().toLittleEndianUByteArray() val tag = Poly1305.poly1305Authenticate(oneTimeKey, macData) return cipherText + tag diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt index a9340f6..34b8c01 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt @@ -15,7 +15,7 @@ import com.ionspin.kotlin.crypto.util.* class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { companion object : AuthenticatedEncryption { - override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { + override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray { val subKey = XChaCha20Pure.hChacha(key, nonce) val authKey = ChaCha20Pure.xorWithKeystream( @@ -28,17 +28,17 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { // at org.jetbrains.kotlin.ir.backend.js.lower.ConstTransformer.lowerConst(ConstLowering.kt:38) ) val cipherText = XChaCha20Pure.xorWithKeystream(key, nonce, message, 1U) - val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U } + val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U } val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U } - val macData = additionalData + additionalDataPad + + val macData = associatedData + associatedDataPad + cipherText + cipherTextPad + - additionalData.size.toULong().toLittleEndianUByteArray() + + associatedData.size.toULong().toLittleEndianUByteArray() + cipherText.size.toULong().toLittleEndianUByteArray() val tag = Poly1305.poly1305Authenticate(authKey, macData) return cipherText + tag } - override fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray { + override fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, associatedData: UByteArray) : UByteArray { val subKey = XChaCha20Pure.hChacha(key, nonce) val authKey = ChaCha20Pure.xorWithKeystream( @@ -51,11 +51,11 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { val tag = cipherText.sliceArray(cipherText.size - 16 until cipherText.size) //3. Verify tag is valid val cipherTextWithoutTag = cipherText.sliceArray(0 until cipherText.size - 16) - val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U } + val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U } val cipherTextPad = UByteArray(16 - cipherTextWithoutTag.size % 16) { 0U } - val macData = additionalData + additionalDataPad + + val macData = associatedData + associatedDataPad + cipherTextWithoutTag + cipherTextPad + - additionalData.size.toULong().toLittleEndianUByteArray() + + associatedData.size.toULong().toLittleEndianUByteArray() + cipherTextWithoutTag.size.toULong().toLittleEndianUByteArray() val calculatedTag = Poly1305.poly1305Authenticate(authKey, macData) if (!calculatedTag.contentEquals(tag)) { @@ -86,15 +86,15 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { calcNonce[3] = 0U } - fun streamEncrypt(data: UByteArray, additionalData: UByteArray, tag : UByte) : UByteArray { + fun streamEncrypt(data: UByteArray, associatedData: UByteArray, tag : UByte) : UByteArray { //get encryption state val block = UByteArray(64) { 0U } ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 0U).copyInto(block) // This is equivalent to the first 64 bytes of keystream val poly1305 = Poly1305(block) block.overwriteWithZeroes() - if (additionalData.isNotEmpty()) { - val additionalDataPadded = additionalData + UByteArray(16 - additionalData.size % 16) { 0U } - processPolyBytes(poly1305, additionalDataPadded) + if (associatedData.isNotEmpty()) { + val associatedDataPadded = associatedData + UByteArray(16 - associatedData.size % 16) { 0U } + processPolyBytes(poly1305, associatedDataPadded) } block[0] = tag ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block) // This just xors block[0] with keystream @@ -109,21 +109,21 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { // From security standpoint there are no obvious drawbacks, as padding was initially added to decrease implementation complexity. processPolyBytes(poly1305, ciphertext + UByteArray(((16U + data.size.toUInt() - block.size.toUInt()) % 16U).toInt()) { 0U } ) //TODO this is inefficient as it creates a new array and copies data // Last 16byte block containing actual additional data nad ciphertext sizes - val finalMac = additionalData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() + val finalMac = associatedData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() processPolyBytes(poly1305, finalMac) val mac = poly1305.finalizeMac(polyBuffer.sliceArray(0 until polyBufferByteCounter)) calcNonce.xorWithPositionsAndInsertIntoArray(0, 12, mac, 0, calcNonce, 0) return ubyteArrayOf(encryptedTag) + ciphertext + mac } - fun streamDecrypt(data: UByteArray, additionalData: UByteArray, tag: UByte) : UByteArray { + fun streamDecrypt(data: UByteArray, associatedData: UByteArray, tag: UByte) : UByteArray { val block = UByteArray(64) { 0U } ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 0U).copyInto(block) // This is equivalent to the first 64 bytes of keystream val poly1305 = Poly1305(block) block.overwriteWithZeroes() - if (additionalData.isNotEmpty()) { - val additionalDataPadded = additionalData + UByteArray(16 - additionalData.size % 16) { 0U } - processPolyBytes(poly1305, additionalDataPadded) + if (associatedData.isNotEmpty()) { + val associatedDataPadded = associatedData + UByteArray(16 - associatedData.size % 16) { 0U } + processPolyBytes(poly1305, associatedDataPadded) } block[0] = data[0] ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block)// get the keystream xored with zeroes, but also decrypteg tag marker @@ -137,7 +137,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { val ciphertext = data.sliceArray(1 until data.size - 16) processPolyBytes(poly1305, ciphertext + UByteArray(((16U + ciphertext.size.toUInt() - block.size.toUInt()) % 16U).toInt()) { 0U } ) val plaintext = ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, ciphertext, 2U) - val finalMac = additionalData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() + val finalMac = associatedData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() processPolyBytes(poly1305, finalMac) val mac = poly1305.finalizeMac(polyBuffer.sliceArray(0 until polyBufferByteCounter)) val expectedMac = data.sliceArray(data.size - 16 until data.size) diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt index 94cbf76..ae9acbd 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt @@ -145,7 +145,8 @@ internal class AesCbcPure internal constructor(val aesKey: InternalAesKey, val m } /** - * Encrypt fed data and return it alongside the randomly chosen initialization vector + * Encrypt fed data and return it alongside the randomly chosen initialization vector. + * This also applies correct PKCS#7 padding * @return Encrypted data and initialization vector */ fun encrypt(): EncryptedDataAndInitializationVector { @@ -158,6 +159,8 @@ internal class AesCbcPure internal constructor(val aesKey: InternalAesKey, val m } else { output += consumeBlock(lastBlockPadded) } + } else { + output += consumeBlock(UByteArray(BLOCK_BYTES) { BLOCK_BYTES.toUByte()}) } return EncryptedDataAndInitializationVector( output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, @@ -172,11 +175,10 @@ internal class AesCbcPure internal constructor(val aesKey: InternalAesKey, val m fun decrypt(): UByteArray { val removePaddingCount = output.last().last() - val removedPadding = if (removePaddingCount > 0U && removePaddingCount < 16U) { output.last().dropLast(removePaddingCount.toInt() and 0x7F) } else { - output.last().toList() + ubyteArrayOf() }.toUByteArray() val preparedOutput = (output.dropLast(1) + listOf(removedPadding)) //JS compiler freaks out here if we don't supply exact type @@ -238,4 +240,4 @@ data class EncryptedDataAndInitializationVector(val encryptedData : UByteArray, result = 31 * result + initializationVector.contentHashCode() return result } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt index e477d39..6b62b14 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt @@ -54,8 +54,8 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m * Creates and returns AesCtr instance that can be fed data using [addData]. Once you have submitted all * data call [decrypt] */ - fun createDecryptor(aesKey : InternalAesKey) : AesCtrPure { - return AesCtrPure(aesKey, Mode.DECRYPT) + fun createDecryptor(aesKey : InternalAesKey, initialCounter: UByteArray) : AesCtrPure { + return AesCtrPure(aesKey, Mode.DECRYPT, initialCounter) } /** * Bulk encryption, returns encrypted data and a random initial counter @@ -69,7 +69,7 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m * Bulk decryption, returns decrypted data */ fun decrypt(aesKey: InternalAesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { - val aesCtr = AesCtrPure(aesKey, Mode.DECRYPT, initialCounter) + val aesCtr = AesCtrPure(aesKey = aesKey, mode = Mode.DECRYPT, initialCounter = initialCounter) aesCtr.addData(data) return aesCtr.decrypt() } diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt index 26975f4..ca0a763 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt @@ -19,7 +19,7 @@ class ChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -44,7 +44,7 @@ class ChaCha20Poly1305Test { 0x61U, 0x16U, 0x1aU, 0xe1U, 0x0bU, 0x59U, 0x4fU, 0x09U, 0xe2U, 0x6aU, 0x7eU, 0x90U, 0x2eU, 0xcbU, 0xd0U, 0x60U, 0x06U, 0x91U ) - val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) + val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData) result.hexColumsPrint() assertTrue { result.contentEquals(expected) @@ -53,4 +53,4 @@ class ChaCha20Poly1305Test { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt index 8445606..c186102 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt @@ -20,7 +20,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -55,8 +55,8 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) - val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) - val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, additionalData) + val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData) + val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, associatedData) encrypted.contentEquals(expected) && decrypted.contentEquals(message) } @@ -65,7 +65,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -84,8 +84,8 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) - val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) - val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, additionalData) + val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData) + val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, associatedData) encrypted.contentEquals(expected) && decrypted.contentEquals(message) } @@ -99,7 +99,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -134,7 +134,7 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) -// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData) val firstChunk = +// val xChaChaPoly = XChaCha20Poly1305Pure(key, associatedData) val firstChunk = // xChaChaPoly.encryptPartialData(message) val finalChunk = xChaChaPoly.finishEncryption().first val result = // firstChunk + finalChunk result.contentEquals(expected) 1 == 1 @@ -144,7 +144,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -163,7 +163,7 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) -// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData) +// val xChaChaPoly = XChaCha20Poly1305Pure(key, associatedData) // val firstChunk = xChaChaPoly.encryptPartialData(message) // val finalChunk = xChaChaPoly.finishEncryption().first // val result = firstChunk + finalChunk diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt index a163517..d8f05da 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt @@ -20,18 +20,18 @@ class EncryptionTest { "ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" + "EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray() plaintext.hexColumsPrint() - val additionalData = "Additional data 1".encodeToUByteArray() -// val additionalData = ubyteArrayOf() + val associatedData = "Additional data 1".encodeToUByteArray() +// val associatedData = ubyteArrayOf() val keyValue = UByteArray(32) { it.toUByte() } val key = SymmetricKey(keyValue) val encryptor = Crypto.Encryption.createMultipartEncryptor(key) val header = encryptor.startEncryption() - val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), additionalData) + val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), associatedData) val ciphertext2 = encryptor.encryptPartialData(plaintext.sliceArray(100 until 200)) val ciphertext3 = encryptor.encryptPartialData(plaintext.sliceArray(200 until 250)) //decrypt val decryptor = Crypto.Encryption.createMultipartDecryptor(key, header) - val plaintext1 = decryptor.decryptPartialData(ciphertext1, additionalData) + val plaintext1 = decryptor.decryptPartialData(ciphertext1, associatedData) val plaintext2 = decryptor.decryptPartialData(ciphertext2) val plaintext3 = decryptor.decryptPartialData(ciphertext3) diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt index 8a6af88..c84a345 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt @@ -35,7 +35,9 @@ class AesCbcTest { val key = "4278b840fb44aaa757c1bf04acbe1a3e" val iv = "57f02a5c5339daeb0a2908a06ac6393f" val plaintext = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" - val expectedCipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" + val expectedCipherText = "479c89ec14bc98994e62b2c705b5014e" + + "175bd7832e7e60a1e92aac568a861eb7" + + "fc2dc2f4a527ce39f79c56b31432c779" val aesCbc = AesCbcPure(InternalAesKey.Aes128Key(key), mode = Mode.ENCRYPT, initializationVector = iv.hexStringToUByteArray()) aesCbc.addData(plaintext.hexStringToUByteArray()) @@ -73,7 +75,9 @@ class AesCbcTest { assertTrue { val key = "4278b840fb44aaa757c1bf04acbe1a3e" val iv = "57f02a5c5339daeb0a2908a06ac6393f" - val cipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" + val cipherText = "479c89ec14bc98994e62b2c705b5014e" + + "175bd7832e7e60a1e92aac568a861eb7" + + "fc2dc2f4a527ce39f79c56b31432c779" val expectedPlainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" val aesCbc = AesCbcPure(InternalAesKey.Aes128Key(key), mode = Mode.DECRYPT, initializationVector = iv.hexStringToUByteArray()) @@ -93,7 +97,9 @@ class AesCbcTest { assertTrue { val key = "4278b840fb44aaa757c1bf04acbe1a3e" val iv = "57f02a5c5339daeb0a2908a06ac6393f" - val cipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" + val cipherText = "479c89ec14bc98994e62b2c705b5014e" + + "175bd7832e7e60a1e92aac568a861eb7" + + "fc2dc2f4a527ce39f79c56b31432c779" val expectedPlainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" val decrypted = AesCbcPure.decrypt(InternalAesKey.Aes128Key(key), cipherText.hexStringToUByteArray(), iv.hexStringToUByteArray()) println("Decrypted: ${decrypted.toHexString()}") @@ -104,4 +110,4 @@ class AesCbcTest { -} \ No newline at end of file +} diff --git a/settings.gradle.kts b/settings.gradle.kts index e201525..085d14b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,5 +40,4 @@ include("multiplatform-crypto") include("multiplatform-crypto-delegated") include("multiplatform-crypto-libsodium-bindings") include("sample") -include("kotlin-multiplatform-libsodium-generator") diff --git a/supported_bindings_list.md b/supported_bindings_list.md new file mode 100644 index 0000000..a797b30 --- /dev/null +++ b/supported_bindings_list.md @@ -0,0 +1,380 @@ +|Function name| Implemented | +|-------------|-------------| +| add | | +| memcmp | :heavy_check_mark: | +| memzero | :heavy_check_mark: | +| output_formats | | +| pad | :heavy_check_mark: | +| unpad | :heavy_check_mark: | +| symbols | | +| to_base64 | :heavy_check_mark: | +| to_hex | :heavy_check_mark: | +| from_base64 | :heavy_check_mark: | +| from_hex | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_decrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_decrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_encrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_encrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_decrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_decrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_encrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_encrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_keygen | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_keygen | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_decrypt | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_decrypt_detached | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_encrypt | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_encrypt_detached | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_keygen | :heavy_check_mark: | +| crypto_auth | :heavy_check_mark: | +| crypto_auth_hmacsha256 | :heavy_check_mark: | +| crypto_auth_hmacsha256_keygen | :heavy_check_mark: | +| crypto_auth_hmacsha256_verify | :heavy_check_mark: | +| crypto_auth_hmacsha512 | :heavy_check_mark: | +| crypto_auth_hmacsha512_keygen | :heavy_check_mark: | +| crypto_auth_hmacsha512_verify | :heavy_check_mark: | +| crypto_auth_keygen | :heavy_check_mark: | +| crypto_auth_verify | :heavy_check_mark: | +| crypto_box_beforenm | :heavy_check_mark: | +| crypto_box_curve25519xchacha20poly1305_keypair | not present in LazySodium | +| crypto_box_curve25519xchacha20poly1305_seal | not present in LazySodium | +| crypto_box_curve25519xchacha20poly1305_seal_open |not present in LazySodium | +| crypto_box_detached | :heavy_check_mark: | +| crypto_box_easy | :heavy_check_mark: | +| crypto_box_easy_afternm | :heavy_check_mark: | +| crypto_box_keypair | :heavy_check_mark: | +| crypto_box_open_detached | :heavy_check_mark: | +| crypto_box_open_easy | :heavy_check_mark: | +| crypto_box_open_easy_afternm | :heavy_check_mark: | +| crypto_box_seal | :heavy_check_mark: | +| crypto_box_seal_open | :heavy_check_mark: | +| crypto_box_seed_keypair | :heavy_check_mark: | +| crypto_core_ristretto255_add | not present in LazySodium | +| crypto_core_ristretto255_from_hash | not present in LazySodium | +| crypto_core_ristretto255_is_valid_point | not present in LazySodium | +| crypto_core_ristretto255_random | not present in LazySodium | +| crypto_core_ristretto255_scalar_add | not present in LazySodium | +| crypto_core_ristretto255_scalar_complement | not present in LazySodium | +| crypto_core_ristretto255_scalar_invert | not present in LazySodium | +| crypto_core_ristretto255_scalar_mul | not present in LazySodium | +| crypto_core_ristretto255_scalar_negate | not present in LazySodium | +| crypto_core_ristretto255_scalar_random | not present in LazySodium | +| crypto_core_ristretto255_scalar_reduce | not present in LazySodium | +| crypto_core_ristretto255_scalar_sub | not present in LazySodium | +| crypto_core_ristretto255_sub | not present in LazySodium | +| crypto_generichash | :heavy_check_mark: | +| crypto_generichash_blake2b_salt_personal | | +| crypto_generichash_final | :heavy_check_mark: | +| crypto_generichash_init | :heavy_check_mark: | +| crypto_generichash_keygen | :heavy_check_mark: | +| crypto_generichash_update | :heavy_check_mark: | +| crypto_hash | | +| crypto_hash_sha256 | :heavy_check_mark: | +| crypto_hash_sha256_final | :heavy_check_mark: | +| crypto_hash_sha256_init | :heavy_check_mark: | +| crypto_hash_sha256_update | :heavy_check_mark: | +| crypto_hash_sha512 | :heavy_check_mark: | +| crypto_hash_sha512_final | :heavy_check_mark: | +| crypto_hash_sha512_init | :heavy_check_mark: | +| crypto_hash_sha512_update | :heavy_check_mark: | +| crypto_kdf_derive_from_key | :heavy_check_mark: | +| crypto_kdf_keygen | :heavy_check_mark: | +| crypto_kx_client_session_keys | | +| crypto_kx_keypair | | +| crypto_kx_seed_keypair | | +| crypto_kx_server_session_keys | | +| crypto_onetimeauth | not present in LazySodium | +| crypto_onetimeauth_final | not present in LazySodium | +| crypto_onetimeauth_init | not present in LazySodium | +| crypto_onetimeauth_keygen | not present in LazySodium | +| crypto_onetimeauth_update | not present in LazySodium | +| crypto_onetimeauth_verify | not present in LazySodium | +| crypto_pwhash | :heavy_check_mark: | +| crypto_pwhash_scryptsalsa208sha256 | not present in LazySodium for Android | +| crypto_pwhash_scryptsalsa208sha256_ll | not present in LazySodium for Android | +| crypto_pwhash_scryptsalsa208sha256_str | not present in LazySodium for Android | +| crypto_pwhash_scryptsalsa208sha256_str_verify | not present in LazySodium for Android | +| crypto_pwhash_str | :heavy_check_mark: | +| crypto_pwhash_str_needs_rehash | :heavy_check_mark: | +| crypto_pwhash_str_verify | :heavy_check_mark: | +| crypto_scalarmult | | +| crypto_scalarmult_base | | +| crypto_scalarmult_ristretto255 | | +| crypto_scalarmult_ristretto255_base | | +| crypto_secretbox_detached | :heavy_check_mark: | +| crypto_secretbox_easy | :heavy_check_mark: | +| crypto_secretbox_keygen | :heavy_check_mark: | +| crypto_secretbox_open_detached | :heavy_check_mark: | +| crypto_secretbox_open_easy | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_init_pull | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_init_push | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_keygen | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_pull | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_push | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_rekey | :heavy_check_mark: | +| crypto_shorthash |:heavy_check_mark: | +| crypto_shorthash_keygen | :heavy_check_mark: | +| crypto_shorthash_siphashx24 | | +| crypto_sign | :heavy_check_mark: | +| crypto_sign_detached | :heavy_check_mark: | +| crypto_sign_ed25519_pk_to_curve25519 | :heavy_check_mark: | +| crypto_sign_ed25519_sk_to_curve25519 | :heavy_check_mark: | +| crypto_sign_ed25519_sk_to_pk | :heavy_check_mark: | +| crypto_sign_ed25519_sk_to_seed | :heavy_check_mark: | +| crypto_sign_final_create | :heavy_check_mark: | +| crypto_sign_final_verify | :heavy_check_mark: | +| crypto_sign_init | :heavy_check_mark: | +| crypto_sign_keypair | :heavy_check_mark: | +| crypto_sign_open | :heavy_check_mark: | +| crypto_sign_seed_keypair | :heavy_check_mark: | +| crypto_sign_update | :heavy_check_mark: | +| crypto_sign_verify_detached | :heavy_check_mark: | +| crypto_stream_chacha20 | | +| crypto_stream_chacha20_ietf_xor | | +| crypto_stream_chacha20_ietf_xor_ic | | +| crypto_stream_chacha20_keygen | | +| crypto_stream_chacha20_xor | | +| crypto_stream_chacha20_xor_ic | | +| crypto_stream_keygen | | +| 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 | +| randombytes_buf | :heavy_check_mark: | +| randombytes_buf_deterministic | :heavy_check_mark: | +| randombytes_close | not present in LazySodium | +| randombytes_random | :heavy_check_mark: | +| randombytes_stir | not present in LazySodium | +| randombytes_uniform | :heavy_check_mark: | +| sodium_version_string | | +| SODIUM_LIBRARY_VERSION_MAJOR | | +| SODIUM_LIBRARY_VERSION_MINOR | | +| crypto_aead_chacha20poly1305_ABYTES | | +| crypto_aead_chacha20poly1305_IETF_ABYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_IETF_KEYBYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX | | +| crypto_aead_chacha20poly1305_IETF_NPUBBYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_IETF_NSECBYTES | | +| crypto_aead_chacha20poly1305_KEYBYTES | | +| crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_aead_chacha20poly1305_NPUBBYTES | | +| crypto_aead_chacha20poly1305_NSECBYTES | | +| crypto_aead_chacha20poly1305_ietf_ABYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_KEYBYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX | | +| crypto_aead_chacha20poly1305_ietf_NPUBBYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_NSECBYTES | | +| crypto_aead_xchacha20poly1305_IETF_ABYTES | | +| crypto_aead_xchacha20poly1305_IETF_KEYBYTES | | +| crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX | | +| crypto_aead_xchacha20poly1305_IETF_NPUBBYTES | | +| crypto_aead_xchacha20poly1305_IETF_NSECBYTES | | +| crypto_aead_xchacha20poly1305_ietf_ABYTES | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_KEYBYTES | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX | | +| crypto_aead_xchacha20poly1305_ietf_NPUBBYTES | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_NSECBYTES | | +| crypto_auth_BYTES | :heavy_check_mark: | +| crypto_auth_KEYBYTES | :heavy_check_mark: | +| crypto_auth_hmacsha256_BYTES | :heavy_check_mark: | +| crypto_auth_hmacsha256_KEYBYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512256_BYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512256_KEYBYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512_BYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512_KEYBYTES | :heavy_check_mark: | +| crypto_box_BEFORENMBYTES | | +| crypto_box_MACBYTES | | +| crypto_box_MESSAGEBYTES_MAX | | +| crypto_box_NONCEBYTES | | +| crypto_box_PUBLICKEYBYTES | | +| crypto_box_SEALBYTES | | +| crypto_box_SECRETKEYBYTES | | +| crypto_box_SEEDBYTES | | +| crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES | | +| crypto_box_curve25519xchacha20poly1305_MACBYTES | | +| crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_box_curve25519xchacha20poly1305_NONCEBYTES | | +| crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES | | +| crypto_box_curve25519xchacha20poly1305_SEALBYTES | | +| crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES | | +| crypto_box_curve25519xchacha20poly1305_SEEDBYTES | | +| crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES | | +| crypto_box_curve25519xsalsa20poly1305_MACBYTES | | +| crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX | | +| crypto_box_curve25519xsalsa20poly1305_NONCEBYTES | | +| crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES | | +| crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES | | +| crypto_box_curve25519xsalsa20poly1305_SEEDBYTES | | +| crypto_core_ed25519_BYTES | | +| crypto_core_ed25519_HASHBYTES | | +| crypto_core_ed25519_NONREDUCEDSCALARBYTES | | +| crypto_core_ed25519_SCALARBYTES | | +| crypto_core_ed25519_UNIFORMBYTES | | +| crypto_core_hchacha20_CONSTBYTES | | +| crypto_core_hchacha20_INPUTBYTES | | +| crypto_core_hchacha20_KEYBYTES | | +| crypto_core_hchacha20_OUTPUTBYTES | | +| crypto_core_hsalsa20_CONSTBYTES | | +| crypto_core_hsalsa20_INPUTBYTES | | +| crypto_core_hsalsa20_KEYBYTES | | +| crypto_core_hsalsa20_OUTPUTBYTES | | +| crypto_core_ristretto255_BYTES | | +| crypto_core_ristretto255_HASHBYTES | | +| crypto_core_ristretto255_NONREDUCEDSCALARBYTES | | +| crypto_core_ristretto255_SCALARBYTES | | +| crypto_core_salsa2012_CONSTBYTES | | +| crypto_core_salsa2012_INPUTBYTES | | +| crypto_core_salsa2012_KEYBYTES | | +| crypto_core_salsa2012_OUTPUTBYTES | | +| crypto_core_salsa20_CONSTBYTES | | +| crypto_core_salsa20_INPUTBYTES | | +| crypto_core_salsa20_KEYBYTES | | +| crypto_core_salsa20_OUTPUTBYTES | | +| crypto_generichash_BYTES | | +| crypto_generichash_BYTES_MAX | | +| crypto_generichash_BYTES_MIN | | +| crypto_generichash_KEYBYTES | | +| crypto_generichash_KEYBYTES_MAX | | +| crypto_generichash_KEYBYTES_MIN | | +| crypto_generichash_blake2b_BYTES | | +| crypto_generichash_blake2b_BYTES_MAX | | +| crypto_generichash_blake2b_BYTES_MIN | | +| crypto_generichash_blake2b_KEYBYTES | | +| crypto_generichash_blake2b_KEYBYTES_MAX | | +| crypto_generichash_blake2b_KEYBYTES_MIN | | +| crypto_generichash_blake2b_PERSONALBYTES | | +| crypto_generichash_blake2b_SALTBYTES | | +| crypto_hash_BYTES | | +| crypto_hash_sha256_BYTES | :heavy_check_mark: | +| crypto_hash_sha512_BYTES | :heavy_check_mark: | +| crypto_kdf_BYTES_MAX | | +| crypto_kdf_BYTES_MIN | | +| crypto_kdf_CONTEXTBYTES | | +| crypto_kdf_KEYBYTES | | +| crypto_kdf_blake2b_BYTES_MAX | | +| 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_onetimeauth_BYTES | | +| crypto_onetimeauth_KEYBYTES | | +| crypto_onetimeauth_poly1305_BYTES | | +| crypto_onetimeauth_poly1305_KEYBYTES | | +| crypto_pwhash_ALG_ARGON2I13 | :heavy_check_mark: | +| crypto_pwhash_ALG_ARGON2ID13 | :heavy_check_mark: | +| crypto_pwhash_ALG_DEFAULT | :heavy_check_mark: | +| crypto_pwhash_BYTES_MAX | | +| crypto_pwhash_BYTES_MIN | :heavy_check_mark: | +| crypto_pwhash_MEMLIMIT_INTERACTIVE | :heavy_check_mark: | +| crypto_pwhash_MEMLIMIT_MAX | | +| crypto_pwhash_MEMLIMIT_MIN | :heavy_check_mark: | +| crypto_pwhash_MEMLIMIT_MODERATE | :heavy_check_mark: | +| crypto_pwhash_MEMLIMIT_SENSITIVE | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_INTERACTIVE | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_MAX | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_MIN | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_MODERATE | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_SENSITIVE | :heavy_check_mark: | +| crypto_pwhash_PASSWD_MAX | :heavy_check_mark: | +| crypto_pwhash_PASSWD_MIN | :heavy_check_mark: | +| crypto_pwhash_SALTBYTES | :heavy_check_mark: | +| crypto_pwhash_STRBYTES | :heavy_check_mark: | +| crypto_pwhash_argon2i_BYTES_MAX | | +| crypto_pwhash_argon2i_BYTES_MIN | | +| crypto_pwhash_argon2i_SALTBYTES | | +| crypto_pwhash_argon2i_STRBYTES | | +| crypto_pwhash_argon2id_BYTES_MAX | | +| crypto_pwhash_argon2id_BYTES_MIN | | +| crypto_pwhash_argon2id_SALTBYTES | | +| crypto_pwhash_argon2id_STRBYTES | | +| crypto_pwhash_scryptsalsa208sha256_BYTES_MAX | | +| crypto_pwhash_scryptsalsa208sha256_BYTES_MIN | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE | | +| crypto_pwhash_scryptsalsa208sha256_SALTBYTES | | +| crypto_pwhash_scryptsalsa208sha256_STRBYTES | | +| crypto_scalarmult_BYTES | | +| crypto_scalarmult_SCALARBYTES | | +| crypto_scalarmult_curve25519_BYTES | :heavy_check_mark: | +| crypto_scalarmult_curve25519_SCALARBYTES | | +| crypto_scalarmult_ed25519_BYTES | | +| crypto_scalarmult_ed25519_SCALARBYTES | | +| crypto_scalarmult_ristretto255_BYTES | | +| crypto_scalarmult_ristretto255_SCALARBYTES | | +| crypto_secretbox_KEYBYTES | :heavy_check_mark: | +| crypto_secretbox_MACBYTES | :heavy_check_mark: | +| crypto_secretbox_MESSAGEBYTES_MAX | | +| crypto_secretbox_NONCEBYTES | :heavy_check_mark: | +| crypto_secretbox_xchacha20poly1305_KEYBYTES | | +| crypto_secretbox_xchacha20poly1305_MACBYTES | | +| crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_secretbox_xchacha20poly1305_NONCEBYTES | | +| crypto_secretbox_xsalsa20poly1305_KEYBYTES | | +| crypto_secretbox_xsalsa20poly1305_MACBYTES | | +| crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX | | +| crypto_secretbox_xsalsa20poly1305_NONCEBYTES | | +| crypto_secretstream_xchacha20poly1305_ABYTES | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_HEADERBYTES | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_KEYBYTES | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_secretstream_xchacha20poly1305_TAG_FINAL | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_TAG_MESSAGE | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_TAG_PUSH | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_TAG_REKEY | :heavy_check_mark: | +| crypto_shorthash_BYTES | | +| crypto_shorthash_KEYBYTES | | +| crypto_shorthash_siphash24_BYTES | | +| crypto_shorthash_siphash24_KEYBYTES | | +| crypto_shorthash_siphashx24_BYTES | | +| crypto_shorthash_siphashx24_KEYBYTES | | +| crypto_sign_BYTES | :heavy_check_mark: | +| crypto_sign_MESSAGEBYTES_MAX | | +| crypto_sign_PUBLICKEYBYTES | :heavy_check_mark: | +| crypto_sign_SECRETKEYBYTES | :heavy_check_mark: | +| crypto_sign_SEEDBYTES | :heavy_check_mark: | +| crypto_sign_ed25519_BYTES | | +| crypto_sign_ed25519_MESSAGEBYTES_MAX | | +| crypto_sign_ed25519_PUBLICKEYBYTES | | +| crypto_sign_ed25519_SECRETKEYBYTES | | +| crypto_sign_ed25519_SEEDBYTES | | +| crypto_stream_KEYBYTES | | +| crypto_stream_MESSAGEBYTES_MAX | | +| crypto_stream_NONCEBYTES | | +| crypto_stream_chacha20_IETF_KEYBYTES | | +| crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX | | +| crypto_stream_chacha20_IETF_NONCEBYTES | | +| crypto_stream_chacha20_KEYBYTES | | +| crypto_stream_chacha20_MESSAGEBYTES_MAX | | +| crypto_stream_chacha20_NONCEBYTES | | +| crypto_stream_chacha20_ietf_KEYBYTES | | +| crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX | | +| crypto_stream_chacha20_ietf_NONCEBYTES | | +| crypto_stream_salsa2012_KEYBYTES | | +| crypto_stream_salsa2012_MESSAGEBYTES_MAX | | +| crypto_stream_salsa2012_NONCEBYTES | | +| crypto_stream_salsa208_KEYBYTES | | +| crypto_stream_salsa208_MESSAGEBYTES_MAX | | +| crypto_stream_salsa208_NONCEBYTES | | +| crypto_stream_salsa20_KEYBYTES | | +| crypto_stream_salsa20_MESSAGEBYTES_MAX | | +| crypto_stream_salsa20_NONCEBYTES | | +| crypto_stream_xchacha20_KEYBYTES | | +| crypto_stream_xchacha20_MESSAGEBYTES_MAX | | +| crypto_stream_xchacha20_NONCEBYTES | | +| crypto_stream_xsalsa20_KEYBYTES | | +| crypto_stream_xsalsa20_MESSAGEBYTES_MAX | | +| crypto_stream_xsalsa20_NONCEBYTES | | +| crypto_verify_16_BYTES | | +| crypto_verify_32_BYTES | | +| crypto_verify_64_BYTES | | +| SODIUM_VERSION_STRING | | +| crypto_pwhash_STRPREFIX | | +| crypto_pwhash_scryptsalsa208sha256_STRPREFIX | | diff --git a/test b/test new file mode 100644 index 0000000..e69de29