diff --git a/.gitignore b/.gitignore index d17c8f7..3d16a63 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,9 @@ build/ /multiplatform-crypto-delegated/node_modules /multiplatform-crypto-delegated/package.json /multiplatform-crypto-delegated/package-lock.json - +/multiplatform-crypto-libsodium-bindings/node_modules +/multiplatform-crypto-libsodium-bindings/package.json +/multiplatform-crypto-libsodium-bindings/package-lock.json /sodiumWrapper/include/ /sodiumWrapper/lib/ /sodiumWrapper/ios-include/ @@ -29,3 +31,4 @@ build/ /sodiumWrapper/static-mingw-x86-64/ /sodiumWrapper/static-tvos/ /sodiumWrapper/static-watchos/ +/kotlin-multiplatform-libsodium-generator/out/ diff --git a/.travis.yml b/.travis.yml index 112f209..278043b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,9 +15,9 @@ matrix: script: - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./linuxBuild.sh; fi' - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./linuxBuildAndPublish.sh; fi' -# OSX macos/ios + # OSX macos - os: osx - name: osx-mac-ios + name: osx-mac osx_image: xcode11.4 language: java jdk: openjdk12 @@ -26,8 +26,21 @@ matrix: KBUILD=linux JAVA_OPTS=-Xmx2g script: - - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-mac-ios.sh; fi' - - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-mac-ios.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-mac.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-mac.sh; fi' + # OSX ios + - os: osx + name: osx-ios + osx_image: xcode11.4 + language: java + jdk: openjdk12 + install: true + env: + KBUILD=linux + JAVA_OPTS=-Xmx2g + script: + - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-ios.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-ios.sh; fi' # OSX watchos - os: osx name: osx-watchos @@ -54,9 +67,10 @@ matrix: script: - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-tvos.sh; fi' - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-tvos.sh; fi' - # OSX pure + + # OSX macos PURE - os: osx - name: osx-pure + name: osx-mac-pure osx_image: xcode11.4 language: java jdk: openjdk12 @@ -65,10 +79,50 @@ matrix: KBUILD=linux JAVA_OPTS=-Xmx2g script: - - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure.sh; fi' - - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-mac.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-mac.sh; fi' + # OSX ios PURE + - os: osx + name: osx-ios-pure + osx_image: xcode11.4 + language: java + jdk: openjdk12 + install: true + env: + KBUILD=linux + JAVA_OPTS=-Xmx2g + script: + - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-ios.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-ios.sh; fi' + # OSX watchos PURE + - os: osx + name: osx-watchos-pure + osx_image: xcode11.4 + language: java + jdk: openjdk12 + install: true + env: + KBUILD=linux + JAVA_OPTS=-Xmx2g + script: + - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-watchos.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-watchos.sh; fi' + # OSX tvos PURE + - os: osx + name: osx-tvos-pure + osx_image: xcode11.4 + language: java + jdk: openjdk12 + install: true + env: + KBUILD=linux + JAVA_OPTS=-Xmx2g + script: + - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then bash ./macBuild-pure-tvos.sh; fi' + - 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./macBuildAndPublish-pure-tvos.sh; fi' + - os: windows - name: windwos-pure + name: windows-pure language: shell jdk: openjdk12 env: @@ -134,10 +188,8 @@ matrix: cache: directories: - $HOME/.m2/ - - $HOME/.gradle/caches/ - - $HOME/.gradle/wrapper/ - - $HOME/.konan/cache - - $HOME/.konan/dependencies + - $HOME/.gradle + - $HOME/.konan - $HOME/AppData/Local/Temp/chocolatey - /C/tools/msys64 branches: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d2f660..32928b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,12 @@ ## Descriptive changelog (All dates are DD.MM.YYYY) -#### AES - 0.0.3-SNAPSHOT - 25.9.2019 +#### - 0.1.0 - SNAPSHOT +- Complete rework of the library +- Creating in parallel both Pure Kotlin and Delegated flavours (backed by libsodium) +- Introducing libsodium bindings generator + +#### AES - 0.0.3 - 25.9.2019 - Added AES with CBC and CTR modes #### Updatable SHA hash implementation - 0.0.2 - 21.7.2019 diff --git a/README.md b/README.md index 497e3fc..d0a8635 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,31 @@ # Kotlin Multiplatform Crypto Library +#Note: +### Next stable release will be published after public release of Kotlin 1.4, until then API will change significantly + Kotlin Multiplatform Crypto is a library for various cryptographic applications. -The library comes in two flavors `multiplatform-crypto` and `multiplatform-crypto-delegated` +The library comes in two flavors `multiplatform-crypto` and `multiplatform-crypto-delegated`. This project also provides +direct libsodium bindings under `multiplatform-crypto-libsodium-bindings`. * `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, like libsodium, but care should still be taken that the kotlin code is not reviewed or proven safe. +* `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. +* `multiplatform-crypto-libsodium-bindings` is a generated bindings library using `kotlin-multiplatform-libsodium-generator` + * Under HEAVY development at the moment + + + +### Table of contents +1. [Supported platforms](#supported-platforms-by-variant) +2. [API](#api) +3. TODO + ## Supported platforms by variant |Platform|Pure variant| Delegated variant| |--------|------------|------------------| @@ -41,41 +55,31 @@ The library includes sample project that shows usage on different platforms **The API will move fast and break often until v1.0** Next steps: -- Expand API (AEAD, ECC ...) -- Include AES and Argon2 in new API approach -- Add primitives missing in `delegated` variant that are supported in `pure` (at the moment AES and Argon2) +- Expand API (ECC, Signing ...) ## Should I use this in production? - -No, until it is reviewed. - -## Should I use this in code that is *critical* in any way, shape or form? - -No, but even if after being warned you decide to, then use `multiplatform-crypto-delegated` as it relies on reputable libraries. +**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. +It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure. -## Currently supported +## API for Pure and Delegated flavourd ### Hashing functions * Blake2b * SHA512 * SHA256 - -### Symmetric cipher -* AES - * Modes: CBC, CTR ### Key Derivation * Argon2 -### AEAD +### Authenticated symmetric encryption (AEAD) -TODO() +* XChaCha20-Poly1305 ### Delegated flavor dependancy table @@ -86,8 +90,8 @@ The following table describes which library is used for particular cryptographic | Blake2b | LazySodium | libsodium.js | libsodium | | SHA256 | LazySodium | libsodium.js | libsodium | | SHA512 | LazySodium | libsodium.js | libsodium | -| AES-CBC | LazySodium | libsodium.js | libsodium | -| AES-CTR | LazySodium | libsodium.js | libsodium | +| XChaCha20-Poly1305 | LazySodium | libsodium.js | libsodium | + ## Integration @@ -195,7 +199,34 @@ sha512.update("abc".encodeToUByteArray()) val result = sha512.digest() ``` -### Symmetric encryption +### 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 @@ -241,32 +272,9 @@ plainText == decrypted.toHexString() ``` -### Key derivation +## Libsodium bindings -#### 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) -``` +* Under development @@ -284,5 +292,3 @@ assertEquals(tagString, expectedTagString) - - \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 1ed63da..6b9af03 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -28,7 +28,7 @@ repositories { } dependencies { - implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4-M2") + implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0-rc") } 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 1c80a48..a4617e6 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -15,19 +15,21 @@ */ object Versions { - val kotlinCoroutines = "1.3.5-native-mt-arm-1.4-M2-SNAPSHOT" //NOTE: my linux arm32 and arm64 build - val kotlin = "1.4-M2" - val kotlinSerialization = "0.20.0-1.4-M2" + 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 atomicfu = "0.14.3-M2-2-SNAPSHOT" //NOTE: my linux arm32 and arm64 build val nodePlugin = "1.3.0" - val dokkaPlugin = "0.11.0-dev-44" + val dokkaPlugin = "1.4.0-M3-dev-92" val taskTreePlugin = "1.5" - val kotlinBigNumVersion = "0.1.6-1.4-M2-SNAPSHOT" + val kotlinBigNumVersion = "0.1.6-1.4.0-rc-SNAPSHOT" val lazySodium = "4.2.6" val jna = "5.5.0" + val kotlinPoet = "1.6.0" + } @@ -42,8 +44,7 @@ object Deps { val stdLib = "stdlib-common" val test = "test-common" val testAnnotation = "test-annotations-common" -// val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:${Versions.kotlinCoroutines}" - val coroutines = "com.ionspin.kotlin.coroutines:kotlinx-coroutines-core:${Versions.kotlinCoroutines}" + val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-common:${Versions.kotlinCoroutines}" val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-common:${Versions.kotlinSerialization}" val atomicfu = "com.ionspin.kotlin.atomicfu:atomicfu:${Versions.atomicfu}" @@ -56,13 +57,11 @@ object Deps { object Js { val stdLib = "stdlib-js" val test = "test-js" -// val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Versions.kotlinCoroutines}" - val coroutines = "com.ionspin.kotlin.coroutines:kotlinx-coroutines-core:${Versions.kotlinCoroutines}" + val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Versions.kotlinCoroutines}" 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", "0.7.6") val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "file:${getProjectPath()}/multiplatform-crypto-delegated/libsodium-wrappers-sumo-0.7.6.tgz") } @@ -73,12 +72,12 @@ object Deps { val test = "test" val testJUnit = "test-junit" val reflection = "reflect" -// val coroutinesCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.kotlinCoroutines}" - val coroutinesCore = "com.ionspin.kotlin.coroutines:kotlinx-coroutines-core:${Versions.kotlinCoroutines}" + val coroutinesCore = "org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.kotlinCoroutines}" val coroutinesjdk8 = "org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:${Versions.kotlinCoroutines}" val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime:${Versions.kotlinSerialization}" -// val coroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${Versions.kotlinCoroutines}" - val coroutinesTest = "com.ionspin.kotlin.coroutines:kotlinx-coroutines-test:${Versions.kotlinCoroutines}" + val coroutinesTest = "org.jetbrains.kotlinx:kotlinx-coroutines-test:${Versions.kotlinCoroutines}" + + val kotlinPoet = "com.squareup:kotlinpoet:${Versions.kotlinPoet}" object Delegated { val lazysodium = "com.goterl.lazycode:lazysodium-java:${Versions.lazySodium}" @@ -88,14 +87,12 @@ object Deps { object iOs { val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:${Versions.kotlinSerialization}" -// val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:${Versions.kotlinCoroutines}" - val coroutines = "com.ionspin.kotlin.coroutines:kotlinx-coroutines-core:${Versions.kotlinCoroutines}" + val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:${Versions.kotlinCoroutines}" } object Native { val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-native:${Versions.kotlinSerialization}" -// val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:${Versions.kotlinCoroutines}" - val coroutines = "com.ionspin.kotlin.coroutines:kotlinx-coroutines-core:${Versions.kotlinCoroutines}" + val coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:${Versions.kotlinCoroutines}" } diff --git a/kotlin-multiplatform-libsodium-generator/build.gradle.kts b/kotlin-multiplatform-libsodium-generator/build.gradle.kts new file mode 100644 index 0000000..934c736 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/build.gradle.kts @@ -0,0 +1,36 @@ +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 new file mode 100644 index 0000000..6287381 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,26 @@ +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 new file mode 100644 index 0000000..727d9c7 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,53 @@ +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 new file mode 100644 index 0000000..1213842 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,62 @@ +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 new file mode 100644 index 0000000..5224235 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,88 @@ +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 new file mode 100644 index 0000000..f20abfc --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt @@ -0,0 +1,13 @@ +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 new file mode 100644 index 0000000..9bcf7ff --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt @@ -0,0 +1,10 @@ +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 new file mode 100644 index 0000000..dfd1175 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -0,0 +1,174 @@ +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 new file mode 100644 index 0000000..61cacf0 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt @@ -0,0 +1,15 @@ +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 new file mode 100644 index 0000000..d6d47fd --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt @@ -0,0 +1,38 @@ +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 new file mode 100644 index 0000000..b196ecf --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt @@ -0,0 +1,80 @@ +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/generator/CommonLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt new file mode 100644 index 0000000..1ff5af6 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt @@ -0,0 +1,89 @@ +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 new file mode 100644 index 0000000..c347f7c --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt @@ -0,0 +1,31 @@ +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 new file mode 100644 index 0000000..4d05181 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -0,0 +1,154 @@ +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 { + + + 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()) + } + val file = fileBuilder.build() + file.writeTo(System.out) + return file + } + + 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) + methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList + 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 + } + } + 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()) + if (actualReturnTypeFound) { + methodBuilder.returns(actualReturnType) + return methodBuilder.build() + } + + if (methodDefinition.dynamicJsReturn) { + methodBuilder.returns(Dynamic) + } else { + methodBuilder.returns(methodDefinition.returnType.typeName) + } + 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 new file mode 100644 index 0000000..e303c2f --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -0,0 +1,215 @@ +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 new file mode 100644 index 0000000..46bcea0 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -0,0 +1,291 @@ +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 new file mode 100644 index 0000000..189561b --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt @@ -0,0 +1,37 @@ +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 new file mode 100644 index 0000000..74f517f --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm @@ -0,0 +1,101 @@ +// 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 new file mode 100644 index 0000000..d9073d2 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm @@ -0,0 +1,261 @@ +// 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 new file mode 100644 index 0000000..55096ca --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm @@ -0,0 +1,261 @@ +// 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 new file mode 100644 index 0000000..926379c --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm @@ -0,0 +1,261 @@ +// 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 new file mode 100644 index 0000000..2d912db --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm @@ -0,0 +1,261 @@ +// 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 new file mode 100644 index 0000000..dbcc66b --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm @@ -0,0 +1,261 @@ +// 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 new file mode 100644 index 0000000..7a15690 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm @@ -0,0 +1,261 @@ +// 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 new file mode 100644 index 0000000..eb6a78a --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm @@ -0,0 +1,261 @@ +// 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 new file mode 100644 index 0000000..60ee5dc --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm @@ -0,0 +1,145 @@ +// 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 new file mode 100644 index 0000000..32aa3b2 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt @@ -0,0 +1,18 @@ +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/linuxBuild.sh b/linuxBuild.sh index 329aeef..332984c 100755 --- a/linuxBuild.sh +++ b/linuxBuild.sh @@ -16,6 +16,8 @@ fi #now we can do the delegated build cd .. ./gradlew multiplatform-crypto-delegated:build +#build libsodium bindings +./gradlew multiplatform-crypto-libsodium-bindings:build #and finally pure build ./gradlew multiplatform-crypto:build set +e diff --git a/linuxBuildAndPublish.sh b/linuxBuildAndPublish.sh index 3df17bf..719e4d5 100755 --- a/linuxBuildAndPublish.sh +++ b/linuxBuildAndPublish.sh @@ -16,9 +16,11 @@ fi #now we can do the delegated build cd .. ./gradlew multiplatform-crypto-delegated:build +#build libsodium bindings +./gradlew multiplatform-crypto-libsodium-bindings:build #and finally pure build ./gradlew multiplatform-crypto:build ./gradlew publishJvmPublicationToSnapshotRepository publishJsPublicationToSnapshotRepository \ publishKotlinMultiplatformPublicationToSnapshotRepository publishLinuxX64PublicationToSnapshotRepository \ publishLinuxArm64PublicationToSnapshotRepository publishMetadataPublicationToSnapshotRepository -set +e \ No newline at end of file +set +e diff --git a/macBuild-mac-ios.sh b/macBuild-ios.sh similarity index 57% rename from macBuild-mac-ios.sh rename to macBuild-ios.sh index 237ae0d..2fbd792 100755 --- a/macBuild-mac-ios.sh +++ b/macBuild-ios.sh @@ -10,9 +10,12 @@ cd sodiumWrapper cd .. ./gradlew multiplatform-crypto-delegated:iosArm32MainKlibrary multiplatform-crypto-delegated:iosArm32TestKlibrary \ multiplatform-crypto-delegated:iosArm64MainKlibrary multiplatform-crypto-delegated:iosArm64TestKlibrary \ -multiplatform-crypto-delegated:iosX64MainKlibrary multiplatform-crypto-delegated:iosX64TestKlibrary \ -multiplatform-crypto-delegated:macosX64MainKlibrary multiplatform-crypto-delegated:macosX64TestKlibrary +multiplatform-crypto-delegated:iosX64MainKlibrary multiplatform-crypto-delegated:iosX64TestKlibrary ./gradlew multiplatform-crypto-delegated:iosX64Test -./gradlew multiplatform-crypto-delegated:macosX64Test + +./gradlew multiplatform-crypto-libsodium-bindings:iosArm32MainKlibrary multiplatform-crypto-libsodium-bindings:iosArm32TestKlibrary \ +multiplatform-crypto-libsodium-bindings:iosArm64MainKlibrary multiplatform-crypto-libsodium-bindings:iosArm64TestKlibrary \ +multiplatform-crypto-libsodium-bindings:iosX64MainKlibrary multiplatform-crypto-libsodium-bindings:iosX64TestKlibrary +./gradlew multiplatform-crypto-libsodium-bindings:iosX64Test set +e diff --git a/macBuild-mac.sh b/macBuild-mac.sh new file mode 100755 index 0000000..bb42c97 --- /dev/null +++ b/macBuild-mac.sh @@ -0,0 +1,17 @@ +set -e +#!/bin/sh +#this will hopefully download all konan dependancies that we use in the build scripts +./gradlew multiplatform-crypto-api:build +#now let's build linux deps +cd sodiumWrapper +./makeMacosX86-64.sh +./makeIos.sh +#now we can do the delegated build of ios and macos libraries +cd .. +./gradlew multiplatform-crypto-delegated:macosX64MainKlibrary multiplatform-crypto-delegated:macosX64TestKlibrary +./gradlew multiplatform-crypto-delegated:macosX64Test + +./gradlew multiplatform-crypto-libsodium-bindings:macosX64MainKlibrary multiplatform-crypto-libsodium-bindings:macosX64TestKlibrary +./gradlew multiplatform-crypto-libsodium-bindings:macosX64Test +set +e + diff --git a/macBuild-pure-ios.sh b/macBuild-pure-ios.sh new file mode 100755 index 0000000..85dc166 --- /dev/null +++ b/macBuild-pure-ios.sh @@ -0,0 +1,9 @@ +set -e +#!/bin/sh +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto:iosArm32MainKlibrary multiplatform-crypto:iosArm32TestKlibrary \ +multiplatform-crypto:iosArm64MainKlibrary multiplatform-crypto:iosArm64TestKlibrary \ +multiplatform-crypto:iosX64MainKlibrary multiplatform-crypto:iosX64TestKlibrary +./gradlew multiplatform-crypto:iosX64Test + +set +e diff --git a/macBuild-pure-mac.sh b/macBuild-pure-mac.sh new file mode 100755 index 0000000..66b5ae4 --- /dev/null +++ b/macBuild-pure-mac.sh @@ -0,0 +1,7 @@ +set -e +#!/bin/sh +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto:macosX64MainKlibrary multiplatform-crypto:macosX64TestKlibrary +./gradlew multiplatform-crypto:macosX64Test + +set +e diff --git a/macBuild-pure-tvos.sh b/macBuild-pure-tvos.sh new file mode 100755 index 0000000..b9c6e22 --- /dev/null +++ b/macBuild-pure-tvos.sh @@ -0,0 +1,7 @@ +set -e +#!/bin/sh +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto:tvosArm64MainKlibrary multiplatform-crypto:tvosArm64TestKlibrary \ +multiplatform-crypto:tvosX64MainKlibrary multiplatform-crypto:tvosX64TestKlibrary +./gradlew multiplatform-crypto:tvosX64Test +set +e diff --git a/macBuild-pure-watchos.sh b/macBuild-pure-watchos.sh new file mode 100755 index 0000000..75dd98b --- /dev/null +++ b/macBuild-pure-watchos.sh @@ -0,0 +1,8 @@ +set -e +#!/bin/sh +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto:watchosArm32MainKlibrary multiplatform-crypto:watchosArm32TestKlibrary \ +multiplatform-crypto:watchosArm64MainKlibrary multiplatform-crypto:watchosArm64TestKlibrary \ +multiplatform-crypto:watchosX86MainKlibrary multiplatform-crypto:watchosX86TestKlibrary +./gradlew multiplatform-crypto:watchosX86Test +set +e diff --git a/macBuild-pure.sh b/macBuild-pure.sh deleted file mode 100755 index 37dfce7..0000000 --- a/macBuild-pure.sh +++ /dev/null @@ -1,5 +0,0 @@ -set -e -#!/bin/sh -./gradlew multiplatform-crypto-api:build -./gradlew multiplatform-crypto:build -set +e \ No newline at end of file diff --git a/macBuild-tvos.sh b/macBuild-tvos.sh index 5c6fcc7..0fbc520 100755 --- a/macBuild-tvos.sh +++ b/macBuild-tvos.sh @@ -10,4 +10,8 @@ cd .. ./gradlew multiplatform-crypto-delegated:tvosArm64MainKlibrary multiplatform-crypto-delegated:tvosArm64TestKlibrary \ multiplatform-crypto-delegated:tvosX64MainKlibrary multiplatform-crypto-delegated:tvosX64TestKlibrary ./gradlew multiplatform-crypto-delegated:tvosX64Test -set +e \ No newline at end of file + +./gradlew multiplatform-crypto-libsodium-bindings:tvosArm64MainKlibrary multiplatform-crypto-libsodium-bindings:tvosArm64TestKlibrary \ +multiplatform-crypto-libsodium-bindings:tvosX64MainKlibrary multiplatform-crypto-libsodium-bindings:tvosX64TestKlibrary +./gradlew multiplatform-crypto-libsodium-bindings:tvosX64Test +set +e diff --git a/macBuild-watchos.sh b/macBuild-watchos.sh index 8187481..6935420 100755 --- a/macBuild-watchos.sh +++ b/macBuild-watchos.sh @@ -11,4 +11,9 @@ cd .. multiplatform-crypto-delegated:watchosArm64MainKlibrary multiplatform-crypto-delegated:watchosArm64TestKlibrary \ multiplatform-crypto-delegated:watchosX86MainKlibrary multiplatform-crypto-delegated:watchosX86TestKlibrary ./gradlew multiplatform-crypto-delegated:watchosX86Test -set +e \ No newline at end of file + +./gradlew multiplatform-crypto-libsodium-bindings:watchosArm32MainKlibrary multiplatform-crypto-libsodium-bindings:watchosArm32TestKlibrary \ +multiplatform-crypto-libsodium-bindings:watchosArm64MainKlibrary multiplatform-crypto-libsodium-bindings:watchosArm64TestKlibrary \ +multiplatform-crypto-libsodium-bindings:watchosX86MainKlibrary multiplatform-crypto-libsodium-bindings:watchosX86TestKlibrary +./gradlew multiplatform-crypto-libsodium-bindings:watchosX86Test +set +e diff --git a/macBuildAndPublish-mac-ios.sh b/macBuildAndPublish-ios.sh similarity index 64% rename from macBuildAndPublish-mac-ios.sh rename to macBuildAndPublish-ios.sh index 3c9da6a..a789f82 100755 --- a/macBuildAndPublish-mac-ios.sh +++ b/macBuildAndPublish-ios.sh @@ -4,12 +4,14 @@ set -e ./gradlew multiplatform-crypto-api:build #now let's build linux deps cd sodiumWrapper -./makeMacosX86-64.sh ./makeIos.sh #now we can do the delegated build of ios and macos libraries cd .. ./gradlew multiplatform-crypto-delegated:publishIosArm32PublicationToSnapshotRepository \ multiplatform-crypto-delegated:publishIosArm64PublicationToSnapshotRepository \ -multiplatform-crypto-delegated:publishIosX64PublicationToSnapshotRepository \ -multiplatform-crypto-delegated:publishMacosX64PublicationToSnapshotRepository +multiplatform-crypto-delegated:publishIosX64PublicationToSnapshotRepository + +./gradlew multiplatform-crypto-libsodium-bindings:publishIosArm32PublicationToSnapshotRepository \ +multiplatform-crypto-libsodium-bindings:publishIosArm64PublicationToSnapshotRepository \ +multiplatform-crypto-libsodium-bindings:publishIosX64PublicationToSnapshotRepository set +e diff --git a/macBuildAndPublish-mac.sh b/macBuildAndPublish-mac.sh new file mode 100755 index 0000000..c92cf58 --- /dev/null +++ b/macBuildAndPublish-mac.sh @@ -0,0 +1,13 @@ +set -e +#!/bin/sh +#this will hopefully download all konan dependancies that we use in the build scripts +./gradlew multiplatform-crypto-api:build +#now let's build linux deps +cd sodiumWrapper +./makeMacosX86-64.sh +#now we can do the delegated build of ios and macos libraries +cd .. +./gradlew multiplatform-crypto-delegated:publishMacosX64PublicationToSnapshotRepository + +./gradlew multiplatform-crypto-libsodium-bindings:publishMacosX64PublicationToSnapshotRepository +set +e diff --git a/macBuildAndPublish-pure-ios.sh b/macBuildAndPublish-pure-ios.sh new file mode 100755 index 0000000..e49a80e --- /dev/null +++ b/macBuildAndPublish-pure-ios.sh @@ -0,0 +1,8 @@ +set -e +#!/bin/sh +#this will hopefully download all konan dependancies that we use in the build scripts +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto:publishIos32ArmPublicationToSnapshotRepository \ +multiplatform-crypto:publishIos64ArmPublicationToSnapshotRepository \ +multiplatform-crypto:publishIosPublicationToSnapshotRepository +set +e diff --git a/macBuildAndPublish-pure-mac-ios.sh b/macBuildAndPublish-pure-mac-ios.sh new file mode 100755 index 0000000..6dc40b5 --- /dev/null +++ b/macBuildAndPublish-pure-mac-ios.sh @@ -0,0 +1,6 @@ +set -e +#!/bin/sh +#this will hopefully download all konan dependancies that we use in the build scripts +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto:publishMacosX64PublicationToSnapshotRepository +set +e diff --git a/macBuildAndPublish-pure-tvos.sh b/macBuildAndPublish-pure-tvos.sh new file mode 100755 index 0000000..d1cd8e4 --- /dev/null +++ b/macBuildAndPublish-pure-tvos.sh @@ -0,0 +1,8 @@ +set -e +#!/bin/sh +#this will hopefully download all konan dependancies that we use in the build scripts +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto-delegated:publishTvosArm64PublicationToSnapshotRepository \ +multiplatform-crypto-delegated:publishTvosX64PublicationToSnapshotRepository + +set +e diff --git a/macBuildAndPublish-pure-watchos.sh b/macBuildAndPublish-pure-watchos.sh new file mode 100755 index 0000000..30724cd --- /dev/null +++ b/macBuildAndPublish-pure-watchos.sh @@ -0,0 +1,8 @@ +set -e +#!/bin/sh +#this will hopefully download all konan dependancies that we use in the build scripts +./gradlew multiplatform-crypto-api:build +./gradlew multiplatform-crypto:publishWatchosArm32PublicationToSnapshotRepository \ +multiplatform-crypto:publishWatchosArm64PublicationToSnapshotRepository \ +multiplatform-crypto:publishWatchosX86PublicationToSnapshotRepository +set +e diff --git a/macBuildAndPublish-pure.sh b/macBuildAndPublish-pure.sh deleted file mode 100755 index 945a8cb..0000000 --- a/macBuildAndPublish-pure.sh +++ /dev/null @@ -1,14 +0,0 @@ -set -e -#!/bin/sh -#this will hopefully download all konan dependancies that we use in the build scripts -./gradlew multiplatform-crypto-api:build -./gradlew multiplatform-crypto:publishIos32ArmPublicationToSnapshotRepository \ -multiplatform-crypto:publishIos64ArmPublicationToSnapshotRepository \ -multiplatform-crypto:publishIosPublicationToSnapshotRepository \ -multiplatform-crypto:publishMacosX64PublicationToSnapshotRepository \ -multiplatform-crypto:publishTvosArm64PublicationToSnapshotRepository \ -multiplatform-crypto:publishTvosX64PublicationToSnapshotRepository \ -multiplatform-crypto:publishWatchosArm32PublicationToSnapshotRepository \ -multiplatform-crypto:publishWatchosArm64PublicationToSnapshotRepository \ -multiplatform-crypto:publishWatchosX86PublicationToSnapshotRepository -set +e diff --git a/macBuildAndPublish-tvos.sh b/macBuildAndPublish-tvos.sh index 90ab267..1533e8d 100755 --- a/macBuildAndPublish-tvos.sh +++ b/macBuildAndPublish-tvos.sh @@ -2,11 +2,7 @@ set -e #!/bin/sh #this will hopefully download all konan dependancies that we use in the build scripts ./gradlew multiplatform-crypto-api:build -#now let's build linux deps -cd sodiumWrapper -./makeTvos.sh -#now we can do the delegated build of ios and macos libraries -cd .. -./gradlew multiplatform-crypto-delegated:publishTvosArm64PublicationToSnapshotRepository \ -multiplatform-crypto-delegated:publishTvosX64PublicationToSnapshotRepository +./gradlew multiplatform-crypto:publishTvosArm64PublicationToSnapshotRepository \ +multiplatform-crypto:publishTvosX64PublicationToSnapshotRepository + set +e diff --git a/macBuildAndPublish-watchos.sh b/macBuildAndPublish-watchos.sh index eee58f8..3125ec4 100755 --- a/macBuildAndPublish-watchos.sh +++ b/macBuildAndPublish-watchos.sh @@ -10,4 +10,8 @@ cd .. ./gradlew multiplatform-crypto-delegated:publishWatchosArm32PublicationToSnapshotRepository \ multiplatform-crypto-delegated:publishWatchosArm64PublicationToSnapshotRepository \ multiplatform-crypto-delegated:publishWatchosX86PublicationToSnapshotRepository + +./gradlew multiplatform-crypto-libsodium-bindings:publishWatchosArm32PublicationToSnapshotRepository \ +multiplatform-crypto-libsodium-bindings:publishWatchosArm64PublicationToSnapshotRepository \ +multiplatform-crypto-libsodium-bindings:publishWatchosX86PublicationToSnapshotRepository set +e diff --git a/multiplatform-crypto-api/build.gradle.kts b/multiplatform-crypto-api/build.gradle.kts index 4ec7aba..110e300 100644 --- a/multiplatform-crypto-api/build.gradle.kts +++ b/multiplatform-crypto-api/build.gradle.kts @@ -22,9 +22,9 @@ import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest plugins { kotlin(PluginsDeps.multiplatform) - id (PluginsDeps.mavenPublish) - id (PluginsDeps.signing) - id (PluginsDeps.dokka) + id(PluginsDeps.mavenPublish) + id(PluginsDeps.signing) + id(PluginsDeps.dokka) } repositories { @@ -69,7 +69,6 @@ kotlin { } } - //Not supported in OFFICIAL coroutines at the moment linuxArm64() { binaries { staticLib { @@ -77,7 +76,6 @@ kotlin { } } - //Not supported in OFFICAL coroutines at the moment linuxArm32Hfp() { binaries { staticLib { @@ -269,12 +267,12 @@ kotlin { tasks { create("javadocJar") { - dependsOn(dokka) + dependsOn(dokkaJavadoc) archiveClassifier.set("javadoc") - from(dokka.get().outputDirectory) + from(dokkaJavadoc.get().outputDirectory) } - dokka { + dokkaJavadoc { println("Dokka !") } if (getHostOsName() == "linux" && getHostArchitecture() == "x86-64") { 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 new file mode 100644 index 0000000..427ffd4 --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt @@ -0,0 +1,87 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.hash.MultipartHash +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 23-Jun-2020 + */ +inline class EncryptableString(val content: String) : Encryptable { + override fun toEncryptableForm(): UByteArray { + return content.encodeToUByteArray() + } + + override fun fromEncryptableForm(): (UByteArray) -> EncryptableString { + return { uByteArray -> + EncryptableString(uByteArray.toByteArray().decodeToString()) + } + } + + fun asString() : String = content + + +} + +fun String.asEncryptableString() : EncryptableString { + return EncryptableString(this) +} + +interface Encryptable { + fun toEncryptableForm() : UByteArray + fun fromEncryptableForm() : (UByteArray) -> T +} + +data class HashedData(val hash: UByteArray) { + fun toHexString() : String { + return hash.toHexString() + } +} + +data class SymmetricKey(val value : UByteArray) { + companion object { + + } +} + +data class EncryptedData constructor(val ciphertext: UByteArray, val nonce: UByteArray) + +interface HashApi { + fun hash(data: UByteArray, key : UByteArray = ubyteArrayOf()) : HashedData + fun multipartHash(key: UByteArray? = null) : MultipartHash +} + +interface EncryptionApi { + fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData + fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: 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 + +} + +data class EncryptedDataPart(val data : UByteArray) +data class DecryptedDataPart(val data : UByteArray) + +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 cleanup() +} + +interface MultipartAuthenticatedEncryption { + fun encryptPartialData(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : EncryptedDataPart + fun startEncryption() : MultipartEncryptionHeader + fun cleanup() + +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoInitializer.kt similarity index 70% rename from multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt rename to multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoInitializer.kt index e836850..c97df6b 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoInitializer.kt @@ -5,8 +5,10 @@ package com.ionspin.kotlin.crypto * ugljesa.jovanovic@ionspin.com * on 27-May-2020 */ -interface CryptoProvider { +interface CryptoInitializer { suspend fun initialize() + fun isInitialized() : Boolean -} \ No newline at end of file + +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/PrimitivesApi.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/PrimitivesApi.kt new file mode 100644 index 0000000..494521b --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/PrimitivesApi.kt @@ -0,0 +1,37 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties +import com.ionspin.kotlin.crypto.hash.sha.Sha256 +import com.ionspin.kotlin.crypto.hash.sha.Sha512Multipart +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 23-Jun-2020 + */ +interface PrimitivesApi { + fun hashBlake2bMultipart(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): Blake2bMultipart + fun hashBlake2b(message: UByteArray, key: UByteArray = ubyteArrayOf(), hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): UByteArray + + fun hashSha256Multipart(): Sha256 + fun hashSha256(message: UByteArray) : UByteArray + + fun hashSha512Multipart(): Sha512Multipart + fun hashSha512(message: UByteArray) : UByteArray + + fun deriveKey( + password: String, + salt: String? = null, + key: String, + associatedData: String, + parallelism: Int = 16, + tagLength: Int = 64, + memory: Int = 4096, + numberOfIterations: Int = 10, + ) : ArgonResult + +} + + diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305.kt new file mode 100644 index 0000000..68fa7fd --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305.kt @@ -0,0 +1,8 @@ +package com.ionspin.kotlin.crypto.authenticated + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +interface XChaCha20Poly1305 \ No newline at end of file diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/HashFunction.kt similarity index 79% rename from multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt rename to multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/HashFunction.kt index 8d9ebc3..50bc267 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/HashFunction.kt @@ -22,12 +22,12 @@ package com.ionspin.kotlin.crypto.hash * ugljesa.jovanovic@ionspin.com * on 20-Jul-2019 */ -interface Hash { +interface HashFunction { val MAX_HASH_BYTES : Int } -interface UpdatableHash : Hash { +interface MultipartHash : HashFunction { fun update(data : UByteArray) fun digest() : UByteArray @@ -35,11 +35,15 @@ interface UpdatableHash : Hash { } -interface StatelessHash : Hash { +interface Hash : HashFunction { } fun String.encodeToUByteArray() : UByteArray{ - return encodeToByteArray().toUByteArray() + return encodeToByteArray().asUByteArray() +} + +fun UByteArray.decodeToString() : String { + return this.asByteArray().contentToString() } diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt index cac59c5..0cc7cb2 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2b.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b -import com.ionspin.kotlin.crypto.hash.StatelessHash -import com.ionspin.kotlin.crypto.hash.UpdatableHash +import com.ionspin.kotlin.crypto.hash.Hash +import com.ionspin.kotlin.crypto.hash.MultipartHash /** * Created by Ugljesa Jovanovic @@ -13,12 +13,12 @@ object Blake2bProperties { const val MAX_HASH_BYTES = 64 } -interface Blake2b : UpdatableHash { +interface Blake2bMultipart : MultipartHash { override val MAX_HASH_BYTES: Int get() = Blake2bProperties.MAX_HASH_BYTES } -interface Blake2bStateless : StatelessHash { +interface Blake2b : Hash { override val MAX_HASH_BYTES: Int get() = Blake2bProperties.MAX_HASH_BYTES diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt index 6097f3a..90c2dcd 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha -import com.ionspin.kotlin.crypto.hash.StatelessHash -import com.ionspin.kotlin.crypto.hash.UpdatableHash +import com.ionspin.kotlin.crypto.hash.Hash +import com.ionspin.kotlin.crypto.hash.MultipartHash /** * Created by Ugljesa Jovanovic @@ -12,15 +12,15 @@ object Sha256Properties { const val MAX_HASH_BYTES = 32 } -interface Sha256 : UpdatableHash { +interface Sha256 : MultipartHash { override val MAX_HASH_BYTES: Int get() = Sha256Properties.MAX_HASH_BYTES } -interface StatelessSha256 : StatelessHash { +interface StatelessSha256 : Hash { override val MAX_HASH_BYTES: Int get() = Sha256Properties.MAX_HASH_BYTES fun digest( inputMessage: UByteArray = ubyteArrayOf() ): UByteArray -} \ No newline at end of file +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt index f60e92d..2268fc6 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha -import com.ionspin.kotlin.crypto.hash.StatelessHash -import com.ionspin.kotlin.crypto.hash.UpdatableHash +import com.ionspin.kotlin.crypto.hash.Hash +import com.ionspin.kotlin.crypto.hash.MultipartHash /** * Created by Ugljesa Jovanovic @@ -11,15 +11,15 @@ import com.ionspin.kotlin.crypto.hash.UpdatableHash object Sha512Properties { const val MAX_HASH_BYTES = 64 } -interface Sha512 : UpdatableHash { +interface Sha512Multipart : MultipartHash { override val MAX_HASH_BYTES: Int get() = Sha256Properties.MAX_HASH_BYTES } -interface StatelessSha512 : StatelessHash { +interface Sha512 : Hash { override val MAX_HASH_BYTES: Int get() = Sha512Properties.MAX_HASH_BYTES fun digest( inputMessage: UByteArray = ubyteArrayOf() ): UByteArray -} \ No newline at end of file +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt index 3a6463b..bdd0031 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/KeyDerivationFunction.kt @@ -23,4 +23,13 @@ package com.ionspin.kotlin.crypto.keyderivation */ interface KeyDerivationFunction { fun derive() : UByteArray -} \ No newline at end of file +} + +data class ArgonResult( + val hashBytes: UByteArray, + val salt: UByteArray +) { + val hashString by lazy { hashBytes.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } + val saltString by lazy { salt.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } + +} diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Mode.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Mode.kt similarity index 100% rename from multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Mode.kt rename to multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Mode.kt diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20.kt new file mode 100644 index 0000000..a14a769 --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20.kt @@ -0,0 +1,47 @@ +package com.ionspin.kotlin.crypto.symmetric + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +interface XChaCha20 { + interface Nonce { + val content: UByteArray + } + + interface Key { + val content : UByteArray + } + fun encrypt(key: Key, inputMessage: UByteArray) : XChaCha20EncryptionResult + + fun decrypt(key: Key, nonce: Nonce) : UByteArray +} + +data class XChaCha20EncryptionResult(val nonce: UByteArray, val encryptionData: UByteArray) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || this::class != other::class) return false + + other as XChaCha20EncryptionResult + + if (nonce != other.nonce) return false + if (encryptionData != other.encryptionData) return false + + return true + } + + override fun hashCode(): Int { + var result = nonce.hashCode() + result = 31 * result + encryptionData.hashCode() + return result + } +} + + + +interface XChaCha20KeyProvider { + fun generateNewKey() : XChaCha20.Key + + fun createFromUByteArray(uByteArray: UByteArray) : XChaCha20.Key +} \ No newline at end of file diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/ByteArrayConversions.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/ByteArrayConversions.kt new file mode 100644 index 0000000..61065cb --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/ByteArrayConversions.kt @@ -0,0 +1,10 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 26-Jul-2020 + */ +fun UByteArray.fromLittleEndianUByteArrayToBigEndianUByteArray() : UByteArray { + return this.reversedArray() +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/CryptoUtil.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/CryptoUtil.kt new file mode 100644 index 0000000..6739eaa --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/CryptoUtil.kt @@ -0,0 +1,20 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 22-Jun-2020 + */ +val _emit = IntArray(0) + +fun UByteArray.overwriteWithZeroes() { + for (i in 0 until size) { + this[i] = 0U + } +} + +fun UIntArray.overwriteWithZeroes() { + for (i in 0 until size) { + this[i] = 0U + } +} diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/StringUtil.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/StringUtil.kt new file mode 100644 index 0000000..0d665d5 --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/StringUtil.kt @@ -0,0 +1,56 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 22-Jun-2020 + */ +fun Array.hexColumsPrint() { + val printout = this.map { it.toString(16) }.chunked(16) + printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } +} + +fun Array.hexColumsPrint(chunk : Int = 16) { + val printout = this.map { it.toString(16).padStart(2, '0') }.chunked(chunk) + printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } +} + +fun UByteArray.hexColumsPrint(chunk : Int = 16) { + val printout = this.map { it.toString(16).padStart(2, '0') }.chunked(chunk) + printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } +} + +fun Array.hexColumsPrint(chunk: Int = 3) { + val printout = this.map { it.toString(16) }.chunked(chunk) + printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } +} + +fun String.hexStringToTypedUByteArray() : Array { + return this.chunked(2).map { it.toUByte(16) }.toTypedArray() +} + + +fun String.hexStringToUByteArray() : UByteArray { + return this.chunked(2).map { it.toUByte(16) }.toUByteArray() +} + +fun Array.toHexString() : String { + return this.joinToString(separator = "") { + if (it <= 0x0FU) { + "0${it.toString(16)}" + } else { + it.toString(16) + } + } +} + + +fun UByteArray.toHexString() : String { + return this.joinToString(separator = "") { + if (it <= 0x0FU) { + "0${it.toString(16)}" + } else { + it.toString(16) + } + } +} diff --git a/multiplatform-crypto-delegated/build.gradle.kts b/multiplatform-crypto-delegated/build.gradle.kts index ddfc8a8..12f3783 100644 --- a/multiplatform-crypto-delegated/build.gradle.kts +++ b/multiplatform-crypto-delegated/build.gradle.kts @@ -131,7 +131,6 @@ kotlin { } - //Not supported in OFFICIAL coroutines at the moment (we're running a custom build) runningOnLinuxArm64 { println("Configuring Linux Arm 64 targets") @@ -249,7 +248,6 @@ kotlin { dependencies { implementation(kotlin(Deps.Common.stdLib)) implementation(kotlin(Deps.Common.test)) - implementation(Deps.Common.coroutines) implementation(Deps.Common.kotlinBigNum) api(project(Deps.Common.apiProject)) } @@ -262,7 +260,6 @@ kotlin { } val nativeDependencies = independentDependencyBlock { - implementation(Deps.Native.coroutines) } val nativeMain by creating { @@ -281,7 +278,6 @@ kotlin { kotlin.setSrcDirs(emptySet()) } dependencies { - implementation(Deps.Native.coroutines) } } @@ -420,7 +416,6 @@ kotlin { implementation(kotlin(Deps.Jvm.stdLib)) implementation(kotlin(Deps.Jvm.test)) implementation(kotlin(Deps.Jvm.testJUnit)) - implementation(Deps.Jvm.coroutinesCore) //lazysodium implementation(Deps.Jvm.Delegated.lazysodium) @@ -431,20 +426,17 @@ kotlin { dependencies { implementation(kotlin(Deps.Jvm.test)) implementation(kotlin(Deps.Jvm.testJUnit)) - implementation(Deps.Jvm.coroutinesTest) implementation(kotlin(Deps.Jvm.reflection)) } } val jsMain by getting { dependencies { implementation(kotlin(Deps.Js.stdLib)) - implementation(Deps.Js.coroutines) implementation(npm(Deps.Js.Npm.libsodiumWrappers.first, Deps.Js.Npm.libsodiumWrappers.second)) } } val jsTest by getting { dependencies { - implementation(Deps.Js.coroutines) implementation(kotlin(Deps.Js.test)) implementation(npm(Deps.Js.Npm.libsodiumWrappers.first, Deps.Js.Npm.libsodiumWrappers.second)) } @@ -536,12 +528,12 @@ tasks { create("javadocJar") { - dependsOn(dokka) + dependsOn(dokkaJavadoc) archiveClassifier.set("javadoc") - from(dokka.get().outputDirectory) + from(dokkaJavadoc.get().outputDirectory) } - dokka { + dokkaJavadoc { println("Dokka !") } if (getHostOsName() == "linux" && getHostArchitecture() == "x86-64") { 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 0d4d849..5d3d87a 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 @@ -1,9 +1,12 @@ package com.ionspin.kotlin.crypto +import com.ionspin.kotlin.crypto.authenticated.XChaCha20Poly1305Delegated import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart import com.ionspin.kotlin.crypto.hash.sha.* +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult /** * Created by Ugljesa Jovanovic @@ -11,7 +14,7 @@ import com.ionspin.kotlin.crypto.hash.sha.* * on 24-May-2020 */ -object Crypto : CryptoProvider { +object CryptoInitializerDelegated : CryptoInitializer { override suspend fun initialize() { Initializer.initialize() } @@ -20,9 +23,15 @@ object Crypto : CryptoProvider { Initializer.initializeWithCallback(done) } + override fun isInitialized(): Boolean { + return Initializer.isInitialized() + } +} + +object CryptoPrimitives : PrimitivesApi { object Blake2b { - fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b { + fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart { checkInitialization() return Blake2bDelegated(key, hashLength) } @@ -46,7 +55,7 @@ object Crypto : CryptoProvider { } object Sha512 { - fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha512 { + fun updateable(): Sha512Multipart { checkInitialization() return Sha512Delegated() } @@ -63,12 +72,136 @@ object Crypto : CryptoProvider { } } + override fun hashBlake2bMultipart(key: UByteArray?, hashLength: Int): Blake2bMultipart { + checkInitialization() + return Blake2bDelegated(key, hashLength) + } + + override fun hashBlake2b(message: UByteArray, key: UByteArray, hashLength: Int): UByteArray { + checkInitialization() + return Blake2bDelegatedStateless.digest(message, key, hashLength) + } + + override fun hashSha256Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha256 { + checkInitialization() + return Sha256Delegated() + } + + override fun hashSha256(message: UByteArray): UByteArray { + checkInitialization() + return Sha256StatelessDelegated.digest(inputMessage = message) + } + + override fun hashSha512Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha512Multipart { + checkInitialization() + return Sha512Delegated() + } + + override fun hashSha512(message: UByteArray): UByteArray { + checkInitialization() + return Sha512StatelessDelegated.digest(inputMessage = message) + } + + override fun deriveKey( + password: String, + salt: String?, + key: String, + associatedData: String, + parallelism: Int, + tagLength: Int, + memory: Int, + numberOfIterations: Int + ): ArgonResult { +// return Argon2Delegated.derive( +// password, +// salt, +// key, +// associatedData, +// parallelism +// tagLength, +// memory, +// numberOfIterations +// ) + TODO() + } + } -object SimpleCrypto { - fun hash(message: String): UByteArray { - return ubyteArrayOf(0U) +fun SymmetricKey.Companion.randomKey() : SymmetricKey { + return SymmetricKey(SRNG.getRandomBytes(32)) +} + +object Crypto { + + object Hash : HashApi { + override fun hash(data: UByteArray, key : UByteArray) : HashedData { + return HashedData(Blake2bDelegatedStateless.digest(data, key)) + } + + override fun multipartHash(key: UByteArray?) : com.ionspin.kotlin.crypto.hash.MultipartHash { + return Blake2bDelegated(key) + } + } + + object Encryption : EncryptionApi { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : 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) + + } + + 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 createMultipartEncryptor(key: SymmetricKey): MultipartAuthenticatedEncryption { + return MultipartAuthenticatedEncryptor(key) + } + + override fun createMultipartDecryptor(key: SymmetricKey, header: MultipartEncryptionHeader) : MultipartAuthenticatedDecryption { + val decryptor = XChaCha20Poly1305Delegated() + decryptor.initializeForDecryption(key.value, header.nonce) + return MultipartAuthenticatedDecryptor(decryptor) + } + + + } +} + +class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey) : MultipartAuthenticatedEncryption { + + val header : MultipartEncryptionHeader + val primitive = XChaCha20Poly1305Delegated() + init { + header = MultipartEncryptionHeader(primitive.initializeForEncryption(key.value)) + } + + override fun startEncryption(): MultipartEncryptionHeader { + return header + } + + override fun encryptPartialData(data: UByteArray, additionalData: UByteArray): EncryptedDataPart { + return EncryptedDataPart(primitive.encrypt(data, additionalData)) + } + + override fun cleanup() { + primitive.cleanup() + } +} + + +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 cleanup() { + decryptor.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 new file mode 100644 index 0000000..7166932 --- /dev/null +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt @@ -0,0 +1,24 @@ +package com.ionspin.kotlin.crypto.authenticated + + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +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 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 cleanup() + + +} + + diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index 1e15a51..4887631 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -23,9 +23,9 @@ package com.ionspin.kotlin.crypto.hash.blake2b */ -expect class Blake2bDelegated(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES) : Blake2b +expect class Blake2bDelegated(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES) : Blake2bMultipart -expect object Blake2bDelegatedStateless : Blake2bStateless +expect object Blake2bDelegatedStateless : Blake2b diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index 13a809d..8d5b857 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -24,6 +24,6 @@ package com.ionspin.kotlin.crypto.hash.sha */ -expect class Sha512Delegated() : Sha512 +expect class Sha512Delegated() : Sha512Multipart -expect object Sha512StatelessDelegated : StatelessSha512 \ No newline at end of file +expect object Sha512StatelessDelegated : Sha512 diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt deleted file mode 100644 index 134b671..0000000 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.symmetric - -import com.ionspin.kotlin.crypto.SRNG -import com.ionspin.kotlin.crypto.util.xor - -/** - * Advanced encryption standard with cipher block chaining and PKCS #5 - * - * For bulk encryption/decryption use [AesCbcPure.encrypt] and [AesCbcPure.decrypt] - * - * To get an instance of AesCbc and then feed it data sequentially with [addData] use [createEncryptor] and [createDecryptor] - * - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 21-Sep-2019 - */ - -class AesCbcPure internal constructor(val aesKey: AesKey, val mode: Mode, initializationVector: UByteArray? = null) { - - companion object { - const val BLOCK_BYTES = 16 - /** - * Creates and returns AesCbc instance that can be fed data using [addData]. Once you have submitted all - * data call [encrypt] - */ - fun createEncryptor(aesKey: AesKey) : AesCbcPure { - return AesCbcPure(aesKey, Mode.ENCRYPT) - } - /** - * Creates and returns AesCbc instance that can be fed data using [addData]. Once you have submitted all - * data call [decrypt] - */ - fun createDecryptor(aesKey : AesKey) : AesCbcPure { - return AesCbcPure(aesKey, Mode.DECRYPT) - } - - /** - * Bulk encryption, returns encrypted data and a random initialization vector - */ - fun encrypt(aesKey: AesKey, data: UByteArray): EncryptedDataAndInitializationVector { - val aesCbc = AesCbcPure(aesKey, Mode.ENCRYPT) - aesCbc.addData(data) - return aesCbc.encrypt() - } - - /** - * Bulk decryption, returns decrypted data - */ - fun decrypt(aesKey: AesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { - val aesCbc = AesCbcPure(aesKey, Mode.DECRYPT, initialCounter) - aesCbc.addData(data) - return aesCbc.decrypt() - } - - private fun padToBlock(unpadded: UByteArray): UByteArray { - val paddingSize = 16 - unpadded.size - if (unpadded.size == BLOCK_BYTES) { - return unpadded - } - - if (unpadded.size == BLOCK_BYTES) { - return UByteArray(BLOCK_BYTES) { - BLOCK_BYTES.toUByte() - } - } - - if (unpadded.size > BLOCK_BYTES) { - throw IllegalStateException("Block larger than 128 bytes") - } - - return UByteArray(BLOCK_BYTES) { - when (it) { - in unpadded.indices -> unpadded[it] - else -> paddingSize.toUByte() - } - } - - } - } - - var currentOutput: UByteArray = ubyteArrayOf() - var previousEncrypted: UByteArray = ubyteArrayOf() - val initVector = if (initializationVector.isNullOrEmpty()) { - SRNG.getRandomBytes(16) - } else { - initializationVector - } - - val output = MutableList(0) { ubyteArrayOf() } - - var buffer: UByteArray = UByteArray(16) { 0U } - var bufferCounter = 0 - - fun addData(data: UByteArray) { - //Padding - when { - bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) - bufferCounter + data.size >= BLOCK_BYTES -> { - val chunked = data.chunked(BLOCK_BYTES) - chunked.forEach { chunk -> - if (bufferCounter + chunk.size < BLOCK_BYTES) { - appendToBuffer(chunk.toUByteArray(), bufferCounter) - } else { - chunk.toUByteArray().copyInto( - destination = buffer, - destinationOffset = bufferCounter, - startIndex = 0, - endIndex = BLOCK_BYTES - bufferCounter - ) - output += consumeBlock(buffer) - buffer = UByteArray(BLOCK_BYTES) { - when (it) { - in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { - chunk[it + (BLOCK_BYTES - bufferCounter)] - } - else -> { - 0U - } - } - - } - bufferCounter = chunk.size - (BLOCK_BYTES - bufferCounter) - } - } - - } - } - - } - - /** - * Encrypt fed data and return it alongside the randomly chosen initialization vector - * @return Encrypted data and initialization vector - */ - fun encrypt(): EncryptedDataAndInitializationVector { - if (bufferCounter > 0) { - val lastBlockPadded = padToBlock(buffer) - if (lastBlockPadded.size > BLOCK_BYTES) { - val chunks = lastBlockPadded.chunked(BLOCK_BYTES).map { it.toUByteArray() } - output += consumeBlock(chunks[0]) - output += consumeBlock(chunks[1]) - } else { - output += consumeBlock(lastBlockPadded) - } - } - return EncryptedDataAndInitializationVector( - output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, - initVector - ) - } - - /** - * Decrypt data - * @return Decrypted data - */ - 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() - }.toUByteArray() - val preparedOutput = (output.dropLast(1) + listOf(removedPadding)) - //JS compiler freaks out here if we don't supply exact type - val reversed : List = preparedOutput.reversed() as List - val folded : UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { uByteArray, acc -> - acc + uByteArray - } - return folded - - } - - private fun appendToBuffer(array: UByteArray, start: Int) { - array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) - bufferCounter += array.size - } - - private fun consumeBlock(data: UByteArray): UByteArray { - return when (mode) { - Mode.ENCRYPT -> { - currentOutput = if (currentOutput.isEmpty()) { - println("IV: $initVector") - AesPure.encrypt(aesKey, data xor initVector) - } else { - AesPure.encrypt(aesKey, data xor currentOutput) - } - currentOutput - } - Mode.DECRYPT -> { - if (currentOutput.isEmpty()) { - currentOutput = AesPure.decrypt(aesKey, data) xor initVector - } else { - currentOutput = AesPure.decrypt(aesKey, data) xor previousEncrypted - } - previousEncrypted = data - currentOutput - } - } - - } - -} - - -data class EncryptedDataAndInitializationVector(val encryptedData : UByteArray, val initilizationVector : UByteArray) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other == null || this::class != other::class) return false - - other as EncryptedDataAndInitializationVector - - if (!encryptedData.contentEquals(other.encryptedData)) return false - if (!initilizationVector.contentEquals(other.initilizationVector)) return false - - return true - } - - override fun hashCode(): Int { - var result = encryptedData.contentHashCode() - result = 31 * result + initilizationVector.contentHashCode() - return result - } -} \ No newline at end of file diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt deleted file mode 100644 index 6c2aa51..0000000 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.symmetric - -import com.ionspin.kotlin.bignum.Endianness -import com.ionspin.kotlin.bignum.integer.BigInteger -import com.ionspin.kotlin.bignum.modular.ModularBigInteger -import com.ionspin.kotlin.crypto.SRNG -import com.ionspin.kotlin.crypto.symmetric.AesCtrPure.Companion.encrypt -import com.ionspin.kotlin.crypto.util.xor - -/** - * - * Advanced encryption standard with counter mode - * - * For bulk encryption/decryption use [AesCtrPure.encrypt] and [AesCtrPure.decrypt] - * - * To get an instance of AesCtr and then feed it data sequentially with [addData] use [createEncryptor] and [createDecryptor] - * - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 22-Sep-2019 - */ - -class AesCtrPure internal constructor(val aesKey: AesKey, val mode: Mode, initialCounter: UByteArray? = null) { - - companion object { - const val BLOCK_BYTES = 16 - - val modularCreator = ModularBigInteger.creatorForModulo(BigInteger.ONE.shl(128) - 1) - /** - * Creates and returns AesCtr instance that can be fed data using [addData]. Once you have submitted all - * data call [encrypt] - */ - fun createEncryptor(aesKey: AesKey) : AesCtrPure { - return AesCtrPure(aesKey, Mode.ENCRYPT) - } - /** - * Creates and returns AesCtr instance that can be fed data using [addData]. Once you have submitted all - * data call [decrypt] - */ - fun createDecryptor(aesKey : AesKey) : AesCtrPure { - return AesCtrPure(aesKey, Mode.DECRYPT) - } - /** - * Bulk encryption, returns encrypted data and a random initial counter - */ - fun encrypt(aesKey: AesKey, data: UByteArray): EncryptedDataAndInitialCounter { - val aesCtr = AesCtrPure(aesKey, Mode.ENCRYPT) - aesCtr.addData(data) - return aesCtr.encrypt() - } - /** - * Bulk decryption, returns decrypted data - */ - fun decrypt(aesKey: AesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { - val aesCtr = AesCtrPure(aesKey, Mode.DECRYPT, initialCounter) - aesCtr.addData(data) - return aesCtr.decrypt() - } - - } - - var currentOutput: UByteArray = ubyteArrayOf() - var previousEncrypted: UByteArray = ubyteArrayOf() - val counterStart = if (initialCounter.isNullOrEmpty()) { - SRNG.getRandomBytes(16) - } else { - initialCounter - } - var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart.toTypedArray(), Endianness.BIG)) - - val output = MutableList(0) { ubyteArrayOf() } - - var buffer: UByteArray = UByteArray(16) { 0U } - var bufferCounter = 0 - - fun addData(data: UByteArray) { - //Padding - when { - bufferCounter + data.size < BLOCK_BYTES -> appendToBuffer(data, bufferCounter) - bufferCounter + data.size >= BLOCK_BYTES -> { - val chunked = data.chunked(BLOCK_BYTES) - chunked.forEach { chunk -> - if (bufferCounter + chunk.size < BLOCK_BYTES) { - appendToBuffer(chunk.toUByteArray(), bufferCounter) - } else { - chunk.toUByteArray().copyInto( - destination = buffer, - destinationOffset = bufferCounter, - startIndex = 0, - endIndex = BLOCK_BYTES - bufferCounter - ) - output += consumeBlock(buffer, blockCounter) - blockCounter += 1 - buffer = UByteArray(BLOCK_BYTES) { - when (it) { - in (0 until (chunk.size - (BLOCK_BYTES - bufferCounter))) -> { - chunk[it + (BLOCK_BYTES - bufferCounter)] - } - else -> { - 0U - } - } - - } - bufferCounter = chunk.size - (BLOCK_BYTES - bufferCounter) - } - } - - } - } - - } - /** - * Encrypt fed data and return it alongside the randomly chosen initial counter state - * @return Encrypted data and initial counter state - */ - fun encrypt(): EncryptedDataAndInitialCounter { - if (bufferCounter > 0) { - output += consumeBlock(buffer, blockCounter) - } - return EncryptedDataAndInitialCounter( - output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, - counterStart - ) - } - /** - * Decrypt data - * @return Decrypted data - */ - fun decrypt(): UByteArray { - if (bufferCounter > 0) { - output += consumeBlock(buffer, blockCounter) - } - //JS compiler freaks out here if we don't supply exact type - val reversed: List = output.reversed() as List - val folded: UByteArray = reversed.foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> - acc + arrayOfUBytes - } - return folded - } - - private fun appendToBuffer(array: UByteArray, start: Int) { - array.copyInto(destination = buffer, destinationOffset = start, startIndex = 0, endIndex = array.size) - bufferCounter += array.size - } - - private fun consumeBlock(data: UByteArray, blockCount: ModularBigInteger): UByteArray { - val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).toUByteArray().expandCounterTo16Bytes() - return when (mode) { - Mode.ENCRYPT -> { - AesPure.encrypt(aesKey, blockCountAsByteArray) xor data - } - Mode.DECRYPT -> { - AesPure.encrypt(aesKey, blockCountAsByteArray) xor data - } - } - - } - - private fun UByteArray.expandCounterTo16Bytes() : UByteArray { - return if (this.size < 16) { - println("Expanding") - val diff = 16 - this.size - val pad = UByteArray(diff) { 0U } - pad + this - } else { - this - } - } - -} - - -data class EncryptedDataAndInitialCounter(val encryptedData : UByteArray, val initialCounter : UByteArray) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other == null || this::class != other::class) return false - - other as EncryptedDataAndInitializationVector - - if (!encryptedData.contentEquals(other.encryptedData)) return false - if (!initialCounter.contentEquals(other.initilizationVector)) return false - - return true - } - - override fun hashCode(): Int { - var result = encryptedData.contentHashCode() - result = 31 * result + initialCounter.contentHashCode() - return result - } -} \ No newline at end of file diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesPure.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesPure.kt deleted file mode 100644 index 86ea0eb..0000000 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesPure.kt +++ /dev/null @@ -1,378 +0,0 @@ -package com.ionspin.kotlin.crypto.symmetric - -import com.ionspin.kotlin.crypto.util.flattenToUByteArray - -/** - * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 07/Sep/2019 - */ - -internal class AesPure internal constructor(val aesKey: AesKey, val input: UByteArray) { - companion object { - private val debug = false - - private val sBox: UByteArray = - ubyteArrayOf( - // @formatter:off - 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, - 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, - 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, - 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, - 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, - 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, - 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, - 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, - 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, - 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, - 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, - 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, - 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, - 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, - 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, - 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U - // @formatter:on - ) - - private val inverseSBox: UByteArray = - ubyteArrayOf( - // @formatter:off - 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, - 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, - 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, - 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, - 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, - 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, - 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, - 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, - 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, - 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, - 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, - 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, - 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, - 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, - 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, - 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU - // @formatter:on - ) - - val rcon: UByteArray = ubyteArrayOf(0x8DU, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U, 0x1BU, 0x36U) - - fun encrypt(aesKey: AesKey, input: UByteArray): UByteArray { - return AesPure(aesKey, input).encrypt() - } - - fun decrypt(aesKey: AesKey, input: UByteArray): UByteArray { - return AesPure(aesKey, input).decrypt() - } - - } - - val state: Array = (0 until 4).map { outerCounter -> - UByteArray(4) { innerCounter -> input[innerCounter * 4 + outerCounter] } - }.toTypedArray() - - val numberOfRounds = when (aesKey) { - is AesKey.Aes128Key -> 10 - is AesKey.Aes192Key -> 12 - is AesKey.Aes256Key -> 14 - } - - val expandedKey: Array = expandKey() - - - var round = 0 - var completed : Boolean = false - private set - - fun subBytes() { - state.forEachIndexed { indexRow, row -> - row.forEachIndexed { indexColumn, element -> - state[indexRow][indexColumn] = getSBoxValue(element) - } - } - } - - fun getSBoxValue(element: UByte): UByte { - val firstDigit = (element / 16U).toInt() - val secondDigit = (element % 16U).toInt() - return sBox[firstDigit * 16 + secondDigit] - } - - fun inverseSubBytes() { - state.forEachIndexed { indexRow, row -> - row.forEachIndexed { indexColumn, element -> - state[indexRow][indexColumn] = getInverseSBoxValue(element) - } - } - } - - fun getInverseSBoxValue(element: UByte): UByte { - val firstDigit = (element / 16U).toInt() - val secondDigit = (element % 16U).toInt() - return inverseSBox[firstDigit * 16 + secondDigit] - } - - fun shiftRows() { - state[0] = ubyteArrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) - state[1] = ubyteArrayOf(state[1][1], state[1][2], state[1][3], state[1][0]) - state[2] = ubyteArrayOf(state[2][2], state[2][3], state[2][0], state[2][1]) - state[3] = ubyteArrayOf(state[3][3], state[3][0], state[3][1], state[3][2]) - } - - fun inversShiftRows() { - state[0] = ubyteArrayOf(state[0][0], state[0][1], state[0][2], state[0][3]) - state[1] = ubyteArrayOf(state[1][3], state[1][0], state[1][1], state[1][2]) - state[2] = ubyteArrayOf(state[2][2], state[2][3], state[2][0], state[2][1]) - state[3] = ubyteArrayOf(state[3][1], state[3][2], state[3][3], state[3][0]) - } - - fun mixColumns() { - val stateMixed: Array = (0 until 4).map { - UByteArray(4) { 0U } - }.toTypedArray() - for (c in 0..3) { - - stateMixed[0][c] = (2U gfm state[0][c]) xor (3U gfm state[1][c]) xor state[2][c] xor state[3][c] - stateMixed[1][c] = state[0][c] xor (2U gfm state[1][c]) xor (3U gfm state[2][c]) xor state[3][c] - stateMixed[2][c] = state[0][c] xor state[1][c] xor (2U gfm state[2][c]) xor (3U gfm state[3][c]) - stateMixed[3][c] = 3U gfm state[0][c] xor state[1][c] xor state[2][c] xor (2U gfm state[3][c]) - } - stateMixed.copyInto(state) - } - - fun inverseMixColumns() { - val stateMixed: Array = (0 until 4).map { - UByteArray(4) { 0U } - }.toTypedArray() - for (c in 0..3) { - stateMixed[0][c] = - (0x0eU gfm state[0][c]) xor (0x0bU gfm state[1][c]) xor (0x0dU gfm state[2][c]) xor (0x09U gfm state[3][c]) - stateMixed[1][c] = - (0x09U gfm state[0][c]) xor (0x0eU gfm state[1][c]) xor (0x0bU gfm state[2][c]) xor (0x0dU gfm state[3][c]) - stateMixed[2][c] = - (0x0dU gfm state[0][c]) xor (0x09U gfm state[1][c]) xor (0x0eU gfm state[2][c]) xor (0x0bU gfm state[3][c]) - stateMixed[3][c] = - (0x0bU gfm state[0][c]) xor (0x0dU gfm state[1][c]) xor (0x09U gfm state[2][c]) xor (0x0eU gfm state[3][c]) - } - stateMixed.copyInto(state) - } - - fun galoisFieldAdd(first: UByte, second: UByte): UByte { - return first xor second - } - - fun galoisFieldMultiply(first: UByte, second: UByte): UByte { - var result: UInt = 0U - var firstInt = first.toUInt() - var secondInt = second.toUInt() - var carry: UInt = 0U - for (i in 0..7) { - if (secondInt and 0x01U == 1U) { - result = result xor firstInt - } - carry = firstInt and 0x80U - firstInt = firstInt shl 1 - if (carry == 0x80U) { - firstInt = firstInt xor 0x001BU - } - secondInt = secondInt shr 1 - firstInt = firstInt and 0xFFU - } - return result.toUByte() - } - - fun addRoundKey() { - - for (i in 0 until 4) { - state[0][i] = state[0][i] xor expandedKey[round * 4 + i][0] - state[1][i] = state[1][i] xor expandedKey[round * 4 + i][1] - state[2][i] = state[2][i] xor expandedKey[round * 4 + i][2] - state[3][i] = state[3][i] xor expandedKey[round * 4 + i][3] - } - round++ - } - - fun inverseAddRoundKey() { - for (i in 0 until 4) { - state[0][i] = state[0][i] xor expandedKey[round * 4 + i][0] - state[1][i] = state[1][i] xor expandedKey[round * 4 + i][1] - state[2][i] = state[2][i] xor expandedKey[round * 4 + i][2] - state[3][i] = state[3][i] xor expandedKey[round * 4 + i][3] - } - round-- - } - - infix fun UInt.gfm(second: UByte): UByte { - return galoisFieldMultiply(this.toUByte(), second) - } - - fun expandKey(): Array { - val expandedKey = (0 until 4 * (numberOfRounds + 1)).map { - UByteArray(4) { 0U } - }.toTypedArray() - // First round - for (i in 0 until aesKey.numberOf32BitWords) { - expandedKey[i][0] = aesKey.keyArray[i * 4 + 0] - expandedKey[i][1] = aesKey.keyArray[i * 4 + 1] - expandedKey[i][2] = aesKey.keyArray[i * 4 + 2] - expandedKey[i][3] = aesKey.keyArray[i * 4 + 3] - } - - for (i in aesKey.numberOf32BitWords until 4 * (numberOfRounds + 1)) { - val temp = expandedKey[i - 1].copyOf() - if (i % aesKey.numberOf32BitWords == 0) { - //RotWord - val tempTemp = temp[0] - temp[0] = temp[1] - temp[1] = temp[2] - temp[2] = temp[3] - temp[3] = tempTemp - - //SubWord - temp[0] = getSBoxValue(temp[0]) - temp[1] = getSBoxValue(temp[1]) - temp[2] = getSBoxValue(temp[2]) - temp[3] = getSBoxValue(temp[3]) - - temp[0] = temp[0] xor rcon[i / aesKey.numberOf32BitWords] - - } else if (aesKey is AesKey.Aes256Key && i % aesKey.numberOf32BitWords == 4) { - temp[0] = getSBoxValue(temp[0]) - temp[1] = getSBoxValue(temp[1]) - temp[2] = getSBoxValue(temp[2]) - temp[3] = getSBoxValue(temp[3]) - } - expandedKey[i] = expandedKey[i - aesKey.numberOf32BitWords].mapIndexed { index, it -> - it xor temp[index] - }.toUByteArray() - clearArray(temp) - } - return expandedKey - } - - fun encrypt(): UByteArray { - if (completed) { - throw RuntimeException("Encrypt can only be called once per Aes instance, since the state is cleared at the " + - "end of the operation") - } - printState() - addRoundKey() - printState() - for (i in 0 until numberOfRounds - 1) { - subBytes() - printState() - shiftRows() - printState() - mixColumns() - printState() - addRoundKey() - printState() - } - - subBytes() - printState() - shiftRows() - printState() - addRoundKey() - printState() - val transposedMatrix = (0 until 4).map { outerCounter -> - UByteArray(4) { 0U } - } - for (i in 0 until 4) { - for (j in 0 until 4) { - transposedMatrix[i][j] = state[j][i] - } - } - state.forEach { clearArray(it) } - completed = true - return transposedMatrix.flattenToUByteArray() - } - - fun decrypt(): UByteArray { - if (completed) { - throw RuntimeException("Decrypt can only be called once per Aes instance, since the state is cleared at the " + - "end of the operation") - } - round = numberOfRounds - printState() - inverseAddRoundKey() - printState() - for (i in 0 until numberOfRounds - 1) { - inversShiftRows() - printState() - inverseSubBytes() - printState() - inverseAddRoundKey() - printState() - inverseMixColumns() - printState() - } - - inversShiftRows() - printState() - inverseSubBytes() - printState() - inverseAddRoundKey() - printState() - - val transposedMatrix = (0 until 4).map { outerCounter -> - UByteArray(4) { 0U } - } - for (i in 0 until 4) { - for (j in 0 until 4) { - transposedMatrix[i][j] = state[j][i] - } - } - state.forEach { clearArray(it) } - completed = true - return transposedMatrix.flattenToUByteArray() - } - - private fun clearArray(array : UByteArray) { - array.indices.forEach { array[it] = 0U } - } - - - - private fun printState() { - if (!debug) { - return - } - println() - state.forEach { - println(it.joinToString(separator = " ") { it.toString(16) }) - } - } - - private fun printState(specific : List) { - if (!debug) { - return - } - println() - specific.forEach { - println(it.joinToString(separator = " ") { it.toString(16) }) - } - } - - -} - -sealed class AesKey(val key: String, val keyLength: Int) { - val keyArray: UByteArray = key.chunked(2).map { it.toUByte(16) }.toUByteArray() - val numberOf32BitWords = keyLength / 32 - - class Aes128Key(key: String) : AesKey(key, 128) - class Aes192Key(key: String) : AesKey(key, 192) - class Aes256Key(key: String) : AesKey(key, 256) - - init { - checkKeyLength(key, keyLength) - } - - fun checkKeyLength(key: String, expectedLength: Int) { - if ((key.length / 2) != expectedLength / 8) { - throw RuntimeException("Invalid key length") - } - } -} - - 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 28e9232..6b8eb10 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 @@ -23,25 +23,7 @@ package com.ionspin.kotlin.crypto.util * ugljesa.jovanovic@ionspin.com * on 15-Jul-2019 */ -fun Array.hexColumsPrint() { - val printout = this.map { it.toString(16) }.chunked(16) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} -fun Array.hexColumsPrint(chunk : Int = 16) { - val printout = this.map { it.toString(16).padStart(2, '0') }.chunked(chunk) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} - -fun UByteArray.hexColumsPrint(chunk : Int = 16) { - val printout = this.map { it.toString(16).padStart(2, '0') }.chunked(chunk) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} - -fun Array.hexColumsPrint(chunk: Int = 3) { - val printout = this.map { it.toString(16) }.chunked(chunk) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} inline fun Array.chunked(sliceSize: Int): Array> { val last = this.size % sliceSize @@ -89,36 +71,8 @@ infix fun UByteArray.xor(other : UByteArray) : UByteArray { } -fun String.hexStringToTypedUByteArray() : Array { - return this.chunked(2).map { it.toUByte(16) }.toTypedArray() -} -fun String.hexStringToUByteArray() : UByteArray { - return this.chunked(2).map { it.toUByte(16) }.toUByteArray() -} - - -fun Array.toHexString() : String { - return this.joinToString(separator = "") { - if (it <= 0x0FU) { - "0${it.toString(16)}" - } else { - it.toString(16) - } - } -} - - -fun UByteArray.toHexString() : String { - return this.joinToString(separator = "") { - if (it <= 0x0FU) { - "0${it.toString(16)}" - } else { - it.toString(16) - } - } -} // UInt / Array utils diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/DebugTest.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/DebugTest.kt new file mode 100644 index 0000000..07bd5fd --- /dev/null +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/DebugTest.kt @@ -0,0 +1,13 @@ +package com.ionspin.kotlin.crypto + +import kotlin.test.Test + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jul-2020 + */ +class DebugTest { + + +} diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SRNGTest.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SRNGTest.kt index 187264b..0e2235f 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SRNGTest.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SRNGTest.kt @@ -28,10 +28,10 @@ import kotlin.test.assertTrue class SRNGTest { @Test fun testSrng() = testBlocking { - Crypto.initialize() + CryptoInitializerDelegated.initialize() //Just a sanity test, need to add better srng tests. val randomBytes1 = SRNG.getRandomBytes(10) val randomBytes2 = SRNG.getRandomBytes(10) assertTrue { !randomBytes1.contentEquals(randomBytes2) } } -} \ 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 new file mode 100644 index 0000000..f553169 --- /dev/null +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt @@ -0,0 +1,238 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.ionspin.kotlin.crypto.CryptoInitializerDelegated +import com.ionspin.kotlin.crypto.Initializer +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexColumsPrint +import com.ionspin.kotlin.crypto.util.testBlocking +import kotlin.test.Ignore +import kotlin.test.Test +import kotlin.test.assertFails +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +class XChaCha20Poly1305Test { + + + @Test + fun xChaCha20Poly1305() = testBlocking { + CryptoInitializerDelegated.initialize() + + assertTrue { + 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( + 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 + ) + val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, additionalData) + encrypted.hexColumsPrint() + val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData) + println("Decrypted") + decrypted.hexColumsPrint() + println("----------") + encrypted.contentEquals(expected) && decrypted.contentEquals(message) + } + + assertTrue { + val message = ubyteArrayOf( + 0x00U + ) + val additionalData = ubyteArrayOf( + 0x00U + ) + val key = ubyteArrayOf( + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + ) + + val nonce = ubyteArrayOf( + 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0aU, 0x0bU, + 0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, 0x12U, 0x13U, 0x14U, 0x15U, 0x16U, 0x17U, + ) + + val expected = ubyteArrayOf( + 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) + + encrypted.contentEquals(expected) && decrypted.contentEquals(message) + } + + + } + + @Ignore() //"Will fail because nonce is not a parameter any more" + @Test + fun updateableXChaCha20Poly1305() { + assertTrue { + 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( + 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 + ) +// val xChaChaPoly = XChaCha20Poly1305Delegated(key, additionalData) +// val firstChunk = xChaChaPoly.encrypt(message) +// val finalChunk = xChaChaPoly.finishEncryption().first +// val result = firstChunk + finalChunk + +// result.contentEquals(expected) + 1 == 1 + } + + assertTrue { + val message = ubyteArrayOf( + 0x00U + ) + val additionalData = ubyteArrayOf( + 0x00U + ) + val key = ubyteArrayOf( + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + ) + + val nonce = ubyteArrayOf( + 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0aU, 0x0bU, + 0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, 0x12U, 0x13U, 0x14U, 0x15U, 0x16U, 0x17U, + ) + + val expected = ubyteArrayOf( + 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, + 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU + ) +// val xChaChaPoly = XChaCha20Poly1305Delegated(key, additionalData) +// val firstChunk = xChaChaPoly.encrypt(message) +// val finalChunk = xChaChaPoly.finishEncryption().first +// val result = firstChunk + finalChunk +// result.contentEquals(expected) + 1 == 1 + } + + + } + + @Test + fun testStreamingImpl() = testBlocking { + Initializer.initialize() + val key = UByteArray(32) { 0U } + val state = ubyteArrayOf( + 0x2DU, 0xDBU, 0xC7U, 0xB2U, 0x03U, 0xBCU, 0xC3U, 0x22U, 0xBDU, 0x0CU, 0xBAU, 0x82U, 0xADU, 0x77U, 0x79U, 0x44U, + 0xE6U, 0x8FU, 0xA9U, 0x94U, 0x89U, 0xB1U, 0xDFU, 0xBEU, 0x00U, 0x9FU, 0x69U, 0xECU, 0x21U, 0x88U, 0x47U, 0x55U, + 0x01U, 0x00U, 0x00U, 0x00U, 0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, + ) + val header = ubyteArrayOf( + 0x49U, 0x62U, 0x22U, 0x03U, 0xB7U, 0x46U, 0x11U, 0x97U, 0x8FU, 0x46U, 0x4AU, 0x3BU, 0x2FU, 0x2AU, 0x81U, 0x03U, + 0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU, + ) + val expected = ubyteArrayOf( + 0xAFU, 0xD3U, 0x2DU, 0x59U, 0xB8U, 0xC4U, 0x66U, 0x2EU, 0x47U, 0x29U, 0xC6U, 0xF9U, 0x93U, 0x4BU, 0x09U, 0x27U, + 0x24U, 0xDDU, 0xF3U, 0x05U, 0x48U, 0x94U, 0x67U, 0x10U, 0x00U, 0x21U, 0x85U, 0x22U, 0x96U, 0x3CU, 0xCEU, 0x8EU, + 0xB7U, 0x53U, 0x9DU, 0x46U, 0xF5U, 0x3CU, 0x5EU, 0x48U, 0x9BU, 0x8CU, 0x13U, 0xB7U, 0x28U, 0x6BU, 0xB3U, 0x6CU, + 0x3AU, 0x04U, 0xB7U, 0x25U, 0xB9U, 0x50U, 0x45U, 0x08U, 0x0BU, 0x89U, 0xA2U, 0x0FU, 0x70U, 0xCCU, 0x60U, 0x1BU, + 0xC3U, 0x17U, 0x35U, 0x9FU, 0xAEU, 0x82U, 0x51U, 0x43U, 0x1BU, 0x9DU, 0x53U, 0x9EU, 0xE2U, 0xAFU, 0x20U, 0x1FU, + 0xFDU, 0x03U, 0x59U, 0x11U, 0x51U, 0x9EU, 0xACU, 0x83U, 0xCDU, 0x78U, 0xD1U, 0xD0U, 0xE5U, 0xD7U, 0x0EU, 0x41U, + 0xDEU, 0xFBU, 0x5CU, 0x7FU, 0x1CU, 0x26U, 0x32U, 0x2CU, 0x51U, 0xF6U, 0xEFU, 0xC6U, 0x34U, 0xC4U, 0xACU, 0x6CU, + 0xE8U, 0xF9U, 0x4BU, 0xABU, 0xA3U, + ) + val encryptor = XChaCha20Poly1305Delegated(key, state, header, false) + val decryptor = XChaCha20Poly1305Delegated(key, state, header, true) + val data = UByteArray(100) { 0U } + val result = encryptor.encrypt(data) + val decrypted = decryptor.decrypt(result) + println("Encrypted -----------") + result.hexColumsPrint() + println("Encrypted end -----------") + println("Decrypted -----------") + decrypted.hexColumsPrint() + println("Decrypted end -----------") + assertTrue { + expected.contentEquals(result) && decrypted.contentEquals(data) + } + val messedUpTag = result.copyOf() + messedUpTag[messedUpTag.size - 2] = 0U + assertFails { + val decryptorForWrongTag = XChaCha20Poly1305Delegated(key, state, header, true) + val plaintext = decryptorForWrongTag.decrypt(messedUpTag) + println("Decrypted with wrong tag -----------") + plaintext.hexColumsPrint() + println("Decrypted with wrong tag end -----------") + } + } +} diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bTest.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bTest.kt index 6f98052..1fea8a7 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bTest.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bTest.kt @@ -1,6 +1,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.crypto.Crypto +import com.ionspin.kotlin.crypto.CryptoPrimitives import com.ionspin.kotlin.crypto.Initializer import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking @@ -23,7 +24,7 @@ class Blake2bTest { Initializer.initialize() val expected = "a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a483aa9bc33b582f77d30a65e6f29a89" + "6c0411f38312e1d66e0bf16386c86a89bea572" - val result = Crypto.Blake2b.stateless("test".encodeToUByteArray()).toHexString() + val result = CryptoPrimitives.Blake2b.stateless("test".encodeToUByteArray()).toHexString() // println("Result: $result") assertTrue { result == expected } } @@ -35,11 +36,11 @@ class Blake2bTest { Initializer.initialize() val expected = "a71079d42853dea26e453004338670a53814b78137ffbed07603a41d76a483aa9bc33b582f77d30a65e6f29a89" + "6c0411f38312e1d66e0bf16386c86a89bea572" - val blake2b = Crypto.Blake2b.updateable() + val blake2b = CryptoPrimitives.Blake2b.updateable() blake2b.update("t".encodeToUByteArray()) blake2b.update(("est".encodeToUByteArray())) val result = blake2b.digest().toHexString() // println("Result: $result") assertTrue { result == expected } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt index 4a73910..2068b0f 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt @@ -1,6 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha import com.ionspin.kotlin.crypto.Crypto +import com.ionspin.kotlin.crypto.CryptoPrimitives import com.ionspin.kotlin.crypto.Initializer import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking @@ -21,9 +22,10 @@ class Sha256Test { } @Test - fun statelessSimpleTest() { + fun statelessSimpleTest() = testBlocking { + Initializer.initialize() val expected = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" - val result = Crypto.Sha256.stateless("test".encodeToUByteArray()).toHexString() + val result = CryptoPrimitives.Sha256.stateless("test".encodeToUByteArray()).toHexString() // println("Result: $result") assertTrue { result == expected } } @@ -31,13 +33,14 @@ class Sha256Test { //This is a bad test since it's not larger than one block //but for now I'm testing that the platform library is being correctly called @Test - fun updateableSimpleTest() { + fun updateableSimpleTest() = testBlocking { + Initializer.initialize() val expected = "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08" - val sha256 = Crypto.Sha256.updateable() + val sha256 = CryptoPrimitives.Sha256.updateable() sha256.update("t".encodeToUByteArray()) sha256.update(("est".encodeToUByteArray())) val result = sha256.digest().toHexString() // println("Result: $result") assertTrue { result == expected } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt index 88ea916..44a0375 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt @@ -1,6 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha import com.ionspin.kotlin.crypto.Crypto +import com.ionspin.kotlin.crypto.CryptoPrimitives import com.ionspin.kotlin.crypto.Initializer import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking @@ -21,10 +22,11 @@ class Sha512Test { } @Test - fun statelessSimpleTest() { + fun statelessSimpleTest() = testBlocking { + Initializer.initialize() val expected = "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67" + "b143732c304cc5fa9ad8e6f57f50028a8ff" - val result = Crypto.Sha512.stateless("test".encodeToUByteArray()).toHexString() + val result = CryptoPrimitives.Sha512.stateless("test".encodeToUByteArray()).toHexString() // println("Result: $result") assertTrue { result == expected } } @@ -32,14 +34,15 @@ class Sha512Test { //This is a bad test since it's not larger than one block //but for now I'm testing that the platform library is being correctly called @Test - fun updateableSimpleTest() { + fun updateableSimpleTest() = testBlocking { + Initializer.initialize() val expected = "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67" + "b143732c304cc5fa9ad8e6f57f50028a8ff" - val sha512 = Crypto.Sha512.updateable() + val sha512 = CryptoPrimitives.Sha512.updateable() sha512.update("t".encodeToUByteArray()) sha512.update(("est".encodeToUByteArray())) val result = sha512.digest().toHexString() // println("Result: $result") assertTrue { result == expected } } -} \ No newline at end of file +} 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 new file mode 100644 index 0000000..c85fad2 --- /dev/null +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt @@ -0,0 +1,50 @@ +package com.ionspin.kotlin.crypto.highlevel + +import com.ionspin.kotlin.crypto.Crypto +import com.ionspin.kotlin.crypto.Initializer +import com.ionspin.kotlin.crypto.SymmetricKey +import com.ionspin.kotlin.crypto.hash.decodeToString +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexColumsPrint +import com.ionspin.kotlin.crypto.util.testBlocking +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 09-Jul-2020 + */ +class EncryptionTest { + @Test + fun testMultipartEncryption() = testBlocking { + Initializer.initialize() + val plaintext = ("pUoR4JVXJUeMKNkt6ZGGzEdTo33ajNGXwXpivBKA0XKs8toGRYI9Eul4bELRDkaQDNhd4vZseEFU" + + "ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" + + "EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray() + val additionalData = "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 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 plaintext2 = decryptor.decryptPartialData(ciphertext2) + val plaintext3 = decryptor.decryptPartialData(ciphertext3) + + val combinedPlaintext = plaintext1.data + plaintext2.data + plaintext3.data + assertTrue { + plaintext.contentEquals(combinedPlaintext) + } + encryptor.cleanup() + decryptor.cleanup() + + + + + } +} diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt index ab0598d..7d938dd 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt @@ -16,11 +16,22 @@ package com.ionspin.kotlin.crypto.util -import kotlinx.coroutines.CoroutineScope +import kotlin.coroutines.Continuation +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.coroutines.startCoroutine + /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 20-Jul-2019 */ -expect fun testBlocking(block : suspend () -> Unit) \ No newline at end of file +fun testBlocking(block : suspend () -> Unit) { + val continuation = Continuation(EmptyCoroutineContext) { + //Do nothing + if (it.isFailure) { + throw it.exceptionOrNull()!! + } + } + block.startCoroutine(continuation) +} 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 9233b77..1934eb9 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 @@ -39,5 +39,22 @@ 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 + //encrypt + fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: 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 + + //util + fun memzero(array: Uint8Array) + + } diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumLoader.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumLoader.kt index 47b3867..b445487 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumLoader.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumLoader.kt @@ -53,4 +53,4 @@ object JsSodiumLoader { doneCallback.invoke() } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt new file mode 100644 index 0000000..1c001d2 --- /dev/null +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt @@ -0,0 +1,27 @@ +package ext.libsodium.com.ionspin.kotlin.crypto + +import org.khronos.webgl.Uint8Array +import org.khronos.webgl.get +import org.khronos.webgl.set + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 25-Jun-2020 + * + * TODO investigate using unsafe cast + */ +fun UByteArray.toUInt8Array() : Uint8Array { + val uint8Result = Uint8Array(toByteArray().toTypedArray()) + return uint8Result +} + + +fun Uint8Array.toUByteArray() : UByteArray { + val result = UByteArray(length) + for (i in 0 until length) { + result[i] = get(i).toUByte() + } + + return result +} 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 new file mode 100644 index 0000000..2ab0433 --- /dev/null +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -0,0 +1,130 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.ionspin.kotlin.crypto.InvalidTagException +import com.ionspin.kotlin.crypto.getSodium +import com.ionspin.kotlin.crypto.util.hexColumsPrint +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 25-Jun-2020 + */ + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +actual class XChaCha20Poly1305Delegated internal actual constructor() { + actual companion object { + actual fun encrypt( + key: UByteArray, + nonce: UByteArray, + message: UByteArray, + additionalData: UByteArray + ): UByteArray { + val encrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt( + message.toUInt8Array(), + additionalData.toUInt8Array(), + Uint8Array(0), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return encrypted.toUByteArray() + } + + actual fun decrypt( + key: UByteArray, + nonce: UByteArray, + ciphertext: UByteArray, + additionalData: UByteArray + ): UByteArray { + val decrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt( + Uint8Array(0), + ciphertext.toUInt8Array(), + additionalData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return decrypted.toUByteArray() + } + } + + var state : dynamic = null + var isInitialized = false + var isEncryptor = false + + actual fun initializeForEncryption(key: UByteArray) : UByteArray { + println("Initializaing for encryption") + val stateAndHeader = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) + state = stateAndHeader.state + val header = stateAndHeader.header as Uint8Array + console.log(state) + console.log(header) + println("Done initializaing for encryption") + isInitialized = true + isEncryptor = true + return header.toUByteArray() + } + + actual fun initializeForDecryption(key: UByteArray, header: UByteArray) { + println("Initializing for decryption") + header.hexColumsPrint() + state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), key.toUInt8Array()) + console.log(state) + isInitialized = true + isEncryptor = false + } + + internal actual constructor( + key: UByteArray, + testState: UByteArray, + testHeader: UByteArray, + isDecryptor: Boolean + ) : this() { + state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(testHeader.toUInt8Array(), key.toUInt8Array()) + console.log(state) + println("Done initializaing test state") + isInitialized = true + isEncryptor = !isDecryptor + } + + actual fun encrypt(data: UByteArray, additionalData: 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) + return encrypted.toUByteArray() + } + + actual fun decrypt(data: UByteArray, additionalData: 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 decrypted = decryptedWithTag.message as Uint8Array + val validTag = decryptedWithTag.tag + + if (validTag != 0U) { + println("Tag validation failed") + throw InvalidTagException() + } + return decrypted.toUByteArray() + } + + actual fun cleanup() { + //TODO JS cleanup + } + + + +} diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index 25eb586..fa53403 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -1,8 +1,6 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.crypto.getSodium -import com.ionspin.kotlin.crypto.hash.sha.Sha256StatelessDelegated -import com.ionspin.kotlin.crypto.util.toHexString import org.khronos.webgl.Uint8Array import org.khronos.webgl.get @@ -13,7 +11,7 @@ import org.khronos.webgl.get */ -actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2b { +actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart { override val MAX_HASH_BYTES: Int = 64 @@ -43,7 +41,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLengt -actual object Blake2bDelegatedStateless : Blake2bStateless { +actual object Blake2bDelegatedStateless : Blake2b { override val MAX_HASH_BYTES: Int = 64 override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { @@ -59,4 +57,4 @@ actual object Blake2bDelegatedStateless : Blake2bStateless { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index 4d68c4d..552932b 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -1,6 +1,5 @@ package com.ionspin.kotlin.crypto.hash.sha -import com.ionspin.kotlin.crypto.getSodium import com.ionspin.kotlin.crypto.getSodium import org.khronos.webgl.Uint8Array @@ -13,7 +12,7 @@ import org.khronos.webgl.get */ -actual class Sha512Delegated : Sha512 { +actual class Sha512Delegated : Sha512Multipart { val state : dynamic init { @@ -35,7 +34,7 @@ actual class Sha512Delegated : Sha512 { } -actual object Sha512StatelessDelegated : StatelessSha512 { +actual object Sha512StatelessDelegated : Sha512 { override fun digest(inputMessage: UByteArray): UByteArray { val hashed = getSodium().crypto_hash_sha512(Uint8Array(inputMessage.toByteArray().toTypedArray())) @@ -45,4 +44,4 @@ actual object Sha512StatelessDelegated : StatelessSha512 { } return hash } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jsTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt b/multiplatform-crypto-delegated/src/jsTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt index 2df4151..a366756 100644 --- a/multiplatform-crypto-delegated/src/jsTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt +++ b/multiplatform-crypto-delegated/src/jsTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt @@ -15,14 +15,14 @@ */ package com.ionspin.kotlin.crypto.util - -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.promise - - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 20-Jul-2019 - */ -actual fun testBlocking(block: suspend ()-> Unit) : dynamic = GlobalScope.promise { block() } \ No newline at end of file +// +//import kotlinx.coroutines.GlobalScope +//import kotlinx.coroutines.promise +// +// +///** +// * Created by Ugljesa Jovanovic +// * ugljesa.jovanovic@ionspin.com +// * on 20-Jul-2019 +// */ +//actual fun testBlocking(block: suspend ()-> Unit) : dynamic = GlobalScope.promise { block() } diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt index d136901..3d50e6f 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt @@ -29,6 +29,6 @@ actual object SRNG { actual fun getRandomBytes(amount: Int): UByteArray { val byteArray = ByteArray(amount) secureRandom.nextBytes(byteArray) - return byteArray.toUByteArray() + return byteArray.asUByteArray() } -} \ No newline at end of file +} 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 new file mode 100644 index 0000000..4edc35b --- /dev/null +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -0,0 +1,142 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.goterl.lazycode.lazysodium.SodiumJava +import com.goterl.lazycode.lazysodium.interfaces.SecretStream +import com.ionspin.kotlin.crypto.InvalidTagException +import com.ionspin.kotlin.crypto.util.hexColumsPrint + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +actual class XChaCha20Poly1305Delegated internal actual constructor() { + actual companion object { + actual fun encrypt( + key: UByteArray, + nonce: UByteArray, + message: UByteArray, + additionalData: UByteArray + ): UByteArray { + val ciphertext = ByteArray(message.size + 16) + SodiumJava().crypto_aead_xchacha20poly1305_ietf_encrypt( + ciphertext, + longArrayOf(ciphertext.size.toLong()), + message.toByteArray(), + message.size.toLong(), + additionalData.toByteArray(), + additionalData.size.toLong(), + null, + nonce.toByteArray(), + key.toByteArray() + + ) + return ciphertext.asUByteArray() + } + + actual fun decrypt( + key: UByteArray, + nonce: UByteArray, + ciphertext: UByteArray, + additionalData: UByteArray + ): UByteArray { + val message = ByteArray(ciphertext.size - 16) + SodiumJava().crypto_aead_xchacha20poly1305_ietf_decrypt( + message, + longArrayOf(ciphertext.size.toLong()), + null, + ciphertext.toByteArray(), + ciphertext.size.toLong(), + additionalData.toByteArray(), + additionalData.size.toLong(), + nonce.toByteArray(), + key.toByteArray() + + ) + return message.asUByteArray() + } + } + + val state : SecretStream.State = SecretStream.State() + val sodium = SodiumJava() + + var isInitialized = false + var isEncryptor = false + + internal actual constructor( + key: UByteArray, + testState: UByteArray, + testHeader: UByteArray, + isDecryptor: Boolean + ) : this() { + state.k = testState.sliceArray(0 until 32).toByteArray() + state.nonce = testState.sliceArray(32 until 44).toByteArray() + isInitialized = true + isEncryptor = !isDecryptor + } + + actual fun initializeForEncryption(key: UByteArray) : UByteArray { + val header = UByteArray(24) + sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) + isInitialized = true + isEncryptor = true + return header + } + + actual fun initializeForDecryption(key: UByteArray, header: UByteArray) { + sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray()) + isInitialized = true + isEncryptor = false + } + + actual fun encrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + if (!isInitialized) { + throw RuntimeException("Not initalized!") + } + if (!isEncryptor) { + throw RuntimeException("Initialized as decryptor, attempted to use as encryptor") + } + val ciphertext = ByteArray(1 + data.size + 16) + sodium.crypto_secretstream_xchacha20poly1305_push( + state, ciphertext, null, + data.asByteArray(), data.size.toLong(), + additionalData.asByteArray(), additionalData.size.toLong(), + 0 + ) + return ciphertext.asUByteArray() + } + + actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + if (!isInitialized) { + throw RuntimeException("Not initalized!") + } + if (isEncryptor) { + throw RuntimeException("Initialized as encryptor, attempted to use as decryptor") + } + val plaintext = ByteArray(data.size - 17) + + val validTag = sodium.crypto_secretstream_xchacha20poly1305_pull( + state, plaintext, null, + null, + data.asByteArray(), + (data.size).toLong(), + additionalData.asByteArray(), + additionalData.size.toLong() + ) + if (validTag != 0) { + println("Tag validation failed") + throw InvalidTagException() + } + return plaintext.asUByteArray() + + } + + actual fun cleanup() { + sodium.sodium_memzero(state.k, 32) + sodium.sodium_memzero(state.nonce, 12) + } + + + + +} diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index 7ab8196..bc46c5b 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -8,7 +8,7 @@ import com.ionspin.kotlin.crypto.Initializer.sodium */ -actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2b { +actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLength: Int) : Blake2bMultipart { val state = ByteArray(sodium.crypto_generichash_statebytes()) @@ -23,18 +23,18 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, val hashLengt override fun digest(): UByteArray { val hashed = ByteArray(hashLength) sodium.crypto_generichash_final(state, hashed, hashLength) - return hashed.toUByteArray() + return hashed.asUByteArray() } } -actual object Blake2bDelegatedStateless : Blake2bStateless { +actual object Blake2bDelegatedStateless : Blake2b { override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { val hashed = ByteArray(hashLength) sodium.crypto_generichash(hashed, hashed.size, inputMessage.toByteArray(), inputMessage.size.toLong(), key.toByteArray(), key.size) - return hashed.toUByteArray() + return hashed.asUByteArray() } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt index 8849dbd..ff8faa9 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt @@ -26,7 +26,7 @@ actual class Sha256Delegated actual constructor() : Sha256 { override fun digest(): UByteArray { val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES) sodium.crypto_hash_sha256_final(state, hashed) - return hashed.toUByteArray() + return hashed.asUByteArray() } } @@ -36,6 +36,6 @@ actual object Sha256StatelessDelegated : StatelessSha256 { override fun digest(inputMessage: UByteArray): UByteArray { val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES) sodium.crypto_hash_sha256(hashed, inputMessage.toByteArray(), inputMessage.size.toLong()) - return hashed.toUByteArray() + return hashed.asUByteArray() } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index ca00e48..adbb1b4 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -10,7 +10,7 @@ import com.ionspin.kotlin.crypto.Initializer */ -actual class Sha512Delegated : Sha512 { +actual class Sha512Delegated : Sha512Multipart { val state = Hash.State512() @@ -25,16 +25,16 @@ actual class Sha512Delegated : Sha512 { override fun digest(): UByteArray { val hashed = ByteArray(Sha512Properties.MAX_HASH_BYTES) Initializer.sodium.crypto_hash_sha512_final(state, hashed) - return hashed.toUByteArray() + return hashed.asUByteArray() } } -actual object Sha512StatelessDelegated : StatelessSha512 { +actual object Sha512StatelessDelegated : Sha512 { override fun digest(inputMessage: UByteArray): UByteArray { val hashed = ByteArray(Sha512Properties.MAX_HASH_BYTES) Initializer.sodium.crypto_hash_sha512(hashed, inputMessage.toByteArray(), inputMessage.size.toLong()) - return hashed.toUByteArray() + return hashed.asUByteArray() } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-delegated/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt b/multiplatform-crypto-delegated/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt index 8fb509a..5c561f7 100644 --- a/multiplatform-crypto-delegated/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt +++ b/multiplatform-crypto-delegated/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt @@ -16,12 +16,19 @@ package com.ionspin.kotlin.crypto.util -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.runBlocking +import kotlin.coroutines.Continuation +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.coroutines.startCoroutine /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 20-Jul-2019 */ -actual fun testBlocking(block: suspend () -> Unit) = runBlocking { block() } \ No newline at end of file +//actual fun testBlocking(block: suspend () -> Unit) { +// val continuation = Continuation(EmptyCoroutineContext) { +// println("Done") +// } +// block.startCoroutine(continuation) +// +//} diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt index 7541afa..944c199 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt @@ -1,9 +1,7 @@ +@file:Suppress("VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL") + package com.ionspin.kotlin.crypto -import kotlinx.atomicfu.AtomicBoolean -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch import libsodium.sodium_init import kotlin.native.concurrent.AtomicInt @@ -29,4 +27,4 @@ actual object Initializer { actual fun isInitialized(): Boolean { return isPlatformInitialized.value != 0 } -} \ No newline at end of file +} 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 new file mode 100644 index 0000000..0d60110 --- /dev/null +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -0,0 +1,163 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.InvalidTagException +import kotlinx.cinterop.* +import libsodium.* + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +actual class XChaCha20Poly1305Delegated internal actual constructor() { + actual companion object { + actual fun encrypt( + key: UByteArray, + nonce: UByteArray, + message: UByteArray, + additionalData: 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), + ulongArrayOf(ciphertextLength.convert()).toCValues(), + message.toCValues(), + message.size.convert(), + additionalData.toCValues(), + additionalData.size.convert(), + null, + nonce.toCValues(), + key.toCValues() + ) + ciphertextPinned.unpin() + return ciphertext + } + + actual fun decrypt( + key: UByteArray, + nonce: UByteArray, + ciphertext: UByteArray, + additionalData: 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), + ulongArrayOf(messageLength.convert()).toCValues(), + null, + ciphertext.toCValues(), + ciphertext.size.convert(), + additionalData.toCValues(), + additionalData.size.convert(), + nonce.toCValues(), + key.toCValues() + ) + messagePinned.unpin() + return message + } + } + + var state = + sodium_malloc(crypto_secretstream_xchacha20poly1305_state.size.convert())!! + .reinterpret() + .pointed + val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } + + var isInitialized = false + var isEncryptor = false + + actual internal constructor( + key: UByteArray, + testState: UByteArray, + testHeader: UByteArray, + isDecryptor: Boolean + ) : this() { + val pointer = state.ptr.reinterpret() + for (i in 0 until crypto_secretstream_xchacha20poly1305_state.size.toInt()) { + pointer[i] = testState[i] + } + println("state after setting-----------") + state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).asUByteArray().hexColumsPrint() + println("state after setting-----------") + println("header after setting-----------") + testHeader.copyInto(header) + header.hexColumsPrint() + println("header after setting-----------") + isInitialized = true + isEncryptor = !isDecryptor + } + + + + actual fun initializeForEncryption(key: UByteArray) : UByteArray { + val pinnedHeader = header.pin() + crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues()) + println("state-----------") + state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).asUByteArray().hexColumsPrint() + println("state-----------") + println("--------header-----------") + header.hexColumsPrint() + println("--------header-----------") + pinnedHeader.unpin() + return header + } + + actual fun initializeForDecryption(key: UByteArray, header: UByteArray) { + crypto_secretstream_xchacha20poly1305_init_pull(state.ptr, header.toCValues(), key.toCValues()) + } + + + actual fun encrypt(data: UByteArray, additionalData: 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), + null, + data.toCValues(), + data.size.convert(), + additionalData.toCValues(), + additionalData.size.convert(), + 0U, + ) + println("Encrypt partial") + ciphertextWithTag.hexColumsPrint() + println("Encrypt partial end") + ciphertextWithTagPinned.unpin() + return ciphertextWithTag + } + + actual fun decrypt(data: UByteArray, additionalData: 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), + null, + null, + data.toCValues(), + data.size.convert(), + additionalData.toCValues(), + additionalData.size.convert() + ) + plaintextPinned.unpin() + println("tag: $validTag") + if (validTag != 0) { + println("Tag validation failed") + throw InvalidTagException() + } + return plaintext + } + + actual fun cleanup() { + sodium_free(state.ptr) + } + + + + +} 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 7b49789..a72383b 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 @@ -11,7 +11,7 @@ import platform.posix.malloc */ -actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: Int) : Blake2b { +actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: Int) : Blake2bMultipart { override val MAX_HASH_BYTES: Int = 64 val requestedHashLength : Int @@ -20,7 +20,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I requestedHashLength = hashLength val allocated = malloc(crypto_generichash_state.size.convert())!! state = allocated.reinterpret().pointed - crypto_generichash_init(state.ptr, key?.run { this.toUByteArray().toCValues() }, key?.size?.convert() ?: 0UL.convert(), hashLength.convert()) + crypto_generichash_init(state.ptr, key?.run { this.toCValues() }, key?.size?.convert() ?: 0UL.convert(), hashLength.convert()) } override fun update(data: UByteArray) { @@ -38,7 +38,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I } @Suppress("EXPERIMENTAL_API_USAGE", "EXPERIMENTAL_UNSIGNED_LITERALS") -actual object Blake2bDelegatedStateless : Blake2bStateless { +actual object Blake2bDelegatedStateless : Blake2b { override fun digest(inputMessage: UByteArray, key: UByteArray, hashLength: Int): UByteArray { val hashResult = UByteArray(MAX_HASH_BYTES) @@ -57,4 +57,4 @@ actual object Blake2bDelegatedStateless : Blake2bStateless { } -} \ No newline at end of file +} 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 b7d31a1..0663629 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 @@ -18,7 +18,7 @@ actual class Sha256Delegated : Sha256 { val state : crypto_hash_sha256_state init { - val allocated = malloc(crypto_hash_sha256_state.size.convert())!! + val allocated = sodium_malloc(crypto_hash_sha256_state.size.convert())!! state = allocated.reinterpret().pointed crypto_hash_sha256_init(state.ptr) } @@ -33,7 +33,7 @@ actual class Sha256Delegated : Sha256 { val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0)) - free(state.ptr) + sodium_free(state.ptr) return hashResult } @@ -51,4 +51,4 @@ actual object Sha256StatelessDelegated : StatelessSha256 { return hashResult } -} \ No newline at end of file +} 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 7e5991e..f4b80a6 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 @@ -12,7 +12,7 @@ import platform.posix.malloc */ -actual class Sha512Delegated : Sha512 { +actual class Sha512Delegated : Sha512Multipart { val state : crypto_hash_sha512_state init { @@ -37,7 +37,7 @@ actual class Sha512Delegated : Sha512 { } -actual object Sha512StatelessDelegated : StatelessSha512 { +actual object Sha512StatelessDelegated : Sha512 { override fun digest(inputMessage: UByteArray): UByteArray { val hashResult = UByteArray(Sha512StatelessDelegated.MAX_HASH_BYTES) @@ -46,4 +46,4 @@ actual object Sha512StatelessDelegated : StatelessSha512 { hashResultPinned.unpin() return hashResult } -} \ No newline at end of file +} 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 new file mode 100644 index 0000000..fd6827e --- /dev/null +++ b/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt @@ -0,0 +1,76 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlinx.cinterop.* +import libsodium.* +import platform.posix.free +import platform.posix.malloc +import kotlin.test.Ignore +import kotlin.test.Test + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 13-Jul-2020 + */ +class HelperTest { + @Ignore //Just used for debugging pure implementation + @Test + fun longSha256() { + for (target in 0L until 10L) { + generateForRounds256(target) + } + for (target in 0L until 16_777_216L step 1_000_000L) { + generateForRounds256(target) + } + generateForRounds256(16_777_216L) + } + + fun generateForRounds256(target: Long) { + val updateValue = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno".encodeToUByteArray().toCValues() + val state = malloc(crypto_hash_sha256_state.size.convert())!! + .reinterpret() + + crypto_hash_sha256_init(state) + for (i in 0 until target) { + crypto_hash_sha256_update(state, updateValue, updateValue.size.convert()) + } + val result = UByteArray(32) + val resultPinned = result.pin() + crypto_hash_sha256_final(state, resultPinned.addressOf(0)) + println("$target to \"${result.toHexString()}\",") + free(state) + } + @Ignore //Just used for debugging pure implementation + @Test + fun longSha512() { + + for (target in 0L until 10L) { + generateForRounds512(target) + } + for (target in 0L until 16_777_216L step 1_000_000L) { + generateForRounds512(target) + } + generateForRounds512(16_777_216L) + } + + fun generateForRounds512(target: Long) { + println("Wut") + val updateValue = + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno".encodeToUByteArray().toCValues() + val state = malloc(crypto_hash_sha512_state.size.convert())!! + .reinterpret() + + crypto_hash_sha512_init(state) + for (i in 0 until target) { + crypto_hash_sha512_update(state, updateValue, updateValue.size.convert()) + } + val result = UByteArray(32) + val resultPinned = result.pin() + crypto_hash_sha512_final(state, resultPinned.addressOf(0)) + println("$target to \"${result.toHexString()}\",") + free(state) + } +} diff --git a/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt b/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt index 8fb509a..8101dca 100644 --- a/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt +++ b/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.util - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.runBlocking - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 20-Jul-2019 - */ -actual fun testBlocking(block: suspend () -> Unit) = runBlocking { block() } \ No newline at end of file +//package com.ionspin.kotlin.crypto.util +// +//import kotlinx.coroutines.CoroutineScope +//import kotlinx.coroutines.runBlocking +// +///** +// * Created by Ugljesa Jovanovic +// * ugljesa.jovanovic@ionspin.com +// * on 20-Jul-2019 +// */ +//actual fun testBlocking(block: suspend () -> Unit) = runBlocking { block() } diff --git a/multiplatform-crypto-libsodium-bindings/build.gradle.kts b/multiplatform-crypto-libsodium-bindings/build.gradle.kts new file mode 100644 index 0000000..d81fe4e --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/build.gradle.kts @@ -0,0 +1,660 @@ +/* + * Copyright 2019 Ugljesa Jovanovic + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +@file:Suppress("UnstableApiUsage") + +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest +import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest + +plugins { + kotlin(PluginsDeps.multiplatform) + id(PluginsDeps.mavenPublish) + id(PluginsDeps.signing) + id(PluginsDeps.node) version Versions.nodePlugin + id(PluginsDeps.dokka) + id(PluginsDeps.taskTree) version Versions.taskTreePlugin +} + +val sonatypeStaging = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" +val sonatypeSnapshots = "https://oss.sonatype.org/content/repositories/snapshots/" + +val sonatypePassword: String? by project + +val sonatypeUsername: String? by project + +val sonatypePasswordEnv: String? = System.getenv()["SONATYPE_PASSWORD"] +val sonatypeUsernameEnv: String? = System.getenv()["SONATYPE_USERNAME"] + +repositories { + mavenCentral() + jcenter() + +} +group = ReleaseInfo.group +version = ReleaseInfo.version + +val ideaActive = isInIdea() +println("Idea active: $ideaActive") + + + +kotlin { + val hostOsName = getHostOsName() + runningOnLinuxx86_64 { + println("Configuring Linux X86-64 targets") + jvm() + js { + browser { + testTask { + isRunningInTravis { + enabled = false //Until I sort out testing on travis + } + useKarma { + useChrome() + } + } + } + nodejs { + testTask { + useMocha() { + timeout = "10s" + } + } + } + + } + linuxX64() { + compilations.getByName("main") { + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-linux-x86-64/include/") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-linux-x86-64/lib/libsodium.a" + ) + } + binaries { + staticLib { + } + } + } + + + linuxArm64() { + binaries { + staticLib { + } + } + } + // Linux 32 is using target-sysroot-2-raspberrypi which is missing getrandom and explicit_bzero in stdlib + // so konanc can't build klib because getrandom missing will cause sodium_misuse() + // ld.lld: error: undefined symbol: explicit_bzero + // >>> referenced by utils.c + // >>> libsodium_la-utils.o:(sodium_memzero) in archive /tmp/included11051337748775083797/libsodium.a + // + // ld.lld: error: undefined symbol: getrandom + // >>> 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") + + } + + runningOnLinuxArm32 { + println("Configuring Linux Arm 32 targets") + + } + + runningOnMacos { + println("Configuring macos targets") + iosX64() { + binaries { + framework { + optimized = true + } + } + } + iosArm64() { + binaries { + framework { + optimized = true + } + } + } + + iosArm32() { + binaries { + framework { + optimized = true + } + } + } + macosX64() { + binaries { + framework { + optimized = true + } + } + compilations.getByName("main") { + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-macos-x86-64/include") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-macos-x86-64/lib/libsodium.a" + ) + } + } + tvosX64() { + binaries { + framework { + optimized = true + } + } + } + + tvosArm64() { + binaries { + framework { + optimized = true + } + } + } + + watchosArm64() { + binaries { + framework { + optimized = true + } + } + } + + watchosArm32() { + binaries { + framework { + optimized = true + } + } + } + + watchosX86() { + binaries { + framework { + optimized = true + } + } + } + } + runningOnWindows { + println("Configuring Mingw targets") + mingwX64() { + binaries { + staticLib { + optimized = true + } + } + compilations.getByName("main") { + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-mingw-x86-64/include") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-mingw-x86-64/lib/libsodium.a" + ) + } + } + } + + println(targets.names) + + sourceSets { + val commonMain by getting { + dependencies { + implementation(kotlin(Deps.Common.stdLib)) + implementation(kotlin(Deps.Common.test)) + implementation(Deps.Common.kotlinBigNum) + api(project(Deps.Common.apiProject)) + } + } + val commonTest by getting { + dependencies { + implementation(kotlin(Deps.Common.test)) + implementation(kotlin(Deps.Common.testAnnotation)) + } + } + + val nativeDependencies = independentDependencyBlock { + } + + val nativeMain by creating { + dependsOn(commonMain) + isRunningInIdea { + kotlin.setSrcDirs(emptySet()) + } + dependencies { + nativeDependencies(this) + } + } + + val nativeTest by creating { + dependsOn(commonTest) + isRunningInIdea { + kotlin.setSrcDirs(emptySet()) + } + dependencies { + } + } + + //Set up shared source sets + //linux, linuxArm32Hfp, linuxArm64 + val linux64Bit = setOf( + "linuxX64" + ) + val linuxArm64Bit = setOf( + "linuxArm64" + ) + val linux32Bit = setOf( + "" // "linuxArm32Hfp" + ) + + //iosArm32, iosArm64, iosX64, macosX64, metadata, tvosArm64, tvosX64, watchosArm32, watchosArm64, watchosX86 + val macos64Bit = setOf( + "macosX64" + ) + val ios64Bit = setOf( + "iosArm64", "iosX64" + ) + val ios32Bit = setOf( + "iosArm32" + ) + val mingw64Bit = setOf( + "mingwX64" + ) + + val tvos64Bit = setOf( + "tvosArm64", "tvosX64" + ) + + val watchos32Bit = setOf( + "watchosX86", "watchosArm32", "watchosArm64" + ) + + targets.withType { + println("Target $name") + + compilations.getByName("main") { + if (linux64Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn(nativeMain) + } + if (linuxArm64Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn( + createWorkaroundNativeMainSourceSet( + this@withType.name, + nativeDependencies + ) + ) + + compilations.getByName("main") { + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-arm64/include/") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-arm64/lib/libsodium.a" + ) + } + } + if (linux32Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies)) + } + if (macos64Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies)) + } + //All ioses share the same static library + if (ios64Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies)) + println("Setting ios cinterop for $this") + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-ios/include") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-ios/lib/libsodium.a" + ) + } + + if (ios32Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies)) + println("Setting ios cinterop for $this") + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-ios/include") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-ios/lib/libsodium.a" + ) + } + + if (tvos64Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies)) + println("Setting ios cinterop for $this") + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-tvos/include") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-tvos/lib/libsodium.a" + ) + } + + if (watchos32Bit.contains(this@withType.name)) { + defaultSourceSet.dependsOn(createWorkaroundNativeMainSourceSet(this@withType.name, nativeDependencies)) + println("Setting ios cinterop for $this") + val libsodiumCinterop by cinterops.creating { + defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) + compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-watchos/include") + } + kotlinOptions.freeCompilerArgs = listOf( + "-include-binary", "${project.rootDir}/sodiumWrapper/static-watchos/lib/libsodium.a" + ) + } + + + + } + compilations.getByName("test") { + println("Setting native test dep for $this@withType.name") + defaultSourceSet.dependsOn(nativeTest) + + + } + } + + + + + runningOnLinuxx86_64 { + println("Configuring Linux 64 Bit source sets") + val jvmMain by getting { + dependencies { + implementation(kotlin(Deps.Jvm.stdLib)) + implementation(kotlin(Deps.Jvm.test)) + implementation(kotlin(Deps.Jvm.testJUnit)) + + //lazysodium + implementation(Deps.Jvm.Delegated.lazysodium) + implementation(Deps.Jvm.Delegated.jna) + } + } + val jvmTest by getting { + dependencies { + implementation(kotlin(Deps.Jvm.test)) + implementation(kotlin(Deps.Jvm.testJUnit)) + implementation(kotlin(Deps.Jvm.reflection)) + } + } + val jsMain by getting { + dependencies { + implementation(kotlin(Deps.Js.stdLib)) + implementation(npm(Deps.Js.Npm.libsodiumWrappers.first, Deps.Js.Npm.libsodiumWrappers.second)) + } + } + val jsTest by getting { + dependencies { + implementation(kotlin(Deps.Js.test)) + implementation(npm(Deps.Js.Npm.libsodiumWrappers.first, Deps.Js.Npm.libsodiumWrappers.second)) + } + } + val linuxX64Main by getting { + isRunningInIdea { + kotlin.srcDir("src/nativeMain/kotlin") + } + } + val linuxX64Test by getting { + dependsOn(nativeTest) + isRunningInIdea { + kotlin.srcDir("src/nativeTest/kotlin") + } + } + + } + + runningOnMacos { + println("Configuring Macos source sets") + val macosX64Main by getting { + dependsOn(nativeMain) + if (ideaActive) { + kotlin.srcDir("src/nativeMain/kotlin") + } + + } + val macosX64Test by getting { + dependsOn(nativeTest) + if (ideaActive) { + kotlin.srcDir("src/nativeTest/kotlin") + } + + } + + val tvosX64Main by getting { + dependsOn(commonMain) + } + + val tvosArm64Main by getting { + dependsOn(commonMain) + } + + val watchosX86Main by getting { + dependsOn(commonMain) + } + + val watchosArm64Main by getting { + dependsOn(commonMain) + } + + val watchosArm32Main by getting { + dependsOn(commonMain) + } + + } + + + if (hostOsName == "windows") { + val mingwX64Main by getting { + dependsOn(nativeMain) + if (ideaActive) { + kotlin.srcDir("src/nativeMain/kotlin") + } + } + + val mingwX64Test by getting { + dependsOn(nativeTest) + if (ideaActive) { + kotlin.srcDir("src/nativeTest/kotlin") + } + } + } + + + all { + languageSettings.enableLanguageFeature("InlineClasses") + languageSettings.useExperimentalAnnotation("kotlin.ExperimentalUnsignedTypes") + languageSettings.useExperimentalAnnotation("kotlin.ExperimentalStdlibApi") + } + } + + +} + + + +tasks { + + + create("javadocJar") { + dependsOn(dokkaJavadoc) + archiveClassifier.set("javadoc") + from(dokkaJavadoc.get().outputDirectory) + } + + dokkaJavadoc { + println("Dokka !") + } + if (getHostOsName() == "linux" && getHostArchitecture() == "x86-64") { + val jvmTest by getting(Test::class) { + testLogging { + events("PASSED", "FAILED", "SKIPPED") + } + } + + val linuxX64Test by getting(KotlinNativeTest::class) { + + testLogging { + events("PASSED", "FAILED", "SKIPPED") + showStandardStreams = true + } + } + + val jsNodeTest by getting(KotlinJsTest::class) { + testLogging { + events("PASSED", "FAILED", "SKIPPED") +// showStandardStreams = true + } + } + +// val legacyjsNodeTest by getting(KotlinJsTest::class) { +// +// testLogging { +// events("PASSED", "FAILED", "SKIPPED") +// showStandardStreams = true +// } +// } + + val jsBrowserTest by getting(KotlinJsTest::class) { + testLogging { + events("PASSED", "FAILED", "SKIPPED") + showStandardStreams = true + } + } + } + + if (getHostOsName() == "windows") { + val mingwX64Test by getting(KotlinNativeTest::class) { + + testLogging { + events("PASSED", "FAILED", "SKIPPED") + showStandardStreams = true + } + } + } + +} + + + +signing { + isRequired = false + sign(publishing.publications) +} + +publishing { + publications.withType(MavenPublication::class) { + artifact(tasks["javadocJar"]) + pom { + name.set("Kotlin Multiplatform Crypto") + description.set("Kotlin Multiplatform Crypto library") + url.set("https://github.com/ionspin/kotlin-multiplatform-crypto") + licenses { + license { + name.set("The Apache License, Version 2.0") + url.set("http://www.apache.org/licenses/LICENSE-2.0.txt") + } + } + developers { + developer { + id.set("ionspin") + name.set("Ugljesa Jovanovic") + email.set("opensource@ionspin.com") + } + } + scm { + url.set("https://github.com/ionspin/kotlin-multiplatform-crypto") + connection.set("scm:git:git://git@github.com:ionspin/kotlin-multiplatform-crypto.git") + developerConnection.set("scm:git:ssh://git@github.com:ionspin/kotlin-multiplatform-crypto.git") + + } + + } + } + repositories { + maven { + + url = uri(sonatypeStaging) + credentials { + username = sonatypeUsername ?: sonatypeUsernameEnv ?: "" + password = sonatypePassword ?: sonatypePasswordEnv ?: "" + } + } + + maven { + name = "snapshot" + url = uri(sonatypeSnapshots) + credentials { + username = sonatypeUsername ?: sonatypeUsernameEnv ?: "" + password = sonatypePassword ?: sonatypePasswordEnv ?: "" + } + } + } +} + +//configurations.forEach { +// +// if (it.name == "linuxCompileKlibraries") { +// println("Configuration name: ${it.name}") +// it.attributes { +// this.keySet().forEach { key -> +// val attribute = getAttribute(key) +// println(" |-- Attribute $key ${attribute}") +// attribute(org.jetbrains.kotlin.gradle.plugin.ProjectLocalConfigurations.ATTRIBUTE, "publicZ") +// } +// } +// } +//} + + diff --git a/multiplatform-crypto-libsodium-bindings/libsodium-wrappers-sumo-0.7.6.tgz b/multiplatform-crypto-libsodium-bindings/libsodium-wrappers-sumo-0.7.6.tgz new file mode 100644 index 0000000..97837ca Binary files /dev/null and b/multiplatform-crypto-libsodium-bindings/libsodium-wrappers-sumo-0.7.6.tgz differ 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/Initializer.kt new file mode 100644 index 0000000..2ea2e2f --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/Initializer.kt @@ -0,0 +1,12 @@ +package com.ionspin.kotlin.crypto + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020 + */ +expect object Initializer { + 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/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt new file mode 100644 index 0000000..6287381 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,26 @@ +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/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 new file mode 100644 index 0000000..905a71c --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -0,0 +1,36 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.crypto.hash.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 + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 08-Aug-2020 + */ +class SmokeTest { + //TODO Browser ignores our testBlocking, node works fine though + @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") + assertTrue { + "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969" == resultString + } + + } + } +} diff --git a/multiplatform-crypto/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt similarity index 66% rename from multiplatform-crypto/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt rename to multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt index 8fb509a..3cb5304 100644 --- a/multiplatform-crypto/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt @@ -16,12 +16,21 @@ package com.ionspin.kotlin.crypto.util -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.runBlocking +import kotlin.coroutines.Continuation +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.coroutines.startCoroutine /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 20-Jul-2019 */ -actual fun testBlocking(block: suspend () -> Unit) = runBlocking { block() } \ No newline at end of file +fun testBlocking(block : suspend () -> Unit) { + val continuation = Continuation(EmptyCoroutineContext) { + //Do nothing + if (it.isFailure) { + throw it.exceptionOrNull()!! + } + } + block.startCoroutine(continuation) +} diff --git a/multiplatform-crypto-libsodium-bindings/src/iosMain/kotlin/com/ionspin/kotlin/bignum/integer/Placeholder b/multiplatform-crypto-libsodium-bindings/src/iosMain/kotlin/com/ionspin/kotlin/bignum/integer/Placeholder new file mode 100644 index 0000000..e69de29 diff --git a/multiplatform-crypto-libsodium-bindings/src/iosTest/kotlin/com/ionspin/kotlin/bignum/integer/Placeholder b/multiplatform-crypto-libsodium-bindings/src/iosTest/kotlin/com/ionspin/kotlin/bignum/integer/Placeholder new file mode 100644 index 0000000..e69de29 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/Initializer.kt new file mode 100644 index 0000000..9567243 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt @@ -0,0 +1,43 @@ +package com.ionspin.kotlin.crypto + +import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumInterface +import ext.libsodium.com.ionspin.kotlin.crypto.JsSodiumLoader +/* 1.4-M1 has some weirdness with static/objects, or I'm misusing something, not sure */ +lateinit var sodiumPointer : JsSodiumInterface +var sodiumLoaded: Boolean = false + +fun getSodium() : JsSodiumInterface = sodiumPointer + +//fun getSodiumAdvanced() : JsSodiumAdvancedInterface = js("sodiumPointer.libsodium") + +fun setSodiumPointer(jsSodiumInterface: JsSodiumInterface) { + js("sodiumPointer = jsSodiumInterface") +} + +fun getSodiumLoaded() : Boolean = sodiumLoaded + +fun setSodiumLoaded(loaded: Boolean) { + js("sodiumLoaded = loaded") +} + +actual object Initializer { + private var isPlatformInitialized = false + + actual suspend fun initialize() { + JsSodiumLoader.load() + isPlatformInitialized = true + } + + actual fun initializeWithCallback(done: () -> Unit) { + JsSodiumLoader.loadWithCallback { + isPlatformInitialized = true + done() + } + } + + actual fun isInitialized(): Boolean { + return isPlatformInitialized + } + + +} \ No newline at end of file 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 new file mode 100644 index 0000000..1934eb9 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -0,0 +1,60 @@ +package ext.libsodium.com.ionspin.kotlin.crypto + + +import org.khronos.webgl.Uint8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-May-2020 + */ +interface JsSodiumInterface { + + fun randombytes_buf(numberOfBytes: Int): 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 + + fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic + + fun crypto_generichash_update(state: dynamic, inputMessage: Uint8Array) + + fun crypto_generichash_final(state: dynamic, hashLength: Int) : Uint8Array + + + fun crypto_hash_sha256_init() : dynamic + + fun crypto_hash_sha256_update(state: dynamic, message: Uint8Array) + + fun crypto_hash_sha256_final(state: dynamic): Uint8Array + + fun crypto_hash_sha512_init() : dynamic + + fun crypto_hash_sha512_update(state: dynamic, message: Uint8Array) + + 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 + //encrypt + fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: 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 + + //util + fun memzero(array: Uint8Array) + + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumLoader.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumLoader.kt new file mode 100644 index 0000000..b445487 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumLoader.kt @@ -0,0 +1,56 @@ +package ext.libsodium.com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.getSodiumLoaded +import com.ionspin.kotlin.crypto.setSodiumPointer +import com.ionspin.kotlin.crypto.sodiumLoaded +import ext.libsodium.* +import kotlin.coroutines.Continuation +import kotlin.coroutines.suspendCoroutine + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-May-2020 + */ +object JsSodiumLoader { + + class _EmitJsSodiumFunction { + init { + println(::crypto_generichash) + println(::crypto_hash_sha256) + println(::crypto_hash_sha512) + println(::crypto_hash_sha256_init) + } + + } + + fun storeSodium(promisedSodium: dynamic, continuation: Continuation) { + setSodiumPointer(promisedSodium) + sodiumLoaded = true + continuation.resumeWith(Result.success(Unit)) + } + + suspend fun load() = suspendCoroutine { continuation -> + console.log(getSodiumLoaded()) + if (!getSodiumLoaded()) { + val libsodiumModule = js("\$module\$libsodium_wrappers_sumo") + _libsodiumPromise.then { storeSodium(libsodiumModule, continuation) } + } else { + continuation.resumeWith(Result.success(Unit)) + } + } + + fun loadWithCallback(doneCallback: () -> (Unit)) { + console.log(getSodiumLoaded()) + if (!getSodiumLoaded()) { + val libsodiumModule = js("\$module\$libsodium_wrappers_sumo") + _libsodiumPromise.then { + setSodiumPointer(libsodiumModule) + sodiumLoaded = true + doneCallback.invoke() + } + } else { + doneCallback.invoke() + } + } +} 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 new file mode 100644 index 0000000..9cecbbd --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt @@ -0,0 +1,24 @@ +package ext.libsodium.com.ionspin.kotlin.crypto + +import org.khronos.webgl.Uint8Array +import org.khronos.webgl.get + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 02-Aug-2020 + */ +fun UByteArray.toUInt8Array() : Uint8Array { + val uint8Result = Uint8Array(toByteArray().toTypedArray()) + return uint8Result +} + + +fun Uint8Array.toUByteArray() : UByteArray { + val result = UByteArray(length) + for (i in 0 until length) { + result[i] = get(i).toUByte() + } + + return result +} 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 new file mode 100644 index 0000000..727d9c7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,53 @@ +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/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/libsodium.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/libsodium.kt new file mode 100644 index 0000000..f37c329 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/libsodium.kt @@ -0,0 +1,28 @@ +@file:JsModule("libsodium-wrappers-sumo") +@file:JsNonModule +package ext.libsodium + +import org.khronos.webgl.Uint8Array +import kotlin.js.Promise + + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 25-May-2020 + */ + +@JsName("ready") +external val _libsodiumPromise : Promise + +external fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array) : Uint8Array + +external fun crypto_hash_sha256(message: Uint8Array) : Uint8Array +external fun crypto_hash_sha512(message: Uint8Array) : Uint8Array + +external fun crypto_hash_sha256_init(): dynamic + + + + + 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/Initializer.kt new file mode 100644 index 0000000..2af22a3 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt @@ -0,0 +1,27 @@ +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 { + private var isPlatformInitialized = false + + lateinit var sodium : SodiumJava + actual suspend fun initialize() { + sodium = SodiumJava() + isPlatformInitialized = true + } + + actual fun initializeWithCallback(done: () -> Unit) { + sodium = SodiumJava() + isPlatformInitialized = true + done() + } + + actual fun isInitialized(): Boolean { + return isPlatformInitialized + } + +} \ No newline at end of file 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 new file mode 100644 index 0000000..1213842 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,62 @@ +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/multiplatform-crypto-libsodium-bindings/src/linuxArm32HfpMain/kotlin/com/ionspin/kotlin/crypto/Placeholder b/multiplatform-crypto-libsodium-bindings/src/linuxArm32HfpMain/kotlin/com/ionspin/kotlin/crypto/Placeholder new file mode 100644 index 0000000..e69de29 diff --git a/multiplatform-crypto-libsodium-bindings/src/linuxArm32HfpTest/kotlin/com/ionspin/kotlin/crypto/Placeholder b/multiplatform-crypto-libsodium-bindings/src/linuxArm32HfpTest/kotlin/com/ionspin/kotlin/crypto/Placeholder new file mode 100644 index 0000000..e69de29 diff --git a/multiplatform-crypto-libsodium-bindings/src/linuxX64Main/kotlin/com/ionspin/kotlin/crypto/Placeholder b/multiplatform-crypto-libsodium-bindings/src/linuxX64Main/kotlin/com/ionspin/kotlin/crypto/Placeholder new file mode 100644 index 0000000..e69de29 diff --git a/multiplatform-crypto-libsodium-bindings/src/linuxX64Test/kotlin/com/ionspin/kotlin/crypto/Placeholder b/multiplatform-crypto-libsodium-bindings/src/linuxX64Test/kotlin/com/ionspin/kotlin/crypto/Placeholder new file mode 100644 index 0000000..e69de29 diff --git a/multiplatform-crypto-libsodium-bindings/src/mingwX64Main/kotlin/com/ionspin/kotlin/crypto/SRNG.kt b/multiplatform-crypto-libsodium-bindings/src/mingwX64Main/kotlin/com/ionspin/kotlin/crypto/SRNG.kt new file mode 100644 index 0000000..1a83ce8 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/mingwX64Main/kotlin/com/ionspin/kotlin/crypto/SRNG.kt @@ -0,0 +1,44 @@ +//We'll handle SRNG through libsodium +///* +// * Copyright 2019 Ugljesa Jovanovic +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ +// +//package com.ionspin.kotlin.crypto +// +//import kotlinx.cinterop.* +//import platform.windows.* +// +///** +// * Created by Ugljesa Jovanovic +// * ugljesa.jovanovic@ionspin.com +// * on 21-Sep-2019 +// */ +//actual object SRNG { +// private val advapi by lazy { LoadLibraryA("ADVAPI32.DLL")} +// +// private val advapiRandom by lazy { +// GetProcAddress(advapi, "SystemFunction036")?.reinterpret, ULong, Int>>>() ?: error("Failed getting advapi random") +// } +// +// @Suppress("EXPERIMENTAL_UNSIGNED_LITERALS") +// actual fun getRandomBytes(amount: Int): UByteArray { +// memScoped { +// val randArray = allocArray(amount) +// val pointer = randArray.getPointer(this) +// val status = advapiRandom(pointer.reinterpret(), amount.convert()) +// return UByteArray(amount) { pointer[it].toUByte() } +// } +// } +//} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeInterop/cinterop/libsodium.def b/multiplatform-crypto-libsodium-bindings/src/nativeInterop/cinterop/libsodium.def new file mode 100644 index 0000000..0b00392 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeInterop/cinterop/libsodium.def @@ -0,0 +1,6 @@ +headers = sodium.h +headerFilter = sodium.h sodium/** +#staticLibraries = libsodium.a +#libraryPaths = sodiumWrapper/lib +#compilerOpts = -I./sodiumWrapper/include +linkerOpts = \ No newline at end of file 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/Initializer.kt new file mode 100644 index 0000000..944c199 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt @@ -0,0 +1,30 @@ +@file:Suppress("VARIABLE_IN_SINGLETON_WITHOUT_THREAD_LOCAL") + +package com.ionspin.kotlin.crypto + +import libsodium.sodium_init +import kotlin.native.concurrent.AtomicInt + +actual object Initializer { + + private var isPlatformInitialized : AtomicInt = AtomicInt(0) + + actual suspend fun initialize() { + if (isPlatformInitialized.compareAndSet(0, 1)) { + sodium_init() + } + + + } + + actual fun initializeWithCallback(done: () -> Unit) { + if (isPlatformInitialized.compareAndSet(0, 1)) { + sodium_init() + } + done() + } + + actual fun isInitialized(): Boolean { + return isPlatformInitialized.value != 0 + } +} 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 new file mode 100644 index 0000000..5224235 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -0,0 +1,88 @@ +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/multiplatform-crypto/build.gradle.kts b/multiplatform-crypto/build.gradle.kts index f11341a..d883037 100644 --- a/multiplatform-crypto/build.gradle.kts +++ b/multiplatform-crypto/build.gradle.kts @@ -101,14 +101,14 @@ kotlin { } runningOnMacos { - iosX64("ios") { + iosX64() { binaries { framework { optimized = true } } } - iosArm64("ios64Arm") { + iosArm64() { binaries { framework { optimized = true @@ -116,7 +116,7 @@ kotlin { } } - iosArm32("ios32Arm") { + iosArm32() { binaries { framework { optimized = true @@ -197,7 +197,6 @@ kotlin { dependencies { implementation(kotlin(Deps.Common.stdLib)) implementation(kotlin(Deps.Common.test)) - implementation(Deps.Common.coroutines) implementation(Deps.Common.kotlinBigNum) implementation(project(Deps.Common.apiProject)) } @@ -213,7 +212,6 @@ kotlin { val nativeMain by creating { dependsOn(commonMain) dependencies { - implementation(Deps.Native.coroutines) } isRunningInIdea { kotlin.setSrcDirs(emptySet()) @@ -224,7 +222,6 @@ kotlin { val nativeTest by creating { dependsOn(commonTest) dependencies { - implementation(Deps.Native.coroutines) } } @@ -257,26 +254,22 @@ kotlin { implementation(kotlin(Deps.Jvm.stdLib)) implementation(kotlin(Deps.Jvm.test)) implementation(kotlin(Deps.Jvm.testJUnit)) - implementation(Deps.Jvm.coroutinesCore) } } val jvmTest by getting { dependencies { implementation(kotlin(Deps.Jvm.test)) implementation(kotlin(Deps.Jvm.testJUnit)) - implementation(Deps.Jvm.coroutinesTest) implementation(kotlin(Deps.Jvm.reflection)) } } val jsMain by getting { dependencies { implementation(kotlin(Deps.Js.stdLib)) - implementation(Deps.Js.coroutines) } } val jsTest by getting { dependencies { - implementation(Deps.Js.coroutines) implementation(kotlin(Deps.Js.test)) } } @@ -316,24 +309,24 @@ kotlin { runningOnMacos{ - val iosMain by getting { + val iosX64Main by getting { dependsOn(nativeMain) } - val iosTest by getting { + val iosX64Test by getting { dependsOn(nativeTest) } - val ios64ArmMain by getting { + val iosArm64Main by getting { dependsOn(nativeMain) } - val ios64ArmTest by getting { + val iosArm64Test by getting { dependsOn(nativeTest) } - val ios32ArmMain by getting { + val iosArm32Main by getting { dependsOn(nativeMain) } - val ios32ArmTest by getting { + val iosArm32Test by getting { dependsOn(nativeTest) } @@ -355,7 +348,6 @@ kotlin { // val mingwX86Main by getting { // dependsOn(commonMain) // dependencies { -// implementation(Deps.Native.coroutines) // } // } @@ -367,7 +359,6 @@ kotlin { val mingwX64Main by getting { dependsOn(commonMain) dependencies { - implementation(Deps.Native.coroutines) } } @@ -401,12 +392,12 @@ tasks { create("javadocJar") { - dependsOn(dokka) + dependsOn(dokkaJavadoc) archiveClassifier.set("javadoc") - from(dokka.get().outputDirectory) + from(dokkaJavadoc.get().outputDirectory) } - dokka { + dokkaJavadoc { println("Dokka !") } if (getHostOsName() == "linux" && getHostArchitecture() == "x86-64") { 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 new file mode 100644 index 0000000..385aaec --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt @@ -0,0 +1,155 @@ +package com.ionspin.kotlin.crypto + +import com.ionspin.kotlin.crypto.authenticated.* +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bMultipart +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure +import com.ionspin.kotlin.crypto.hash.sha.Sha256Pure +import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult +import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Pure + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 24-May-2020 + */ +object CryptoInitializerPure : CryptoInitializer { + override suspend fun initialize() { + //Nothing to do atm. + } + + fun initializeWithCallback(done: () -> Unit) { + done() + } + + override fun isInitialized(): Boolean { + return true + } +} + +object CryptoPrimitives : PrimitivesApi { + private fun checkInitialization() { + CryptoInitializerPure.isInitialized() + } + + override fun hashBlake2bMultipart(key: UByteArray?, hashLength: Int): Blake2bMultipart { + checkInitialization() + return Blake2bPure(key, hashLength) + } + + override fun hashBlake2b(message: UByteArray, key: UByteArray, hashLength: Int): UByteArray { + checkInitialization() + return Blake2bPure.digest(message, key, hashLength) + } + + override fun hashSha256Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha256 { + checkInitialization() + return Sha256Pure() + } + + override fun hashSha256(message: UByteArray): UByteArray { + checkInitialization() + return Sha256Pure.digest(inputMessage = message) + } + + override fun hashSha512Multipart(): com.ionspin.kotlin.crypto.hash.sha.Sha512Multipart { + checkInitialization() + return Sha512Pure() + } + + override fun hashSha512(message: UByteArray): UByteArray { + checkInitialization() + return Sha512Pure.digest(inputMessage = message) + } + + override fun deriveKey( + password: String, + salt: String?, + key: String, + associatedData: String, + parallelism: Int, + tagLength: Int, + memory: Int, + numberOfIterations: Int + ): ArgonResult { + return Argon2Pure.derive( + password, + salt, + key, + associatedData, + parallelism, + tagLength, + memory, + numberOfIterations + ) + } +} + +fun SymmetricKey.Companion.randomKey() : SymmetricKey { + return SymmetricKey(SRNG.getRandomBytes(32)) +} + +object Crypto { + + object Hash : HashApi { + override fun hash(data: UByteArray, key : UByteArray) : HashedData { + return HashedData(Blake2bPure.digest(data, key)) + } + + override fun multipartHash(key: UByteArray?) : com.ionspin.kotlin.crypto.hash.MultipartHash { + return Blake2bPure(key) + } + } + + object Encryption : EncryptionApi { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : 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) + + } + + 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 createMultipartEncryptor(key: SymmetricKey) : MultipartAuthenticatedEncryption { + return MultipartAuthenticatedEncryptor(key) + } + + override fun createMultipartDecryptor(key: SymmetricKey, header: MultipartEncryptionHeader) : MultipartAuthenticatedDecryption { + val decryptor = XChaCha20Poly1305Pure(key.value, header.nonce) + return MultipartAuthenticatedDecryptor(decryptor) + } + } +} + +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 startEncryption(): MultipartEncryptionHeader { + return header.copy() + } + + override fun cleanup() { + primitive.cleanup() + } +} + +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 cleanup() { + decryptor.cleanup() + } + +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt deleted file mode 100644 index 526d2d4..0000000 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/CryptoProvider.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.ionspin.kotlin.crypto - -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bProperties -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure -import com.ionspin.kotlin.crypto.hash.sha.Sha256Pure -import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 24-May-2020 - */ -typealias Blake2bPureStateless = Blake2bPure.Companion -typealias Sha256PureStateless = Sha256Pure.Companion -typealias Sha512PureStateless = Sha512Pure.Companion - -object Crypto : CryptoProvider { - override suspend fun initialize() { - //Nothing to do atm. - } - - fun initializeWithCallback(done: () -> Unit) { - done() - } - - - object Blake2b { - fun updateable(key: UByteArray? = null, hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): com.ionspin.kotlin.crypto.hash.blake2b.Blake2b { - checkInitialization() - return Blake2bPure(key, hashLength) - } - - fun stateless(message: UByteArray, key: UByteArray = ubyteArrayOf(), hashLength: Int = Blake2bProperties.MAX_HASH_BYTES): UByteArray { - checkInitialization() - return Blake2bPureStateless.digest(message, key, hashLength) - } - } - - object Sha256 { - fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha256 { - checkInitialization() - return Sha256Pure() - } - - fun stateless(message: UByteArray) : UByteArray{ - checkInitialization() - return Sha256PureStateless.digest(inputMessage = message) - } - } - - object Sha512 { - fun updateable(): com.ionspin.kotlin.crypto.hash.sha.Sha512 { - checkInitialization() - return Sha512Pure() - } - - fun stateless(message: UByteArray) : UByteArray { - checkInitialization() - return Sha512PureStateless.digest(inputMessage = message) - } - } - - private fun checkInitialization() { - // Nothing to do atm - } - -} \ No newline at end of file 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 new file mode 100644 index 0000000..3c6d6ef --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt @@ -0,0 +1,50 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.ionspin.kotlin.crypto.mac.Poly1305 +import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure +import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUIntWithPosition +import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +internal class ChaCha20Poly1305Pure { + companion object { + + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { + val state = UIntArray(16) { + when (it) { + 0 -> ChaCha20Pure.sigma0_32 + 1 -> ChaCha20Pure.sigma1_32 + 2 -> ChaCha20Pure.sigma2_32 + 3 -> ChaCha20Pure.sigma3_32 + 4 -> key.fromLittleEndianArrayToUIntWithPosition(0) + 5 -> key.fromLittleEndianArrayToUIntWithPosition(4) + 6 -> key.fromLittleEndianArrayToUIntWithPosition(8) + 7 -> key.fromLittleEndianArrayToUIntWithPosition(12) + 8 -> key.fromLittleEndianArrayToUIntWithPosition(16) + 9 -> key.fromLittleEndianArrayToUIntWithPosition(20) + 10 -> key.fromLittleEndianArrayToUIntWithPosition(24) + 11 -> key.fromLittleEndianArrayToUIntWithPosition(28) + 12 -> 0U + 13 -> nonce.fromLittleEndianArrayToUIntWithPosition(0) + 14 -> nonce.fromLittleEndianArrayToUIntWithPosition(4) + 15 -> nonce.fromLittleEndianArrayToUIntWithPosition(8) + else -> 0U + } + } + 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 cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U } + val macData = additionalData + additionalDataPad + + cipherText + cipherTextPad + + additionalData.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 new file mode 100644 index 0000000..a9340f6 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt @@ -0,0 +1,203 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.ionspin.kotlin.crypto.AuthenticatedEncryption +import com.ionspin.kotlin.crypto.InvalidTagException +import com.ionspin.kotlin.crypto.mac.Poly1305 +import com.ionspin.kotlin.crypto.symmetric.ChaCha20Pure +import com.ionspin.kotlin.crypto.symmetric.XChaCha20Pure +import com.ionspin.kotlin.crypto.util.* + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { + companion object : AuthenticatedEncryption { + + override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { + val subKey = XChaCha20Pure.hChacha(key, nonce) + val authKey = + ChaCha20Pure.xorWithKeystream( + subKey.toLittleEndianUByteArray(), + ubyteArrayOf(0U, 0U, 0U, 0U) + nonce.sliceArray(16 until 24), + UByteArray(64) { 0U }, + 0U // If this is moved as a default parameter in encrypt, and not here (in 1.4-M2) + // js compiler dies with: e: java.lang.NullPointerException + // at org.jetbrains.kotlin.ir.backend.js.lower.ConstTransformer$visitConst$1$3.invoke(ConstLowering.kt:28) + // 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 cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U } + val macData = additionalData + additionalDataPad + + cipherText + cipherTextPad + + additionalData.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 { + val subKey = XChaCha20Pure.hChacha(key, nonce) + val authKey = + ChaCha20Pure.xorWithKeystream( + subKey.toLittleEndianUByteArray(), + ubyteArrayOf(0U, 0U, 0U, 0U) + nonce.sliceArray(16 until 24), + UByteArray(64) { 0U }, + 0U + ) + //2. Get the tag + 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 cipherTextPad = UByteArray(16 - cipherTextWithoutTag.size % 16) { 0U } + val macData = additionalData + additionalDataPad + + cipherTextWithoutTag + cipherTextPad + + additionalData.size.toULong().toLittleEndianUByteArray() + + cipherTextWithoutTag.size.toULong().toLittleEndianUByteArray() + val calculatedTag = Poly1305.poly1305Authenticate(authKey, macData) + if (!calculatedTag.contentEquals(tag)) { + throw InvalidTagException() + } + //4. Decrypt data + return XChaCha20Pure.xorWithKeystream(key, nonce, cipherTextWithoutTag, 1U) + } + + } + + + private val polyBuffer = UByteArray(16) + private var polyBufferByteCounter = 0 + + private var processedBytes = 0 + + internal val calcKey : UByteArray = UByteArray(32) + internal val calcNonce : UByteArray = UByteArray(12) + + init { + val calc = XChaCha20Pure.hChacha(key, nonce).toLittleEndianUByteArray() + calc.sliceArray(0 until 32).copyInto(calcKey) + nonce.sliceArray(16 until 24).copyInto(calcNonce, 4) + calcNonce[0] = 1U + calcNonce[1] = 0U + calcNonce[2] = 0U + calcNonce[3] = 0U + } + + fun streamEncrypt(data: UByteArray, additionalData: 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) + } + block[0] = tag + ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block) // This just xors block[0] with keystream + processPolyBytes(poly1305, block) // but updates the mac with the full block! + // In libsodium c code, it now sets the first byte to be a tag, we'll just save it for now + val encryptedTag = block[0] + //And then encrypt the rest of the message + val ciphertext = ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, data, 2U) // With appropriate counter + // Next we update the poly1305 with ciphertext and padding, BUT the padding in libsodium is not correctly calculated, so it doesn't + // pad correctly. https://github.com/jedisct1/libsodium/issues/976 + // We want to use libsodium in delegated flavour, so we will use the same incorrect padding here. + // 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() + 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 { + 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) + } + block[0] = data[0] + ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block)// get the keystream xored with zeroes, but also decrypteg tag marker + val tag = block[0] //get the decrypted tag + block[0] = data[0] // this brings it back to state that is delivered to poly in encryption function + processPolyBytes(poly1305, block) + // Next we update the poly1305 with ciphertext and padding, BUT the padding in libsodium is not correctly calculated, so it doesn't + // pad correctly. https://github.com/jedisct1/libsodium/issues/976 + // We want to use libsodium in delegated flavour, so we will use the same incorrect padding here. + // From security standpoint there are no obvious drawbacks, as padding was initially added to decrease implementation complexity. + 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() + processPolyBytes(poly1305, finalMac) + val mac = poly1305.finalizeMac(polyBuffer.sliceArray(0 until polyBufferByteCounter)) + val expectedMac = data.sliceArray(data.size - 16 until data.size) + + if (expectedMac.contentEquals(mac).not()){ + throw InvalidTagException() + } + calcNonce.xorWithPositionsAndInsertIntoArray(0, 12, mac, 0, calcNonce, 0) + return plaintext + } + + fun cleanup() { + key.overwriteWithZeroes() + nonce.overwriteWithZeroes() + calcKey.overwriteWithZeroes() + calcNonce.overwriteWithZeroes() + } + + + + private fun processPolyBytes(updateableMacPrimitive: Poly1305, data: UByteArray) { + if (polyBufferByteCounter == 0) { + val polyBlocks = data.size / 16 + val polyRemainder = data.size % 16 + for (i in 0 until polyBlocks) { + updateableMacPrimitive.updateMac(data.sliceArray(i * 16 until i * 16 + 16)) + } + if (polyRemainder != 0) { + for (i in 0 until polyRemainder) { + polyBuffer[i] = data[data.size - polyRemainder + i] + } + polyBufferByteCounter = polyRemainder + } + } else { + if (polyBufferByteCounter + data.size < 16) { + for (i in 0 until data.size) { + polyBuffer[polyBufferByteCounter + i] = data[i] + } + polyBufferByteCounter += data.size + } else { + val borrowed = 16 - polyBufferByteCounter + for (i in polyBufferByteCounter until 16) { + polyBuffer[i] = data[i - polyBufferByteCounter] + } + updateableMacPrimitive.updateMac(polyBuffer) + polyBufferByteCounter = 0 + val polyBlocks = (data.size - borrowed) / 16 + val polyRemainder = (data.size - borrowed) % 16 + for (i in 0 until polyBlocks) { + updateableMacPrimitive.updateMac(data.sliceArray(borrowed + i * 16 until borrowed + i * 16 + 16)) + } + if (polyRemainder != 0) { + for (i in 0 until polyRemainder) { + polyBuffer[i] = data[borrowed + i] + } + polyBufferByteCounter = polyRemainder + } + } + } + } + + +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt index a3c5bef..5e72b76 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bPure.kt @@ -19,6 +19,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.bignum.integer.BigInteger import com.ionspin.kotlin.bignum.integer.toBigInteger import com.ionspin.kotlin.crypto.* +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.rotateRight /** @@ -28,9 +29,9 @@ import com.ionspin.kotlin.crypto.util.rotateRight */ -class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake2b { +class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake2bMultipart { - companion object : Blake2bStateless { + companion object : Blake2b { //Hack start //If this line is not included konanc 1.4-M1 fails to link because it cant find ByteArray which is //a backing class for UByteArray @@ -146,9 +147,9 @@ class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake fun digest(inputString: String, key: String?, hashLength: Int): UByteArray { - val array = inputString.encodeToByteArray().toUByteArray() + val array = inputString.encodeToUByteArray() val keyBytes = key?.run { - encodeToByteArray().toUByteArray() + encodeToUByteArray() } ?: ubyteArrayOf() return digest(inputMessage = array, key = keyBytes, hashLength = hashLength) @@ -248,7 +249,7 @@ class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake key: String?, requestedHashLenght: Int = 64 ) : this( - (key?.encodeToByteArray()?.toUByteArray() ?: ubyteArrayOf()), + (key?.encodeToUByteArray() ?: ubyteArrayOf()), requestedHashLenght ) @@ -310,7 +311,7 @@ class Blake2bPure(val key: UByteArray? = null, val hashLength: Int = 64) : Blake } fun update(data: String) { - update(data.encodeToByteArray().toUByteArray()) + update(data.encodeToUByteArray()) } private fun appendToBuffer(array: UByteArray, start: Int) { diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Pure.kt index 0f0950f..eda11e8 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Pure.kt @@ -16,6 +16,7 @@ package com.ionspin.kotlin.crypto.hash.sha +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.rotateRight @@ -68,7 +69,7 @@ class Sha256Pure : Sha256 { var h = iv.copyOf() - val expansionArray = createExpansionArray(inputMessage.size) + val expansionArray = createExpansionArray(inputMessage.size.toLong()) val chunks = ( inputMessage + @@ -178,15 +179,15 @@ class Sha256Pure : Sha256 { } - fun createExpansionArray(originalSizeInBytes: Int): UByteArray { + fun createExpansionArray(originalSizeInBytes: Long): UByteArray { val originalMessageSizeInBits = originalSizeInBytes * 8 //K such that L + 1 + K + 64 is a multiple of 512 val expandedRemainderOf512 = (originalMessageSizeInBits + BLOCK_SIZE_IN_BYTES + 1) % BLOCK_SIZE val zeroAddAmount = when (expandedRemainderOf512) { - 0 -> 0 - else -> (BLOCK_SIZE - expandedRemainderOf512) / 8 + 0L -> 0 + else -> ((BLOCK_SIZE - expandedRemainderOf512) / 8).toInt() } val expansionArray = UByteArray(zeroAddAmount + 1) { when (it) { @@ -230,13 +231,17 @@ class Sha256Pure : Sha256 { } var h = iv.copyOf() - var counter = 0 + var counter = 0L var bufferCounter = 0 var buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { 0U } + var digested = false fun update(data: String) { - return update(data.encodeToByteArray().toUByteArray()) + if (digested) { + throw RuntimeException("This instance of updateable SHA256 was already finished once. You should use new instance") + } + return update(data.encodeToUByteArray()) } override fun update(data: UByteArray) { @@ -246,6 +251,14 @@ class Sha256Pure : Sha256 { when { bufferCounter + data.size < BLOCK_SIZE_IN_BYTES -> appendToBuffer(data, bufferCounter) + bufferCounter + data.size == BLOCK_SIZE_IN_BYTES -> { + counter += BLOCK_SIZE_IN_BYTES + consumeBlock(data) + } + bufferCounter + data.size == BLOCK_SIZE_IN_BYTES -> { + counter += BLOCK_SIZE_IN_BYTES + consumeBlock(data) + } bufferCounter + data.size >= BLOCK_SIZE_IN_BYTES -> { val chunked = data.chunked(BLOCK_SIZE_IN_BYTES) chunked.forEach { chunk -> @@ -302,6 +315,7 @@ class Sha256Pure : Sha256 { h[5].toPaddedByteArray() + h[6].toPaddedByteArray() + h[7].toPaddedByteArray() + digested = true return digest } @@ -311,4 +325,4 @@ class Sha256Pure : Sha256 { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt index 7fe3eee..2aba3af 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Pure.kt @@ -16,6 +16,7 @@ package com.ionspin.kotlin.crypto.hash.sha +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.rotateRight /** @@ -25,11 +26,11 @@ import com.ionspin.kotlin.crypto.util.rotateRight */ -class Sha512Pure : Sha512 { +class Sha512Pure : Sha512Multipart { override val MAX_HASH_BYTES: Int = 32 - companion object : StatelessSha512 { + companion object : Sha512 { const val BLOCK_SIZE = 1024 const val BLOCK_SIZE_IN_BYTES = 128 const val CHUNK_SIZE = 80 @@ -136,7 +137,7 @@ class Sha512Pure : Sha512 { var h = iv.copyOf() - val expansionArray = createExpansionArray(inputMessage.size) + val expansionArray = createExpansionArray(inputMessage.size.toLong()) val chunks = (inputMessage + expansionArray + (inputMessage.size * 8).toULong().toPadded128BitByteArray()).chunked( @@ -248,13 +249,13 @@ class Sha512Pure : Sha512 { return h } - fun createExpansionArray(originalSizeInBytes: Int): UByteArray { + fun createExpansionArray(originalSizeInBytes: Long): UByteArray { val originalMessageSizeInBits = originalSizeInBytes * 8 val expandedRemainderOf1024 = (originalMessageSizeInBits + 129) % BLOCK_SIZE val zeroAddAmount = when (expandedRemainderOf1024) { - 0 -> 0 - else -> (BLOCK_SIZE - expandedRemainderOf1024) / 8 + 0L -> 0 + else -> ((BLOCK_SIZE - expandedRemainderOf1024) / 8).toInt() } val expansionArray = UByteArray(zeroAddAmount + 1) { when (it) { @@ -304,19 +305,23 @@ class Sha512Pure : Sha512 { } var h = iv.copyOf() - var counter = 0 + var counter = 0L var bufferCounter = 0 var buffer = UByteArray(BLOCK_SIZE_IN_BYTES) { 0U } + var digested = false fun update(data: String) { - return update(data.encodeToByteArray().toUByteArray()) + return update(data.encodeToUByteArray()) } override fun update(data: UByteArray) { if (data.isEmpty()) { throw RuntimeException("Updating with empty array is not allowed. If you need empty hash, just call digest without updating") } + if (digested) { + throw RuntimeException("This instance of updateable SHA256 was already finished once. You should use new instance") + } when { bufferCounter + data.size < BLOCK_SIZE_IN_BYTES -> appendToBuffer(data, bufferCounter) @@ -376,6 +381,7 @@ class Sha512Pure : Sha512 { h[5].toPaddedByteArray() + h[6].toPaddedByteArray() + h[7].toPaddedByteArray() + digested = true return digest } @@ -385,4 +391,4 @@ class Sha512Pure : Sha512 { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt index c7ccc50..f32883f 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/argon2/Argon2Pure.kt @@ -19,8 +19,11 @@ package com.ionspin.kotlin.crypto.keyderivation.argon2 import com.ionspin.kotlin.bignum.integer.toBigInteger -import com.ionspin.kotlin.crypto.Blake2bPureStateless + import com.ionspin.kotlin.crypto.SRNG +import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bPure +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.keyderivation.ArgonResult import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.argonBlake2bArbitraryLenghtHash import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.compressionFunctionG import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Utils.validateArgonParameters @@ -42,14 +45,7 @@ data class SegmentPosition( val slice: Int ) -data class ArgonResult( - val hashBytes: UByteArray, - val salt: UByteArray -) { - val hashString by lazy { hashBytes.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } - val saltString by lazy { salt.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") } -} @@ -79,14 +75,14 @@ class Argon2Pure( ): ArgonResult { val salt = SRNG.getRandomBytes(64) val argon = Argon2Pure( - password.encodeToByteArray().toUByteArray(), + password.encodeToUByteArray(), salt, parallelism, tagLength.toUInt(), memory.toUInt(), numberOfIterations, - key.encodeToByteArray().toUByteArray(), - associatedData.encodeToByteArray().toUByteArray(), + key.encodeToUByteArray(), + associatedData.encodeToUByteArray(), ArgonType.Argon2id ) val resultArray = argon.derive() @@ -105,14 +101,14 @@ class Argon2Pure( associatedData: String = "", argonType: ArgonType = ArgonType.Argon2id ) : this( - password.encodeToByteArray().toUByteArray(), - salt.encodeToByteArray().toUByteArray(), + password.encodeToUByteArray(), + salt.encodeToUByteArray(), parallelism, tagLength, requestedMemorySize, numberOfIterations, - key.encodeToByteArray().toUByteArray(), - associatedData.encodeToByteArray().toUByteArray(), + key.encodeToUByteArray(), + associatedData.encodeToUByteArray(), argonType ) @@ -296,7 +292,7 @@ class Argon2Pure( salt.size.toUInt().toLittleEndianUByteArray() + salt + key.size.toUInt().toLittleEndianUByteArray() + key + associatedData.size.toUInt().toLittleEndianUByteArray() + associatedData - val h0 = Blake2bPureStateless.digest( + val h0 = Blake2bPure.digest( blakeInput ) diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305.kt new file mode 100644 index 0000000..406ebeb --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305.kt @@ -0,0 +1,118 @@ +package com.ionspin.kotlin.crypto.mac + +import com.ionspin.kotlin.bignum.Endianness +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign +import com.ionspin.kotlin.crypto.util.fromLittleEndianUByteArrayToBigEndianUByteArray +import com.ionspin.kotlin.crypto.util.hexColumsPrint + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 18-Jun-2020 + */ +class Poly1305(key: UByteArray) { + companion object { + fun clampR(r: UByteArray) : UByteArray { + val clamped = UByteArray(16) { r[it] } + clamped[3] = r[3] and 0b00001111U + clamped[7] = r[7] and 0b00001111U + clamped[11] = r[11] and 0b00001111U + clamped[15] = r[15] and 0b00001111U + + clamped[4] = r[4] and 0b11111100U + clamped[8] = r[8] and 0b11111100U + clamped[12] = r[12] and 0b11111100U + return clamped + + } + + val P = BigInteger.fromUByteArray( + ubyteArrayOf( + 0x03U, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xfbU + ), + Sign.POSITIVE + ) + val powersOfTwo = Array(129) { + BigInteger.ONE shl it + } + val resultMask = (BigInteger.ONE shl 128) - 1 + //Doesn't have to be every power, just divisible by 8 + val twoToThe128 = BigInteger.ONE.shl(128) + + /** + * Limit - stop poly calculating tag at desired index, ignored if 0 + */ + fun poly1305Authenticate(key: UByteArray, message: UByteArray) : UByteArray { + val r = clampR(UByteArray(16) { key[it] }) + val s= UByteArray(16) { key[it + 16]} + + var accumulator = BigInteger.ZERO + val rAsBigInt = BigInteger.fromUByteArray(r.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) //TODO convert from little endian ubyte array to what BigInteger expects + val sAsBigInt = BigInteger.fromUByteArray(s.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) + val blocks = message.size / 16 + val remainder = message.size % 16 + + for (i in 0 until blocks) { + val slice = message.sliceArray(i * 16 until i * 16 + 16) + slice.hexColumsPrint() + val blockAsInt = BigInteger.fromUByteArray(slice.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) + powersOfTwo[128] + accumulator += blockAsInt + accumulator *= rAsBigInt + accumulator %= P + } + if (remainder != 0) { + val slice = message.sliceArray(blocks * 16 until blocks * 16 + remainder) + val blockAsInt = BigInteger.fromUByteArray(slice.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) + powersOfTwo[remainder * 8] + accumulator += blockAsInt + accumulator *= rAsBigInt + accumulator %= P + } + + accumulator += sAsBigInt + accumulator = accumulator and resultMask + val result = accumulator.toUByteArray() + result.reverse() + return result + + + } + } + var rAsBigInt = BigInteger.fromUByteArray( + clampR(key.sliceArray(0 until 16)).fromLittleEndianUByteArrayToBigEndianUByteArray(), + Sign.POSITIVE + ) + var sAsBigInt = BigInteger.fromUByteArray( + key.sliceArray(16 until 32).fromLittleEndianUByteArrayToBigEndianUByteArray(), + Sign.POSITIVE) + var accumulator = BigInteger.ZERO + + fun updateMac(data : UByteArray) { + if (data.size != 16) { + throw RuntimeException("Invalide block size, required 16, got ${data.size}") + } + val blockAsInt = BigInteger.fromUByteArray( + data.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE + ) + powersOfTwo[128] + accumulator += blockAsInt + accumulator *= rAsBigInt + accumulator %= P + } + + fun finalizeMac(data: UByteArray = ubyteArrayOf()) : UByteArray{ + if (data.size != 0) { + val blockAsInt = BigInteger.fromUByteArray( + data.fromLittleEndianUByteArrayToBigEndianUByteArray(), + Sign.POSITIVE + ) + powersOfTwo[data.size * 8] + accumulator += blockAsInt + accumulator *= rAsBigInt + accumulator %= P + } + accumulator += sAsBigInt + accumulator = accumulator and resultMask + val result = accumulator.toUByteArray() + result.reverse() + return result + } +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/parallelization/Coroutines14.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/parallelization/Coroutines14.kt deleted file mode 100644 index 6a05cbb..0000000 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/parallelization/Coroutines14.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.parallelization - -import kotlin.time.ExperimentalTime - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 17-May-2020 - */ -@ExperimentalTime -object Coroutines14 { - fun argonParallel() : Array { -// val argon = Argon2() -// argon - println("Placeholder") - return emptyArray() - } -} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt new file mode 100644 index 0000000..55ceeb7 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Aes.kt @@ -0,0 +1,28 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 13-Jun-2020 + */ +internal sealed class InternalAesKey(val key: String, val keyLength: Int) { + val keyArray: UByteArray = key.hexStringToUByteArray() + val numberOf32BitWords = keyLength / 32 + + class Aes128Key(key: String) : InternalAesKey(key, 128) + class Aes192Key(key: String) : InternalAesKey(key, 192) + class Aes256Key(key: String) : InternalAesKey(key, 256) + + init { + checkKeyLength(key, keyLength) + } + + fun checkKeyLength(key: String, expectedLength: Int) { + if ((key.length / 2) != expectedLength / 8) { + throw RuntimeException("Invalid key length") + } + } +} + 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 134b671..94cbf76 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 @@ -31,7 +31,7 @@ import com.ionspin.kotlin.crypto.util.xor * on 21-Sep-2019 */ -class AesCbcPure internal constructor(val aesKey: AesKey, val mode: Mode, initializationVector: UByteArray? = null) { +internal class AesCbcPure internal constructor(val aesKey: InternalAesKey, val mode: Mode, initializationVector: UByteArray? = null) { companion object { const val BLOCK_BYTES = 16 @@ -39,21 +39,21 @@ class AesCbcPure internal constructor(val aesKey: AesKey, val mode: Mode, initia * Creates and returns AesCbc instance that can be fed data using [addData]. Once you have submitted all * data call [encrypt] */ - fun createEncryptor(aesKey: AesKey) : AesCbcPure { + fun createEncryptor(aesKey: InternalAesKey) : AesCbcPure { return AesCbcPure(aesKey, Mode.ENCRYPT) } /** * Creates and returns AesCbc instance that can be fed data using [addData]. Once you have submitted all * data call [decrypt] */ - fun createDecryptor(aesKey : AesKey) : AesCbcPure { + fun createDecryptor(aesKey : InternalAesKey) : AesCbcPure { return AesCbcPure(aesKey, Mode.DECRYPT) } /** * Bulk encryption, returns encrypted data and a random initialization vector */ - fun encrypt(aesKey: AesKey, data: UByteArray): EncryptedDataAndInitializationVector { + fun encrypt(aesKey: InternalAesKey, data: UByteArray): EncryptedDataAndInitializationVector { val aesCbc = AesCbcPure(aesKey, Mode.ENCRYPT) aesCbc.addData(data) return aesCbc.encrypt() @@ -62,7 +62,7 @@ class AesCbcPure internal constructor(val aesKey: AesKey, val mode: Mode, initia /** * Bulk decryption, returns decrypted data */ - fun decrypt(aesKey: AesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { + fun decrypt(aesKey: InternalAesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { val aesCbc = AesCbcPure(aesKey, Mode.DECRYPT, initialCounter) aesCbc.addData(data) return aesCbc.decrypt() @@ -220,7 +220,7 @@ class AesCbcPure internal constructor(val aesKey: AesKey, val mode: Mode, initia } -data class EncryptedDataAndInitializationVector(val encryptedData : UByteArray, val initilizationVector : UByteArray) { +data class EncryptedDataAndInitializationVector(val encryptedData : UByteArray, val initializationVector : UByteArray) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false @@ -228,14 +228,14 @@ data class EncryptedDataAndInitializationVector(val encryptedData : UByteArray, other as EncryptedDataAndInitializationVector if (!encryptedData.contentEquals(other.encryptedData)) return false - if (!initilizationVector.contentEquals(other.initilizationVector)) return false + if (!initializationVector.contentEquals(other.initializationVector)) return false return true } override fun hashCode(): Int { var result = encryptedData.contentHashCode() - result = 31 * result + initilizationVector.contentHashCode() + 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 6c2aa51..e477d39 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 @@ -18,6 +18,7 @@ package com.ionspin.kotlin.crypto.symmetric import com.ionspin.kotlin.bignum.Endianness import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import com.ionspin.kotlin.bignum.modular.ModularBigInteger import com.ionspin.kotlin.crypto.SRNG import com.ionspin.kotlin.crypto.symmetric.AesCtrPure.Companion.encrypt @@ -36,7 +37,7 @@ import com.ionspin.kotlin.crypto.util.xor * on 22-Sep-2019 */ -class AesCtrPure internal constructor(val aesKey: AesKey, val mode: Mode, initialCounter: UByteArray? = null) { +internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val mode: Mode, initialCounter: UByteArray? = null) { companion object { const val BLOCK_BYTES = 16 @@ -46,20 +47,20 @@ class AesCtrPure internal constructor(val aesKey: AesKey, val mode: Mode, initia * Creates and returns AesCtr instance that can be fed data using [addData]. Once you have submitted all * data call [encrypt] */ - fun createEncryptor(aesKey: AesKey) : AesCtrPure { + fun createEncryptor(aesKey: InternalAesKey) : AesCtrPure { return AesCtrPure(aesKey, Mode.ENCRYPT) } /** * Creates and returns AesCtr instance that can be fed data using [addData]. Once you have submitted all * data call [decrypt] */ - fun createDecryptor(aesKey : AesKey) : AesCtrPure { + fun createDecryptor(aesKey : InternalAesKey) : AesCtrPure { return AesCtrPure(aesKey, Mode.DECRYPT) } /** - * Bulk encryption, returns encrypted data and a random initial counter + * Bulk encryption, returns encrypted data and a random initial counter */ - fun encrypt(aesKey: AesKey, data: UByteArray): EncryptedDataAndInitialCounter { + fun encrypt(aesKey: InternalAesKey, data: UByteArray): EncryptedDataAndInitialCounter { val aesCtr = AesCtrPure(aesKey, Mode.ENCRYPT) aesCtr.addData(data) return aesCtr.encrypt() @@ -67,7 +68,7 @@ class AesCtrPure internal constructor(val aesKey: AesKey, val mode: Mode, initia /** * Bulk decryption, returns decrypted data */ - fun decrypt(aesKey: AesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { + fun decrypt(aesKey: InternalAesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { val aesCtr = AesCtrPure(aesKey, Mode.DECRYPT, initialCounter) aesCtr.addData(data) return aesCtr.decrypt() @@ -82,7 +83,7 @@ class AesCtrPure internal constructor(val aesKey: AesKey, val mode: Mode, initia } else { initialCounter } - var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart.toTypedArray(), Endianness.BIG)) + var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart, Sign.POSITIVE)) val output = MutableList(0) { ubyteArrayOf() } @@ -161,7 +162,7 @@ class AesCtrPure internal constructor(val aesKey: AesKey, val mode: Mode, initia } private fun consumeBlock(data: UByteArray, blockCount: ModularBigInteger): UByteArray { - val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).toUByteArray().expandCounterTo16Bytes() + val blockCountAsByteArray = blockCount.toUByteArray().expandCounterTo16Bytes() return when (mode) { Mode.ENCRYPT -> { AesPure.encrypt(aesKey, blockCountAsByteArray) xor data @@ -186,16 +187,15 @@ class AesCtrPure internal constructor(val aesKey: AesKey, val mode: Mode, initia } - data class EncryptedDataAndInitialCounter(val encryptedData : UByteArray, val initialCounter : UByteArray) { override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false - other as EncryptedDataAndInitializationVector + other as EncryptedDataAndInitialCounter if (!encryptedData.contentEquals(other.encryptedData)) return false - if (!initialCounter.contentEquals(other.initilizationVector)) return false + if (!initialCounter.contentEquals(other.initialCounter)) return false return true } @@ -205,4 +205,5 @@ data class EncryptedDataAndInitialCounter(val encryptedData : UByteArray, val in result = 31 * result + initialCounter.contentHashCode() return result } -} \ No newline at end of file +} + diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesPure.kt index 86ea0eb..d20b8e4 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesPure.kt @@ -6,7 +6,7 @@ import com.ionspin.kotlin.crypto.util.flattenToUByteArray * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 07/Sep/2019 */ -internal class AesPure internal constructor(val aesKey: AesKey, val input: UByteArray) { +internal class AesPure internal constructor(val aesKey: InternalAesKey, val input: UByteArray) { companion object { private val debug = false @@ -56,11 +56,11 @@ internal class AesPure internal constructor(val aesKey: AesKey, val input: UByte val rcon: UByteArray = ubyteArrayOf(0x8DU, 0x01U, 0x02U, 0x04U, 0x08U, 0x10U, 0x20U, 0x40U, 0x80U, 0x1BU, 0x36U) - fun encrypt(aesKey: AesKey, input: UByteArray): UByteArray { + fun encrypt(aesKey: InternalAesKey, input: UByteArray): UByteArray { return AesPure(aesKey, input).encrypt() } - fun decrypt(aesKey: AesKey, input: UByteArray): UByteArray { + fun decrypt(aesKey: InternalAesKey, input: UByteArray): UByteArray { return AesPure(aesKey, input).decrypt() } @@ -71,9 +71,9 @@ internal class AesPure internal constructor(val aesKey: AesKey, val input: UByte }.toTypedArray() val numberOfRounds = when (aesKey) { - is AesKey.Aes128Key -> 10 - is AesKey.Aes192Key -> 12 - is AesKey.Aes256Key -> 14 + is InternalAesKey.Aes128Key -> 10 + is InternalAesKey.Aes192Key -> 12 + is InternalAesKey.Aes256Key -> 14 } val expandedKey: Array = expandKey() @@ -235,7 +235,7 @@ internal class AesPure internal constructor(val aesKey: AesKey, val input: UByte temp[0] = temp[0] xor rcon[i / aesKey.numberOf32BitWords] - } else if (aesKey is AesKey.Aes256Key && i % aesKey.numberOf32BitWords == 4) { + } else if (aesKey is InternalAesKey.Aes256Key && i % aesKey.numberOf32BitWords == 4) { temp[0] = getSBoxValue(temp[0]) temp[1] = getSBoxValue(temp[1]) temp[2] = getSBoxValue(temp[2]) @@ -356,23 +356,6 @@ internal class AesPure internal constructor(val aesKey: AesKey, val input: UByte } -sealed class AesKey(val key: String, val keyLength: Int) { - val keyArray: UByteArray = key.chunked(2).map { it.toUByte(16) }.toUByteArray() - val numberOf32BitWords = keyLength / 32 - - class Aes128Key(key: String) : AesKey(key, 128) - class Aes192Key(key: String) : AesKey(key, 192) - class Aes256Key(key: String) : AesKey(key, 256) - - init { - checkKeyLength(key, keyLength) - } - - fun checkKeyLength(key: String, expectedLength: Int) { - if ((key.length / 2) != expectedLength / 8) { - throw RuntimeException("Invalid key length") - } - } -} + diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Pure.kt new file mode 100644 index 0000000..d475395 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Pure.kt @@ -0,0 +1,99 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.symmetric.LatinDancesCommon.littleEndianInverted +import com.ionspin.kotlin.crypto.util.* + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 16-Jun-2020 + */ +internal class ChaCha20Pure { + companion object { + fun quarterRound(input: UIntArray, aPosition: Int, bPosition: Int, cPosition: Int, dPosition: Int) { + input[aPosition] += input[bPosition] + input[dPosition] = input[dPosition] xor input[aPosition] + input[dPosition] = input[dPosition] rotateLeft 16 + + input[cPosition] += input[dPosition] + input[bPosition] = input[bPosition] xor input[cPosition] + input[bPosition] = input[bPosition] rotateLeft 12 + + input[aPosition] += input[bPosition] + input[dPosition] = input[dPosition] xor input[aPosition] + input[dPosition] = input[dPosition] rotateLeft 8 + + input[cPosition] += input[dPosition] + input[bPosition] = input[bPosition] xor input[cPosition] + input[bPosition] = input[bPosition] rotateLeft 7 + } + + fun doubleRound(input: UIntArray) { + quarterRound(input, 0, 4, 8, 12) + quarterRound(input, 1, 5, 9, 13) + quarterRound(input, 2, 6, 10, 14) + quarterRound(input, 3, 7, 11, 15) + + quarterRound(input, 0, 5, 10, 15) + quarterRound(input, 1, 6, 11, 12) + quarterRound(input, 2, 7, 8, 13) + quarterRound(input, 3, 4, 9, 14) + } + + fun hash(initialState: UIntArray): UByteArray { + val state = initialState.copyOf() + for (i in 0 until 10) { + doubleRound(state) + } + val result = UByteArray(64) + for (i in 0 until 16) { + littleEndianInverted(initialState[i] + state[i], result, i * 4) + } + return result + } + + val sigma0_32 = 1634760805U //ubyteArrayOf(101U, 120U, 112U, 97U) + val sigma1_32 = 857760878U //ubyteArrayOf(110U, 100U, 32U, 51U) + val sigma2_32 = 2036477234U //ubyteArrayOf(50U, 45U, 98U, 121U) + val sigma3_32 = 1797285236U //ubyteArrayOf(116U, 101U, 32U, 107U) + + fun xorWithKeystream(key: UByteArray, nonce: UByteArray, message: UByteArray, initialCounter: UInt): UByteArray { + val ciphertext = UByteArray(message.size) + val state = UIntArray(16) { + when (it) { + 0 -> sigma0_32 + 1 -> sigma1_32 + 2 -> sigma2_32 + 3 -> sigma3_32 + 4 -> key.fromLittleEndianArrayToUIntWithPosition(0) + 5 -> key.fromLittleEndianArrayToUIntWithPosition(4) + 6 -> key.fromLittleEndianArrayToUIntWithPosition(8) + 7 -> key.fromLittleEndianArrayToUIntWithPosition(12) + 8 -> key.fromLittleEndianArrayToUIntWithPosition(16) + 9 -> key.fromLittleEndianArrayToUIntWithPosition(20) + 10 -> key.fromLittleEndianArrayToUIntWithPosition(24) + 11 -> key.fromLittleEndianArrayToUIntWithPosition(28) + 12 -> initialCounter + 13 -> nonce.fromLittleEndianArrayToUIntWithPosition(0) + 14 -> nonce.fromLittleEndianArrayToUIntWithPosition(4) + 15 -> nonce.fromLittleEndianArrayToUIntWithPosition(8) + else -> 0U + } + } + val blocks = message.size / 64 + val remainder = message.size % 64 + for (i in 0 until blocks) { + hash(state).xorWithPositionsAndInsertIntoArray(0, 64, message, i * 64, ciphertext, i * 64) + state[12] += 1U + } + + hash(state).xorWithPositionsAndInsertIntoArray( + 0, remainder, + message, blocks * 64, + ciphertext, blocks * 64 + ) + state.overwriteWithZeroes() + return ciphertext + } + } +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/LatinDancesCommon.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/LatinDancesCommon.kt new file mode 100644 index 0000000..202cf62 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/LatinDancesCommon.kt @@ -0,0 +1,55 @@ +package com.ionspin.kotlin.crypto.symmetric + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 16-Jun-2020 + */ + + + + +object LatinDancesCommon { + + val _emitIntArray: IntArray = intArrayOf(1) + + fun littleEndian( + input: UByteArray, + byte0Position: Int, + byte1Position: Int, + byte2Position: Int, + byte3Position: Int + ): UInt { + var uint = 0U + uint = input[byte0Position].toUInt() + uint = uint or (input[byte1Position].toUInt() shl 8) + uint = uint or (input[byte2Position].toUInt() shl 16) + uint = uint or (input[byte3Position].toUInt() shl 24) + + return uint + } + + fun littleEndianInverted( + input: UIntArray, + startingPosition: Int, + output: UByteArray, + outputPosition: Int + ) { + output[outputPosition] = (input[startingPosition] and 0xFFU).toUByte() + output[outputPosition + 1] = ((input[startingPosition] shr 8) and 0xFFU).toUByte() + output[outputPosition + 2] = ((input[startingPosition] shr 16) and 0xFFU).toUByte() + output[outputPosition + 3] = ((input[startingPosition] shr 24) and 0xFFU).toUByte() + } + + fun littleEndianInverted( + input: UInt, + output: UByteArray, + outputPosition: Int + ) { + output[outputPosition] = (input and 0xFFU).toUByte() + output[outputPosition + 1] = ((input shr 8) and 0xFFU).toUByte() + output[outputPosition + 2] = ((input shr 16) and 0xFFU).toUByte() + output[outputPosition + 3] = ((input shr 24) and 0xFFU).toUByte() + } + +} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Mode.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Mode.kt deleted file mode 100644 index a0d43f9..0000000 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Mode.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.symmetric - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 18-Sep-2019 - */ - -enum class Mode { - ENCRYPT, DECRYPT -} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Pure.kt new file mode 100644 index 0000000..2fc3761 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Pure.kt @@ -0,0 +1,122 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.symmetric.LatinDancesCommon.littleEndianInverted +import com.ionspin.kotlin.crypto.util.* + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +internal class Salsa20Pure { + companion object { + fun quarterRound(input: UIntArray, y0position: Int, y1position: Int, y2position: Int, y3position: Int) { + input[y1position] = input[y1position] xor ((input[y0position] + input[y3position]) rotateLeft 7) + input[y2position] = input[y2position] xor ((input[y1position] + input[y0position]) rotateLeft 9) + input[y3position] = input[y3position] xor ((input[y2position] + input[y1position]) rotateLeft 13) + input[y0position] = input[y0position] xor ((input[y3position] + input[y2position]) rotateLeft 18) + } + + fun rowRound(input: UIntArray) { + quarterRound(input, 0, 1, 2, 3) + quarterRound(input, 5, 6, 7, 4) + quarterRound(input, 10, 11, 8, 9) + quarterRound(input, 15, 12, 13, 14) + } + + fun columnRound(input: UIntArray) { + quarterRound(input, 0, 4, 8, 12) + quarterRound(input, 5, 9, 13, 1) + quarterRound(input, 10, 14, 2, 6) + quarterRound(input, 15, 3, 7, 11) + } + + fun doubleRound(input: UIntArray) { + columnRound(input) + rowRound(input) + } + + + + fun hash(initialState: UIntArray): UByteArray { + val state = initialState.copyOf() + for (i in 0 until 10) { + doubleRound(state) + } + val result = UByteArray(64) + for (i in 0 until 16) { + littleEndianInverted(initialState[i] + state[i], result, i * 4) + } + return result + } + + internal var sigma0_32_uint = 1634760805U //ubyteArrayOf(101U, 120U, 112U, 97U) + internal var sigma1_32_uint = 857760878U //ubyteArrayOf(110U, 100U, 32U, 51U) + internal var sigma2_32_uint = 2036477234U //ubyteArrayOf(50U, 45U, 98U, 121U) + internal var sigma3_32_uint = 1797285236U //ubyteArrayOf(116U, 101U, 32U, 107U) + + val sigma0_32 = ubyteArrayOf(101U, 120U, 112U, 97U) + val sigma1_32 = ubyteArrayOf(110U, 100U, 32U, 51U) + val sigma2_32 = ubyteArrayOf(50U, 45U, 98U, 121U) + val sigma3_32 = ubyteArrayOf(116U, 101U, 32U, 107U) + + val tau0_16 = ubyteArrayOf(101U, 120U, 112U, 97U) + val tau1_16 = ubyteArrayOf(110U, 100U, 32U, 49U) + val tau2_16 = ubyteArrayOf(54U, 45U, 98U, 121U) + val tau3_16 = ubyteArrayOf(116U, 101U, 32U, 107U) + + fun expansion16(k: UByteArray, n: UByteArray) : UByteArray { + return hash((tau0_16 + k + tau1_16 + n + tau2_16 + k + tau3_16).fromLittleEndianToUInt()) + } + + fun expansion32(key :UByteArray, nonce : UByteArray) : UByteArray { + return hash((sigma0_32 + key.slice(0 until 16) + sigma1_32 + nonce + sigma2_32 + key.slice(16 until 32) + sigma3_32).fromLittleEndianToUInt()) + } + + fun encrypt(key : UByteArray, nonce: UByteArray, message: UByteArray) : UByteArray { + val ciphertext = UByteArray(message.size) + val state = UIntArray(16) { + when (it) { + 0 -> sigma0_32_uint + 1 -> key.fromLittleEndianArrayToUIntWithPosition(0) + 2 -> key.fromLittleEndianArrayToUIntWithPosition(4) + 3 -> key.fromLittleEndianArrayToUIntWithPosition(8) + 4 -> key.fromLittleEndianArrayToUIntWithPosition(12) + 5 -> sigma1_32_uint + 6 -> nonce.fromLittleEndianArrayToUIntWithPosition(0) + 7 -> nonce.fromLittleEndianArrayToUIntWithPosition(4) + 8 -> 0U + 9 -> 0U + 10 -> sigma2_32_uint + 11 -> key.fromLittleEndianArrayToUIntWithPosition(16) + 12 -> key.fromLittleEndianArrayToUIntWithPosition(20) + 13 -> key.fromLittleEndianArrayToUIntWithPosition(24) + 14 -> key.fromLittleEndianArrayToUIntWithPosition(28) + 15 -> sigma3_32_uint + else -> 0U + } + } + val blocks = message.size / 64 + val remainder = message.size % 64 + for (i in 0 until blocks) { + hash(state).xorWithPositionsAndInsertIntoArray(0, 64, message, i * 64, ciphertext, i * 64) + state[8] += 1U + if (state[8] == 0U) { + state[9] += 1U + } + } + + hash(state).xorWithPositionsAndInsertIntoArray( + 0, remainder, + message, blocks * 64, + ciphertext, blocks * 64) + state.overwriteWithZeroes() + return ciphertext + } + + fun decrypt(key : UByteArray, nonce: UByteArray, ciphertext: UByteArray) : UByteArray { + return encrypt(key, nonce, ciphertext) + } + } + +} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Pure.kt new file mode 100644 index 0000000..5631cbd --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Pure.kt @@ -0,0 +1,179 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUIntWithPosition +import com.ionspin.kotlin.crypto.util.overwriteWithZeroes +import com.ionspin.kotlin.crypto.util.xorWithPositionsAndInsertIntoArray + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +class XChaCha20Pure(key: UByteArray, nonce: UByteArray, initialCounter: UInt = 0U) { + companion object { + + fun hChacha(key: UByteArray, nonce: UByteArray) : UIntArray { + val state = UIntArray(16) { + when (it) { + 0 -> ChaCha20Pure.sigma0_32 + 1 -> ChaCha20Pure.sigma1_32 + 2 -> ChaCha20Pure.sigma2_32 + 3 -> ChaCha20Pure.sigma3_32 + 4 -> key.fromLittleEndianArrayToUIntWithPosition(0) + 5 -> key.fromLittleEndianArrayToUIntWithPosition(4) + 6 -> key.fromLittleEndianArrayToUIntWithPosition(8) + 7 -> key.fromLittleEndianArrayToUIntWithPosition(12) + 8 -> key.fromLittleEndianArrayToUIntWithPosition(16) + 9 -> key.fromLittleEndianArrayToUIntWithPosition(20) + 10 -> key.fromLittleEndianArrayToUIntWithPosition(24) + 11 -> key.fromLittleEndianArrayToUIntWithPosition(28) + 12 -> nonce.fromLittleEndianArrayToUIntWithPosition(0) + 13 -> nonce.fromLittleEndianArrayToUIntWithPosition(4) + 14 -> nonce.fromLittleEndianArrayToUIntWithPosition(8) + 15 -> nonce.fromLittleEndianArrayToUIntWithPosition(12) + else -> 0U + } + } + for (i in 0 until 10) { + ChaCha20Pure.doubleRound(state) + } + + val result = UIntArray(8) { + when (it) { + 0 -> state[0] + 1 -> state[1] + 2 -> state[2] + 3 -> state[3] + 4 -> state[12] + 5 -> state[13] + 6 -> state[14] + 7 -> state[15] + else -> throw RuntimeException("Invalid index $it") + } + } + return result + + } + + fun xorWithKeystream(key: UByteArray, nonce: UByteArray, message: UByteArray, initialCounter: UInt = 0U): UByteArray { + + val ciphertext = UByteArray(message.size) + val hChaChaKey = hChacha(key, nonce) + val state = UIntArray(16) { + when (it) { + 0 -> ChaCha20Pure.sigma0_32 + 1 -> ChaCha20Pure.sigma1_32 + 2 -> ChaCha20Pure.sigma2_32 + 3 -> ChaCha20Pure.sigma3_32 + 4 -> hChaChaKey[0] + 5 -> hChaChaKey[1] + 6 -> hChaChaKey[2] + 7 -> hChaChaKey[3] + 8 -> hChaChaKey[4] + 9 -> hChaChaKey[5] + 10 -> hChaChaKey[6] + 11 -> hChaChaKey[7] + 12 -> initialCounter + 13 -> 0U + 14 -> nonce.fromLittleEndianArrayToUIntWithPosition(16) + 15 -> nonce.fromLittleEndianArrayToUIntWithPosition(20) + else -> 0U + } + } + hChaChaKey.overwriteWithZeroes() + val blocks = message.size / 64 + val remainder = message.size % 64 + for (i in 0 until blocks) { + ChaCha20Pure.hash(state).xorWithPositionsAndInsertIntoArray(0, 64, message, i * 64, ciphertext, i * 64) + state[12] += 1U + if (state[12] == 0U) { + state[13] += 1U + } + } + ChaCha20Pure.hash(state).xorWithPositionsAndInsertIntoArray( + 0, remainder, + message, blocks * 64, + ciphertext, blocks * 64 + ) + state.overwriteWithZeroes() + return ciphertext + } + + } + + val state: UIntArray + val keystreamBuffer = UByteArray(64) { 0U} + var keystreamRemainingCounter = 0 + var processedBytesSoFar = 0 + + init { + val hChaChaKey = hChacha(key, nonce) + state = UIntArray(16) { + when (it) { + 0 -> ChaCha20Pure.sigma0_32 + 1 -> ChaCha20Pure.sigma1_32 + 2 -> ChaCha20Pure.sigma2_32 + 3 -> ChaCha20Pure.sigma3_32 + 4 -> hChaChaKey[0] + 5 -> hChaChaKey[1] + 6 -> hChaChaKey[2] + 7 -> hChaChaKey[3] + 8 -> hChaChaKey[4] + 9 -> hChaChaKey[5] + 10 -> hChaChaKey[6] + 11 -> hChaChaKey[7] + 12 -> initialCounter + 13 -> 0U + 14 -> nonce.fromLittleEndianArrayToUIntWithPosition(16) + 15 -> nonce.fromLittleEndianArrayToUIntWithPosition(20) + else -> 0U + } + } + hChaChaKey.overwriteWithZeroes() + } + + fun xorWithKeystream(data: UByteArray) : UByteArray { + val ciphertext = UByteArray(data.size) { 0U } + //First use remaining keystream + var processedBytes = 0 + if (data.size > keystreamRemainingCounter) { + keystreamBuffer.xorWithPositionsAndInsertIntoArray( + 64 - keystreamRemainingCounter, 64, + data, 0, + ciphertext, 0 + ) + processedBytes += keystreamRemainingCounter + keystreamRemainingCounter = 0 + } + //Then do full blocks + var remainingBytes = data.size - processedBytes + for (i in 0 until remainingBytes / 64) { + ChaCha20Pure.hash(state).xorWithPositionsAndInsertIntoArray( + 0, 64, + data, processedBytes, + ciphertext, processedBytes + ) + state[12] += 1U + if (state[12] == 0U) { + state[13] += 1U + } + processedBytes += 64 + } + //Then do the remainder that didn't fit into 64byte blocks + remainingBytes = data.size - processedBytes + ChaCha20Pure.hash(state).copyInto(keystreamBuffer) + state[12] += 1U + if (state[12] == 0U) { + state[13] += 1U + } + keystreamBuffer.xorWithPositionsAndInsertIntoArray( + 0, remainingBytes, + data, processedBytes, + ciphertext, processedBytes + ) + keystreamRemainingCounter = 64 - remainingBytes + processedBytesSoFar += data.size + return ciphertext + } + +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Pure.kt new file mode 100644 index 0000000..ca83a60 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Pure.kt @@ -0,0 +1,105 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUInt +import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToUIntWithPosition +import com.ionspin.kotlin.crypto.util.overwriteWithZeroes +import com.ionspin.kotlin.crypto.util.xorWithPositionsAndInsertIntoArray + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 16-Jun-2020 + */ +internal class XSalsa20Pure { + companion object { + fun hSalsa(key: UByteArray, nonce: UByteArray): UIntArray { + val state = UIntArray(16) { + when (it) { + 0 -> Salsa20Pure.sigma0_32.fromLittleEndianArrayToUInt() + 1 -> key.fromLittleEndianArrayToUIntWithPosition(0) + 2 -> key.fromLittleEndianArrayToUIntWithPosition(4) + 3 -> key.fromLittleEndianArrayToUIntWithPosition(8) + 4 -> key.fromLittleEndianArrayToUIntWithPosition(12) + 5 -> Salsa20Pure.sigma1_32.fromLittleEndianArrayToUInt() + 6 -> nonce.fromLittleEndianArrayToUIntWithPosition(0) + 7 -> nonce.fromLittleEndianArrayToUIntWithPosition(4) + 8 -> nonce.fromLittleEndianArrayToUIntWithPosition(8) + 9 -> nonce.fromLittleEndianArrayToUIntWithPosition(12) + 10 -> Salsa20Pure.sigma2_32.fromLittleEndianArrayToUInt() + 11 -> key.fromLittleEndianArrayToUIntWithPosition(16) + 12 -> key.fromLittleEndianArrayToUIntWithPosition(20) + 13 -> key.fromLittleEndianArrayToUIntWithPosition(24) + 14 -> key.fromLittleEndianArrayToUIntWithPosition(28) + 15 -> Salsa20Pure.sigma3_32.fromLittleEndianArrayToUInt() + else -> throw RuntimeException("Invalid index $it") + } + } + for (i in 0 until 10) { + Salsa20Pure.doubleRound(state) + } + val result = UIntArray(8) { + when (it) { + 0 -> state[0] + 1 -> state[5] + 2 -> state[10] + 3 -> state[15] + 4 -> state[6] + 5 -> state[7] + 6 -> state[8] + 7 -> state[9] + else -> throw RuntimeException("Invalid index $it") + } + } + return result + + } + + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray): UByteArray { + if (nonce.size != 24) { + throw RuntimeException("Invalid nonce size. required 192 bits, got ${nonce.size * 8}") + } + val ciphertext = UByteArray(message.size) + val hSalsaKey = hSalsa(key, nonce) + val state = UIntArray(16) { + when (it) { + 0 -> Salsa20Pure.sigma0_32_uint + 1 -> hSalsaKey[0] + 2 -> hSalsaKey[1] + 3 -> hSalsaKey[2] + 4 -> hSalsaKey[3] + 5 -> Salsa20Pure.sigma1_32_uint + 6 -> nonce.fromLittleEndianArrayToUIntWithPosition(16) //Last 63 bit of 192 bit nonce + 7 -> nonce.fromLittleEndianArrayToUIntWithPosition(20) + 8 -> 0U + 9 -> 0U + 10 -> Salsa20Pure.sigma2_32_uint + 11 -> hSalsaKey[4] + 12 -> hSalsaKey[5] + 13 -> hSalsaKey[6] + 14 -> hSalsaKey[7] + 15 -> Salsa20Pure.sigma3_32_uint + else -> 0U + } + } + hSalsaKey.overwriteWithZeroes() + val blocks = message.size / 64 + val remainder = message.size % 64 + for (i in 0 until blocks) { + Salsa20Pure.hash(state).xorWithPositionsAndInsertIntoArray(0, 64, message, i * 64, ciphertext, i * 64) + state[8] += 1U + if (state[8] == 0U) { + state[9] += 1U + } + } + + Salsa20Pure.hash(state).xorWithPositionsAndInsertIntoArray( + 0, remainder, + message, blocks * 64, + ciphertext, blocks * 64) + state.overwriteWithZeroes() + return ciphertext + } + + } + +} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt index 28e9232..1dc57f9 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt @@ -18,30 +18,14 @@ package com.ionspin.kotlin.crypto.util +//TODO Reorganize this, currently it's just a pile of useful helper functions + +val _emitIntArray: IntArray = intArrayOf(1) /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 15-Jul-2019 */ -fun Array.hexColumsPrint() { - val printout = this.map { it.toString(16) }.chunked(16) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} - -fun Array.hexColumsPrint(chunk : Int = 16) { - val printout = this.map { it.toString(16).padStart(2, '0') }.chunked(chunk) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} - -fun UByteArray.hexColumsPrint(chunk : Int = 16) { - val printout = this.map { it.toString(16).padStart(2, '0') }.chunked(chunk) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} - -fun Array.hexColumsPrint(chunk: Int = 3) { - val printout = this.map { it.toString(16) }.chunked(chunk) - printout.forEach { println(it.joinToString(separator = " ") { it.toUpperCase() }) } -} inline fun Array.chunked(sliceSize: Int): Array> { val last = this.size % sliceSize @@ -72,6 +56,14 @@ infix fun ULong.rotateRight(places: Int): ULong { return (this shr places) xor (this shl (64 - places)) } +infix fun UInt.rotateLeft(places: Int): UInt { + return (this shl places) xor (this shr (32 - places)) +} + + +infix fun ULong.rotateLeft(places: Int): ULong { + return (this shl places) xor (this shr (64 - places)) +} infix fun Array.xor(other : Array) : Array { if (this.size != other.size) { @@ -88,35 +80,21 @@ infix fun UByteArray.xor(other : UByteArray) : UByteArray { return UByteArray(this.size) { this[it] xor other[it] } } - -fun String.hexStringToTypedUByteArray() : Array { - return this.chunked(2).map { it.toUByte(16) }.toTypedArray() +fun UByteArray.xorWithPositions(start: Int, end: Int, other : UByteArray, otherStart: Int) : UByteArray { + return UByteArray(end - start) { this[start + it] xor other[otherStart + it] } } - -fun String.hexStringToUByteArray() : UByteArray { - return this.chunked(2).map { it.toUByte(16) }.toUByteArray() -} - - -fun Array.toHexString() : String { - return this.joinToString(separator = "") { - if (it <= 0x0FU) { - "0${it.toString(16)}" - } else { - it.toString(16) - } - } -} - - -fun UByteArray.toHexString() : String { - return this.joinToString(separator = "") { - if (it <= 0x0FU) { - "0${it.toString(16)}" - } else { - it.toString(16) - } +/** + * Start index is included, end index is excluded + */ +fun UByteArray.xorWithPositionsAndInsertIntoArray( + start: Int, end: Int, + other : UByteArray, otherStart: Int, + targetArray: UByteArray, targetStart : Int +) { + val length = end - start + for (i in 0 until length) { + targetArray[targetStart + i] = this[start + i] xor other[otherStart + i] } } @@ -141,6 +119,19 @@ fun UInt.toLittleEndianUByteArray() : UByteArray { } } + +fun UIntArray.toLittleEndianUByteArray() : UByteArray { + val result = UByteArray(size * 4) + for (i in 0 until size) { + val converted = this[i].toLittleEndianUByteArray() + result[i * 4] = converted[0] + result[i * 4 + 1] = converted[1] + result[i * 4 + 2] = converted[2] + result[i * 4 + 3] = converted[3] + } + return result +} + // UInt / Array utils fun ULong.toBigEndianUByteArray() : Array { @@ -231,9 +222,60 @@ fun UByteArray.fromLittleEndianArrayToUInt() : UInt { return uint } +fun UByteArray.fromLittleEndianArrayToUIntWithPosition(position: Int) : UInt{ + var uint = 0U + for (i in 0 until 4) { + uint = uint or (this[position + i].toUInt() shl (i * 8)) + } + return uint +} + +fun UByteArray.fromBigEndianArrayToUInt() : UInt{ + var uint = 0U + for (i in 0 until 4) { + uint = uint shl 8 or (this[i].toUInt()) + } + return uint +} + +fun UByteArray.fromBigEndianArrayToUIntWithPosition(position: Int) : UInt{ + var uint = 0U + for (i in 0 until 4) { + uint = uint shl 8 or (this[position + i].toUInt()) + } + return uint +} + +fun UByteArray.insertUIntAtPositionAsLittleEndian(position: Int, value: UInt) { + for (i in position until position + 4) { + this[i] = ((value shr (i * 8)) and 0xFFU).toUByte() + } +} + +fun UByteArray.insertUIntAtPositionAsBigEndian(position: Int, value: UInt) { + for (i in position until position + 4) { + this[i] = ((value shr (24 - i * 8)) and 0xFFU).toUByte() + } +} + +fun UByteArray.fromLittleEndianToUInt() : UIntArray { + if (size % 4 != 0) { + throw RuntimeException("Invalid size (not divisible by 4)") + } + return UIntArray(size / 4) { + fromLittleEndianArrayToUIntWithPosition(it * 4) + } +} - +fun UByteArray.fromBigEndianToUInt() : UIntArray { + if (size % 4 != 0) { + throw RuntimeException("Invalid size (not divisible by 4)") + } + return UIntArray(size / 4) { + fromBigEndianArrayToUIntWithPosition(it * 4) + } +} fun Array.fromBigEndianArrayToUInt() : UInt { if (this.size > 4) { @@ -259,4 +301,4 @@ fun Collection.flattenToUByteArray(): UByteArray { } } return result -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt index 8b92c99..301eeb2 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/ReadmeTest.kt @@ -22,6 +22,7 @@ import com.ionspin.kotlin.crypto.hash.sha.Sha256Pure import com.ionspin.kotlin.crypto.hash.sha.Sha512Pure import com.ionspin.kotlin.crypto.keyderivation.argon2.Argon2Pure import com.ionspin.kotlin.crypto.keyderivation.argon2.ArgonType +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.toHexString import kotlin.test.Test @@ -70,7 +71,7 @@ class ReadmeTest { } val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" + "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") - .chunked(2).map { it.toUByte(16) }.toUByteArray() + .hexStringToUByteArray() assertTrue { result.contentEquals(expectedResult) @@ -84,7 +85,7 @@ class ReadmeTest { val result = Sha256Pure.digest(input.encodeToUByteArray()) val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } @@ -94,12 +95,12 @@ class ReadmeTest { @Test fun sha512Example() { val input = "abc" - val result = Sha512Pure.digest(inputMessage = input.encodeToByteArray().map { it.toUByte() }.toUByteArray()) + val result = Sha512Pure.digest(inputMessage = input.encodeToUByteArray()) println(result.map { it.toString(16) }) val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } @@ -113,7 +114,7 @@ class ReadmeTest { val result = sha256.digest() val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } } @@ -126,7 +127,7 @@ class ReadmeTest { val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } @@ -159,9 +160,9 @@ class ReadmeTest { @Test fun debugTest() { - val result = Blake2bPureStateless.digest("test".encodeToUByteArray()) + val result = Blake2bPure.digest("test".encodeToUByteArray()) println(result.toHexString()) } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/UtilTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/UtilTest.kt similarity index 90% rename from multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/UtilTest.kt rename to multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/UtilTest.kt index a72224d..aa90414 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/UtilTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/UtilTest.kt @@ -14,8 +14,13 @@ * limitations under the License. */ -package com.ionspin.kotlin.crypto.util +package com.ionspin.kotlin.crypto +import com.ionspin.kotlin.crypto.util.chunked +import com.ionspin.kotlin.crypto.util.fromBigEndianArrayToULong +import com.ionspin.kotlin.crypto.util.fromLittleEndianArrayToULong +import com.ionspin.kotlin.crypto.util.toBigEndianUByteArray +import com.ionspin.kotlin.crypto.util.toLittleEndianTypedUByteArray import kotlin.test.Test import kotlin.test.assertTrue @@ -106,4 +111,4 @@ class UtilTest { } } -} \ No newline at end of file +} 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 new file mode 100644 index 0000000..26975f4 --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt @@ -0,0 +1,56 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexColumsPrint +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +class ChaCha20Poly1305Test { + + + + @Test + fun chaCha20Poly1305() { + 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( + 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( + 0x07U, 0x00U, 0x00U, 0x00U, 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U + ) + //Ciphertext + Poly1305TAG + val expected = ubyteArrayOf( + 0xd3U, 0x1aU, 0x8dU, 0x34U, 0x64U, 0x8eU, 0x60U, 0xdbU, 0x7bU, 0x86U, 0xafU, 0xbcU, 0x53U, 0xefU, 0x7eU, 0xc2U, + 0xa4U, 0xadU, 0xedU, 0x51U, 0x29U, 0x6eU, 0x08U, 0xfeU, 0xa9U, 0xe2U, 0xb5U, 0xa7U, 0x36U, 0xeeU, 0x62U, 0xd6U, + 0x3dU, 0xbeU, 0xa4U, 0x5eU, 0x8cU, 0xa9U, 0x67U, 0x12U, 0x82U, 0xfaU, 0xfbU, 0x69U, 0xdaU, 0x92U, 0x72U, 0x8bU, + 0x1aU, 0x71U, 0xdeU, 0x0aU, 0x9eU, 0x06U, 0x0bU, 0x29U, 0x05U, 0xd6U, 0xa5U, 0xb6U, 0x7eU, 0xcdU, 0x3bU, 0x36U, + 0x92U, 0xddU, 0xbdU, 0x7fU, 0x2dU, 0x77U, 0x8bU, 0x8cU, 0x98U, 0x03U, 0xaeU, 0xe3U, 0x28U, 0x09U, 0x1bU, 0x58U, + 0xfaU, 0xb3U, 0x24U, 0xe4U, 0xfaU, 0xd6U, 0x75U, 0x94U, 0x55U, 0x85U, 0x80U, 0x8bU, 0x48U, 0x31U, 0xd7U, 0xbcU, + 0x3fU, 0xf4U, 0xdeU, 0xf0U, 0x8eU, 0x4bU, 0x7aU, 0x9dU, 0xe5U, 0x76U, 0xd2U, 0x65U, 0x86U, 0xceU, 0xc6U, 0x4bU, + 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) + result.hexColumsPrint() + assertTrue { + result.contentEquals(expected) + } + + } + + +} \ 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 new file mode 100644 index 0000000..8445606 --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt @@ -0,0 +1,211 @@ +package com.ionspin.kotlin.crypto.authenticated + +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexColumsPrint +import kotlin.test.Ignore +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +class XChaCha20Poly1305Test { + + + @Test + fun xChaCha20Poly1305() { + assertTrue { + 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( + 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 + ) + val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) + val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, additionalData) + + encrypted.contentEquals(expected) && decrypted.contentEquals(message) + } + + assertTrue { + val message = ubyteArrayOf( + 0x00U + ) + val additionalData = ubyteArrayOf( + 0x00U + ) + val key = ubyteArrayOf( + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + ) + + val nonce = ubyteArrayOf( + 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0aU, 0x0bU, + 0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, 0x12U, 0x13U, 0x14U, 0x15U, 0x16U, 0x17U, + ) + + val expected = ubyteArrayOf( + 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) + + encrypted.contentEquals(expected) && decrypted.contentEquals(message) + } + + + } + @Ignore() //"Will fail because nonce is not a parameter any more" + @Test + fun updateableXChaCha20Poly1305() { + assertTrue { + 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( + 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 + ) +// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData) val firstChunk = +// xChaChaPoly.encryptPartialData(message) val finalChunk = xChaChaPoly.finishEncryption().first val result = +// firstChunk + finalChunk result.contentEquals(expected) + 1 == 1 + } + + assertTrue { + val message = ubyteArrayOf( + 0x00U + ) + val additionalData = ubyteArrayOf( + 0x00U + ) + val key = ubyteArrayOf( + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, + ) + + val nonce = ubyteArrayOf( + 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, 0x0aU, 0x0bU, + 0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, 0x12U, 0x13U, 0x14U, 0x15U, 0x16U, 0x17U, + ) + + val expected = ubyteArrayOf( + 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, + 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU + ) +// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData) +// val firstChunk = xChaChaPoly.encryptPartialData(message) +// val finalChunk = xChaChaPoly.finishEncryption().first +// val result = firstChunk + finalChunk +// result.contentEquals(expected) + 1 == 1 + } + + + } + + @Test + fun multipartXChaCha20Poly1305() { + val key = UByteArray(32) { 0U} + + val state = ubyteArrayOf( + 0x2DU, 0xDBU, 0xC7U, 0xB2U, 0x03U, 0xBCU, 0xC3U, 0x22U, 0xBDU, 0x0CU, 0xBAU, 0x82U, 0xADU, 0x77U, 0x79U, 0x44U, + 0xE6U, 0x8FU, 0xA9U, 0x94U, 0x89U, 0xB1U, 0xDFU, 0xBEU, 0x00U, 0x9FU, 0x69U, 0xECU, 0x21U, 0x88U, 0x47U, 0x55U, + 0x01U, 0x00U, 0x00U, 0x00U, 0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU, 0x00U, 0x00U, 0x00U, 0x00U, + 0x00U, 0x00U, 0x00U, 0x00U, + ) + val header = ubyteArrayOf( + 0x49U, 0x62U, 0x22U, 0x03U, 0xB7U, 0x46U, 0x11U, 0x97U, 0x8FU, 0x46U, 0x4AU, 0x3BU, 0x2FU, 0x2AU, 0x81U, 0x03U, + 0xC5U, 0x55U, 0x06U, 0x38U, 0xEBU, 0xA3U, 0x12U, 0x7BU, + ) + val expected = ubyteArrayOf( + 0xAFU, 0xD3U, 0x2DU, 0x59U, 0xB8U, 0xC4U, 0x66U, 0x2EU, 0x47U, 0x29U, 0xC6U, 0xF9U, 0x93U, 0x4BU, 0x09U, 0x27U, + 0x24U, 0xDDU, 0xF3U, 0x05U, 0x48U, 0x94U, 0x67U, 0x10U, 0x00U, 0x21U, 0x85U, 0x22U, 0x96U, 0x3CU, 0xCEU, 0x8EU, + 0xB7U, 0x53U, 0x9DU, 0x46U, 0xF5U, 0x3CU, 0x5EU, 0x48U, 0x9BU, 0x8CU, 0x13U, 0xB7U, 0x28U, 0x6BU, 0xB3U, 0x6CU, + 0x3AU, 0x04U, 0xB7U, 0x25U, 0xB9U, 0x50U, 0x45U, 0x08U, 0x0BU, 0x89U, 0xA2U, 0x0FU, 0x70U, 0xCCU, 0x60U, 0x1BU, + 0xC3U, 0x17U, 0x35U, 0x9FU, 0xAEU, 0x82U, 0x51U, 0x43U, 0x1BU, 0x9DU, 0x53U, 0x9EU, 0xE2U, 0xAFU, 0x20U, 0x1FU, + 0xFDU, 0x03U, 0x59U, 0x11U, 0x51U, 0x9EU, 0xACU, 0x83U, 0xCDU, 0x78U, 0xD1U, 0xD0U, 0xE5U, 0xD7U, 0x0EU, 0x41U, + 0xDEU, 0xFBU, 0x5CU, 0x7FU, 0x1CU, 0x26U, 0x32U, 0x2CU, 0x51U, 0xF6U, 0xEFU, 0xC6U, 0x34U, 0xC4U, 0xACU, 0x6CU, + 0xE8U, 0xF9U, 0x4BU, 0xABU, 0xA3U, + ) + + val xcha = XChaCha20Poly1305Pure(key, header) + //Verify the state is correctly created + assertTrue { + xcha.calcKey.contentEquals(state.sliceArray(0 until 32)) + xcha.calcNonce.contentEquals(state.sliceArray(32 until 44)) + } + val data = UByteArray(100) { 0U } + xcha.streamEncrypt(data, ubyteArrayOf(), 0U).hexColumsPrint() + } +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt index f198667..b90cbd6 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2BTest.kt @@ -17,6 +17,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import kotlin.test.Test import kotlin.test.assertFailsWith import kotlin.test.assertTrue @@ -82,7 +83,7 @@ class Blake2BTest { val expectedResultString = "800bb78cd4da18995c8074713bb674" + "3cd94b2b6490a693fe4000ed00833b88b7b474d94af9cfed246b1b" + "4ce1935a76154d7ea7c410493557741d18ec3a08da75" - val expectedResult = expectedResultString.chunked(2).map { it.toUByte(16) }.toUByteArray() + val expectedResult = expectedResultString.hexStringToUByteArray() assertTrue { result.contentEquals(expectedResult) @@ -123,7 +124,7 @@ class Blake2BTest { } val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" + "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") - .chunked(2).map { it.toUByte(16) }.toUByteArray() + .hexStringToUByteArray() assertTrue { result.contentEquals(expectedResult) @@ -291,4 +292,4 @@ class Blake2BTest { } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt index b9b1e95..68cb23e 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bInstanceTest.kt @@ -16,6 +16,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import com.ionspin.kotlin.crypto.util.toHexString import kotlin.test.Test import kotlin.test.assertTrue @@ -84,10 +85,10 @@ class Blake2bInstanceTest { } val expectedResult = ("5c6a9a4ae911c02fb7e71a991eb9aea371ae993d4842d206e" + "6020d46f5e41358c6d5c277c110ef86c959ed63e6ecaaaceaaff38019a43264ae06acf73b9550b1") - .chunked(2).map { it.toUByte(16) }.toUByteArray() + .hexStringToUByteArray() assertTrue { result.contentEquals(expectedResult) } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt index ab3dc88..21fb963 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bKnowAnswerTests.kt @@ -16,6 +16,7 @@ package com.ionspin.kotlin.crypto.hash.blake2b +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import kotlin.test.Test import kotlin.test.assertTrue @@ -36,13 +37,13 @@ class Blake2bKnowAnswerTests { @Test fun knownAnswerTest() { kat.forEach { - val parsedInput = it.input.chunked(2).map { it.toUByte(16) }.toUByteArray() + val parsedInput = it.input.hexStringToUByteArray() val result = Blake2bPure.digest( inputMessage = parsedInput, - key = it.key.chunked(2).map { it.toUByte(16) }.toUByteArray() + key = it.key.hexStringToUByteArray() ) assertTrue { - result.contentEquals(it.hash.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(it.hash.hexStringToUByteArray()) } } } @@ -51,13 +52,13 @@ class Blake2bKnowAnswerTests { fun knownAnswerTestInstance() { kat.forEach { kat -> - val parsedInput = kat.input.chunked(2).map { it.toUByte(16) }.toUByteArray() + val parsedInput = kat.input.hexStringToUByteArray() val chunkedInput = parsedInput.toList().chunked(128).map { it.toUByteArray() } - val blake2b = Blake2bPure(key = kat.key.chunked(2).map { it.toUByte(16) }.toUByteArray()) + val blake2b = Blake2bPure(key = kat.key.hexStringToUByteArray()) chunkedInput.forEach { blake2b.update(it) } val result = blake2b.digest() assertTrue("KAT ${kat.input} \nkey: ${kat.key} \nexpected: {${kat.hash}") { - result.contentEquals(kat.hash.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(kat.hash.hexStringToUByteArray()) } } } diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt index 83bc801..f77caf2 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Test.kt @@ -17,6 +17,7 @@ package com.ionspin.kotlin.crypto.hash.sha import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import kotlin.test.Test import kotlin.test.assertTrue @@ -35,7 +36,7 @@ class Sha256Test { val result = Sha256Pure.digest("abc".encodeToUByteArray()) val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } @@ -48,7 +49,7 @@ class Sha256Test { val resultDoubleBlock = Sha256Pure.digest("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq".encodeToUByteArray()) val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } @@ -61,7 +62,7 @@ class Sha256Test { println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } @@ -75,7 +76,7 @@ class Sha256Test { val resultDoubleBlock = Sha256Pure.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toUByteArray()) val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt index 8e94be5..8e18be7 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256UpdateableTest.kt @@ -16,6 +16,9 @@ package com.ionspin.kotlin.crypto.hash.sha +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertTrue @@ -36,7 +39,7 @@ class Sha256UpdatableTest { val result = sha256.digest() val expectedResult = "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } } @@ -49,7 +52,7 @@ class Sha256UpdatableTest { println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } @@ -62,7 +65,7 @@ class Sha256UpdatableTest { println(resultDoubleBlock.map{ it.toString(16)}.joinToString(separator = "")) val expectedResultForDoubleBlock = "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } @@ -73,28 +76,59 @@ class Sha256UpdatableTest { for (i in 0 until 10000) { sha256.update("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") } - val resultDoubleBlock = sha256.digest() - val expectedResultForDoubleBlock = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" + val result = sha256.digest() + val expectedResult = "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } } - @Ignore() - + @Ignore // Takes too long on native and js, but it now finishes correctly (and surprisingly quickly) on JVM @Test fun testWellKnownLonger() { - val sha256 = Sha256Pure() - for (i in 0 until 16_777_216) { - if (i % 10000 == 0) { - println("$i/16777216") + + //Obtained from libsodium runs + val roundsExpectedMap = mapOf( + 0 to "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + 1 to "2ff100b36c386c65a1afc462ad53e25479bec9498ed00aa5a04de584bc25301b", + 2 to "a9161e25f5e45eddf9a4cfa8b23456ba66be8098e474dc145bfceb2a99808b89", + 3 to "7bd37dc113762cb012b69105b6302638d414ebfcabde205669aab2b8bbe1f3c4", + 4 to "8fa352dc79b2482d1b55777b4932aff67f52e87bafdf9b9d45d57405a672de7a", + 5 to "a229ab9b1bce3f3281b9d06a592aadb7e765029472a6b9ebf5ecd6c45a31f2f6", + 6 to "09b49600c40293a902e52f89478d4886cf5771faabe38f53a63f3e9051b23e32", + 7 to "02372493fd93330a8371f1dea20f5c29e5411baa1b08ba6cb33c6ca745c364a1", + 8 to "e38b73d311ac89575d4e69a965763cdc618d0879142574231268f2b014fd0fec", + 9 to "37ed309f368eef8560c8cbfb1d8b619f3cc5460689984b8c687f46373ff62087", + 0 to "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + 1000000 to "7d9d6bcd4ffc9eb37899bbd7b5810e1762c55e4104f1b26b061349dbc67b5500", + 2000000 to "6b324148d357b3bb6549d339cec1a2a9ce45543eca0efcece78eecb3337097c2", + 3000000 to "3a52d0fb3383bca84dab55b2f41f0827d08325dbc65e3db4f15264597a8ac828", + 4000000 to "afd4587cf84fe7b6ffd7146a702d9b5dd4f0b754971eef36b7e0a6c4c3e84d58", + 5000000 to "d2b74e1a88652cce4450c3040decf40f9496ec92ad5e3443045922952db7894d", + 6000000 to "6e27932f14dfbbce11c9c9523e8b5a11616fd7864504d607639a98f81d5c0701", + 7000000 to "06e320b651981e13fb192805ff12a848815671d15885b636f99148b0089efabe", + 8000000 to "acc52c42ee92c046430f6e5454670e4f82da684a157eddd393a74c6883c881a5", + 9000000 to "493a7d3a40f3575bd5e5b4a5fec005f37392f3ce44565da314d173a062f499be", + 10000000 to "b3c6a178986ae0f5c81875ed68da2c72c8be961e9abc05e02982f723bd52a489", + 11000000 to "48387a098f9e919ea15ae5d1a347857f1043116e24bf9224b718120e0bfdaa9f", + 12000000 to "3ec9b9e64073f1c89f6d1c817a75610294d32c33d089af45540a352634e4a74a", + 13000000 to "cfb7c272408acdabf35c5cf1e2c0e2e81092d4e86bf8d51575a8a3baea2e7f8c", + 14000000 to "aa678e14a7d9a160177d52f153f30edd20c7f8a25fe36a3500fc1e11bd99029f", + 15000000 to "77c0a6256b17d6fdfd0926312ab168c6ac7357b11e93933e31f2f5fd5aefd400", + 16000000 to "28598fc683ac23a324e732ae398e093b5b80b03f01bdcf2f2d1b8e6bc76d183e", + 16777216 to "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e", + ) + val encoded = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno".encodeToUByteArray() + for (roundsExpected in roundsExpectedMap) { + val sha256 = Sha256Pure() + for (i in 0 until roundsExpected.key) { + sha256.update(encoded) + } + val result = sha256.digest() + assertTrue("Failed on ${roundsExpected.key} rounds, expected ${roundsExpected.value}, but got result ${result.toHexString()}") { + result.contentEquals(roundsExpected.value.hexStringToUByteArray()) } - sha256.update("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno") - } - val resultDoubleBlock = sha256.digest() - val expectedResultForDoubleBlock = "50e72a0e26442fe2552dc3938ac58658228c0cbfb1d2ca872ae435266fcd055e" - assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) } + } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt index 18ac132..0378054 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Test.kt @@ -16,6 +16,7 @@ package com.ionspin.kotlin.crypto.hash.sha +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import kotlin.test.Test import kotlin.test.assertTrue @@ -35,7 +36,7 @@ class Sha512Test { val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } @@ -51,7 +52,7 @@ class Sha512Test { val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" + "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } @@ -65,7 +66,7 @@ class Sha512Test { val resultDoubleBlock = Sha512Pure.digest(inputMessage = (inputBuilder.toString()).encodeToByteArray().map { it.toUByte() }.toUByteArray()) val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt index 3ea6e0c..38aa37e 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512UpdateableTest.kt @@ -16,6 +16,7 @@ package com.ionspin.kotlin.crypto.hash.sha +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertTrue @@ -35,7 +36,7 @@ class Sha512UpdatableTest { val expectedResult = "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a" + "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f" assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } @@ -51,7 +52,7 @@ class Sha512UpdatableTest { val expectedResultForDoubleBlock = "8e959b75dae313da8cf4f72814fc143f8f7779c6eb9f7fa17299aeadb6889018" + "501d289e4900f7e4331b99dec4b5433ac7d329eeb6dd26545e96e55b874be909" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } @@ -65,25 +66,22 @@ class Sha512UpdatableTest { val resultDoubleBlock = sha512.digest() val expectedResultForDoubleBlock = "e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.hexStringToUByteArray()) } } - @Ignore() //Interestingly enough I'm not the only one having trouble with this test. + @Ignore // Takes too long on native and js, but it now finishes correctly (and surprisingly quickly) on JVM @Test fun testWellKnownLonger() { val sha512 = Sha512Pure() for (i in 0 until 16_777_216) { - if (i % 10000 == 0) { - println("$i/16777216") - } sha512.update("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmno") } - val resultDoubleBlock = sha512.digest() - val expectedResultForDoubleBlock = "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086" + val result = sha512.digest() + val expectedResult = "b47c933421ea2db149ad6e10fce6c7f93d0752380180ffd7f4629a712134831d77be6091b819ed352c2967a2e2d4fa5050723c9630691f1a05a7281dbe6c1086" assertTrue { - resultDoubleBlock.contentEquals(expectedResultForDoubleBlock.chunked(2).map { it.toUByte(16) }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } } -} \ No newline at end of file +} 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 new file mode 100644 index 0000000..a163517 --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt @@ -0,0 +1,48 @@ +package com.ionspin.kotlin.crypto.highlevel + +import com.ionspin.kotlin.crypto.Crypto +import com.ionspin.kotlin.crypto.SymmetricKey +import com.ionspin.kotlin.crypto.hash.decodeToString +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexColumsPrint +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 09-Jul-2020 + */ +class EncryptionTest { + @Test + fun testMultipartEncryption() { + val plaintext = ("pUoR4JVXJUeMKNkt6ZGGzEdTo33ajNGXwXpivBKA0XKs8toGRYI9Eul4bELRDkaQDNhd4vZseEFU" + + "ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" + + "EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray() + plaintext.hexColumsPrint() + val additionalData = "Additional data 1".encodeToUByteArray() +// val additionalData = 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 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 plaintext2 = decryptor.decryptPartialData(ciphertext2) + val plaintext3 = decryptor.decryptPartialData(ciphertext3) + + val combinedPlaintext = plaintext1.data + plaintext2.data + plaintext3.data + + combinedPlaintext.hexColumsPrint() + assertTrue { + plaintext.contentEquals(combinedPlaintext) + } + + + + } +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305Test.kt new file mode 100644 index 0000000..b24c72e --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305Test.kt @@ -0,0 +1,224 @@ +package com.ionspin.kotlin.crypto.mac + +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 18-Jun-2020 + */ +class Poly1305Test { + + /** + * From RFC7539 + */ + @Test + fun testPoly1305() { + assertTrue { + val key = ubyteArrayOf( + 0x85U, 0xd6U, 0xbeU, 0x78U, 0x57U, 0x55U, 0x6dU, + 0x33U, 0x7fU, 0x44U, 0x52U, 0xfeU, 0x42U, 0xd5U, + 0x06U, 0xa8U, 0x01U, 0x03U, 0x80U, 0x8aU, 0xfbU, + 0x0dU, 0xb2U, 0xfdU, 0x4aU, 0xbfU, 0xf6U, 0xafU, + 0x41U, 0x49U, 0xf5U, 0x1bU + ) + val message = ubyteArrayOf( + 0x43U, 0x72U, 0x79U, 0x70U, 0x74U, 0x6fU, 0x67U, 0x72U, + 0x61U, 0x70U, 0x68U, 0x69U, 0x63U, 0x20U, 0x46U, 0x6fU, + 0x72U, 0x75U, 0x6dU, 0x20U, 0x52U, 0x65U, 0x73U, 0x65U, + 0x61U, 0x72U, 0x63U, 0x68U, 0x20U, 0x47U, 0x72U, 0x6fU, + 0x75U, 0x70U + ) + val expected = ubyteArrayOf( + 0xA8U, 0x06U, 0x1DU, 0xC1U, + 0x30U, 0x51U, 0x36U, 0xC6U, + 0xC2U, 0x2BU, 0x8BU, 0xAFU, + 0x0CU, 0x01U, 0x27U, 0xA9U, + ) + + val result = + Poly1305.poly1305Authenticate( + key, + message, + ) + expected.contentEquals(result) + } + assertTrue { + val key = ubyteArrayOf( + 0x85U, 0x1fU, 0xc4U, 0x0cU, 0x34U, 0x67U, 0xacU, 0x0bU, + 0xe0U, 0x5cU, 0xc2U, 0x04U, 0x04U, 0xf3U, 0xf7U, 0x00U, + 0x58U, 0x0bU, 0x3bU, 0x0fU, 0x94U, 0x47U, 0xbbU, 0x1eU, + 0x69U, 0xd0U, 0x95U, 0xb5U, 0x92U, 0x8bU, 0x6dU, 0xbcU + ) + val message = ubyteArrayOf( + 0xf3U, 0xf6U + ) + val expected = ubyteArrayOf( + 0xf4U, 0xc6U, 0x33U, 0xc3U, 0x04U, 0x4fU, 0xc1U, 0x45U, + 0xf8U, 0x4fU, 0x33U, 0x5cU, 0xb8U, 0x19U, 0x53U, 0xdeU + ) + + val result = + Poly1305.poly1305Authenticate( + key, + message, + ) + expected.contentEquals(result) + } + + assertTrue { + val key = ubyteArrayOf( + 0x75U, 0xdeU, 0xaaU, 0x25U, 0xc0U, 0x9fU, 0x20U, 0x8eU, + 0x1dU, 0xc4U, 0xceU, 0x6bU, 0x5cU, 0xadU, 0x3fU, 0xbfU, + 0xddU, 0x3fU, 0xabU, 0x22U, 0x51U, 0xf1U, 0x1aU, 0xc7U, + 0x59U, 0xf0U, 0x88U, 0x71U, 0x29U, 0xccU, 0x2eU, 0xe7U, + ) + val message = ubyteArrayOf( + + ) + val expected = ubyteArrayOf( + 0xddU, 0x3fU, 0xabU, 0x22U, 0x51U, 0xf1U, 0x1aU, 0xc7U, + 0x59U, 0xf0U, 0x88U, 0x71U, 0x29U, 0xccU, 0x2eU, 0xe7U + ) + + val result = + Poly1305.poly1305Authenticate( + key, + message, + ) + expected.contentEquals(result) + } + + assertTrue { + val key = ubyteArrayOf( + 0x12U, 0x97U, 0x6aU, 0x08U, 0xc4U, 0x42U, 0x6dU, 0x0cU, + 0xe8U, 0xa8U, 0x24U, 0x07U, 0xc4U, 0xf4U, 0x82U, 0x07U, + 0x80U, 0xf8U, 0xc2U, 0x0aU, 0xa7U, 0x12U, 0x02U, 0xd1U, + 0xe2U, 0x91U, 0x79U, 0xcbU, 0xcbU, 0x55U, 0x5aU, 0x57U + ) + val message = ubyteArrayOf( + 0xabU, 0x08U, 0x12U, 0x72U, 0x4aU, 0x7fU, 0x1eU, 0x34U, + 0x27U, 0x42U, 0xcbU, 0xedU, 0x37U, 0x4dU, 0x94U, 0xd1U, + 0x36U, 0xc6U, 0xb8U, 0x79U, 0x5dU, 0x45U, 0xb3U, 0x81U, + 0x98U, 0x30U, 0xf2U, 0xc0U, 0x44U, 0x91U, 0xfaU, 0xf0U, + 0x99U, 0x0cU, 0x62U, 0xe4U, 0x8bU, 0x80U, 0x18U, 0xb2U, + 0xc3U, 0xe4U, 0xa0U, 0xfaU, 0x31U, 0x34U, 0xcbU, 0x67U, + 0xfaU, 0x83U, 0xe1U, 0x58U, 0xc9U, 0x94U, 0xd9U, 0x61U, + 0xc4U, 0xcbU, 0x21U, 0x09U, 0x5cU, 0x1bU, 0xf9U, + ) + val expected = ubyteArrayOf( + 0x51U, 0x54U, 0xadU, 0x0dU, 0x2cU, 0xb2U, 0x6eU, 0x01U, + 0x27U, 0x4fU, 0xc5U, 0x11U, 0x48U, 0x49U, 0x1fU, 0x1bU + ) + + val result = + Poly1305.poly1305Authenticate( + key, + message, + ) + expected.contentEquals(result) + } + } + + @Test + fun testUpdateablePoly1305() { + assertTrue { + val key = ubyteArrayOf( + 0x85U, 0xd6U, 0xbeU, 0x78U, 0x57U, 0x55U, 0x6dU, + 0x33U, 0x7fU, 0x44U, 0x52U, 0xfeU, 0x42U, 0xd5U, + 0x06U, 0xa8U, 0x01U, 0x03U, 0x80U, 0x8aU, 0xfbU, + 0x0dU, 0xb2U, 0xfdU, 0x4aU, 0xbfU, 0xf6U, 0xafU, + 0x41U, 0x49U, 0xf5U, 0x1bU + ) + val message = ubyteArrayOf( + 0x43U, 0x72U, 0x79U, 0x70U, 0x74U, 0x6fU, 0x67U, 0x72U, + 0x61U, 0x70U, 0x68U, 0x69U, 0x63U, 0x20U, 0x46U, 0x6fU, + 0x72U, 0x75U, 0x6dU, 0x20U, 0x52U, 0x65U, 0x73U, 0x65U, + 0x61U, 0x72U, 0x63U, 0x68U, 0x20U, 0x47U, 0x72U, 0x6fU, + 0x75U, 0x70U + ) + val expected = ubyteArrayOf( + 0xA8U, 0x06U, 0x1DU, 0xC1U, + 0x30U, 0x51U, 0x36U, 0xC6U, + 0xC2U, 0x2BU, 0x8BU, 0xAFU, + 0x0CU, 0x01U, 0x27U, 0xA9U, + ) + val poly = Poly1305(key) + poly.updateMac(message.sliceArray(0 until 16)) + poly.updateMac(message.sliceArray(16 until 32)) + val result = poly.finalizeMac(message.sliceArray(32 until 34)) + + expected.contentEquals(result) + } + assertTrue { + val key = ubyteArrayOf( + 0x85U, 0x1fU, 0xc4U, 0x0cU, 0x34U, 0x67U, 0xacU, 0x0bU, + 0xe0U, 0x5cU, 0xc2U, 0x04U, 0x04U, 0xf3U, 0xf7U, 0x00U, + 0x58U, 0x0bU, 0x3bU, 0x0fU, 0x94U, 0x47U, 0xbbU, 0x1eU, + 0x69U, 0xd0U, 0x95U, 0xb5U, 0x92U, 0x8bU, 0x6dU, 0xbcU + ) + val message = ubyteArrayOf( + 0xf3U, 0xf6U + ) + val expected = ubyteArrayOf( + 0xf4U, 0xc6U, 0x33U, 0xc3U, 0x04U, 0x4fU, 0xc1U, 0x45U, + 0xf8U, 0x4fU, 0x33U, 0x5cU, 0xb8U, 0x19U, 0x53U, 0xdeU + ) + + val poly = Poly1305(key) + val result = poly.finalizeMac(message) + expected.contentEquals(result) + } + + assertTrue { + val key = ubyteArrayOf( + 0x75U, 0xdeU, 0xaaU, 0x25U, 0xc0U, 0x9fU, 0x20U, 0x8eU, + 0x1dU, 0xc4U, 0xceU, 0x6bU, 0x5cU, 0xadU, 0x3fU, 0xbfU, + 0xddU, 0x3fU, 0xabU, 0x22U, 0x51U, 0xf1U, 0x1aU, 0xc7U, + 0x59U, 0xf0U, 0x88U, 0x71U, 0x29U, 0xccU, 0x2eU, 0xe7U, + ) + val message = ubyteArrayOf( + + ) + val expected = ubyteArrayOf( + 0xddU, 0x3fU, 0xabU, 0x22U, 0x51U, 0xf1U, 0x1aU, 0xc7U, + 0x59U, 0xf0U, 0x88U, 0x71U, 0x29U, 0xccU, 0x2eU, 0xe7U + ) + + val poly = Poly1305(key) + val result = poly.finalizeMac(message) + expected.contentEquals(result) + } + + assertTrue { + val key = ubyteArrayOf( + 0x12U, 0x97U, 0x6aU, 0x08U, 0xc4U, 0x42U, 0x6dU, 0x0cU, + 0xe8U, 0xa8U, 0x24U, 0x07U, 0xc4U, 0xf4U, 0x82U, 0x07U, + 0x80U, 0xf8U, 0xc2U, 0x0aU, 0xa7U, 0x12U, 0x02U, 0xd1U, + 0xe2U, 0x91U, 0x79U, 0xcbU, 0xcbU, 0x55U, 0x5aU, 0x57U + ) + val message = ubyteArrayOf( + 0xabU, 0x08U, 0x12U, 0x72U, 0x4aU, 0x7fU, 0x1eU, 0x34U, + 0x27U, 0x42U, 0xcbU, 0xedU, 0x37U, 0x4dU, 0x94U, 0xd1U, + 0x36U, 0xc6U, 0xb8U, 0x79U, 0x5dU, 0x45U, 0xb3U, 0x81U, + 0x98U, 0x30U, 0xf2U, 0xc0U, 0x44U, 0x91U, 0xfaU, 0xf0U, + 0x99U, 0x0cU, 0x62U, 0xe4U, 0x8bU, 0x80U, 0x18U, 0xb2U, + 0xc3U, 0xe4U, 0xa0U, 0xfaU, 0x31U, 0x34U, 0xcbU, 0x67U, + 0xfaU, 0x83U, 0xe1U, 0x58U, 0xc9U, 0x94U, 0xd9U, 0x61U, + 0xc4U, 0xcbU, 0x21U, 0x09U, 0x5cU, 0x1bU, 0xf9U, + ) + val expected = ubyteArrayOf( + 0x51U, 0x54U, 0xadU, 0x0dU, 0x2cU, 0xb2U, 0x6eU, 0x01U, + 0x27U, 0x4fU, 0xc5U, 0x11U, 0x48U, 0x49U, 0x1fU, 0x1bU + ) + + val poly = Poly1305(key) + poly.updateMac(message.sliceArray(0 until 16)) + poly.updateMac(message.sliceArray(16 until 32)) + poly.updateMac(message.sliceArray(32 until 48)) + val result = poly.finalizeMac(message.sliceArray(48 until 63)) + expected.contentEquals(result) + } + } +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/parallelization/CoroutinesDebugTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/parallelization/CoroutinesDebugTest.kt deleted file mode 100644 index a6a0f05..0000000 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/parallelization/CoroutinesDebugTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.parallelization - -import com.ionspin.kotlin.crypto.util.testBlocking -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlin.test.Test -import kotlin.time.ExperimentalTime - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 17-May-2020 - */ -@ExperimentalTime -class CoroutinesDebugTest { - - @Test - fun debugTest() = testBlocking { - Coroutines14.argonParallel() - } -} \ No newline at end of file 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 4196616..8a6af88 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 @@ -37,13 +37,13 @@ class AesCbcTest { val plaintext = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" val expectedCipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" val aesCbc = - AesCbcPure(AesKey.Aes128Key(key), mode = Mode.ENCRYPT, initializationVector = iv.hexStringToUByteArray()) + AesCbcPure(InternalAesKey.Aes128Key(key), mode = Mode.ENCRYPT, initializationVector = iv.hexStringToUByteArray()) aesCbc.addData(plaintext.hexStringToUByteArray()) val encrypted = aesCbc.encrypt() println("Encrypted: ${encrypted.encryptedData.toHexString()}") expectedCipherText == encrypted.encryptedData.toHexString() && - iv == encrypted.initilizationVector.toHexString() + iv == encrypted.initializationVector.toHexString() } @@ -54,7 +54,7 @@ class AesCbcTest { fun testEncryptionApi() { assertTrue { val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" - val key = AesKey.Aes128Key(keyString) + val key = InternalAesKey.Aes128Key(keyString) val plainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" @@ -62,7 +62,7 @@ class AesCbcTest { val decrypted = AesCbcPure.decrypt( key, encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initilizationVector + encryptedDataAndInitializationVector.initializationVector ) plainText == decrypted.toHexString() } @@ -76,7 +76,7 @@ class AesCbcTest { val cipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" val expectedPlainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" val aesCbc = - AesCbcPure(AesKey.Aes128Key(key), mode = Mode.DECRYPT, initializationVector = iv.hexStringToUByteArray()) + AesCbcPure(InternalAesKey.Aes128Key(key), mode = Mode.DECRYPT, initializationVector = iv.hexStringToUByteArray()) aesCbc.addData(cipherText.hexStringToUByteArray()) val decrypted = aesCbc.decrypt() println("Decrypted: ${decrypted.toHexString()}") @@ -95,7 +95,7 @@ class AesCbcTest { val iv = "57f02a5c5339daeb0a2908a06ac6393f" val cipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" val expectedPlainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" - val decrypted = AesCbcPure.decrypt(AesKey.Aes128Key(key), cipherText.hexStringToUByteArray(), iv.hexStringToUByteArray()) + val decrypted = AesCbcPure.decrypt(InternalAesKey.Aes128Key(key), cipherText.hexStringToUByteArray(), iv.hexStringToUByteArray()) println("Decrypted: ${decrypted.toHexString()}") expectedPlainText == decrypted.toHexString() diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt index 480374a..457e59c 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrTest.kt @@ -38,7 +38,7 @@ class AesCtrTest { "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" val expectedCipherText = "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee" - val aesCtr = AesCtrPure(AesKey.Aes128Key(key), mode = Mode.ENCRYPT, initialCounter = ic.hexStringToUByteArray()) + val aesCtr = AesCtrPure(InternalAesKey.Aes128Key(key), mode = Mode.ENCRYPT, initialCounter = ic.hexStringToUByteArray()) aesCtr.addData( plaintext.hexStringToUByteArray() ) @@ -54,7 +54,7 @@ class AesCtrTest { @Test fun testEncryptionApi() { val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" - val key = AesKey.Aes128Key(keyString) + val key = InternalAesKey.Aes128Key(keyString) val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" val encryptedDataAndInitializationVector = AesCtrPure.encrypt(key, plainText.hexStringToUByteArray()) @@ -77,7 +77,7 @@ class AesCtrTest { "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee" val expectedPlainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" - val aesCtr = AesCtrPure(AesKey.Aes128Key(key), mode = Mode.DECRYPT, initialCounter = ic.hexStringToUByteArray()) + val aesCtr = AesCtrPure(InternalAesKey.Aes128Key(key), mode = Mode.DECRYPT, initialCounter = ic.hexStringToUByteArray()) aesCtr.addData(cipherText.hexStringToUByteArray()) val decrypted = aesCtr.decrypt() println("Decrypted: ${decrypted.toHexString()}") @@ -97,7 +97,7 @@ class AesCtrTest { "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee" val expectedPlainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" - val decrypted = AesCtrPure.decrypt(AesKey.Aes128Key(key), cipherText.hexStringToUByteArray(), ic.hexStringToUByteArray()) + val decrypted = AesCtrPure.decrypt(InternalAesKey.Aes128Key(key), cipherText.hexStringToUByteArray(), ic.hexStringToUByteArray()) println("Decrypted: ${decrypted.toHexString()}") expectedPlainText == decrypted.toHexString() } diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt index e733cb0..be3bbd8 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesTest.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.symmetric +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import kotlin.test.Test import kotlin.test.assertTrue @@ -20,7 +21,7 @@ class AesTest { ubyteArrayOf(0U, 0U, 0U, 0U), ubyteArrayOf(0U, 0U, 0U, 0U) ) - val aes = AesPure(AesKey.Aes128Key(irrelevantKey), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes128Key(irrelevantKey), irrelevantInput) fakeState.copyInto(aes.state) aes.subBytes() assertTrue { @@ -42,7 +43,7 @@ class AesTest { ubyteArrayOf(2U, 3U, 0U, 1U), ubyteArrayOf(3U, 0U, 1U, 2U) ) - val aes = AesPure(AesKey.Aes128Key(irrelevantKey), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes128Key(irrelevantKey), irrelevantInput) fakeState.copyInto(aes.state) aes.shiftRows() assertTrue { @@ -56,7 +57,7 @@ class AesTest { assertTrue { val a = 0x57U val b = 0x83U - val aes = AesPure(AesKey.Aes128Key(irrelevantKey), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes128Key(irrelevantKey), irrelevantInput) val c = aes.galoisFieldMultiply(a.toUByte(), b.toUByte()) c == 0xC1U.toUByte() } @@ -64,7 +65,7 @@ class AesTest { assertTrue { val a = 0x57U val b = 0x13U - val aes = AesPure(AesKey.Aes128Key(irrelevantKey), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes128Key(irrelevantKey), irrelevantInput) val c = aes.galoisFieldMultiply(a.toUByte(), b.toUByte()) c == 0xFEU.toUByte() } @@ -89,7 +90,7 @@ class AesTest { ubyteArrayOf(0xbcU, 0x9dU, 0x01U, 0xc6U) ) - val aes = AesPure(AesKey.Aes128Key(irrelevantKey), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes128Key(irrelevantKey), irrelevantInput) fakeState.copyInto(aes.state) aes.mixColumns() assertTrue { @@ -116,7 +117,7 @@ class AesTest { ).toTypedArray() - val aes = AesPure(AesKey.Aes128Key(key), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes128Key(key), irrelevantInput) val result = aes.expandedKey.map { it.foldIndexed(0U) { index, acc, uByte -> acc + (uByte.toUInt() shl (24 - index * 8)) @@ -140,7 +141,7 @@ class AesTest { ).toTypedArray() - val aes = AesPure(AesKey.Aes192Key(key), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes192Key(key), irrelevantInput) val result = aes.expandedKey.map { it.foldIndexed(0U) { index, acc, uByte -> acc + (uByte.toUInt() shl (24 - index * 8)) @@ -166,7 +167,7 @@ class AesTest { ).toTypedArray() - val aes = AesPure(AesKey.Aes256Key(key), irrelevantInput) + val aes = AesPure(InternalAesKey.Aes256Key(key), irrelevantInput) val result = aes.expandedKey.map { it.foldIndexed(0U) { index, acc, uByte -> acc + (uByte.toUInt() shl (24 - index * 8)) @@ -183,10 +184,10 @@ class AesTest { val key = "2b7e151628aed2a6abf7158809cf4f3c" val expectedResult = "3925841d02dc09fbdc118597196a0b32" - val aes = AesPure(AesKey.Aes128Key(key), input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) + val aes = AesPure(InternalAesKey.Aes128Key(key), input.hexStringToUByteArray()) val result = aes.encrypt() assertTrue { - result.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) + result.contentEquals(expectedResult.hexStringToUByteArray()) } } @@ -196,13 +197,13 @@ class AesTest { val input = "3243f6a8885a308d313198a2e0370734" val key = "2b7e151628aed2a6abf7158809cf4f3c" val expectedResult = "3925841d02dc09fbdc118597196a0b32" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() - val aes = AesPure(AesKey.Aes128Key(key), original) + val original = input.hexStringToUByteArray() + val aes = AesPure(InternalAesKey.Aes128Key(key), original) val encrypted = aes.encrypt() assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) + encrypted.contentEquals(expectedResult.hexStringToUByteArray()) } - val decrypted = AesPure.decrypt(AesKey.Aes128Key(key), encrypted) + val decrypted = AesPure.decrypt(InternalAesKey.Aes128Key(key), encrypted) decrypted.contentEquals(original) } @@ -210,13 +211,13 @@ class AesTest { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f" val expectedResult = "69c4e0d86a7b0430d8cdb78070b4c55a" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() - val aes = AesPure(AesKey.Aes128Key(key), original) + val original = input.hexStringToUByteArray() + val aes = AesPure(InternalAesKey.Aes128Key(key), original) val encrypted = aes.encrypt() assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) + encrypted.contentEquals(expectedResult.hexStringToUByteArray()) } - val aesDec = AesPure(AesKey.Aes128Key(key), encrypted) + val aesDec = AesPure(InternalAesKey.Aes128Key(key), encrypted) val decrypted = aesDec.decrypt() assertTrue { aesDec.expandedKey.contentDeepEquals(aes.expandedKey) @@ -228,12 +229,12 @@ class AesTest { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f" val expectedResult = "69c4e0d86a7b0430d8cdb78070b4c55a" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() - val encrypted = AesPure.encrypt(AesKey.Aes128Key(key), original) + val original = input.hexStringToUByteArray() + val encrypted = AesPure.encrypt(InternalAesKey.Aes128Key(key), original) assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) + encrypted.contentEquals(expectedResult.hexStringToUByteArray()) } - val decrypted = AesPure.decrypt(AesKey.Aes128Key(key), encrypted) + val decrypted = AesPure.decrypt(InternalAesKey.Aes128Key(key), encrypted) decrypted.contentEquals(original) } @@ -241,12 +242,12 @@ class AesTest { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f1011121314151617" val expectedResult = "dda97ca4864cdfe06eaf70a0ec0d7191" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() - val encrypted = AesPure.encrypt(AesKey.Aes192Key(key), original) + val original = input.hexStringToUByteArray() + val encrypted = AesPure.encrypt(InternalAesKey.Aes192Key(key), original) assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) + encrypted.contentEquals(expectedResult.hexStringToUByteArray()) } - val decrypted = AesPure.decrypt(AesKey.Aes192Key(key), encrypted) + val decrypted = AesPure.decrypt(InternalAesKey.Aes192Key(key), encrypted) decrypted.contentEquals(original) } @@ -254,16 +255,16 @@ class AesTest { val input = "00112233445566778899aabbccddeeff" val key = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" val expectedResult = "8ea2b7ca516745bfeafc49904b496089" - val original = input.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray() - val encrypted = AesPure.encrypt(AesKey.Aes256Key(key), original) + val original = input.hexStringToUByteArray() + val encrypted = AesPure.encrypt(InternalAesKey.Aes256Key(key), original) assertTrue { - encrypted.contentEquals(expectedResult.chunked(2).map { it.toInt(16).toUByte() }.toUByteArray()) + encrypted.contentEquals(expectedResult.hexStringToUByteArray()) } - val decrypted = AesPure.decrypt(AesKey.Aes256Key(key), encrypted) + val decrypted = AesPure.decrypt(InternalAesKey.Aes256Key(key), encrypted) decrypted.contentEquals(original) } } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Test.kt new file mode 100644 index 0000000..4687643 --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Test.kt @@ -0,0 +1,90 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 16-Jun-2020 + */ +class ChaCha20Test { + + + @Test + fun testQuarterRound() { + val a = 0x11111111U + val b = 0x01020304U + val c = 0x9b8d6f43U + val d = 0x01234567U + val input = uintArrayOf(a, b, c, d) + val aExpected = 0xea2a92f4U + val bExpected = 0xcb1cf8ceU + val cExpected = 0x4581472eU + val dExpected = 0x5881c4bbU + val expected = uintArrayOf(aExpected, bExpected, cExpected, dExpected) + ChaCha20Pure.quarterRound(input, 0, 1, 2, 3) + assertTrue { + input.contentEquals(expected) + } + } + + @Test + fun testBlockFunction() { + //From RFC 7539 + val state = uintArrayOf( + 0x61707865U, 0x3320646eU, 0x79622d32U, 0x6b206574U, + 0x03020100U, 0x07060504U, 0x0b0a0908U, 0x0f0e0d0cU, + 0x13121110U, 0x17161514U, 0x1b1a1918U, 0x1f1e1d1cU, + 0x00000001U, 0x09000000U, 0x4a000000U, 0x00000000U, + ) + val expected = ubyteArrayOf( + 0x10U, 0xf1U, 0xe7U, 0xe4U, 0xd1U, 0x3bU, 0x59U, 0x15U, 0x50U, 0x0fU, 0xddU, 0x1fU, 0xa3U, 0x20U, 0x71U, 0xc4U, + 0xc7U, 0xd1U, 0xf4U, 0xc7U, 0x33U, 0xc0U, 0x68U, 0x03U, 0x04U, 0x22U, 0xaaU, 0x9aU, 0xc3U, 0xd4U, 0x6cU, 0x4eU, + 0xd2U, 0x82U, 0x64U, 0x46U, 0x07U, 0x9fU, 0xaaU, 0x09U, 0x14U, 0xc2U, 0xd7U, 0x05U, 0xd9U, 0x8bU, 0x02U, 0xa2U, + 0xb5U, 0x12U, 0x9cU, 0xd1U, 0xdeU, 0x16U, 0x4eU, 0xb9U, 0xcbU, 0xd0U, 0x83U, 0xe8U, 0xa2U, 0x50U, 0x3cU, 0x4eU + ) + val result = ChaCha20Pure.hash(state) + assertTrue { + expected.contentEquals(result) + } + } + + @Test + fun testEncryption() { + + //From RFC 7539 + val key = ubyteArrayOf( + 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, + 0x06U, 0x07U, 0x08U, 0x09U, 0x0aU, 0x0bU, + 0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, + 0x12U, 0x13U, 0x14U, 0x15U, 0x16U, 0x17U, + 0x18U, 0x19U, 0x1aU, 0x1bU, 0x1cU, 0x1dU, + 0x1eU, 0x1fU + ) + val nonce = ubyteArrayOf( + 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x4aU, 0x00U, 0x00U, 0x00U, 0x00U + ) + 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 expected = ubyteArrayOf( + 0x6eU, 0x2eU, 0x35U, 0x9aU, 0x25U, 0x68U, 0xf9U, 0x80U, 0x41U, 0xbaU, 0x07U, 0x28U, 0xddU, 0x0dU, 0x69U, 0x81U, + 0xe9U, 0x7eU, 0x7aU, 0xecU, 0x1dU, 0x43U, 0x60U, 0xc2U, 0x0aU, 0x27U, 0xafU, 0xccU, 0xfdU, 0x9fU, 0xaeU, 0x0bU, + 0xf9U, 0x1bU, 0x65U, 0xc5U, 0x52U, 0x47U, 0x33U, 0xabU, 0x8fU, 0x59U, 0x3dU, 0xabU, 0xcdU, 0x62U, 0xb3U, 0x57U, + 0x16U, 0x39U, 0xd6U, 0x24U, 0xe6U, 0x51U, 0x52U, 0xabU, 0x8fU, 0x53U, 0x0cU, 0x35U, 0x9fU, 0x08U, 0x61U, 0xd8U, + 0x07U, 0xcaU, 0x0dU, 0xbfU, 0x50U, 0x0dU, 0x6aU, 0x61U, 0x56U, 0xa3U, 0x8eU, 0x08U, 0x8aU, 0x22U, 0xb6U, 0x5eU, + 0x52U, 0xbcU, 0x51U, 0x4dU, 0x16U, 0xccU, 0xf8U, 0x06U, 0x81U, 0x8cU, 0xe9U, 0x1aU, 0xb7U, 0x79U, 0x37U, 0x36U, + 0x5aU, 0xf9U, 0x0bU, 0xbfU, 0x74U, 0xa3U, 0x5bU, 0xe6U, 0xb4U, 0x0bU, 0x8eU, 0xedU, 0xf2U, 0x78U, 0x5eU, 0x42U, + 0x87U, 0x4dU, + ) + val result = ChaCha20Pure.xorWithKeystream(key, nonce, message, 1U) + assertTrue { + expected.contentEquals(result) + } + + + } + + +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Test.kt new file mode 100644 index 0000000..051722f --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Test.kt @@ -0,0 +1,395 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.symmetric.LatinDancesCommon.littleEndian +import com.ionspin.kotlin.crypto.symmetric.LatinDancesCommon.littleEndianInverted +import com.ionspin.kotlin.crypto.util.fromLittleEndianToUInt +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.rotateLeft +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 14-Jun-2020 + */ +class Salsa20Test { + + @Test + fun testRotateLeft() { + val a = 0xc0a8787eU + val b = a rotateLeft 5 + val expected = 0x150f0fd8U + assertEquals(b, expected) + } + + @Test + fun testQuarterRound() { + assertTrue { + val input = uintArrayOf(0U, 0U, 0U, 0U) + val expected = uintArrayOf(0U, 0U, 0U, 0U) + Salsa20Pure.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + + expected.contentEquals(input) + } + + assertTrue { + val input = uintArrayOf(1U, 0U, 0U, 0U) + val expected = uintArrayOf(0x08008145U, 0x00000080U, 0x00010200U, 0x20500000U) + Salsa20Pure.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + + expected.contentEquals(input) + } + + assertTrue { + val input = uintArrayOf(0U, 1U, 0U, 0U) + val expected = uintArrayOf(0x88000100U, 0x00000001U, 0x00000200U, 0x00402000U) + Salsa20Pure.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + + expected.contentEquals(input) + } + + assertTrue { + val input = uintArrayOf(0U, 0U, 1U, 0U) + val expected = uintArrayOf(0x80040000U, 0x00000000U, 0x00000001U, 0x00002000U) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + Salsa20Pure.quarterRound(input, 0, 1, 2, 3) + expected.contentEquals(input) + } + + assertTrue { + val input = uintArrayOf(0U, 0U, 0U, 1U) + val expected = uintArrayOf(0x00048044U, 0x00000080U, 0x00010000U, 0x20100001U) + Salsa20Pure.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + + expected.contentEquals(input) + } + + + assertTrue { + val input = uintArrayOf(0xd3917c5bU, 0x55f1c407U, 0x52a58a7aU, 0x8f887a3bU) + val expected = uintArrayOf(0x3e2f308cU, 0xd90a8f36U, 0x6ab2a923U, 0x2883524cU) + Salsa20Pure.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } + + @Test + fun testRowRound() { + assertTrue { + val input = uintArrayOf( + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U + ) + val expected = uintArrayOf( + 0x08008145U, 0x00000080U, 0x00010200U, 0x20500000U, + 0x20100001U, 0x00048044U, 0x00000080U, 0x00010000U, + 0x00000001U, 0x00002000U, 0x80040000U, 0x00000000U, + 0x00000001U, 0x00000200U, 0x00402000U, 0x88000100U + ) + + Salsa20Pure.rowRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + assertTrue { + + val input = uintArrayOf( + 0x08521bd6U, 0x1fe88837U, 0xbb2aa576U, 0x3aa26365U, + 0xc54c6a5bU, 0x2fc74c2fU, 0x6dd39cc3U, 0xda0a64f6U, + 0x90a2f23dU, 0x067f95a6U, 0x06b35f61U, 0x41e4732eU, + 0xe859c100U, 0xea4d84b7U, 0x0f619bffU, 0xbc6e965aU + ) + val expected = uintArrayOf( + 0xa890d39dU, 0x65d71596U, 0xe9487daaU, 0xc8ca6a86U, + 0x949d2192U, 0x764b7754U, 0xe408d9b9U, 0x7a41b4d1U, + 0x3402e183U, 0x3c3af432U, 0x50669f96U, 0xd89ef0a8U, + 0x0040ede5U, 0xb545fbceU, 0xd257ed4fU, 0x1818882dU + ) + Salsa20Pure.rowRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } + + @Test + fun testColumnRound() { + assertTrue { + val input = uintArrayOf( + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U + ) + val expected = uintArrayOf( + 0x10090288U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000101U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00020401U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x40a04001U, 0x00000000U, 0x00000000U, 0x00000000U + ) + + Salsa20Pure.columnRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + assertTrue { + + val input = uintArrayOf( + 0x08521bd6U, 0x1fe88837U, 0xbb2aa576U, 0x3aa26365U, + 0xc54c6a5bU, 0x2fc74c2fU, 0x6dd39cc3U, 0xda0a64f6U, + 0x90a2f23dU, 0x067f95a6U, 0x06b35f61U, 0x41e4732eU, + 0xe859c100U, 0xea4d84b7U, 0x0f619bffU, 0xbc6e965aU + ) + val expected = uintArrayOf( + 0x8c9d190aU, 0xce8e4c90U, 0x1ef8e9d3U, 0x1326a71aU, + 0x90a20123U, 0xead3c4f3U, 0x63a091a0U, 0xf0708d69U, + 0x789b010cU, 0xd195a681U, 0xeb7d5504U, 0xa774135cU, + 0x481c2027U, 0x53a8e4b5U, 0x4c1f89c5U, 0x3f78c9c8U + ) + Salsa20Pure.columnRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } + + @Test + fun testDoubleRound() { + assertTrue { + val input = uintArrayOf( + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U + ) + val expected = uintArrayOf( + 0x8186a22dU, 0x0040a284U, 0x82479210U, 0x06929051U, + 0x08000090U, 0x02402200U, 0x00004000U, 0x00800000U, + 0x00010200U, 0x20400000U, 0x08008104U, 0x00000000U, + 0x20500000U, 0xa0000040U, 0x0008180aU, 0x612a8020U + ) + + Salsa20Pure.doubleRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + assertTrue { + + val input = uintArrayOf( + 0xde501066U, 0x6f9eb8f7U, 0xe4fbbd9bU, 0x454e3f57U, + 0xb75540d3U, 0x43e93a4cU, 0x3a6f2aa0U, 0x726d6b36U, + 0x9243f484U, 0x9145d1e8U, 0x4fa9d247U, 0xdc8dee11U, + 0x054bf545U, 0x254dd653U, 0xd9421b6dU, 0x67b276c1U + ) + val expected = uintArrayOf( + 0xccaaf672U, 0x23d960f7U, 0x9153e63aU, 0xcd9a60d0U, + 0x50440492U, 0xf07cad19U, 0xae344aa0U, 0xdf4cfdfcU, + 0xca531c29U, 0x8e7943dbU, 0xac1680cdU, 0xd503ca00U, + 0xa74b2ad6U, 0xbc331c5cU, 0x1dda24c7U, 0xee928277U + ) + Salsa20Pure.doubleRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } + + @Test + fun littleEndianTest() { + assertTrue { + val input = ubyteArrayOf(86U, 75U, 30U, 9U) + val expected = 0x091e4b56U + val result = littleEndian(input, 0, 1, 2, 3) + result == expected + } + + assertTrue { + val input = ubyteArrayOf(255U, 255U, 255U, 250U) + val expected = 0xFAFFFFFFU + val result = littleEndian(input, 0, 1, 2, 3) + result == expected + } + } + + @Test + fun littleEndianInvertedArrayTest() { + assertTrue { + val expected = ubyteArrayOf(86U, 75U, 30U, 9U) + val input = uintArrayOf(0x091e4b56U) + val result = UByteArray(4) + littleEndianInverted(input, 0, result, 0) + result.contentEquals(expected) + } + + assertTrue { + val expected = ubyteArrayOf(255U, 255U, 255U, 250U) + val input = uintArrayOf(0xFAFFFFFFU) + val result = UByteArray(4) + littleEndianInverted(input, 0, result, 0) + result.contentEquals(expected) + } + } + + @Test + fun littleEndianInvertedTest() { + assertTrue { + val expected = ubyteArrayOf(86U, 75U, 30U, 9U) + val input = 0x091e4b56U + val result = UByteArray(4) + littleEndianInverted(input, result, 0) + result.contentEquals(expected) + } + + assertTrue { + val expected = ubyteArrayOf(255U, 255U, 255U, 250U) + val input = 0xFAFFFFFFU + val result = UByteArray(4) + littleEndianInverted(input, result, 0) + result.contentEquals(expected) + } + } + + @Test + fun salsa20HashTest() { + assertTrue { + val input = ubyteArrayOf( + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U + ) + val expected = ubyteArrayOf( + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U + ) + val result = Salsa20Pure.hash(input.fromLittleEndianToUInt()) + input.contentEquals(expected) + } + + assertTrue { + val input = ubyteArrayOf( + 211U, 159U, 13U, 115U, 76U, 55U, 82U, 183U, 3U, 117U, 222U, 37U, 191U, 187U, 234U, 136U, + 49U, 237U, 179U, 48U, 1U, 106U, 178U, 219U, 175U, 199U, 166U, 48U, 86U, 16U, 179U, 207U, + 31U, 240U, 32U, 63U, 15U, 83U, 93U, 161U, 116U, 147U, 48U, 113U, 238U, 55U, 204U, 36U, + 79U, 201U, 235U, 79U, 3U, 81U, 156U, 47U, 203U, 26U, 244U, 243U, 88U, 118U, 104U, 54U + ) + val expected = ubyteArrayOf( + 109U, 42U, 178U, 168U, 156U, 240U, 248U, 238U, 168U, 196U, 190U, 203U, 26U, 110U, 170U, 154U, + 29U, 29U, 150U, 26U, 150U, 30U, 235U, 249U, 190U, 163U, 251U, 48U, 69U, 144U, 51U, 57U, + 118U, 40U, 152U, 157U, 180U, 57U, 27U, 94U, 107U, 42U, 236U, 35U, 27U, 111U, 114U, 114U, + 219U, 236U, 232U, 135U, 111U, 155U, 110U, 18U, 24U, 232U, 95U, 158U, 179U, 19U, 48U, 202U + ) + val result = Salsa20Pure.hash(input.fromLittleEndianToUInt()) + result.contentEquals(expected) + } + + assertTrue { + val input = ubyteArrayOf( + 6U, 124U, 83U, 146U, 38U, 191U, 9U, 50U, 4U, 161U, 47U, 222U, 122U, 182U, 223U, 185U, + 75U, 27U, 0U, 216U, 16U, 122U, 7U, 89U, 162U, 104U, 101U, 147U, 213U, 21U, 54U, 95U, + 225U, 253U, 139U, 176U, 105U, 132U, 23U, 116U, 76U, 41U, 176U, 207U, 221U, 34U, 157U, 108U, + 94U, 94U, 99U, 52U, 90U, 117U, 91U, 220U, 146U, 190U, 239U, 143U, 196U, 176U, 130U, 186U + ) + val expected = ubyteArrayOf( + 8U, 18U, 38U, 199U, 119U, 76U, 215U, 67U, 173U, 127U, 144U, 162U, 103U, 212U, 176U, 217U, + 192U, 19U, 233U, 33U, 159U, 197U, 154U, 160U, 128U, 243U, 219U, 65U, 171U, 136U, 135U, 225U, + 123U, 11U, 68U, 86U, 237U, 82U, 20U, 155U, 133U, 189U, 9U, 83U, 167U, 116U, 194U, 78U, + 122U, 127U, 195U, 185U, 185U, 204U, 188U, 90U, 245U, 9U, 183U, 248U, 226U, 85U, 245U, 104U + ) + val result = (0 until 1_000_000).fold(input) { acc, _ -> + Salsa20Pure.hash(acc.fromLittleEndianToUInt()) + } + result.contentEquals(expected) + } + + } + + @Test + fun testExpansion() { + val k0 = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U) + val k1 = + ubyteArrayOf(201U, 202U, 203U, 204U, 205U, 206U, 207U, 208U, 209U, 210U, 211U, 212U, 213U, 214U, 215U, 216U) + val n = + ubyteArrayOf(101U, 102U, 103U, 104U, 105U, 106U, 107U, 108U, 109U, 110U, 111U, 112U, 113U, 114U, 115U, 116U) + + assertTrue { + val expected = ubyteArrayOf( + 69U, 37U, 68U, 39U, 41U, 15U, 107U, 193U, 255U, 139U, 122U, 6U, 170U, 233U, 217U, 98U, + 89U, 144U, 182U, 106U, 21U, 51U, 200U, 65U, 239U, 49U, 222U, 34U, 215U, 114U, 40U, 126U, + 104U, 197U, 7U, 225U, 197U, 153U, 31U, 2U, 102U, 78U, 76U, 176U, 84U, 245U, 246U, 184U, + 177U, 160U, 133U, 130U, 6U, 72U, 149U, 119U, 192U, 195U, 132U, 236U, 234U, 103U, 246U, 74U + ) + val result = Salsa20Pure.expansion32(k0 + k1, n) + result.contentEquals(expected) + } + + assertTrue { + val expected = ubyteArrayOf( + 39U, 173U, 46U, 248U, 30U, 200U, 82U, 17U, 48U, 67U, 254U, 239U, 37U, 18U, 13U, 247U, + 241U, 200U, 61U, 144U, 10U, 55U, 50U, 185U, 6U, 47U, 246U, 253U, 143U, 86U, 187U, 225U, + 134U, 85U, 110U, 246U, 161U, 163U, 43U, 235U, 231U, 94U, 171U, 51U, 145U, 214U, 112U, 29U, + 14U, 232U, 5U, 16U, 151U, 140U, 183U, 141U, 171U, 9U, 122U, 181U, 104U, 182U, 177U, 193U + ) + val result = Salsa20Pure.expansion16(k0, n) + result.contentEquals(expected) + } + } + + @Test + fun testSalsa20Encryption() { + assertTrue { + val key = "8000000000000000000000000000000000000000000000000000000000000000".hexStringToUByteArray() + val nonce = "0000000000000000".hexStringToUByteArray() + val expectedStartsWith = ( + "E3BE8FDD8BECA2E3EA8EF9475B29A6E7" + + "003951E1097A5C38D23B7A5FAD9F6844" + + "B22C97559E2723C7CBBD3FE4FC8D9A07" + + "44652A83E72A9C461876AF4D7EF1A117").toLowerCase() + val endsWith = ( + "696AFCFD0CDDCC83C7E77F11A649D79A" + + "CDC3354E9635FF137E929933A0BD6F53" + + "77EFA105A3A4266B7C0D089D08F1E855" + + "CC32B15B93784A36E56A76CC64BC8477" + ).toLowerCase() + + val ciphertext = Salsa20Pure.encrypt(key, nonce, UByteArray(512) { 0U }) + ciphertext.toHexString().toLowerCase().startsWith(expectedStartsWith) && + ciphertext.toHexString().toLowerCase().endsWith(endsWith) + } + + assertTrue { + val key = "0A5DB00356A9FC4FA2F5489BEE4194E73A8DE03386D92C7FD22578CB1E71C417".hexStringToUByteArray() + val nonce = "1F86ED54BB2289F0".hexStringToUByteArray() + val expectedStartsWith = ( + "3FE85D5BB1960A82480B5E6F4E965A44" + + "60D7A54501664F7D60B54B06100A37FF" + + "DCF6BDE5CE3F4886BA77DD5B44E95644" + + "E40A8AC65801155DB90F02522B644023").toLowerCase() + val endsWith = ( + "7998204FED70CE8E0D027B206635C08C" + + "8BC443622608970E40E3AEDF3CE790AE" + + "EDF89F922671B45378E2CD03F6F62356" + + "529C4158B7FF41EE854B1235373988C8" + ).toLowerCase() + + val ciphertext = Salsa20Pure.encrypt(key, nonce, UByteArray(131072) { 0U }) + println(ciphertext.slice(0 until 64).toTypedArray().toHexString()) + println(ciphertext.slice(131008 until 131072).toTypedArray().toHexString()) + ciphertext.slice(0 until 64).toTypedArray().toHexString().toLowerCase().startsWith(expectedStartsWith) && + ciphertext.slice(131008 until 131072).toTypedArray().toHexString().toLowerCase().contains(endsWith) + } + + + } + + +} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Test.kt new file mode 100644 index 0000000..53c9d2a --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Test.kt @@ -0,0 +1,341 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexColumsPrint +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +class XChaCha20Test { + + @Test + fun testHChaCha20() { + val key = ubyteArrayOf( + 0x00U, 0x01U, 0x02U, 0x03U, 0x04U, 0x05U, 0x06U, 0x07U, 0x08U, 0x09U, + 0x0aU, 0x0bU, 0x0cU, 0x0dU, 0x0eU, 0x0fU, 0x10U, 0x11U, 0x12U, 0x13U, + 0x14U, 0x15U, 0x16U, 0x17U, 0x18U, 0x19U, 0x1aU, 0x1bU, 0x1cU, 0x1dU, + 0x1eU, 0x1fU + ) + + val nonce = ubyteArrayOf( + 0x00U, 0x00U, 0x00U, 0x09U, 0x00U, 0x00U, 0x00U, 0x4aU, + 0x00U, 0x00U, 0x00U, 0x00U, 0x31U, 0x41U, 0x59U, 0x27U + ) + + val expected = uintArrayOf( + 0x82413b42U, 0x27b27bfeU, 0xd30e4250U, 0x8a877d73U, + 0xa0f9e4d5U, 0x8a74a853U, 0xc12ec413U, 0x26d3ecdcU, + ) + + val result = XChaCha20Pure.hChacha(key, nonce) +// assertTrue { +// result.contentEquals(expected)//Returns little endia, expected big endian +// } + } + + @Test + fun testXChaCha20() { + 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, 0x58U + ) + val message = ubyteArrayOf( + 0x54U, 0x68U, 0x65U, 0x20U, 0x64U, 0x68U, 0x6fU, 0x6cU, + 0x65U, 0x20U, 0x28U, 0x70U, 0x72U, 0x6fU, 0x6eU, 0x6fU, + 0x75U, 0x6eU, 0x63U, 0x65U, 0x64U, 0x20U, 0x22U, 0x64U, + 0x6fU, 0x6cU, 0x65U, 0x22U, 0x29U, 0x20U, 0x69U, 0x73U, + 0x20U, 0x61U, 0x6cU, 0x73U, 0x6fU, 0x20U, 0x6bU, 0x6eU, + 0x6fU, 0x77U, 0x6eU, 0x20U, 0x61U, 0x73U, 0x20U, 0x74U, + 0x68U, 0x65U, 0x20U, 0x41U, 0x73U, 0x69U, 0x61U, 0x74U, + 0x69U, 0x63U, 0x20U, 0x77U, 0x69U, 0x6cU, 0x64U, 0x20U, + 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x72U, 0x65U, 0x64U, + 0x20U, 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x61U, 0x6eU, + 0x64U, 0x20U, 0x77U, 0x68U, 0x69U, 0x73U, 0x74U, 0x6cU, + 0x69U, 0x6eU, 0x67U, 0x20U, 0x64U, 0x6fU, 0x67U, 0x2eU, + 0x20U, 0x49U, 0x74U, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, + 0x62U, 0x6fU, 0x75U, 0x74U, 0x20U, 0x74U, 0x68U, 0x65U, + 0x20U, 0x73U, 0x69U, 0x7aU, 0x65U, 0x20U, 0x6fU, 0x66U, + 0x20U, 0x61U, 0x20U, 0x47U, 0x65U, 0x72U, 0x6dU, 0x61U, + 0x6eU, 0x20U, 0x73U, 0x68U, 0x65U, 0x70U, 0x68U, 0x65U, + 0x72U, 0x64U, 0x20U, 0x62U, 0x75U, 0x74U, 0x20U, 0x6cU, + 0x6fU, 0x6fU, 0x6bU, 0x73U, 0x20U, 0x6dU, 0x6fU, 0x72U, + 0x65U, 0x20U, 0x6cU, 0x69U, 0x6bU, 0x65U, 0x20U, 0x61U, + 0x20U, 0x6cU, 0x6fU, 0x6eU, 0x67U, 0x2dU, 0x6cU, 0x65U, + 0x67U, 0x67U, 0x65U, 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, + 0x2eU, 0x20U, 0x54U, 0x68U, 0x69U, 0x73U, 0x20U, 0x68U, + 0x69U, 0x67U, 0x68U, 0x6cU, 0x79U, 0x20U, 0x65U, 0x6cU, + 0x75U, 0x73U, 0x69U, 0x76U, 0x65U, 0x20U, 0x61U, 0x6eU, + 0x64U, 0x20U, 0x73U, 0x6bU, 0x69U, 0x6cU, 0x6cU, 0x65U, + 0x64U, 0x20U, 0x6aU, 0x75U, 0x6dU, 0x70U, 0x65U, 0x72U, + 0x20U, 0x69U, 0x73U, 0x20U, 0x63U, 0x6cU, 0x61U, 0x73U, + 0x73U, 0x69U, 0x66U, 0x69U, 0x65U, 0x64U, 0x20U, 0x77U, + 0x69U, 0x74U, 0x68U, 0x20U, 0x77U, 0x6fU, 0x6cU, 0x76U, + 0x65U, 0x73U, 0x2cU, 0x20U, 0x63U, 0x6fU, 0x79U, 0x6fU, + 0x74U, 0x65U, 0x73U, 0x2cU, 0x20U, 0x6aU, 0x61U, 0x63U, + 0x6bU, 0x61U, 0x6cU, 0x73U, 0x2cU, 0x20U, 0x61U, 0x6eU, + 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, 0x65U, 0x73U, 0x20U, + 0x69U, 0x6eU, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x74U, + 0x61U, 0x78U, 0x6fU, 0x6eU, 0x6fU, 0x6dU, 0x69U, 0x63U, + 0x20U, 0x66U, 0x61U, 0x6dU, 0x69U, 0x6cU, 0x79U, 0x20U, + 0x43U, 0x61U, 0x6eU, 0x69U, 0x64U, 0x61U, 0x65U, 0x2eU, + ) + + val expected = ubyteArrayOf( + 0x7dU, 0x0aU, 0x2eU, 0x6bU, 0x7fU, 0x7cU, 0x65U, 0xa2U, + 0x36U, 0x54U, 0x26U, 0x30U, 0x29U, 0x4eU, 0x06U, 0x3bU, + 0x7aU, 0xb9U, 0xb5U, 0x55U, 0xa5U, 0xd5U, 0x14U, 0x9aU, + 0xa2U, 0x1eU, 0x4aU, 0xe1U, 0xe4U, 0xfbU, 0xceU, 0x87U, + 0xecU, 0xc8U, 0xe0U, 0x8aU, 0x8bU, 0x5eU, 0x35U, 0x0aU, + 0xbeU, 0x62U, 0x2bU, 0x2fU, 0xfaU, 0x61U, 0x7bU, 0x20U, + 0x2cU, 0xfaU, 0xd7U, 0x20U, 0x32U, 0xa3U, 0x03U, 0x7eU, + 0x76U, 0xffU, 0xdcU, 0xdcU, 0x43U, 0x76U, 0xeeU, 0x05U, + 0x3aU, 0x19U, 0x0dU, 0x7eU, 0x46U, 0xcaU, 0x1dU, 0xe0U, + 0x41U, 0x44U, 0x85U, 0x03U, 0x81U, 0xb9U, 0xcbU, 0x29U, + 0xf0U, 0x51U, 0x91U, 0x53U, 0x86U, 0xb8U, 0xa7U, 0x10U, + 0xb8U, 0xacU, 0x4dU, 0x02U, 0x7bU, 0x8bU, 0x05U, 0x0fU, + 0x7cU, 0xbaU, 0x58U, 0x54U, 0xe0U, 0x28U, 0xd5U, 0x64U, + 0xe4U, 0x53U, 0xb8U, 0xa9U, 0x68U, 0x82U, 0x41U, 0x73U, + 0xfcU, 0x16U, 0x48U, 0x8bU, 0x89U, 0x70U, 0xcaU, 0xc8U, + 0x28U, 0xf1U, 0x1aU, 0xe5U, 0x3cU, 0xabU, 0xd2U, 0x01U, + 0x12U, 0xf8U, 0x71U, 0x07U, 0xdfU, 0x24U, 0xeeU, 0x61U, + 0x83U, 0xd2U, 0x27U, 0x4fU, 0xe4U, 0xc8U, 0xb1U, 0x48U, + 0x55U, 0x34U, 0xefU, 0x2cU, 0x5fU, 0xbcU, 0x1eU, 0xc2U, + 0x4bU, 0xfcU, 0x36U, 0x63U, 0xefU, 0xaaU, 0x08U, 0xbcU, + 0x04U, 0x7dU, 0x29U, 0xd2U, 0x50U, 0x43U, 0x53U, 0x2dU, + 0xb8U, 0x39U, 0x1aU, 0x8aU, 0x3dU, 0x77U, 0x6bU, 0xf4U, + 0x37U, 0x2aU, 0x69U, 0x55U, 0x82U, 0x7cU, 0xcbU, 0x0cU, + 0xddU, 0x4aU, 0xf4U, 0x03U, 0xa7U, 0xceU, 0x4cU, 0x63U, + 0xd5U, 0x95U, 0xc7U, 0x5aU, 0x43U, 0xe0U, 0x45U, 0xf0U, + 0xccU, 0xe1U, 0xf2U, 0x9cU, 0x8bU, 0x93U, 0xbdU, 0x65U, + 0xafU, 0xc5U, 0x97U, 0x49U, 0x22U, 0xf2U, 0x14U, 0xa4U, + 0x0bU, 0x7cU, 0x40U, 0x2cU, 0xdbU, 0x91U, 0xaeU, 0x73U, + 0xc0U, 0xb6U, 0x36U, 0x15U, 0xcdU, 0xadU, 0x04U, 0x80U, + 0x68U, 0x0fU, 0x16U, 0x51U, 0x5aU, 0x7aU, 0xceU, 0x9dU, + 0x39U, 0x23U, 0x64U, 0x64U, 0x32U, 0x8aU, 0x37U, 0x74U, + 0x3fU, 0xfcU, 0x28U, 0xf4U, 0xddU, 0xb3U, 0x24U, 0xf4U, + 0xd0U, 0xf5U, 0xbbU, 0xdcU, 0x27U, 0x0cU, 0x65U, 0xb1U, + 0x74U, 0x9aU, 0x6eU, 0xffU, 0xf1U, 0xfbU, 0xaaU, 0x09U, + 0x53U, 0x61U, 0x75U, 0xccU, 0xd2U, 0x9fU, 0xb9U, 0xe6U, + 0x05U, 0x7bU, 0x30U, 0x73U, 0x20U, 0xd3U, 0x16U, 0x83U, + 0x8aU, 0x9cU, 0x71U, 0xf7U, 0x0bU, 0x5bU, 0x59U, 0x07U, + 0xa6U, 0x6fU, 0x7eU, 0xa4U, 0x9aU, 0xadU, 0xc4U, 0x09U, + + ) + + val result = XChaCha20Pure.xorWithKeystream(key, nonce, message, 1U) + assertTrue { + result.contentEquals(expected) + } + + } + + @Test + fun testXChaCha20Updateable() { + 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, 0x58U + ) + val message = ubyteArrayOf( + 0x54U, 0x68U, 0x65U, 0x20U, 0x64U, 0x68U, 0x6fU, 0x6cU, + 0x65U, 0x20U, 0x28U, 0x70U, 0x72U, 0x6fU, 0x6eU, 0x6fU, + 0x75U, 0x6eU, 0x63U, 0x65U, 0x64U, 0x20U, 0x22U, 0x64U, + 0x6fU, 0x6cU, 0x65U, 0x22U, 0x29U, 0x20U, 0x69U, 0x73U, + 0x20U, 0x61U, 0x6cU, 0x73U, 0x6fU, 0x20U, 0x6bU, 0x6eU, + 0x6fU, 0x77U, 0x6eU, 0x20U, 0x61U, 0x73U, 0x20U, 0x74U, + 0x68U, 0x65U, 0x20U, 0x41U, 0x73U, 0x69U, 0x61U, 0x74U, + 0x69U, 0x63U, 0x20U, 0x77U, 0x69U, 0x6cU, 0x64U, 0x20U, + 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x72U, 0x65U, 0x64U, + 0x20U, 0x64U, 0x6fU, 0x67U, 0x2cU, 0x20U, 0x61U, 0x6eU, + 0x64U, 0x20U, 0x77U, 0x68U, 0x69U, 0x73U, 0x74U, 0x6cU, + 0x69U, 0x6eU, 0x67U, 0x20U, 0x64U, 0x6fU, 0x67U, 0x2eU, + 0x20U, 0x49U, 0x74U, 0x20U, 0x69U, 0x73U, 0x20U, 0x61U, + 0x62U, 0x6fU, 0x75U, 0x74U, 0x20U, 0x74U, 0x68U, 0x65U, + 0x20U, 0x73U, 0x69U, 0x7aU, 0x65U, 0x20U, 0x6fU, 0x66U, + 0x20U, 0x61U, 0x20U, 0x47U, 0x65U, 0x72U, 0x6dU, 0x61U, + 0x6eU, 0x20U, 0x73U, 0x68U, 0x65U, 0x70U, 0x68U, 0x65U, + 0x72U, 0x64U, 0x20U, 0x62U, 0x75U, 0x74U, 0x20U, 0x6cU, + 0x6fU, 0x6fU, 0x6bU, 0x73U, 0x20U, 0x6dU, 0x6fU, 0x72U, + 0x65U, 0x20U, 0x6cU, 0x69U, 0x6bU, 0x65U, 0x20U, 0x61U, + 0x20U, 0x6cU, 0x6fU, 0x6eU, 0x67U, 0x2dU, 0x6cU, 0x65U, + 0x67U, 0x67U, 0x65U, 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, + 0x2eU, 0x20U, 0x54U, 0x68U, 0x69U, 0x73U, 0x20U, 0x68U, + 0x69U, 0x67U, 0x68U, 0x6cU, 0x79U, 0x20U, 0x65U, 0x6cU, + 0x75U, 0x73U, 0x69U, 0x76U, 0x65U, 0x20U, 0x61U, 0x6eU, + 0x64U, 0x20U, 0x73U, 0x6bU, 0x69U, 0x6cU, 0x6cU, 0x65U, + 0x64U, 0x20U, 0x6aU, 0x75U, 0x6dU, 0x70U, 0x65U, 0x72U, + 0x20U, 0x69U, 0x73U, 0x20U, 0x63U, 0x6cU, 0x61U, 0x73U, + 0x73U, 0x69U, 0x66U, 0x69U, 0x65U, 0x64U, 0x20U, 0x77U, + 0x69U, 0x74U, 0x68U, 0x20U, 0x77U, 0x6fU, 0x6cU, 0x76U, + 0x65U, 0x73U, 0x2cU, 0x20U, 0x63U, 0x6fU, 0x79U, 0x6fU, + 0x74U, 0x65U, 0x73U, 0x2cU, 0x20U, 0x6aU, 0x61U, 0x63U, + 0x6bU, 0x61U, 0x6cU, 0x73U, 0x2cU, 0x20U, 0x61U, 0x6eU, + 0x64U, 0x20U, 0x66U, 0x6fU, 0x78U, 0x65U, 0x73U, 0x20U, + 0x69U, 0x6eU, 0x20U, 0x74U, 0x68U, 0x65U, 0x20U, 0x74U, + 0x61U, 0x78U, 0x6fU, 0x6eU, 0x6fU, 0x6dU, 0x69U, 0x63U, + 0x20U, 0x66U, 0x61U, 0x6dU, 0x69U, 0x6cU, 0x79U, 0x20U, + 0x43U, 0x61U, 0x6eU, 0x69U, 0x64U, 0x61U, 0x65U, 0x2eU, + ) + + val expected = ubyteArrayOf( + 0x7dU, 0x0aU, 0x2eU, 0x6bU, 0x7fU, 0x7cU, 0x65U, 0xa2U, + 0x36U, 0x54U, 0x26U, 0x30U, 0x29U, 0x4eU, 0x06U, 0x3bU, + 0x7aU, 0xb9U, 0xb5U, 0x55U, 0xa5U, 0xd5U, 0x14U, 0x9aU, + 0xa2U, 0x1eU, 0x4aU, 0xe1U, 0xe4U, 0xfbU, 0xceU, 0x87U, + 0xecU, 0xc8U, 0xe0U, 0x8aU, 0x8bU, 0x5eU, 0x35U, 0x0aU, + 0xbeU, 0x62U, 0x2bU, 0x2fU, 0xfaU, 0x61U, 0x7bU, 0x20U, + 0x2cU, 0xfaU, 0xd7U, 0x20U, 0x32U, 0xa3U, 0x03U, 0x7eU, + 0x76U, 0xffU, 0xdcU, 0xdcU, 0x43U, 0x76U, 0xeeU, 0x05U, + 0x3aU, 0x19U, 0x0dU, 0x7eU, 0x46U, 0xcaU, 0x1dU, 0xe0U, + 0x41U, 0x44U, 0x85U, 0x03U, 0x81U, 0xb9U, 0xcbU, 0x29U, + 0xf0U, 0x51U, 0x91U, 0x53U, 0x86U, 0xb8U, 0xa7U, 0x10U, + 0xb8U, 0xacU, 0x4dU, 0x02U, 0x7bU, 0x8bU, 0x05U, 0x0fU, + 0x7cU, 0xbaU, 0x58U, 0x54U, 0xe0U, 0x28U, 0xd5U, 0x64U, + 0xe4U, 0x53U, 0xb8U, 0xa9U, 0x68U, 0x82U, 0x41U, 0x73U, + 0xfcU, 0x16U, 0x48U, 0x8bU, 0x89U, 0x70U, 0xcaU, 0xc8U, + 0x28U, 0xf1U, 0x1aU, 0xe5U, 0x3cU, 0xabU, 0xd2U, 0x01U, + 0x12U, 0xf8U, 0x71U, 0x07U, 0xdfU, 0x24U, 0xeeU, 0x61U, + 0x83U, 0xd2U, 0x27U, 0x4fU, 0xe4U, 0xc8U, 0xb1U, 0x48U, + 0x55U, 0x34U, 0xefU, 0x2cU, 0x5fU, 0xbcU, 0x1eU, 0xc2U, + 0x4bU, 0xfcU, 0x36U, 0x63U, 0xefU, 0xaaU, 0x08U, 0xbcU, + 0x04U, 0x7dU, 0x29U, 0xd2U, 0x50U, 0x43U, 0x53U, 0x2dU, + 0xb8U, 0x39U, 0x1aU, 0x8aU, 0x3dU, 0x77U, 0x6bU, 0xf4U, + 0x37U, 0x2aU, 0x69U, 0x55U, 0x82U, 0x7cU, 0xcbU, 0x0cU, + 0xddU, 0x4aU, 0xf4U, 0x03U, 0xa7U, 0xceU, 0x4cU, 0x63U, + 0xd5U, 0x95U, 0xc7U, 0x5aU, 0x43U, 0xe0U, 0x45U, 0xf0U, + 0xccU, 0xe1U, 0xf2U, 0x9cU, 0x8bU, 0x93U, 0xbdU, 0x65U, + 0xafU, 0xc5U, 0x97U, 0x49U, 0x22U, 0xf2U, 0x14U, 0xa4U, + 0x0bU, 0x7cU, 0x40U, 0x2cU, 0xdbU, 0x91U, 0xaeU, 0x73U, + 0xc0U, 0xb6U, 0x36U, 0x15U, 0xcdU, 0xadU, 0x04U, 0x80U, + 0x68U, 0x0fU, 0x16U, 0x51U, 0x5aU, 0x7aU, 0xceU, 0x9dU, + 0x39U, 0x23U, 0x64U, 0x64U, 0x32U, 0x8aU, 0x37U, 0x74U, + 0x3fU, 0xfcU, 0x28U, 0xf4U, 0xddU, 0xb3U, 0x24U, 0xf4U, + 0xd0U, 0xf5U, 0xbbU, 0xdcU, 0x27U, 0x0cU, 0x65U, 0xb1U, + 0x74U, 0x9aU, 0x6eU, 0xffU, 0xf1U, 0xfbU, 0xaaU, 0x09U, + 0x53U, 0x61U, 0x75U, 0xccU, 0xd2U, 0x9fU, 0xb9U, 0xe6U, + 0x05U, 0x7bU, 0x30U, 0x73U, 0x20U, 0xd3U, 0x16U, 0x83U, + 0x8aU, 0x9cU, 0x71U, 0xf7U, 0x0bU, 0x5bU, 0x59U, 0x07U, + 0xa6U, 0x6fU, 0x7eU, 0xa4U, 0x9aU, 0xadU, 0xc4U, 0x09U, + + ) + + val xChaCha = XChaCha20Pure(key, nonce, 1U) + val firstChunk = xChaCha.xorWithKeystream(message.sliceArray(0 until 5)) + val secondChunk = xChaCha.xorWithKeystream(message.sliceArray(5 until 90)) + val thirdChunk = xChaCha.xorWithKeystream(message.sliceArray(90 until message.size)) + val result = firstChunk + secondChunk + thirdChunk + assertTrue { + (result).contentEquals(expected) + } + + } + + @Test + fun testXChaCha20UpdateableLonger() { + 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, 0x58U + ) + val message = ("This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long." + + "This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long." + + "This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long." + + "This is a longer message that should cover all cases in the updateable algorithm. This string is 112 bytes long.").encodeToUByteArray() + + val expected = ubyteArrayOf( + 0x7DU, 0x0AU, 0x22U, 0x38U, 0x3BU, 0x7DU, 0x79U, 0xEEU, + 0x32U, 0x54U, 0x62U, 0x2FU, 0x35U, 0x46U, 0x0DU, 0x26U, + 0x2FU, 0xBAU, 0xB3U, 0x43U, 0xB2U, 0x94U, 0x51U, 0x9BU, + 0xEDU, 0x06U, 0x47U, 0xA2U, 0xB9U, 0xFBU, 0xD4U, 0x9CU, + 0xA3U, 0xDCU, 0xE0U, 0x9DU, 0xC4U, 0x1DU, 0x31U, 0x12U, + 0xB4U, 0x67U, 0x65U, 0x6EU, 0xF7U, 0x7EU, 0x7BU, 0x37U, + 0x25U, 0xECU, 0x92U, 0x12U, 0x61U, 0xA3U, 0x0CU, 0x2AU, + 0x6BU, 0xF4U, 0x99U, 0x8BU, 0x5FU, 0x6AU, 0xEEU, 0x44U, + 0x2AU, 0x13U, 0x0BU, 0x30U, 0x0AU, 0xDDU, 0x58U, 0xE5U, + 0x0DU, 0x47U, 0x85U, 0x16U, 0xC4U, 0xEDU, 0xC2U, 0x2AU, + 0xBAU, 0x51U, 0xB2U, 0x53U, 0x86U, 0xB8U, 0xF3U, 0x0FU, + 0xA5U, 0xB0U, 0x43U, 0x4CU, 0x78U, 0xC4U, 0x0BU, 0x52U, + 0x7CU, 0xC2U, 0x1DU, 0x46U, 0xA9U, 0x39U, 0x8CU, 0x71U, + 0xE3U, 0x4FU, 0xEDU, 0xB1U, 0x27U, 0x98U, 0x4EU, 0x38U, + 0x88U, 0x0DU, 0x48U, 0x82U, 0xCCU, 0x39U, 0xD6U, 0x8EU, + 0x69U, 0xB0U, 0x56U, 0xCDU, 0x37U, 0xBEU, 0xDAU, 0x12U, + 0x5CU, 0xB5U, 0x67U, 0x1CU, 0xC9U, 0x35U, 0xE1U, 0x61U, + 0xD1U, 0xC2U, 0x6FU, 0x4CU, 0xE5U, 0x9CU, 0xE2U, 0x4CU, + 0x55U, 0x2EU, 0xE8U, 0x3BU, 0x5FU, 0xB2U, 0x1EU, 0xC6U, + 0x4BU, 0xAEU, 0x7AU, 0x6BU, 0xE8U, 0xA3U, 0x08U, 0xBEU, + 0x45U, 0x62U, 0x23U, 0xCFU, 0x17U, 0x07U, 0x51U, 0x68U, + 0xABU, 0x36U, 0x1AU, 0xCEU, 0x68U, 0x61U, 0x60U, 0xEDU, + 0x6DU, 0x6FU, 0x5CU, 0x5FU, 0x87U, 0x6AU, 0xCBU, 0x05U, + 0xD8U, 0x4AU, 0xF3U, 0x1DU, 0xB7U, 0x9AU, 0x41U, 0x62U, + 0x8EU, 0xC6U, 0xFAU, 0x44U, 0x4FU, 0xB3U, 0x04U, 0xEDU, + 0xDCU, 0xB3U, 0xE8U, 0x99U, 0x85U, 0xDFU, 0xB8U, 0x73U, + 0xEBU, 0xD4U, 0xCCU, 0x0EU, 0x6FU, 0xE0U, 0x08U, 0xA2U, + 0x4EU, 0x66U, 0x13U, 0x60U, 0xD7U, 0x93U, 0xA8U, 0x2EU, + 0xE7U, 0xB7U, 0x39U, 0x0FU, 0x88U, 0xA0U, 0x57U, 0xD7U, + 0x60U, 0x5BU, 0x12U, 0x1EU, 0x43U, 0x72U, 0xC7U, 0x99U, + 0x7CU, 0x3DU, 0x2DU, 0x37U, 0x22U, 0x84U, 0x29U, 0x7EU, + 0x6BU, 0xEDU, 0x33U, 0xB9U, 0x89U, 0xF9U, 0x36U, 0xFFU, + 0xD4U, 0xE1U, 0xBBU, 0xCBU, 0x2BU, 0x4FU, 0x6BU, 0xA9U, + 0x75U, 0xC8U, 0x28U, 0xF1U, 0xE5U, 0xF2U, 0xF9U, 0x4AU, + 0x5BU, 0x7CU, 0x30U, 0xCBU, 0x9AU, 0x93U, 0xF7U, 0xB2U, + 0x10U, 0x6BU, 0x3AU, 0x3DU, 0x3AU, 0xCEU, 0x1BU, 0x81U, + 0xDEU, 0x9FU, 0x71U, 0xF8U, 0x0EU, 0x52U, 0x00U, 0x46U, + 0x89U, 0x69U, 0x7FU, 0xBFU, 0x97U, 0xB8U, 0xC9U, 0x4AU, + 0x3AU, 0x37U, 0x31U, 0x1EU, 0x88U, 0x68U, 0x35U, 0x98U, + 0x76U, 0x93U, 0xCDU, 0x91U, 0xF7U, 0x6AU, 0x59U, 0xE6U, + 0x82U, 0xB6U, 0x85U, 0x67U, 0x3FU, 0xF5U, 0x9EU, 0x82U, + 0x2DU, 0xFFU, 0x81U, 0x5EU, 0xEAU, 0x3BU, 0xCCU, 0xFBU, + 0x1BU, 0x87U, 0x4AU, 0x93U, 0x40U, 0x96U, 0x3CU, 0xB2U, + 0x8EU, 0xCCU, 0x38U, 0x00U, 0x3FU, 0xBAU, 0xCCU, 0x84U, + 0x88U, 0x2BU, 0xF0U, 0x11U, 0x09U, 0xD5U, 0xAAU, 0x54U, + 0x3AU, 0x5BU, 0x98U, 0xE6U, 0xADU, 0xC0U, 0xB9U, 0x95U, + 0x53U, 0xDFU, 0x9DU, 0x91U, 0x01U, 0x66U, 0x7CU, 0xB3U, + 0xD8U, 0x2BU, 0x2DU, 0xBCU, 0xE0U, 0x77U, 0x71U, 0x59U, + 0x36U, 0xACU, 0x6DU, 0x5EU, 0x55U, 0xC9U, 0x29U, 0x40U, + 0xD4U, 0xA2U, 0x5BU, 0xBDU, 0xC2U, 0xE2U, 0x98U, 0x3DU, + 0x8CU, 0x9FU, 0x07U, 0xE4U, 0x21U, 0x84U, 0x4CU, 0x12U, + 0x83U, 0x77U, 0x88U, 0x06U, 0xA4U, 0x6FU, 0xDFU, 0x9EU, + 0xF5U, 0xD3U, 0xE1U, 0xFCU, 0x49U, 0x66U, 0x36U, 0x96U, + 0x48U, 0xC7U, 0x32U, 0xBAU, 0x73U, 0xFFU, 0xEFU, 0xCCU, + 0x00U, 0xC2U, 0x56U, 0x9CU, 0xD0U, 0x70U, 0x2AU, 0x4FU, + 0x82U, 0xB4U, 0x0BU, 0x68U, 0xEAU, 0xC1U, 0x87U, 0xB3U, + + ) + + val xChaCha = XChaCha20Pure(key, nonce, 1U) + val firstChunk = xChaCha.xorWithKeystream(message.sliceArray(0 until 50)) + val secondChunk = xChaCha.xorWithKeystream(message.sliceArray(50 until 200)) + val thirdChunk = xChaCha.xorWithKeystream(message.sliceArray(200 until message.size)) + val result = (firstChunk + secondChunk + thirdChunk) + assertTrue { + result.contentEquals(expected) + } + + + + } + +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Test.kt new file mode 100644 index 0000000..4f74b04 --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Test.kt @@ -0,0 +1,44 @@ +package com.ionspin.kotlin.crypto.symmetric + +import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 16-Jun-2020 + */ +class XSalsa20Test { + @Test + fun testXSalsa20() { + // values from https://go.googlesource.com/crypto/+/master/salsa20/salsa20_test.go xSalsa20TestData + assertTrue { + val message = "Hello world!".encodeToUByteArray() + val nonce = "24-byte nonce for xsalsa".encodeToUByteArray() + val key = "this is 32-byte key for xsalsa20".encodeToUByteArray() + val expected = ubyteArrayOf(0x00U, 0x2dU, 0x45U, 0x13U, 0x84U, 0x3fU, 0xc2U, 0x40U, 0xc4U, 0x01U, 0xe5U, 0x41U) + val result = XSalsa20Pure.encrypt(key, nonce, message) + result.contentEquals(expected) + } + + assertTrue { + val message = UByteArray(64) { 0U } + val nonce = "24-byte nonce for xsalsa".encodeToUByteArray() + val key = "this is 32-byte key for xsalsa20".encodeToUByteArray() + val expected = ubyteArrayOf( + 0x48U, 0x48U, 0x29U, 0x7fU, 0xebU, 0x1fU, 0xb5U, 0x2fU, 0xb6U, + 0x6dU, 0x81U, 0x60U, 0x9bU, 0xd5U, 0x47U, 0xfaU, 0xbcU, 0xbeU, 0x70U, + 0x26U, 0xedU, 0xc8U, 0xb5U, 0xe5U, 0xe4U, 0x49U, 0xd0U, 0x88U, 0xbfU, + 0xa6U, 0x9cU, 0x08U, 0x8fU, 0x5dU, 0x8dU, 0xa1U, 0xd7U, 0x91U, 0x26U, + 0x7cU, 0x2cU, 0x19U, 0x5aU, 0x7fU, 0x8cU, 0xaeU, 0x9cU, 0x4bU, 0x40U, + 0x50U, 0xd0U, 0x8cU, 0xe6U, 0xd3U, 0xa1U, 0x51U, 0xecU, 0x26U, 0x5fU, + 0x3aU, 0x58U, 0xe4U, 0x76U, 0x48U + ) + val result = XSalsa20Pure.encrypt(key, nonce, message) + result.contentEquals(expected) + } + + + } +} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt index ab0598d..3cb5304 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt @@ -16,11 +16,21 @@ package com.ionspin.kotlin.crypto.util -import kotlinx.coroutines.CoroutineScope +import kotlin.coroutines.Continuation +import kotlin.coroutines.EmptyCoroutineContext +import kotlin.coroutines.startCoroutine /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 20-Jul-2019 */ -expect fun testBlocking(block : suspend () -> Unit) \ No newline at end of file +fun testBlocking(block : suspend () -> Unit) { + val continuation = Continuation(EmptyCoroutineContext) { + //Do nothing + if (it.isFailure) { + throw it.exceptionOrNull()!! + } + } + block.startCoroutine(continuation) +} diff --git a/multiplatform-crypto/src/jsTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt b/multiplatform-crypto/src/jsTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt deleted file mode 100644 index 2df4151..0000000 --- a/multiplatform-crypto/src/jsTest/kotlin/com/ionspin/kotlin/crypto/util/testBlocking.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.util - -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.promise - - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 20-Jul-2019 - */ -actual fun testBlocking(block: suspend ()-> Unit) : dynamic = GlobalScope.promise { block() } \ No newline at end of file diff --git a/multiplatform-crypto/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt b/multiplatform-crypto/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt index d136901..3d50e6f 100644 --- a/multiplatform-crypto/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt +++ b/multiplatform-crypto/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/SRNG.kt @@ -29,6 +29,6 @@ actual object SRNG { actual fun getRandomBytes(amount: Int): UByteArray { val byteArray = ByteArray(amount) secureRandom.nextBytes(byteArray) - return byteArray.toUByteArray() + return byteArray.asUByteArray() } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/mingwX64Test/kotlin/com/ionspin/kotlin/bignum/crypto/util/testBlocking.kt b/multiplatform-crypto/src/mingwX64Test/kotlin/com/ionspin/kotlin/bignum/crypto/util/testBlocking.kt deleted file mode 100644 index 8fb509a..0000000 --- a/multiplatform-crypto/src/mingwX64Test/kotlin/com/ionspin/kotlin/bignum/crypto/util/testBlocking.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.util - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.runBlocking - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 20-Jul-2019 - */ -actual fun testBlocking(block: suspend () -> Unit) = runBlocking { block() } \ No newline at end of file diff --git a/multiplatform-crypto/src/nativeTest/kotlin/com/ionspin/kotlin/bignum/crypto/util/testBlocking.kt b/multiplatform-crypto/src/nativeTest/kotlin/com/ionspin/kotlin/bignum/crypto/util/testBlocking.kt deleted file mode 100644 index 8fb509a..0000000 --- a/multiplatform-crypto/src/nativeTest/kotlin/com/ionspin/kotlin/bignum/crypto/util/testBlocking.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2019 Ugljesa Jovanovic - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.ionspin.kotlin.crypto.util - -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.runBlocking - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 20-Jul-2019 - */ -actual fun testBlocking(block: suspend () -> Unit) = runBlocking { block() } \ No newline at end of file diff --git a/sample/build.gradle.kts b/sample/build.gradle.kts index 96cfab1..8fc774b 100644 --- a/sample/build.gradle.kts +++ b/sample/build.gradle.kts @@ -96,14 +96,14 @@ kotlin { } runningOnMacos { - iosX64("ios") { + iosX64() { binaries { framework { } } } - iosArm64("ios64Arm") { + iosArm64() { binaries { framework { @@ -111,7 +111,7 @@ kotlin { } } - iosArm32("ios32Arm") { + iosArm32() { binaries { framework { @@ -143,7 +143,6 @@ kotlin { dependencies { implementation(kotlin(Deps.Common.stdLib)) implementation(kotlin(Deps.Common.test)) - implementation(Deps.Common.coroutines) implementation(Deps.Common.kotlinBigNum) implementation(project(":multiplatform-crypto-delegated")) } @@ -159,14 +158,12 @@ kotlin { val nativeMain by creating { dependsOn(commonMain) dependencies { - implementation(Deps.Native.coroutines) } } val nativeTest by creating { dependsOn(commonTest) dependencies { - implementation(Deps.Native.coroutines) } } @@ -176,26 +173,22 @@ kotlin { implementation(kotlin(Deps.Jvm.stdLib)) implementation(kotlin(Deps.Jvm.test)) implementation(kotlin(Deps.Jvm.testJUnit)) - implementation(Deps.Jvm.coroutinesCore) } } val jvmTest by getting { dependencies { implementation(kotlin(Deps.Jvm.test)) implementation(kotlin(Deps.Jvm.testJUnit)) - implementation(Deps.Jvm.coroutinesTest) implementation(kotlin(Deps.Jvm.reflection)) } } val jsMain by getting { dependencies { implementation(kotlin(Deps.Js.stdLib)) - implementation(Deps.Js.coroutines) } } val jsTest by getting { dependencies { - implementation(Deps.Js.coroutines) implementation(kotlin(Deps.Js.test)) } } @@ -221,24 +214,24 @@ kotlin { runningOnMacos { - val iosMain by getting { + val iosX64Main by getting { dependsOn(nativeMain) } - val iosTest by getting { + val iosX64Test by getting { dependsOn(nativeTest) } - val ios64ArmMain by getting { + val iosArm64Main by getting { dependsOn(nativeMain) } - val ios64ArmTest by getting { + val iosArm64Test by getting { dependsOn(nativeTest) } - val ios32ArmMain by getting { + val iosArm32Main by getting { dependsOn(nativeMain) } - val ios32ArmTest by getting { + val iosArm32Test by getting { dependsOn(nativeTest) } @@ -254,9 +247,6 @@ kotlin { runningOnWindows { val mingwX64Main by getting { dependsOn(commonMain) - dependencies { - implementation(Deps.Native.coroutines) - } } val mingwX64Test by getting { diff --git a/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt b/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt index effa995..fb7f634 100644 --- a/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt +++ b/sample/src/commonMain/kotlin/com/ionspin/kotlin/crypto/sample/Sample.kt @@ -1,17 +1,15 @@ package com.ionspin.kotlin.crypto.sample import com.ionspin.kotlin.crypto.Crypto -import com.ionspin.kotlin.crypto.CryptoProvider -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2b +import com.ionspin.kotlin.crypto.CryptoInitializerDelegated +import com.ionspin.kotlin.crypto.CryptoPrimitives import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.toHexString -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch object Sample { fun runSample() { println("Initializing crypto library") - Crypto.initializeWithCallback { + CryptoInitializerDelegated.initializeWithCallback { blake2b() } @@ -20,11 +18,11 @@ object Sample { fun blake2b() { println("Blake2b updateable") - val blake2bUpdateable = Crypto.Blake2b.updateable() + val blake2bUpdateable = CryptoPrimitives.Blake2b.updateable() blake2bUpdateable.update("test".encodeToUByteArray()) println(blake2bUpdateable.digest().toHexString()) println("Blake2b stateless") - val statelessResult = Crypto.Blake2b.stateless("test".encodeToByteArray().toUByteArray()) + val statelessResult = CryptoPrimitives.Blake2b.stateless("test".encodeToUByteArray()) println("Blake2b stateless: ${statelessResult.toHexString()}") } -} \ No newline at end of file +} diff --git a/sample/src/linuxArm64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt b/sample/src/linuxArm64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt index faab8b3..22b3ead 100644 --- a/sample/src/linuxArm64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt +++ b/sample/src/linuxArm64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt @@ -1,16 +1,5 @@ -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bStateless import com.ionspin.kotlin.crypto.sample.Sample -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import platform.posix.pthread_self -import platform.posix.sleep -import kotlin.native.concurrent.TransferMode -import kotlin.native.concurrent.Worker import kotlin.time.ExperimentalTime -import kotlin.time.measureTime @ExperimentalTime diff --git a/sample/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt b/sample/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt index 04d9122..1d3c298 100644 --- a/sample/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt +++ b/sample/src/linuxMain/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt @@ -1,7 +1,6 @@ import com.ionspin.kotlin.crypto.sample.Sample -import kotlin.time.ExperimentalTime -@ExperimentalTime + fun main() { Sample.runSample() diff --git a/sample/src/mingwX64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt b/sample/src/mingwX64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt index faab8b3..3343ed0 100644 --- a/sample/src/mingwX64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt +++ b/sample/src/mingwX64Main/kotlin/com/ionspin/kotlin/crypto/sample/Runner.kt @@ -1,21 +1,5 @@ -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegated -import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bStateless import com.ionspin.kotlin.crypto.sample.Sample -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import platform.posix.pthread_self -import platform.posix.sleep -import kotlin.native.concurrent.TransferMode -import kotlin.native.concurrent.Worker -import kotlin.time.ExperimentalTime -import kotlin.time.measureTime - -@ExperimentalTime fun main() { - Sample.runSample() - } diff --git a/settings.gradle.kts b/settings.gradle.kts index 92e8084..e201525 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -38,5 +38,7 @@ rootProject.name = "KotlinMultiplatformCrypto" include("multiplatform-crypto-api") include("multiplatform-crypto") include("multiplatform-crypto-delegated") +include("multiplatform-crypto-libsodium-bindings") include("sample") +include("kotlin-multiplatform-libsodium-generator") diff --git a/windowsBuild-delegated.sh b/windowsBuild-delegated.sh index 252054b..655bb92 100755 --- a/windowsBuild-delegated.sh +++ b/windowsBuild-delegated.sh @@ -14,5 +14,7 @@ echo "completed libsodium build" #now we can do the delegated build cd .. ./gradlew multiplatform-crypto-delegated:build +#and then libsodium bindings +./gradlew multiplatform-crypto-libsodium-bindings:build set +e diff --git a/windowsBuildAndPublish-delegated.sh b/windowsBuildAndPublish-delegated.sh index 6434ff4..6432351 100755 --- a/windowsBuildAndPublish-delegated.sh +++ b/windowsBuildAndPublish-delegated.sh @@ -15,4 +15,7 @@ echo "completed libsodium build" cd .. ./gradlew multiplatform-crypto-delegated:build ./gradlew multiplatform-crypto-delegated:publishMingwX64PublicationToSnapshotRepository -set +e \ No newline at end of file + +./gradlew multiplatform-crypto-libsodium-bindings:build +./gradlew multiplatform-crypto-libsodium-bindings:publishMingwX64PublicationToSnapshotRepository +set +e