Merge pull request #8 from ionspin/jna-android-and-java
Jna android and java
This commit is contained in:
		
						commit
						6db7a828ac
					
				
							
								
								
									
										44
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								README.md
									
									
									
									
									
								
							@ -5,12 +5,26 @@
 | 
			
		||||
 | 
			
		||||
# Libsodium bindings for Kotiln Multiplatform
 | 
			
		||||
 | 
			
		||||
Libsodium bindings project uses libsodium c sources, libsodium.js as well as LazySodium Java and Android to provide a kotlin multiplatform wrapper library for libsodium.
 | 
			
		||||
Libsodium bindings project uses libsodium c sources and libsodium.js to provide a kotlin multiplatform wrapper library for libsodium.
 | 
			
		||||
 | 
			
		||||
## Installation
 | 
			
		||||
 | 
			
		||||
The libsodium binding library is not published yet, once the sample showing the basic usage is ready, the library will be published. You can track the implementation 
 | 
			
		||||
[progress here](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/supported_bindings_list.md)
 | 
			
		||||
#### Gradle
 | 
			
		||||
```kotlin
 | 
			
		||||
implementation("com.ionspin.kotlin:multiplatform-crypto-lisodium-bindings:0.8.0")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Snapshot builds
 | 
			
		||||
```kotlin
 | 
			
		||||
repositories {
 | 
			
		||||
    maven {
 | 
			
		||||
        url = uri("https://oss.sonatype.org/content/repositories/snapshots")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
implementation("com.ionspin.kotlin:multiplatform-crypto-lisodium-bindings:0.8.1-SNAPSHOT ")
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
@ -18,7 +32,6 @@ The libsodium binding library is not published yet, once the sample showing the
 | 
			
		||||
Before using the wrapper you need to initialize the underlying libsodium library. You can use either a callback or coroutines approach
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    = runTest {
 | 
			
		||||
    LibsodiumInitializer.initializeWithCallback {
 | 
			
		||||
        // Libsodium initialized
 | 
			
		||||
    }
 | 
			
		||||
@ -125,31 +138,20 @@ Currently supported native platforms:
 | 
			
		||||
|minGW X86 64|          :heavy_check_mark: |
 | 
			
		||||
|minGW X86 32|          :x: | 
 | 
			
		||||
 | 
			
		||||
[List of supported bindings](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/supported_bindings_list.md)
 | 
			
		||||
### Where do the compiled libraries used by JVM and Android come from
 | 
			
		||||
Android .so files come from running dist-build scripts in libsodium which you can find in the libsodium submodule
 | 
			
		||||
Java Linux Arm/X86_64 and Mac so and dylib are the same as produced by multiplatform builds, also based on the same submodule commit
 | 
			
		||||
Java Windows dll is from https://download.libsodium.org/libsodium/releases/libsodium-1.0.18-stable-msvc.zip
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### TODO:
 | 
			
		||||
- Copy/adapt code documentation, currently only some functions have documentation that is a copy-paste from libsodium website
 | 
			
		||||
- Replace LazySodium with direct JNA calls, and add build scripts for required libraries if missing
 | 
			
		||||
- Android testing 
 | 
			
		||||
- Fix browser testing, both locally and in CI/CD
 | 
			
		||||
- LobsodiumUtil `unpad` and `fromBase64` native implementations use a nasty hack to support shared native sourceset. The hack either needs to be removed and replaced with another solution or additional safeguards need to be added.
 | 
			
		||||
- Complete exposing libsodium constants
 | 
			
		||||
 | 
			
		||||
### Known issues:
 | 
			
		||||
- Using LazySodium self built variant to fix some of the bugs present in LazySodium, but **Android** is using directly
 | 
			
		||||
  LazySodium release which has not been updated (latest version is 4.2.0), this means that randombytes_random, basetobin and
 | 
			
		||||
  base64tohex functions are not working on Android, as well as problems with sodium_pad:
 | 
			
		||||
  
 | 
			
		||||
    https://github.com/terl/lazysodium-java/issues/83
 | 
			
		||||
  
 | 
			
		||||
    https://github.com/terl/lazysodium-java/issues/85
 | 
			
		||||
 | 
			
		||||
    https://github.com/terl/lazysodium-java/issues/86
 | 
			
		||||
 | 
			
		||||
    Also it is not clear where are the precompiled libraries in LazySodium coming from
 | 
			
		||||
  
 | 
			
		||||
    This will be handled by providing a new JNA libsodium wrapper library
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#### Notes for Gitlab runners:
 | 
			
		||||
- At the moment all runners need to have android sdk 
 | 
			
		||||
 | 
			
		||||
@ -24,14 +24,16 @@ object Versions {
 | 
			
		||||
    val dokkaPlugin = "1.4.20"
 | 
			
		||||
    val taskTreePlugin = "1.5"
 | 
			
		||||
    val kotlinBigNumVersion = "0.2.8-SNAPSHOT"
 | 
			
		||||
    val lazySodium = "4.3.1-SNAPSHOT"
 | 
			
		||||
    val jna = "5.5.0"
 | 
			
		||||
    val jna = "5.7.0"
 | 
			
		||||
    val kotlinPoet = "1.6.0"
 | 
			
		||||
    val libsodiumBindings = "0.1.1-SNAPSHOT"
 | 
			
		||||
    val ktor = "1.3.2"
 | 
			
		||||
    val timber = "4.7.1"
 | 
			
		||||
    val kodeinVersion = "7.1.0"
 | 
			
		||||
 | 
			
		||||
    val resourceLoader = "1.3.10"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -39,7 +41,7 @@ object Versions {
 | 
			
		||||
object ReleaseInfo {
 | 
			
		||||
    val group = "com.ionspin.kotlin"
 | 
			
		||||
    val version = "0.1.0-SNAPSHOT"
 | 
			
		||||
    val bindingsVersion = "0.1.1-SNAPSHOT"
 | 
			
		||||
    val bindingsVersion = "0.8.0-SNAPSHOT"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object Deps {
 | 
			
		||||
@ -112,11 +114,9 @@ object Deps {
 | 
			
		||||
 | 
			
		||||
        val kotlinPoet = "com.squareup:kotlinpoet:${Versions.kotlinPoet}"
 | 
			
		||||
 | 
			
		||||
        val resourceLoader = "co.libly:resource-loader:${Versions.resourceLoader}"
 | 
			
		||||
 | 
			
		||||
        object Delegated {
 | 
			
		||||
            // Temporary until reported lazysodium issues are fixed. My snapshot build with
 | 
			
		||||
            // And cause I registered com.ionspin.kotlin as maven central package root now I have to use
 | 
			
		||||
            // that even though this is pure java library. :)
 | 
			
		||||
            val lazysodium = "com.ionspin.kotlin:lazysodium-java:${Versions.lazySodium}"
 | 
			
		||||
            val jna = "net.java.dev.jna:jna:${Versions.jna}"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -139,6 +139,7 @@ object Deps {
 | 
			
		||||
        val ktorClientSerialization = "io.ktor:ktor-client-serialization-jvm:${Versions.ktor}"
 | 
			
		||||
        val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime:${Versions.kotlinSerialization}"
 | 
			
		||||
        val timber = "com.jakewharton.timber:timber:${Versions.timber}"
 | 
			
		||||
        val jna = "net.java.dev.jna:jna:${Versions.jna}@aar"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    object Desktop {
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,6 @@ val sonatypeUsernameEnv: String? = System.getenv()["SONATYPE_USERNAME"]
 | 
			
		||||
repositories {
 | 
			
		||||
    mavenCentral()
 | 
			
		||||
    jcenter()
 | 
			
		||||
    maven("https://dl.bintray.com/terl/lazysodium-maven")
 | 
			
		||||
    maven {
 | 
			
		||||
        url = uri("https://oss.sonatype.org/content/repositories/snapshots")
 | 
			
		||||
    }
 | 
			
		||||
@ -73,6 +72,9 @@ android {
 | 
			
		||||
            isMinifyEnabled = false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    sourceSets.getByName("main") {
 | 
			
		||||
//        jniLibs.srcDir("src/androidMain/libs")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -80,9 +82,10 @@ android {
 | 
			
		||||
kotlin {
 | 
			
		||||
    val hostOsName = getHostOsName()
 | 
			
		||||
    android()
 | 
			
		||||
    jvm()
 | 
			
		||||
    runningOnLinuxx86_64 {
 | 
			
		||||
        println("Configuring Linux X86-64 targets")
 | 
			
		||||
        jvm()
 | 
			
		||||
 | 
			
		||||
        js(IR) {
 | 
			
		||||
            browser {
 | 
			
		||||
                testTask {
 | 
			
		||||
@ -438,14 +441,16 @@ kotlin {
 | 
			
		||||
 | 
			
		||||
            val androidMain by getting {
 | 
			
		||||
                isNotRunningInIdea {
 | 
			
		||||
                    kotlin.srcDirs("src/androidSpecific", "src/jvmMain/kotlin")
 | 
			
		||||
                    kotlin.srcDirs("src/androidMain", "src/androidSpecific", "src/jvmMain/kotlin")
 | 
			
		||||
                }
 | 
			
		||||
                isRunningInIdea {
 | 
			
		||||
                    kotlin.srcDirs("src/androidSpecific")
 | 
			
		||||
                    kotlin.srcDirs("src/androidSpecific", "src/jvmMain/kotlin")
 | 
			
		||||
                }
 | 
			
		||||
                dependencies {
 | 
			
		||||
                    implementation("com.goterl.lazycode:lazysodium-android:4.2.0@aar")
 | 
			
		||||
                    implementation("net.java.dev.jna:jna:5.5.0@aar")
 | 
			
		||||
                    implementation(Deps.Jvm.resourceLoader) {
 | 
			
		||||
                        exclude("net.java.dev.jna", "jna")
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -458,9 +463,6 @@ kotlin {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        runningOnLinuxx86_64 {
 | 
			
		||||
            println("Configuring Linux 64 Bit source sets")
 | 
			
		||||
        val jvmMain by getting {
 | 
			
		||||
            kotlin.srcDirs("src/jvmSpecific", "src/jvmMain/kotlin")
 | 
			
		||||
            dependencies {
 | 
			
		||||
@ -468,9 +470,11 @@ kotlin {
 | 
			
		||||
                implementation(kotlin(Deps.Jvm.test))
 | 
			
		||||
                implementation(kotlin(Deps.Jvm.testJUnit))
 | 
			
		||||
 | 
			
		||||
                    //lazysodium
 | 
			
		||||
                    implementation(Deps.Jvm.Delegated.lazysodium)
 | 
			
		||||
                implementation(Deps.Jvm.resourceLoader)
 | 
			
		||||
 | 
			
		||||
                implementation(Deps.Jvm.Delegated.jna)
 | 
			
		||||
 | 
			
		||||
                implementation("org.slf4j:slf4j-api:1.7.30")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        val jvmTest by getting {
 | 
			
		||||
@ -480,6 +484,9 @@ kotlin {
 | 
			
		||||
                implementation(kotlin(Deps.Jvm.reflection))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        runningOnLinuxx86_64 {
 | 
			
		||||
            println("Configuring Linux 64 Bit source sets")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            val jsMain by getting {
 | 
			
		||||
@ -678,6 +685,13 @@ tasks {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
allprojects {
 | 
			
		||||
    tasks.withType(JavaCompile::class) {
 | 
			
		||||
        sourceCompatibility = "1.8"
 | 
			
		||||
        targetCompatibility = "1.8"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
signing {
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								multiplatform-crypto-libsodium-bindings/src/androidMain/jniLibs/x86/libsodium.so
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								multiplatform-crypto-libsodium-bindings/src/androidMain/jniLibs/x86/libsodium.so
									
									
									
									
									
										Executable file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@ -1,12 +1,2 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto
 | 
			
		||||
 | 
			
		||||
import com.goterl.lazycode.lazysodium.LazySodiumAndroid
 | 
			
		||||
import com.goterl.lazycode.lazysodium.SodiumAndroid
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
 * ugljesa.jovanovic@ionspin.com
 | 
			
		||||
 * on 22-Aug-2020
 | 
			
		||||
 */
 | 
			
		||||
typealias SodiumWrapper = SodiumAndroid
 | 
			
		||||
 | 
			
		||||
@ -9,13 +9,22 @@ const val crypto_stream_chacha20_KEYBYTES = 32
 | 
			
		||||
const val crypto_stream_chacha20_NONCEBYTES = 8
 | 
			
		||||
const val crypto_stream_chacha20_ietf_KEYBYTES = 32
 | 
			
		||||
const val crypto_stream_chacha20_ietf_NONCEBYTES = 12
 | 
			
		||||
const val crypto_stream_xchacha20_NONCEBYTES = 24
 | 
			
		||||
const val crypto_stream_xchacha20_KEYBYTES = 32
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
expect object Stream {
 | 
			
		||||
    fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray) : UByteArray
 | 
			
		||||
    fun chacha20IetfXor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
 | 
			
		||||
    fun chacha20IetfXorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
 | 
			
		||||
    fun chacha20Keygen() : UByteArray
 | 
			
		||||
 | 
			
		||||
    fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray) : UByteArray
 | 
			
		||||
    fun chacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
 | 
			
		||||
    fun chacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
 | 
			
		||||
 | 
			
		||||
    fun chacha20IetfXor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
 | 
			
		||||
    fun chacha20IetfXorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
 | 
			
		||||
 | 
			
		||||
//    fun xChacha20Keygen() : UByteArray
 | 
			
		||||
//
 | 
			
		||||
//    fun xChacha20Xor(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray
 | 
			
		||||
//    fun xChacha20XorIc(message : UByteArray, nonce: UByteArray, initialCounter: ULong, key: UByteArray) : UByteArray
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,9 @@ enum class Base64Variants(val value: Int) {
 | 
			
		||||
    ORIGINAL(1), ORIGINAL_NO_PADDING(3), URLSAFE(5), URLSAFE_NO_PADDING(7)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class ConversionException() : RuntimeException("Conversion failed")
 | 
			
		||||
class PaddingException() : RuntimeException("Padding failed")
 | 
			
		||||
 | 
			
		||||
expect object LibsodiumUtil {
 | 
			
		||||
 | 
			
		||||
    fun memcmp(first: UByteArray, second: UByteArray) : Boolean
 | 
			
		||||
 | 
			
		||||
@ -68,4 +68,26 @@ class StreamTest {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    @Test
 | 
			
		||||
//    fun testXChaCha20IetfStream() = runTest {
 | 
			
		||||
//        LibsodiumInitializer.initializeWithCallback {
 | 
			
		||||
//            val message = "This is a cha cha message".encodeToUByteArray()
 | 
			
		||||
//            val nonce = LibsodiumRandom.bufDeterministic(crypto_stream_xchacha20_NONCEBYTES, seed)
 | 
			
		||||
//            val key = Stream.xChacha20Keygen()
 | 
			
		||||
//            val encryptedUsingLibsodium = Stream.xChacha20Xor(message, nonce, key)
 | 
			
		||||
//            val encryptedUsingLibsodiumWithInitialCounter = Stream.xChacha20XorIc(message, nonce, 0U, key)
 | 
			
		||||
//            println(encryptedUsingLibsodium.toHexString())
 | 
			
		||||
//            println(encryptedUsingLibsodiumWithInitialCounter.toHexString())
 | 
			
		||||
//            assertTrue {
 | 
			
		||||
//                encryptedUsingLibsodium.contentEquals(encryptedUsingLibsodiumWithInitialCounter)
 | 
			
		||||
//            }
 | 
			
		||||
//            val decryptedUsingLibsodium = Stream.xChacha20Xor(encryptedUsingLibsodium, nonce, key)
 | 
			
		||||
//            println(message.toHexString())
 | 
			
		||||
//            println(decryptedUsingLibsodium.toHexString())
 | 
			
		||||
//            assertTrue {
 | 
			
		||||
//                decryptedUsingLibsodium.contentEquals(message)
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -232,6 +232,10 @@ interface JsSodiumInterface {
 | 
			
		||||
    fun crypto_stream_chacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
 | 
			
		||||
    fun crypto_stream_chacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array
 | 
			
		||||
 | 
			
		||||
    fun crypto_stream_xchacha20_keygen() : Uint8Array
 | 
			
		||||
    fun crypto_stream_xchacha20_xor(message : Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array
 | 
			
		||||
    fun crypto_stream_xchacha20_xor_ic(message : Uint8Array, nonce: Uint8Array, initialCounter: UInt, key: Uint8Array) : Uint8Array
 | 
			
		||||
 | 
			
		||||
    // ---- Stream end ----
 | 
			
		||||
 | 
			
		||||
    // ---- Scalar multiplication ----
 | 
			
		||||
 | 
			
		||||
@ -79,4 +79,42 @@ actual object Stream {
 | 
			
		||||
 | 
			
		||||
        return result.toUByteArray()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    actual fun xChacha20Keygen(): UByteArray {
 | 
			
		||||
//        val result = getSodium().crypto_stream_xchacha20_keygen()
 | 
			
		||||
//
 | 
			
		||||
//        return result.toUByteArray()
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    actual fun xChacha20Xor(
 | 
			
		||||
//        message: UByteArray,
 | 
			
		||||
//        nonce: UByteArray,
 | 
			
		||||
//        key: UByteArray
 | 
			
		||||
//    ): UByteArray {
 | 
			
		||||
//        val result = getSodium().crypto_stream_xchacha20_xor(
 | 
			
		||||
//            message.toUInt8Array(),
 | 
			
		||||
//            nonce.toUInt8Array(),
 | 
			
		||||
//            key.toUInt8Array()
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        return result.toUByteArray()
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    actual fun xChacha20XorIc(
 | 
			
		||||
//        message: UByteArray,
 | 
			
		||||
//        nonce: UByteArray,
 | 
			
		||||
//        initialCounter: ULong,
 | 
			
		||||
//        key: UByteArray
 | 
			
		||||
//    ): UByteArray {
 | 
			
		||||
//        val result = getSodium().crypto_stream_xchacha20_xor_ic(
 | 
			
		||||
//            message.toUInt8Array(),
 | 
			
		||||
//            nonce.toUInt8Array(),
 | 
			
		||||
//            initialCounter.toUInt(),
 | 
			
		||||
//            key.toUInt8Array()
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        return result.toUByteArray()
 | 
			
		||||
//    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,19 +1,59 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto
 | 
			
		||||
 | 
			
		||||
import co.libly.resourceloader.FileLoader
 | 
			
		||||
import com.sun.jna.Native
 | 
			
		||||
import com.sun.jna.Platform
 | 
			
		||||
import java.io.File
 | 
			
		||||
import java.lang.RuntimeException
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020
 | 
			
		||||
 */
 | 
			
		||||
actual object LibsodiumInitializer {
 | 
			
		||||
    private var isPlatformInitialized = false
 | 
			
		||||
 | 
			
		||||
    lateinit var sodium : SodiumWrapper
 | 
			
		||||
    private fun loadLibrary() : JnaLibsodiumInterface {
 | 
			
		||||
        val libraryFile = when {
 | 
			
		||||
            Platform.isMac() -> {
 | 
			
		||||
                FileLoader.get().load("dynamic-macos-x86-64.dylib", Any::class.java)
 | 
			
		||||
            }
 | 
			
		||||
            Platform.isLinux() -> {
 | 
			
		||||
                FileLoader.get().load("dynamic-linux-x86-64-libsodium.so", Any::class.java)
 | 
			
		||||
            }
 | 
			
		||||
            Platform.isWindows() -> {
 | 
			
		||||
                FileLoader.get().load("dynamic-msvc-x86-64-libsodium.dll", Any::class.java)
 | 
			
		||||
            }
 | 
			
		||||
            Platform.isAndroid() -> {
 | 
			
		||||
                when {
 | 
			
		||||
                    Platform.is64Bit() -> {
 | 
			
		||||
                        File("irrelevant")
 | 
			
		||||
                    }
 | 
			
		||||
                    else -> throw RuntimeException("Unsupported platform")
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else -> throw RuntimeException("Unknown platform")
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        val library = if (Platform.isAndroid()) {
 | 
			
		||||
            Native.load("sodium", JnaLibsodiumInterface::class.java) as JnaLibsodiumInterface
 | 
			
		||||
        } else {
 | 
			
		||||
            Native.load(libraryFile.absolutePath, JnaLibsodiumInterface::class.java) as JnaLibsodiumInterface
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return library
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    lateinit var sodiumJna : JnaLibsodiumInterface
 | 
			
		||||
    actual suspend fun initialize() {
 | 
			
		||||
        sodium = SodiumWrapper()
 | 
			
		||||
        sodiumJna = loadLibrary()
 | 
			
		||||
        isPlatformInitialized = true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun initializeWithCallback(done: () -> Unit) {
 | 
			
		||||
        sodium = SodiumWrapper()
 | 
			
		||||
        sodiumJna = loadLibrary()
 | 
			
		||||
        isPlatformInitialized = true
 | 
			
		||||
        done()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,10 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
 * ugljesa.jovanovic@ionspin.com
 | 
			
		||||
 * on 21-Feb-2021
 | 
			
		||||
 */
 | 
			
		||||
object TmpAccessor {
 | 
			
		||||
    fun getVersion() : String = LibsodiumInitializer.sodiumJna.sodium_version_string()
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.aead
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val ciphertext = UByteArray(message.size + crypto_aead_xchacha20poly1305_ietf_ABYTES)
 | 
			
		||||
        sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(
 | 
			
		||||
        sodiumJna.crypto_aead_xchacha20poly1305_ietf_encrypt(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
@ -35,7 +35,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertextAndTag.size - crypto_aead_xchacha20poly1305_ietf_ABYTES)
 | 
			
		||||
        val validationResult = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_aead_xchacha20poly1305_ietf_decrypt(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
@ -60,7 +60,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
    ): AeadEncryptedDataAndTag {
 | 
			
		||||
        val ciphertext = UByteArray(message.size)
 | 
			
		||||
        val authenticationTag = UByteArray(crypto_aead_xchacha20poly1305_ietf_ABYTES)
 | 
			
		||||
        sodium.crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
 | 
			
		||||
        sodiumJna.crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            authenticationTag.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
@ -83,7 +83,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size)
 | 
			
		||||
        val validationResult = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
@ -107,7 +107,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ietf_ABYTES)
 | 
			
		||||
        sodium.crypto_aead_chacha20poly1305_ietf_encrypt(
 | 
			
		||||
        sodiumJna.crypto_aead_chacha20poly1305_ietf_encrypt(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
@ -128,7 +128,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertextAndTag.size - crypto_aead_chacha20poly1305_ietf_ABYTES)
 | 
			
		||||
        val validationResult = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_aead_chacha20poly1305_ietf_decrypt(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
@ -153,7 +153,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
    ): AeadEncryptedDataAndTag {
 | 
			
		||||
        val ciphertext = UByteArray(message.size)
 | 
			
		||||
        val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ietf_ABYTES)
 | 
			
		||||
        sodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached(
 | 
			
		||||
        sodiumJna.crypto_aead_chacha20poly1305_ietf_encrypt_detached(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            authenticationTag.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
@ -176,7 +176,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size)
 | 
			
		||||
        val validationResult = sodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_aead_chacha20poly1305_ietf_decrypt_detached(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
@ -200,7 +200,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ABYTES)
 | 
			
		||||
        sodium.crypto_aead_chacha20poly1305_encrypt(
 | 
			
		||||
        sodiumJna.crypto_aead_chacha20poly1305_encrypt(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
@ -221,7 +221,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertextAndTag.size - crypto_aead_chacha20poly1305_ABYTES)
 | 
			
		||||
        val validationResult = sodium.crypto_aead_chacha20poly1305_decrypt(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_aead_chacha20poly1305_decrypt(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            null,
 | 
			
		||||
@ -246,7 +246,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
    ): AeadEncryptedDataAndTag {
 | 
			
		||||
        val ciphertext = UByteArray(message.size)
 | 
			
		||||
        val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ABYTES)
 | 
			
		||||
        sodium.crypto_aead_chacha20poly1305_encrypt_detached(
 | 
			
		||||
        sodiumJna.crypto_aead_chacha20poly1305_encrypt_detached(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            authenticationTag.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
@ -269,7 +269,7 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size)
 | 
			
		||||
        val validationResult = sodium.crypto_aead_chacha20poly1305_decrypt_detached(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_aead_chacha20poly1305_decrypt_detached(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
@ -288,19 +288,19 @@ actual object AuthenticatedEncryptionWithAssociatedData {
 | 
			
		||||
 | 
			
		||||
    actual fun xChaCha20Poly1305IetfKeygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_aead_xchacha20poly1305_ietf_KEYBYTES)
 | 
			
		||||
        sodium.crypto_aead_xchacha20poly1305_ietf_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_aead_xchacha20poly1305_ietf_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun chaCha20Poly1305IetfKeygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_aead_chacha20poly1305_ietf_KEYBYTES)
 | 
			
		||||
        sodium.crypto_aead_chacha20poly1305_ietf_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_aead_chacha20poly1305_ietf_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun chaCha20Poly1305Keygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_aead_chacha20poly1305_KEYBYTES)
 | 
			
		||||
        sodium.crypto_aead_chacha20poly1305_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_aead_chacha20poly1305_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.auth
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object Auth {
 | 
			
		||||
    actual fun authKeygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_auth_KEYBYTES)
 | 
			
		||||
        sodium.crypto_auth_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_auth_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun auth(message: UByteArray, key: UByteArray): UByteArray {
 | 
			
		||||
        val mac = UByteArray(crypto_auth_BYTES)
 | 
			
		||||
        sodium.crypto_auth(
 | 
			
		||||
        sodiumJna.crypto_auth(
 | 
			
		||||
            mac.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -21,7 +21,7 @@ actual object Auth {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun authVerify(tag: UByteArray, message: UByteArray, key: UByteArray): Boolean {
 | 
			
		||||
        return sodium.crypto_auth_verify(
 | 
			
		||||
        return sodiumJna.crypto_auth_verify(
 | 
			
		||||
            tag.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -31,13 +31,13 @@ actual object Auth {
 | 
			
		||||
 | 
			
		||||
    actual fun authHmacSha256Keygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_auth_hmacsha256_KEYBYTES)
 | 
			
		||||
        sodium.crypto_auth_hmacsha256_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_auth_hmacsha256_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray {
 | 
			
		||||
        val mac = UByteArray(crypto_auth_hmacsha256_BYTES)
 | 
			
		||||
        sodium.crypto_auth_hmacsha256(
 | 
			
		||||
        sodiumJna.crypto_auth_hmacsha256(
 | 
			
		||||
            mac.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -51,7 +51,7 @@ actual object Auth {
 | 
			
		||||
        message: UByteArray,
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): Boolean {
 | 
			
		||||
        return sodium.crypto_auth_hmacsha256_verify(
 | 
			
		||||
        return sodiumJna.crypto_auth_hmacsha256_verify(
 | 
			
		||||
            tag.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -61,13 +61,13 @@ actual object Auth {
 | 
			
		||||
 | 
			
		||||
    actual fun authHmacSha512Keygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_auth_hmacsha512_KEYBYTES)
 | 
			
		||||
        sodium.crypto_auth_hmacsha512_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_auth_hmacsha512_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray {
 | 
			
		||||
        val mac = UByteArray(crypto_auth_hmacsha512_BYTES)
 | 
			
		||||
        sodium.crypto_auth_hmacsha512(
 | 
			
		||||
        sodiumJna.crypto_auth_hmacsha512(
 | 
			
		||||
            mac.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -81,7 +81,7 @@ actual object Auth {
 | 
			
		||||
        message: UByteArray,
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): Boolean {
 | 
			
		||||
        return sodium.crypto_auth_hmacsha512_verify(
 | 
			
		||||
        return sodiumJna.crypto_auth_hmacsha512_verify(
 | 
			
		||||
            tag.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.box
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object Box {
 | 
			
		||||
    /**
 | 
			
		||||
@ -11,7 +11,7 @@ actual object Box {
 | 
			
		||||
    actual fun keypair(): BoxKeyPair {
 | 
			
		||||
        val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES)
 | 
			
		||||
        val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
 | 
			
		||||
        sodium.crypto_box_keypair(publicKey.asByteArray(), secretKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_box_keypair(publicKey.asByteArray(), secretKey.asByteArray())
 | 
			
		||||
        return BoxKeyPair(publicKey, secretKey)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ actual object Box {
 | 
			
		||||
    actual fun seedKeypair(seed: UByteArray): BoxKeyPair {
 | 
			
		||||
        val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES)
 | 
			
		||||
        val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
 | 
			
		||||
        sodium.crypto_box_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_box_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
 | 
			
		||||
        return BoxKeyPair(publicKey, secretKey)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -39,7 +39,7 @@ actual object Box {
 | 
			
		||||
        sendersSecretKey: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val ciphertext = UByteArray(message.size + crypto_box_MACBYTES)
 | 
			
		||||
        sodium.crypto_box_easy(
 | 
			
		||||
        sodiumJna.crypto_box_easy(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -64,7 +64,7 @@ actual object Box {
 | 
			
		||||
        recipientsSecretKey: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size - crypto_box_MACBYTES)
 | 
			
		||||
        val validationResult = sodium.crypto_box_open_easy(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_box_open_easy(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            ciphertext.size.toLong(),
 | 
			
		||||
@ -85,7 +85,7 @@ actual object Box {
 | 
			
		||||
     */
 | 
			
		||||
    actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray {
 | 
			
		||||
        val sessionKey = UByteArray(crypto_box_BEFORENMBYTES)
 | 
			
		||||
        sodium.crypto_box_beforenm(sessionKey.asByteArray(), publicKey.asByteArray(), secretKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_box_beforenm(sessionKey.asByteArray(), publicKey.asByteArray(), secretKey.asByteArray())
 | 
			
		||||
        return sessionKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -99,7 +99,7 @@ actual object Box {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val ciphertext = UByteArray(message.size + crypto_box_MACBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_box_easy_afternm(
 | 
			
		||||
        sodiumJna.crypto_box_easy_afternm(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -119,7 +119,7 @@ actual object Box {
 | 
			
		||||
        precomputedKey: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size - crypto_box_MACBYTES)
 | 
			
		||||
        val validationResult = sodium.crypto_box_open_easy_afternm(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_box_open_easy_afternm(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            ciphertext.size.toLong(),
 | 
			
		||||
@ -149,7 +149,7 @@ actual object Box {
 | 
			
		||||
        val ciphertext = UByteArray(message.size)
 | 
			
		||||
        val tag = UByteArray(crypto_box_MACBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_box_detached(
 | 
			
		||||
        sodiumJna.crypto_box_detached(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            tag.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
@ -177,7 +177,7 @@ actual object Box {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size)
 | 
			
		||||
 | 
			
		||||
        val validationResult = sodium.crypto_box_open_detached(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_box_open_detached(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            tag.asByteArray(),
 | 
			
		||||
@ -196,7 +196,7 @@ actual object Box {
 | 
			
		||||
 | 
			
		||||
    actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray {
 | 
			
		||||
        val ciphertextWithPublicKey = UByteArray(message.size + crypto_box_SEALBYTES)
 | 
			
		||||
        sodium.crypto_box_seal(
 | 
			
		||||
        sodiumJna.crypto_box_seal(
 | 
			
		||||
            ciphertextWithPublicKey.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -207,7 +207,7 @@ actual object Box {
 | 
			
		||||
 | 
			
		||||
    actual fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES)
 | 
			
		||||
        val validationResult = sodium.crypto_box_seal_open(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_box_seal_open(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            ciphertext.size.toLong(),
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,14 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.generichash
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.Blake2bState
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
 * ugljesa.jovanovic@ionspin.com
 | 
			
		||||
 * on 21-Aug-2020
 | 
			
		||||
 */
 | 
			
		||||
actual class GenericHashStateInternal(internal val data: ByteArray)
 | 
			
		||||
actual typealias GenericHashStateInternal = Blake2bState
 | 
			
		||||
 | 
			
		||||
actual object GenericHash {
 | 
			
		||||
    actual fun genericHash(
 | 
			
		||||
@ -16,12 +17,12 @@ actual object GenericHash {
 | 
			
		||||
        key: UByteArray?
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val hash = UByteArray(requestedHashLength)
 | 
			
		||||
        sodium.crypto_generichash(
 | 
			
		||||
        sodiumJna.crypto_generichash(
 | 
			
		||||
            hash.asByteArray(),
 | 
			
		||||
            requestedHashLength,
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
            key?.asByteArray(),
 | 
			
		||||
            key?.asByteArray() ?: ByteArray(0),
 | 
			
		||||
            (key?.size ?: 0)
 | 
			
		||||
        )
 | 
			
		||||
        return hash
 | 
			
		||||
@ -31,8 +32,8 @@ actual object GenericHash {
 | 
			
		||||
        requestedHashLength: Int,
 | 
			
		||||
        key: UByteArray?
 | 
			
		||||
    ): GenericHashState {
 | 
			
		||||
        val state = GenericHashStateInternal(ByteArray(sodium.crypto_generichash_statebytes()))
 | 
			
		||||
        sodium.crypto_generichash_init(state.data, key?.asByteArray(), key?.size ?: 0, requestedHashLength)
 | 
			
		||||
        val state = GenericHashStateInternal()
 | 
			
		||||
        sodiumJna.crypto_generichash_init(state, key?.asByteArray() ?: ByteArray(0), key?.size ?: 0, requestedHashLength)
 | 
			
		||||
        return GenericHashState(requestedHashLength, state)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -40,18 +41,18 @@ actual object GenericHash {
 | 
			
		||||
        state: GenericHashState,
 | 
			
		||||
        messagePart: UByteArray
 | 
			
		||||
    ) {
 | 
			
		||||
        sodium.crypto_generichash_update(state.internalState.data, messagePart.asByteArray(), messagePart.size.toLong())
 | 
			
		||||
        sodiumJna.crypto_generichash_update(state.internalState, messagePart.asByteArray(), messagePart.size.toLong())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun genericHashFinal(state: GenericHashState): UByteArray {
 | 
			
		||||
        val hashResult = ByteArray(state.hashLength)
 | 
			
		||||
        sodium.crypto_generichash_final(state.internalState.data, hashResult, state.hashLength)
 | 
			
		||||
        sodiumJna.crypto_generichash_final(state.internalState, hashResult, state.hashLength)
 | 
			
		||||
        return hashResult.asUByteArray()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun genericHashKeygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_generichash_BYTES)
 | 
			
		||||
        sodium.crypto_generichash_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_generichash_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,54 +1,55 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.hash
 | 
			
		||||
 | 
			
		||||
import com.goterl.lazycode.lazysodium.interfaces.Hash
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.Hash256State
 | 
			
		||||
import com.ionspin.kotlin.crypto.Hash512State
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual typealias Sha256State = Hash.State256
 | 
			
		||||
actual typealias Sha512State = Hash.State512
 | 
			
		||||
actual typealias Sha256State = Hash256State
 | 
			
		||||
actual typealias Sha512State = Hash512State
 | 
			
		||||
 | 
			
		||||
actual object Hash {
 | 
			
		||||
 | 
			
		||||
    actual fun sha256(data: UByteArray): UByteArray {
 | 
			
		||||
        val resultHash = UByteArray(crypto_hash_sha256_BYTES)
 | 
			
		||||
        sodium.crypto_hash_sha256(resultHash.asByteArray(), data.asByteArray(), data.size.toLong())
 | 
			
		||||
        sodiumJna.crypto_hash_sha256(resultHash.asByteArray(), data.asByteArray(),  data.size.toLong())
 | 
			
		||||
        return resultHash
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun sha256Init(): Sha256State {
 | 
			
		||||
        val state = Hash.State256()
 | 
			
		||||
        sodium.crypto_hash_sha256_init(state)
 | 
			
		||||
        val state = Hash256State()
 | 
			
		||||
        sodiumJna.crypto_hash_sha256_init(state)
 | 
			
		||||
        return state
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun sha256Update(state: Sha256State, data: UByteArray) {
 | 
			
		||||
        sodium.crypto_hash_sha256_update(state, data.asByteArray(), data.size.toLong())
 | 
			
		||||
        sodiumJna.crypto_hash_sha256_update(state, data.asByteArray(), data.size.toLong())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun sha256Final(state: Sha256State): UByteArray {
 | 
			
		||||
        val resultHash = UByteArray(crypto_hash_sha256_BYTES)
 | 
			
		||||
        sodium.crypto_hash_sha256_final(state, resultHash.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_hash_sha256_final(state, resultHash.asByteArray())
 | 
			
		||||
        return resultHash
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun sha512(data: UByteArray): UByteArray {
 | 
			
		||||
        val resultHash = UByteArray(crypto_hash_sha512_BYTES)
 | 
			
		||||
        sodium.crypto_hash_sha512(resultHash.asByteArray(), data.asByteArray(), data.size.toLong())
 | 
			
		||||
        sodiumJna.crypto_hash_sha512(resultHash.asByteArray(), data.asByteArray(), data.size.toLong())
 | 
			
		||||
        return resultHash
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun sha512Init(): Sha512State {
 | 
			
		||||
        val state = Hash.State512()
 | 
			
		||||
        sodium.crypto_hash_sha512_init(state)
 | 
			
		||||
        val state = Hash512State()
 | 
			
		||||
        sodiumJna.crypto_hash_sha512_init(state)
 | 
			
		||||
        return state
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun sha512Update(state: Sha512State, data: UByteArray) {
 | 
			
		||||
        sodium.crypto_hash_sha512_update(state, data.asByteArray(), data.size.toLong())
 | 
			
		||||
        sodiumJna.crypto_hash_sha512_update(state, data.asByteArray(), data.size.toLong())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun sha512Final(state: Sha512State): UByteArray {
 | 
			
		||||
        val resultHash = UByteArray(crypto_hash_sha512_BYTES)
 | 
			
		||||
        sodium.crypto_hash_sha512_final(state, resultHash.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_hash_sha512_final(state, resultHash.asByteArray())
 | 
			
		||||
        return resultHash
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.kdf
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object Kdf {
 | 
			
		||||
    /**
 | 
			
		||||
@ -26,7 +26,7 @@ actual object Kdf {
 | 
			
		||||
        val subkey = UByteArray(subkeyLength)
 | 
			
		||||
        val contextEncoded = context.encodeToByteArray()
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_kdf_derive_from_key(
 | 
			
		||||
        sodiumJna.crypto_kdf_derive_from_key(
 | 
			
		||||
            subkey.asByteArray(),
 | 
			
		||||
            subkeyLength,
 | 
			
		||||
            subkeyId.toLong(),
 | 
			
		||||
@ -42,7 +42,7 @@ actual object Kdf {
 | 
			
		||||
     */
 | 
			
		||||
    actual fun keygen(): UByteArray {
 | 
			
		||||
        val masterKey = UByteArray(crypto_kdf_KEYBYTES)
 | 
			
		||||
        sodium.crypto_kdf_keygen(masterKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_kdf_keygen(masterKey.asByteArray())
 | 
			
		||||
        return masterKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,13 +1,13 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.keyexchange
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object KeyExchange {
 | 
			
		||||
    actual fun clientSessionKeys(clientPublicKey: UByteArray, clientSecretKey: UByteArray, serverPublicKey: UByteArray) : KeyExchangeSessionKeyPair {
 | 
			
		||||
        val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
 | 
			
		||||
        val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_kx_client_session_keys(
 | 
			
		||||
        sodiumJna.crypto_kx_client_session_keys(
 | 
			
		||||
            receiveKey.asByteArray(),
 | 
			
		||||
            sendKey.asByteArray(),
 | 
			
		||||
            clientPublicKey.asByteArray(),
 | 
			
		||||
@ -25,7 +25,7 @@ actual object KeyExchange {
 | 
			
		||||
        val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_kx_keypair(publicKey.asByteArray(), secretKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_kx_keypair(publicKey.asByteArray(), secretKey.asByteArray())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return KeyExchangeKeyPair(publicKey, secretKey)
 | 
			
		||||
@ -35,7 +35,7 @@ actual object KeyExchange {
 | 
			
		||||
        val publicKey = UByteArray(crypto_kx_PUBLICKEYBYTES)
 | 
			
		||||
        val secretKey = UByteArray(crypto_kx_SECRETKEYBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_kx_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_kx_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
 | 
			
		||||
 | 
			
		||||
        return KeyExchangeKeyPair(publicKey, secretKey)
 | 
			
		||||
    }
 | 
			
		||||
@ -44,7 +44,7 @@ actual object KeyExchange {
 | 
			
		||||
        val receiveKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
 | 
			
		||||
        val sendKey = UByteArray(crypto_kx_SESSIONKEYBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_kx_server_session_keys(
 | 
			
		||||
        sodiumJna.crypto_kx_server_session_keys(
 | 
			
		||||
            receiveKey.asByteArray(),
 | 
			
		||||
            sendKey.asByteArray(),
 | 
			
		||||
            serverPublicKey.asByteArray(),
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.pwhash
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
import com.sun.jna.NativeLong
 | 
			
		||||
 | 
			
		||||
actual object PasswordHash {
 | 
			
		||||
@ -10,7 +10,7 @@ actual object PasswordHash {
 | 
			
		||||
     * PASSWD_MIN and crypto_pwhash_PASSWD_MAX. outlen should be at least crypto_pwhash_BYTES_MIN = 16 (128 bits) and
 | 
			
		||||
     * at most crypto_pwhash_BYTES_MAX.
 | 
			
		||||
     *
 | 
			
		||||
     * See https://libsodium.gitbook.io/doc/password_hashing/default_phf for more details
 | 
			
		||||
     * See https://libsodiumJna.gitbook.io/doc/password_hashing/default_phf for more details
 | 
			
		||||
     */
 | 
			
		||||
    actual fun pwhash(
 | 
			
		||||
        outputLength: Int,
 | 
			
		||||
@ -22,14 +22,14 @@ actual object PasswordHash {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val hashedPassword = UByteArray(outputLength)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_pwhash(
 | 
			
		||||
        sodiumJna.crypto_pwhash(
 | 
			
		||||
            hashedPassword.asByteArray(),
 | 
			
		||||
            outputLength.toLong(),
 | 
			
		||||
            password.encodeToByteArray(),
 | 
			
		||||
            password,
 | 
			
		||||
            password.length.toLong(),
 | 
			
		||||
            salt.asByteArray(),
 | 
			
		||||
            opsLimit.toLong(),
 | 
			
		||||
            NativeLong(memLimit.toLong()),
 | 
			
		||||
            memLimit.toLong(),
 | 
			
		||||
            algorithm
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
@ -48,12 +48,12 @@ actual object PasswordHash {
 | 
			
		||||
     */
 | 
			
		||||
    actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray {
 | 
			
		||||
        val output = ByteArray(crypto_pwhash_STRBYTES)
 | 
			
		||||
        sodium.crypto_pwhash_str(
 | 
			
		||||
        sodiumJna.crypto_pwhash_str(
 | 
			
		||||
            output,
 | 
			
		||||
            password.encodeToByteArray(),
 | 
			
		||||
            password,
 | 
			
		||||
            password.length.toLong(),
 | 
			
		||||
            opslimit.toLong(),
 | 
			
		||||
            NativeLong(memlimit.toLong())
 | 
			
		||||
            memlimit.toLong()
 | 
			
		||||
        )
 | 
			
		||||
        return output.asUByteArray()
 | 
			
		||||
    }
 | 
			
		||||
@ -69,10 +69,10 @@ actual object PasswordHash {
 | 
			
		||||
        opslimit: ULong,
 | 
			
		||||
        memlimit: Int
 | 
			
		||||
    ): Int {
 | 
			
		||||
        return sodium.crypto_pwhash_str_needs_rehash(
 | 
			
		||||
        return sodiumJna.crypto_pwhash_str_needs_rehash(
 | 
			
		||||
            passwordHash.asByteArray(),
 | 
			
		||||
            opslimit.toLong(),
 | 
			
		||||
            NativeLong(memlimit.toLong())
 | 
			
		||||
            memlimit.toLong()
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -82,9 +82,9 @@ actual object PasswordHash {
 | 
			
		||||
     * It returns 0 if the verification succeeds, and -1 on error.
 | 
			
		||||
     */
 | 
			
		||||
    actual fun strVerify(passwordHash: UByteArray, password: String): Boolean {
 | 
			
		||||
        val result = sodium.crypto_pwhash_str_verify(
 | 
			
		||||
        val result = sodiumJna.crypto_pwhash_str_verify(
 | 
			
		||||
            passwordHash.asByteArray(),
 | 
			
		||||
            password.encodeToByteArray(),
 | 
			
		||||
            password,
 | 
			
		||||
            password.length.toLong()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.scalarmult
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object ScalarMultiplication {
 | 
			
		||||
    /**
 | 
			
		||||
@ -18,7 +18,7 @@ actual object ScalarMultiplication {
 | 
			
		||||
    actual fun scalarMultiplication(secretKeyN: UByteArray, publicKeyP: UByteArray): UByteArray {
 | 
			
		||||
        val result = UByteArray(crypto_scalarmult_BYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_scalarmult(result.asByteArray(), secretKeyN.asByteArray(), publicKeyP.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_scalarmult(result.asByteArray(), secretKeyN.asByteArray(), publicKeyP.asByteArray())
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        return result
 | 
			
		||||
@ -35,7 +35,7 @@ actual object ScalarMultiplication {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val result = UByteArray(crypto_scalarmult_BYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_scalarmult_base(result.asByteArray(), secretKeyN.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_scalarmult_base(result.asByteArray(), secretKeyN.asByteArray())
 | 
			
		||||
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,11 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.secretbox
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object SecretBox {
 | 
			
		||||
    actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray {
 | 
			
		||||
        val ciphertext = UByteArray(message.size + crypto_secretbox_MACBYTES)
 | 
			
		||||
        sodium.crypto_secretbox_easy(
 | 
			
		||||
        sodiumJna.crypto_secretbox_easy(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -21,7 +21,7 @@ actual object SecretBox {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val decrypted = UByteArray(ciphertext.size - crypto_secretbox_MACBYTES)
 | 
			
		||||
        val validationResult = sodium.crypto_secretbox_open_easy(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_secretbox_open_easy(
 | 
			
		||||
            decrypted.asByteArray(),
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            ciphertext.size.toLong(),
 | 
			
		||||
@ -41,7 +41,7 @@ actual object SecretBox {
 | 
			
		||||
    ): SecretBoxEncryptedDataAndTag {
 | 
			
		||||
        val ciphertext = UByteArray(message.size)
 | 
			
		||||
        val authenticationTag = UByteArray(crypto_secretbox_MACBYTES)
 | 
			
		||||
        sodium.crypto_secretbox_detached(
 | 
			
		||||
        sodiumJna.crypto_secretbox_detached(
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            authenticationTag.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
@ -59,7 +59,7 @@ actual object SecretBox {
 | 
			
		||||
        key: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val message = UByteArray(ciphertext.size)
 | 
			
		||||
        val validationResult = sodium.crypto_secretbox_open_detached(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_secretbox_open_detached(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            tag.asByteArray(),
 | 
			
		||||
@ -75,7 +75,7 @@ actual object SecretBox {
 | 
			
		||||
 | 
			
		||||
    actual fun keygen() : UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_secretbox_KEYBYTES)
 | 
			
		||||
        sodium.crypto_secretbox_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_secretbox_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,15 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.secretstream
 | 
			
		||||
 | 
			
		||||
import com.goterl.lazycode.lazysodium.interfaces.SecretStream
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
import com.ionspin.kotlin.crypto.SecretStreamXChaCha20Poly1305State
 | 
			
		||||
 | 
			
		||||
actual typealias SecretStreamState = SecretStream.State
 | 
			
		||||
actual typealias SecretStreamState = SecretStreamXChaCha20Poly1305State
 | 
			
		||||
 | 
			
		||||
actual object SecretStream {
 | 
			
		||||
    actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader {
 | 
			
		||||
        val state = SecretStreamState()
 | 
			
		||||
        val header = UByteArray(sodium.crypto_secretstream_xchacha20poly1305_headerbytes())
 | 
			
		||||
        sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray())
 | 
			
		||||
        val header = UByteArray(sodiumJna.crypto_secretstream_xchacha20poly1305_headerbytes())
 | 
			
		||||
        sodiumJna.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray())
 | 
			
		||||
        return SecretStreamStateAndHeader(state, header)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,7 @@ actual object SecretStream {
 | 
			
		||||
        tag: UByte
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val ciphertext = UByteArray(message.size + crypto_secretstream_xchacha20poly1305_ABYTES)
 | 
			
		||||
        sodium.crypto_secretstream_xchacha20poly1305_push(
 | 
			
		||||
        sodiumJna.crypto_secretstream_xchacha20poly1305_push(
 | 
			
		||||
            state,
 | 
			
		||||
            ciphertext.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
@ -38,7 +38,7 @@ actual object SecretStream {
 | 
			
		||||
        header: UByteArray
 | 
			
		||||
    ): SecretStreamStateAndHeader {
 | 
			
		||||
        val state = SecretStreamState()
 | 
			
		||||
        sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray())
 | 
			
		||||
        return SecretStreamStateAndHeader(state, header)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,7 @@ actual object SecretStream {
 | 
			
		||||
    ): DecryptedDataAndTag {
 | 
			
		||||
        val result = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES)
 | 
			
		||||
        val tagArray = UByteArray(1) { 0U }
 | 
			
		||||
        val validationResult = sodium.crypto_secretstream_xchacha20poly1305_pull(
 | 
			
		||||
        val validationResult = sodiumJna.crypto_secretstream_xchacha20poly1305_pull(
 | 
			
		||||
            state,
 | 
			
		||||
            result.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
@ -67,12 +67,12 @@ actual object SecretStream {
 | 
			
		||||
 | 
			
		||||
    actual fun xChaCha20Poly1305Keygen(): UByteArray {
 | 
			
		||||
        val generatedKey = UByteArray(crypto_secretstream_xchacha20poly1305_KEYBYTES)
 | 
			
		||||
        sodium.crypto_secretstream_xchacha20poly1305_keygen(generatedKey.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_secretstream_xchacha20poly1305_keygen(generatedKey.asByteArray())
 | 
			
		||||
        return generatedKey
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) {
 | 
			
		||||
        sodium.crypto_secretstream_xchacha20poly1305_rekey(state)
 | 
			
		||||
        sodiumJna.crypto_secretstream_xchacha20poly1305_rekey(state)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.shortinputhash
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
import com.sun.jna.NativeLong
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
@ -12,13 +13,13 @@ import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
actual object ShortHash {
 | 
			
		||||
    actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray {
 | 
			
		||||
        val hashResult = UByteArray(crypto_shorthash_BYTES)
 | 
			
		||||
        sodium.crypto_shorthash(hashResult.asByteArray(), data.asByteArray(), data.size.toLong(), key.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_shorthash(hashResult.asByteArray(), data.asByteArray(), data.size.toLong(), key.asByteArray())
 | 
			
		||||
        return hashResult
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun shortHashKeygen(): UByteArray {
 | 
			
		||||
        val key = UByteArray(crypto_shorthash_KEYBYTES)
 | 
			
		||||
        sodium.crypto_shorthash_keygen(key.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_shorthash_keygen(key.asByteArray())
 | 
			
		||||
        return key
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.signature
 | 
			
		||||
 | 
			
		||||
import com.goterl.lazycode.lazysodium.interfaces.Sign
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.Ed25519SignatureState
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual typealias SignatureState = Sign.StateCryptoSign
 | 
			
		||||
actual typealias SignatureState = Ed25519SignatureState
 | 
			
		||||
 | 
			
		||||
actual object Signature {
 | 
			
		||||
    actual fun init(): SignatureState {
 | 
			
		||||
@ -11,7 +11,7 @@ actual object Signature {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun update(state: SignatureState, data: UByteArray) {
 | 
			
		||||
        sodium.crypto_sign_update(state, data.asByteArray(), data.size.toLong())
 | 
			
		||||
        sodiumJna.crypto_sign_update(state, data.asByteArray(), data.size.toLong())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun finalCreate(
 | 
			
		||||
@ -19,7 +19,7 @@ actual object Signature {
 | 
			
		||||
        secretKey: UByteArray
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val signature = UByteArray(crypto_sign_BYTES)
 | 
			
		||||
        sodium.crypto_sign_final_create(
 | 
			
		||||
        sodiumJna.crypto_sign_final_create(
 | 
			
		||||
            state,
 | 
			
		||||
            signature.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
@ -33,7 +33,7 @@ actual object Signature {
 | 
			
		||||
        signature: UByteArray,
 | 
			
		||||
        publicKey: UByteArray
 | 
			
		||||
    ) {
 | 
			
		||||
        val verificationResult = sodium.crypto_sign_final_verify(
 | 
			
		||||
        val verificationResult = sodiumJna.crypto_sign_final_verify(
 | 
			
		||||
            state,
 | 
			
		||||
            signature.asByteArray(),
 | 
			
		||||
            publicKey.asByteArray()
 | 
			
		||||
@ -50,7 +50,7 @@ actual object Signature {
 | 
			
		||||
    actual fun keypair(): SignatureKeyPair {
 | 
			
		||||
        val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES)
 | 
			
		||||
        val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES)
 | 
			
		||||
        sodium.crypto_sign_keypair(
 | 
			
		||||
        sodiumJna.crypto_sign_keypair(
 | 
			
		||||
            publicKey.asByteArray(),
 | 
			
		||||
            secretKey.asByteArray(),
 | 
			
		||||
        )
 | 
			
		||||
@ -67,7 +67,7 @@ actual object Signature {
 | 
			
		||||
        val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_sign_seed_keypair(
 | 
			
		||||
        sodiumJna.crypto_sign_seed_keypair(
 | 
			
		||||
            publicKey.asByteArray(),
 | 
			
		||||
            secretKey.asByteArray(),
 | 
			
		||||
            seed.asByteArray()
 | 
			
		||||
@ -76,13 +76,13 @@ actual object Signature {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The sodium.crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk.
 | 
			
		||||
     * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is sodium.crypto_sign_BYTES + mlen bytes long.
 | 
			
		||||
     * The sodiumJna.crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk.
 | 
			
		||||
     * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is sodiumJna.crypto_sign_BYTES + mlen bytes long.
 | 
			
		||||
     */
 | 
			
		||||
    actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray {
 | 
			
		||||
        val signedMessage = UByteArray(message.size + crypto_sign_BYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_sign(
 | 
			
		||||
        sodiumJna.crypto_sign(
 | 
			
		||||
            signedMessage.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
@ -94,13 +94,13 @@ actual object Signature {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The sodium.crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk.
 | 
			
		||||
     * The sodiumJna.crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk.
 | 
			
		||||
     * If the signature is doesn't appear to be valid, the function throws an exception
 | 
			
		||||
     */
 | 
			
		||||
    actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray {
 | 
			
		||||
        val message = UByteArray(signedMessage.size - crypto_sign_BYTES)
 | 
			
		||||
 | 
			
		||||
        val verificationResult = sodium.crypto_sign_open(
 | 
			
		||||
        val verificationResult = sodiumJna.crypto_sign_open(
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            signedMessage.asByteArray(),
 | 
			
		||||
@ -115,13 +115,13 @@ actual object Signature {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * In detached mode, the signature is stored without attaching a copy of the original message to it.
 | 
			
		||||
     * The sodium.crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk,
 | 
			
		||||
     * and puts the signature into sig, which can be up to sodium.crypto_sign_BYTES bytes long.
 | 
			
		||||
     * The sodiumJna.crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk,
 | 
			
		||||
     * and puts the signature into sig, which can be up to sodiumJna.crypto_sign_BYTES bytes long.
 | 
			
		||||
     */
 | 
			
		||||
    actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray {
 | 
			
		||||
        val signature = UByteArray(crypto_sign_BYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_sign_detached(
 | 
			
		||||
        sodiumJna.crypto_sign_detached(
 | 
			
		||||
            signature.asByteArray(),
 | 
			
		||||
            null,
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
@ -133,7 +133,7 @@ actual object Signature {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The sodium.crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length
 | 
			
		||||
     * The sodiumJna.crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length
 | 
			
		||||
     * is mlen bytes, using the signer's public key pk.
 | 
			
		||||
     */
 | 
			
		||||
    actual fun verifyDetached(
 | 
			
		||||
@ -142,7 +142,7 @@ actual object Signature {
 | 
			
		||||
        publicKey: UByteArray
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        val verificationResult = sodium.crypto_sign_verify_detached(
 | 
			
		||||
        val verificationResult = sodiumJna.crypto_sign_verify_detached(
 | 
			
		||||
            signature.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -155,11 +155,11 @@ actual object Signature {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The sodium.crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk.
 | 
			
		||||
     * The sodiumJna.crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk.
 | 
			
		||||
     */
 | 
			
		||||
    actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray {
 | 
			
		||||
        val x25519PublicKey = UByteArray(crypto_scalarmult_curve25519_BYTES)
 | 
			
		||||
        sodium.crypto_sign_ed25519_sk_to_curve25519(
 | 
			
		||||
        sodiumJna.crypto_sign_ed25519_sk_to_curve25519(
 | 
			
		||||
            x25519PublicKey.asByteArray(),
 | 
			
		||||
            ed25519PublicKey.asByteArray()
 | 
			
		||||
        )
 | 
			
		||||
@ -168,7 +168,7 @@ actual object Signature {
 | 
			
		||||
 | 
			
		||||
    actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray {
 | 
			
		||||
        val x25519SecretKey = UByteArray(crypto_scalarmult_curve25519_BYTES)
 | 
			
		||||
        sodium.crypto_sign_ed25519_sk_to_curve25519(
 | 
			
		||||
        sodiumJna.crypto_sign_ed25519_sk_to_curve25519(
 | 
			
		||||
            x25519SecretKey.asByteArray(),
 | 
			
		||||
            ed25519SecretKey.asByteArray()
 | 
			
		||||
        )
 | 
			
		||||
@ -176,13 +176,13 @@ actual object Signature {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key.
 | 
			
		||||
     * The secret key actually includes the seed (either a random seed or the one given to sodiumJna.crypto_sign_seed_keypair()) as well as the public key.
 | 
			
		||||
     * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.
 | 
			
		||||
     */
 | 
			
		||||
    actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray {
 | 
			
		||||
        val seed = UByteArray(crypto_sign_SEEDBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_sign_ed25519_sk_to_seed(
 | 
			
		||||
        sodiumJna.crypto_sign_ed25519_sk_to_seed(
 | 
			
		||||
            seed.asByteArray(),
 | 
			
		||||
            secretKey.asByteArray()
 | 
			
		||||
        )
 | 
			
		||||
@ -192,13 +192,13 @@ actual object Signature {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key.
 | 
			
		||||
     * The secret key actually includes the seed (either a random seed or the one given to sodiumJna.crypto_sign_seed_keypair()) as well as the public key.
 | 
			
		||||
     * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing.
 | 
			
		||||
     */
 | 
			
		||||
    actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray {
 | 
			
		||||
        val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_sign_ed25519_sk_to_pk(
 | 
			
		||||
        sodiumJna.crypto_sign_ed25519_sk_to_pk(
 | 
			
		||||
            publicKey.asByteArray(),
 | 
			
		||||
            secretKey.asByteArray()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.stream
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
actual object Stream {
 | 
			
		||||
    actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
 | 
			
		||||
        val result = UByteArray(clen)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_stream_chacha20(result.asByteArray(), clen.toLong(), nonce.asByteArray(), key.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_stream_chacha20(result.asByteArray(), clen.toLong(), nonce.asByteArray(), key.asByteArray())
 | 
			
		||||
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
@ -18,7 +18,7 @@ actual object Stream {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val result = UByteArray(message.size)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_stream_chacha20_ietf_xor(
 | 
			
		||||
        sodiumJna.crypto_stream_chacha20_ietf_xor(
 | 
			
		||||
            result.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -37,7 +37,7 @@ actual object Stream {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val result = UByteArray(message.size)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_stream_chacha20_ietf_xor_ic(
 | 
			
		||||
        sodiumJna.crypto_stream_chacha20_ietf_xor_ic(
 | 
			
		||||
            result.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -52,7 +52,7 @@ actual object Stream {
 | 
			
		||||
    actual fun chacha20Keygen(): UByteArray {
 | 
			
		||||
        val result = UByteArray(crypto_stream_chacha20_KEYBYTES)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_stream_chacha20_keygen(result.asByteArray())
 | 
			
		||||
        sodiumJna.crypto_stream_chacha20_keygen(result.asByteArray())
 | 
			
		||||
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
@ -64,7 +64,7 @@ actual object Stream {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val result = UByteArray(message.size)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_stream_chacha20_xor(
 | 
			
		||||
        sodiumJna.crypto_stream_chacha20_xor(
 | 
			
		||||
            result.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -83,7 +83,7 @@ actual object Stream {
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        val result = UByteArray(message.size)
 | 
			
		||||
 | 
			
		||||
        sodium.crypto_stream_chacha20_xor_ic(
 | 
			
		||||
        sodiumJna.crypto_stream_chacha20_xor_ic(
 | 
			
		||||
            result.asByteArray(),
 | 
			
		||||
            message.asByteArray(),
 | 
			
		||||
            message.size.toLong(),
 | 
			
		||||
@ -95,4 +95,50 @@ actual object Stream {
 | 
			
		||||
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    actual fun xChacha20Keygen(): UByteArray {
 | 
			
		||||
//        val result = UByteArray(crypto_stream_chacha20_KEYBYTES)
 | 
			
		||||
//
 | 
			
		||||
//        sodiumJna.crypto_stream_xchacha20_keygen(result.asByteArray())
 | 
			
		||||
//
 | 
			
		||||
//        return result
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    actual fun xChacha20Xor(
 | 
			
		||||
//        message: UByteArray,
 | 
			
		||||
//        nonce: UByteArray,
 | 
			
		||||
//        key: UByteArray
 | 
			
		||||
//    ): UByteArray {
 | 
			
		||||
//        val result = UByteArray(message.size)
 | 
			
		||||
//
 | 
			
		||||
//        sodiumJna.crypto_stream_xchacha20_xor(
 | 
			
		||||
//            result.asByteArray(),
 | 
			
		||||
//            message.asByteArray(),
 | 
			
		||||
//            message.size.toLong(),
 | 
			
		||||
//            nonce.asByteArray(),
 | 
			
		||||
//            key.asByteArray()
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        return result
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    actual fun xChacha20XorIc(
 | 
			
		||||
//        message: UByteArray,
 | 
			
		||||
//        nonce: UByteArray,
 | 
			
		||||
//        initialCounter: ULong,
 | 
			
		||||
//        key: UByteArray
 | 
			
		||||
//    ): UByteArray {
 | 
			
		||||
//        val result = UByteArray(message.size)
 | 
			
		||||
//
 | 
			
		||||
//        sodiumJna.crypto_stream_xchacha20_xor_ic(
 | 
			
		||||
//            result.asByteArray(),
 | 
			
		||||
//            message.asByteArray(),
 | 
			
		||||
//            message.size.toLong(),
 | 
			
		||||
//            nonce.asByteArray(),
 | 
			
		||||
//            initialCounter.toLong(),
 | 
			
		||||
//            key.asByteArray()
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        return result
 | 
			
		||||
//    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.util
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
@ -13,7 +13,7 @@ actual object LibsodiumRandom {
 | 
			
		||||
     */
 | 
			
		||||
    actual fun buf(size: Int): UByteArray {
 | 
			
		||||
        val result = ByteArray(size)
 | 
			
		||||
        sodium.randombytes_buf(result, size)
 | 
			
		||||
        sodiumJna.randombytes_buf(result, size)
 | 
			
		||||
        return result.asUByteArray()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ actual object LibsodiumRandom {
 | 
			
		||||
     */
 | 
			
		||||
    actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray {
 | 
			
		||||
        val result = ByteArray(size)
 | 
			
		||||
        sodium.randombytes_buf_deterministic(result, size, seed.asByteArray())
 | 
			
		||||
        sodiumJna.randombytes_buf_deterministic(result, size, seed.asByteArray())
 | 
			
		||||
        return result.asUByteArray()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -35,9 +35,7 @@ actual object LibsodiumRandom {
 | 
			
		||||
     * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included).
 | 
			
		||||
     */
 | 
			
		||||
    actual fun random(): UInt {
 | 
			
		||||
        //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86
 | 
			
		||||
        //Using temporary forked and fixed build until pull request is accepted in original repo
 | 
			
		||||
        return sodium.randombytes_random().toUInt()
 | 
			
		||||
        return sodiumJna.randombytes_random().toUInt()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -48,9 +46,7 @@ actual object LibsodiumRandom {
 | 
			
		||||
     * upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0
 | 
			
		||||
     */
 | 
			
		||||
    actual fun uniform(upperBound: UInt): UInt {
 | 
			
		||||
        //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86
 | 
			
		||||
        //Using temporary fixed build until pull request is accepted
 | 
			
		||||
        return sodium.randombytes_uniform(upperBound.toInt()).toUInt()
 | 
			
		||||
        return sodiumJna.randombytes_uniform(upperBound.toLong()).toUInt()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.util
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
import com.sun.jna.ptr.IntByReference
 | 
			
		||||
import java.lang.RuntimeException
 | 
			
		||||
import java.util.*
 | 
			
		||||
 | 
			
		||||
@ -9,100 +10,63 @@ actual object LibsodiumUtil {
 | 
			
		||||
        if (first.size != second.size) {
 | 
			
		||||
            throw RuntimeException("Sodium memcmp() only supports comparing same length arrays")
 | 
			
		||||
        }
 | 
			
		||||
        return sodium.sodium_memcmp(first.asByteArray(), second.asByteArray(), first.size) == 0
 | 
			
		||||
        return sodiumJna.sodium_memcmp(first.asByteArray(), second.asByteArray(), first.size) == 0
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun memzero(target: UByteArray) {
 | 
			
		||||
        sodium.sodium_memzero(target.asByteArray(), target.size)
 | 
			
		||||
        sodiumJna.sodium_memzero(target.asByteArray(), target.size)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun pad(unpaddedData: UByteArray, blocksize: Int): UByteArray {
 | 
			
		||||
 | 
			
		||||
        // Pad is invalid in lazysodium-java because it uses char arrays, which are 2 bytes in java
 | 
			
		||||
        // while libsodium expects 1 byte char array
 | 
			
		||||
        // See https://github.com/terl/lazysodium-java/issues/85
 | 
			
		||||
 | 
			
		||||
        //This is temporary solution until lazysodium is fixed
 | 
			
		||||
        if (blocksize == 0) {
 | 
			
		||||
            throw RuntimeException("Invalid block size: $blocksize")
 | 
			
		||||
        }
 | 
			
		||||
        val padAmount = blocksize - (unpaddedData.size % blocksize)
 | 
			
		||||
        val result = if (padAmount == blocksize) {
 | 
			
		||||
            unpaddedData + UByteArray(blocksize) {
 | 
			
		||||
                when (it) {
 | 
			
		||||
                    0 -> 0x80U
 | 
			
		||||
                    else -> 0x00U
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        val newPadSizeReference = IntByReference(0)
 | 
			
		||||
        val newSize = ((unpaddedData.size / blocksize) + 1) * blocksize
 | 
			
		||||
        val paddedArray = UByteArray(newSize) {
 | 
			
		||||
            if (it < unpaddedData.size) {
 | 
			
		||||
                unpaddedData[it]
 | 
			
		||||
            } else {
 | 
			
		||||
            unpaddedData + UByteArray(padAmount) {
 | 
			
		||||
                when (it) {
 | 
			
		||||
                    0 -> 0x80U
 | 
			
		||||
                    else -> 0x00U
 | 
			
		||||
                0U
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        val resultCode = sodiumJna.sodium_pad(
 | 
			
		||||
            newPadSizeReference.pointer,
 | 
			
		||||
            paddedArray.asByteArray(),
 | 
			
		||||
            unpaddedData.size,
 | 
			
		||||
            blocksize,
 | 
			
		||||
            newSize
 | 
			
		||||
        )
 | 
			
		||||
        if (resultCode != 0) {
 | 
			
		||||
            throw RuntimeException("Padding failed")
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
//        val newPadSizeReference = IntByReference(0)
 | 
			
		||||
//        val newSize = ((unpaddedData.size / blocksize) + 1) * blocksize
 | 
			
		||||
//        val charArray = CharArray(newSize) {
 | 
			
		||||
//            if (it < unpaddedData.size) {
 | 
			
		||||
//                unpaddedData[it].toByte().toChar()
 | 
			
		||||
//            } else {
 | 
			
		||||
//                '\u0000'
 | 
			
		||||
//            }
 | 
			
		||||
//        }
 | 
			
		||||
//        sodium.sodium_pad(
 | 
			
		||||
//            newPadSizeReference.pointer,
 | 
			
		||||
//            charArray,
 | 
			
		||||
//            unpaddedData.size + 1,
 | 
			
		||||
//            blocksize,
 | 
			
		||||
//            newSize
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        return charArray.slice(0 until newPadSizeReference.value).map { it.toByte().toUByte()}.toUByteArray()
 | 
			
		||||
        return paddedArray.slice(0 until newPadSizeReference.value).map { it.toByte().toUByte()}.toUByteArray()
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun unpad(paddedData: UByteArray, blocksize: Int): UByteArray {
 | 
			
		||||
 | 
			
		||||
        // Pad is invalid in lazysodium-java because it uses char arrays, which are 2 bytes in java
 | 
			
		||||
        // while libsodium expects 1 byte char array
 | 
			
		||||
        // See https://github.com/terl/lazysodium-java/issues/85
 | 
			
		||||
        val paddedDataCopy = paddedData.copyOf().asByteArray()
 | 
			
		||||
        var unpaddedSize =  IntByReference(0)
 | 
			
		||||
 | 
			
		||||
        //This is temporary solution until lazysodium is fixed
 | 
			
		||||
        sodiumJna.sodium_unpad(
 | 
			
		||||
            unpaddedSize.pointer,
 | 
			
		||||
            paddedDataCopy,
 | 
			
		||||
            paddedData.size,
 | 
			
		||||
            blocksize
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        val unpaddedData = paddedData.dropLastWhile { it == 0U.toUByte() }
 | 
			
		||||
        if (unpaddedData.last() != 0x80U.toUByte()) {
 | 
			
		||||
            throw RuntimeException("Invalid padding!")
 | 
			
		||||
        }
 | 
			
		||||
        return unpaddedData.dropLast(1).toUByteArray()
 | 
			
		||||
        val unpadded = paddedDataCopy.sliceArray(0 until unpaddedSize.value).asUByteArray()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//        val paddedDataCopy = paddedData.copyOf().asByteArray().map { it.toChar() }.toCharArray()
 | 
			
		||||
//        var unpaddedSize =  IntByReference(0)
 | 
			
		||||
//
 | 
			
		||||
//        sodium.sodium_unpad(
 | 
			
		||||
//            unpaddedSize.pointer,
 | 
			
		||||
//            paddedDataCopy,
 | 
			
		||||
//            paddedData.size,
 | 
			
		||||
//            blocksize
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        val unpadded = paddedDataCopy.sliceArray(0 until unpaddedSize.value).map { it.toByte().toUByte() }.toUByteArray()
 | 
			
		||||
//
 | 
			
		||||
//        return unpadded
 | 
			
		||||
        return unpadded
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun toBase64(
 | 
			
		||||
        data: UByteArray,
 | 
			
		||||
        variant: Base64Variants
 | 
			
		||||
    ): String {
 | 
			
		||||
        val maxlen = sodium.sodium_base64_encoded_len(data.size, variant.value)
 | 
			
		||||
        val maxlen = sodiumJna.sodium_base64_encoded_len(data.size, variant.value)
 | 
			
		||||
        val result = ByteArray(maxlen) { 0 }
 | 
			
		||||
        sodium.sodium_bin2base64(
 | 
			
		||||
        sodiumJna.sodium_bin2base64(
 | 
			
		||||
            result,
 | 
			
		||||
            maxlen,
 | 
			
		||||
            data.asByteArray(),
 | 
			
		||||
@ -116,49 +80,66 @@ actual object LibsodiumUtil {
 | 
			
		||||
    actual fun toHex(data: UByteArray): String {
 | 
			
		||||
        val hexLen = (data.size * 2) + 1 // +1 for terminator char
 | 
			
		||||
        val result = ByteArray(hexLen)
 | 
			
		||||
        sodium.sodium_bin2hex(
 | 
			
		||||
        sodiumJna.sodium_bin2hex(
 | 
			
		||||
            result,
 | 
			
		||||
            hexLen,
 | 
			
		||||
            data.asByteArray(),
 | 
			
		||||
            data.size
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        //Drop terminating char \0
 | 
			
		||||
        return String(result.sliceArray(0 until result.size - 1))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun fromHex(data: String): UByteArray {
 | 
			
		||||
        val binLenReference = IntByReference(0)
 | 
			
		||||
        val binSize = (data.length + 1) / 2 // -1 for terminator char
 | 
			
		||||
        val hex = data.toCharArray().map { it.toByte() }.toByteArray()
 | 
			
		||||
        val result = ByteArray(binSize)
 | 
			
		||||
        val resultCode = sodiumJna.sodium_hex2bin(
 | 
			
		||||
            result,
 | 
			
		||||
            binSize,
 | 
			
		||||
            hex,
 | 
			
		||||
            hex.size,
 | 
			
		||||
            null,
 | 
			
		||||
            binLenReference.pointer,
 | 
			
		||||
            null
 | 
			
		||||
        )
 | 
			
		||||
        if (resultCode != 0) {
 | 
			
		||||
            throw ConversionException()
 | 
			
		||||
        }
 | 
			
		||||
        return result.slice(0 until binLenReference.value).toByteArray().asUByteArray()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    actual fun fromBase64(
 | 
			
		||||
        data: String,
 | 
			
		||||
        variant: Base64Variants
 | 
			
		||||
    ): UByteArray {
 | 
			
		||||
        // from base64 is currently broken in lazysodium-java
 | 
			
		||||
        // see https://github.com/terl/lazysodium-java/issues/83
 | 
			
		||||
//        val maxLength = (data.length * 3) / 4
 | 
			
		||||
//        val intermediaryResult = UByteArray(maxLength) { 0U }
 | 
			
		||||
//
 | 
			
		||||
//        sodium.sodium_base642bin(
 | 
			
		||||
//            intermediaryResult.asByteArray(),
 | 
			
		||||
//            maxLength,
 | 
			
		||||
//            data.encodeToByteArray(),
 | 
			
		||||
//            data.length,
 | 
			
		||||
//            null,
 | 
			
		||||
//            binLenPinned.addressOf(0),
 | 
			
		||||
//            null,
 | 
			
		||||
//            variant.value
 | 
			
		||||
//
 | 
			
		||||
//        )
 | 
			
		||||
        val decoder = when(variant) {
 | 
			
		||||
            Base64Variants.ORIGINAL -> Base64.getDecoder()
 | 
			
		||||
            Base64Variants.ORIGINAL_NO_PADDING -> Base64.getDecoder()
 | 
			
		||||
            Base64Variants.URLSAFE -> Base64.getUrlDecoder()
 | 
			
		||||
            Base64Variants.URLSAFE_NO_PADDING -> Base64.getUrlDecoder()
 | 
			
		||||
        }
 | 
			
		||||
        return decoder.decode(data).asUByteArray()
 | 
			
		||||
        val binLengthReference = IntByReference(0)
 | 
			
		||||
        val maxLength = (data.length * 3) / 4
 | 
			
		||||
        val intermediaryResult = UByteArray(maxLength) { 0U }
 | 
			
		||||
 | 
			
		||||
        val resultCode = sodiumJna.sodium_base642bin(
 | 
			
		||||
            intermediaryResult.asByteArray(),
 | 
			
		||||
            maxLength,
 | 
			
		||||
            data.encodeToByteArray(),
 | 
			
		||||
            data.length,
 | 
			
		||||
            null,
 | 
			
		||||
            binLengthReference.pointer,
 | 
			
		||||
            null,
 | 
			
		||||
            variant.value
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        if (resultCode != 0) {
 | 
			
		||||
            throw ConversionException()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    actual fun fromHex(data: String): UByteArray {
 | 
			
		||||
        // from hex is currently broken in lazysodium-java
 | 
			
		||||
        // see https://github.com/terl/lazysodium-java/issues/83
 | 
			
		||||
        return data.hexStringToUByteArray()
 | 
			
		||||
        return intermediaryResult.sliceArray(0 until binLengthReference.value)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							@ -1,11 +1,2 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto
 | 
			
		||||
 | 
			
		||||
import com.goterl.lazycode.lazysodium.LazySodiumJava
 | 
			
		||||
import com.goterl.lazycode.lazysodium.SodiumJava
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
 * ugljesa.jovanovic@ionspin.com
 | 
			
		||||
 * on 22-Aug-2020
 | 
			
		||||
 */
 | 
			
		||||
typealias SodiumWrapper = SodiumJava
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,23 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.jnitest
 | 
			
		||||
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.runTest
 | 
			
		||||
import org.junit.Test
 | 
			
		||||
import kotlin.test.assertEquals
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Created by Ugljesa Jovanovic
 | 
			
		||||
 * ugljesa.jovanovic@ionspin.com
 | 
			
		||||
 * on 20-Feb-2021
 | 
			
		||||
 */
 | 
			
		||||
class JnaLibraryLoaderTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun testIfLibraryIsLoaded() = runTest {
 | 
			
		||||
        LibsodiumInitializer.initialize()
 | 
			
		||||
        val version = sodiumJna.sodium_version_string()
 | 
			
		||||
        println("Got loaded sodium version: $version")
 | 
			
		||||
        assertEquals("1.0.18", version)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
package com.ionspin.kotlin.crypto.secretstream
 | 
			
		||||
 | 
			
		||||
actual fun modifyState(state: SecretStreamState, forceNonce: UByteArray) {
 | 
			
		||||
    state.nonce = forceNonce.sliceArray(12 until 24).asByteArray()
 | 
			
		||||
    forceNonce.sliceArray(12 until 24).asByteArray().copyInto(state.nonce)
 | 
			
		||||
    println("Nonce modified ${state.nonce}")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,6 @@ package com.ionspin.kotlin.crypto.stream
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.toPtr
 | 
			
		||||
import kotlinx.cinterop.convert
 | 
			
		||||
import kotlinx.cinterop.pin
 | 
			
		||||
import libsodium.crypto_stream_KEYBYTES
 | 
			
		||||
import libsodium.crypto_stream_chacha20
 | 
			
		||||
import libsodium.crypto_stream_chacha20_ietf_xor
 | 
			
		||||
import libsodium.crypto_stream_chacha20_ietf_xor_ic
 | 
			
		||||
@ -11,6 +10,10 @@ import libsodium.crypto_stream_chacha20_keygen
 | 
			
		||||
import libsodium.crypto_stream_chacha20_xor
 | 
			
		||||
import libsodium.crypto_stream_chacha20_xor_ic
 | 
			
		||||
 | 
			
		||||
//import libsodium.crypto_stream_xchacha20_keygen
 | 
			
		||||
//import libsodium.crypto_stream_xchacha20_xor
 | 
			
		||||
//import libsodium.crypto_stream_xchacha20_xor_ic
 | 
			
		||||
 | 
			
		||||
actual object Stream {
 | 
			
		||||
    actual fun chacha20(clen: Int, nonce: UByteArray, key: UByteArray): UByteArray {
 | 
			
		||||
        val result = UByteArray(clen)
 | 
			
		||||
@ -149,4 +152,71 @@ actual object Stream {
 | 
			
		||||
 | 
			
		||||
        return result
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
//    actual fun xChacha20Keygen(): UByteArray {
 | 
			
		||||
//        val result = UByteArray(crypto_stream_xchacha20_KEYBYTES)
 | 
			
		||||
//        val resultPinned = result.pin()
 | 
			
		||||
//
 | 
			
		||||
//        crypto_stream_xchacha20_keygen(resultPinned.toPtr())
 | 
			
		||||
//
 | 
			
		||||
//        resultPinned.unpin()
 | 
			
		||||
//
 | 
			
		||||
//        return result
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    actual fun xChacha20Xor(
 | 
			
		||||
//        message: UByteArray,
 | 
			
		||||
//        nonce: UByteArray,
 | 
			
		||||
//        key: UByteArray
 | 
			
		||||
//    ): UByteArray {
 | 
			
		||||
//        val result = UByteArray(message.size)
 | 
			
		||||
//        val messagePinned = message.pin()
 | 
			
		||||
//        val resultPinned = result.pin()
 | 
			
		||||
//        val noncePinned = nonce.pin()
 | 
			
		||||
//        val keyPinned = key.pin()
 | 
			
		||||
//
 | 
			
		||||
//        crypto_stream_xchacha20_xor(
 | 
			
		||||
//            resultPinned.toPtr(),
 | 
			
		||||
//            messagePinned.toPtr(),
 | 
			
		||||
//            message.size.convert(),
 | 
			
		||||
//            noncePinned.toPtr(),
 | 
			
		||||
//            keyPinned.toPtr()
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        messagePinned.unpin()
 | 
			
		||||
//        resultPinned.unpin()
 | 
			
		||||
//        noncePinned.unpin()
 | 
			
		||||
//        keyPinned.unpin()
 | 
			
		||||
//
 | 
			
		||||
//        return result
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    actual fun xChacha20XorIc(
 | 
			
		||||
//        message: UByteArray,
 | 
			
		||||
//        nonce: UByteArray,
 | 
			
		||||
//        initialCounter: ULong,
 | 
			
		||||
//        key: UByteArray
 | 
			
		||||
//    ): UByteArray {
 | 
			
		||||
//        val result = UByteArray(message.size)
 | 
			
		||||
//        val messagePinned = message.pin()
 | 
			
		||||
//        val resultPinned = result.pin()
 | 
			
		||||
//        val noncePinned = nonce.pin()
 | 
			
		||||
//        val keyPinned = key.pin()
 | 
			
		||||
//
 | 
			
		||||
//        crypto_stream_xchacha20_xor_ic(
 | 
			
		||||
//            resultPinned.toPtr(),
 | 
			
		||||
//            messagePinned.toPtr(),
 | 
			
		||||
//            message.size.convert(),
 | 
			
		||||
//            noncePinned.toPtr(),
 | 
			
		||||
//            initialCounter.convert(),
 | 
			
		||||
//            keyPinned.toPtr()
 | 
			
		||||
//        )
 | 
			
		||||
//
 | 
			
		||||
//        messagePinned.unpin()
 | 
			
		||||
//        resultPinned.unpin()
 | 
			
		||||
//        noncePinned.unpin()
 | 
			
		||||
//        keyPinned.unpin()
 | 
			
		||||
//
 | 
			
		||||
//        return result
 | 
			
		||||
//    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@ kotlin {
 | 
			
		||||
    android()
 | 
			
		||||
    runningOnLinuxx86_64 {
 | 
			
		||||
        jvm()
 | 
			
		||||
        js {
 | 
			
		||||
        js(IR) {
 | 
			
		||||
            browser {
 | 
			
		||||
                webpackTask {
 | 
			
		||||
 | 
			
		||||
@ -188,7 +188,7 @@ kotlin {
 | 
			
		||||
                implementation(kotlin(Deps.Common.test))
 | 
			
		||||
                implementation(Deps.Common.kotlinBigNum)
 | 
			
		||||
                implementation(Deps.Common.serialization)
 | 
			
		||||
                api(Deps.Common.libsodiumBindings)
 | 
			
		||||
                api(project(":multiplatform-crypto-libsodium-bindings"))
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        val commonTest by getting {
 | 
			
		||||
 | 
			
		||||
@ -6,10 +6,19 @@ package com.ionspin.kotlin.crypto.sample
 | 
			
		||||
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodiumJna
 | 
			
		||||
import com.ionspin.kotlin.crypto.TmpAccessor
 | 
			
		||||
import com.ionspin.kotlin.crypto.box.Box
 | 
			
		||||
import com.ionspin.kotlin.crypto.box.BoxCorruptedOrTamperedDataException
 | 
			
		||||
import com.ionspin.kotlin.crypto.box.crypto_box_NONCEBYTES
 | 
			
		||||
import com.ionspin.kotlin.crypto.hash.Hash
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.decodeFromUByteArray
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.toHexString
 | 
			
		||||
import kotlinx.android.synthetic.main.activity_main.*
 | 
			
		||||
import java.lang.StringBuilder
 | 
			
		||||
import kotlin.random.Random
 | 
			
		||||
import kotlin.random.nextUBytes
 | 
			
		||||
 | 
			
		||||
class MainActivity : AppCompatActivity() {
 | 
			
		||||
 | 
			
		||||
@ -18,9 +27,25 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
        setContentView(R.layout.activity_main)
 | 
			
		||||
        val hash = Hash.sha512("123".encodeToUByteArray())
 | 
			
		||||
        helloWorldTextView.setText("Hash (SHA512) of 123: ${hash.toHexString()}")
 | 
			
		||||
 | 
			
		||||
        val message = "Message message message".encodeToUByteArray()
 | 
			
		||||
        val senderKeypair = Box.keypair()
 | 
			
		||||
        val recipientKeypair = Box.keypair()
 | 
			
		||||
        val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
 | 
			
		||||
        val builder = StringBuilder()
 | 
			
		||||
        val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey)
 | 
			
		||||
        builder.appendLine("Encrypted: ${encrypted.toHexString()}")
 | 
			
		||||
        val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
			
		||||
 | 
			
		||||
        builder.appendLine("Decrypted: ${decrypted.decodeFromUByteArray()}")
 | 
			
		||||
        try {
 | 
			
		||||
            val tampered = encrypted.copyOf()
 | 
			
		||||
            tampered[1] = 0U
 | 
			
		||||
            Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
			
		||||
        } catch (exception : Exception) {
 | 
			
		||||
            builder.appendLine("And caught tamper")
 | 
			
		||||
        }
 | 
			
		||||
        helloWorldTextView.setText(builder.toString())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,11 +7,12 @@ import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
			
		||||
import com.ionspin.kotlin.crypto.util.toHexString
 | 
			
		||||
import react.dom.render
 | 
			
		||||
import kotlinx.browser.document
 | 
			
		||||
import kotlin.browser.window
 | 
			
		||||
import kotlinx.browser.window
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fun main() {
 | 
			
		||||
    val runningOnNode = jsTypeOf(window) == "undefined"
 | 
			
		||||
    if (!runningOnNode) = runTest {
 | 
			
		||||
//    if (!runningOnNode) = runTest {
 | 
			
		||||
        LibsodiumInitializer.initializeWithCallback {
 | 
			
		||||
            render(document.getElementById("root")) {
 | 
			
		||||
                app {
 | 
			
		||||
@ -19,10 +20,10 @@ fun main() {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else = runTest {
 | 
			
		||||
        LibsodiumInitializer.initializeWithCallback {
 | 
			
		||||
            val hash = Hash.sha512("123".encodeToUByteArray())
 | 
			
		||||
            println("Hash (SHA512) of 123: ${hash.toHexString()}")
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
//    } else = runTest {
 | 
			
		||||
//        LibsodiumInitializer.initializeWithCallback {
 | 
			
		||||
//            val hash = Hash.sha512("123".encodeToUByteArray())
 | 
			
		||||
//            println("Hash (SHA512) of 123: ${hash.toHexString()}")
 | 
			
		||||
//        }
 | 
			
		||||
//    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -37,5 +37,5 @@ enableFeaturePreview("GRADLE_METADATA")
 | 
			
		||||
rootProject.name = "KotlinMultiplatformLibsodium"
 | 
			
		||||
include("multiplatform-crypto-api")
 | 
			
		||||
include("multiplatform-crypto-libsodium-bindings")
 | 
			
		||||
//include("sample")
 | 
			
		||||
include("sample")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -143,9 +143,9 @@ native libsodium library.
 | 
			
		||||
| crypto_stream_chacha20_xor | :heavy_check_mark: | 
 | 
			
		||||
| crypto_stream_chacha20_xor_ic | :heavy_check_mark: |  
 | 
			
		||||
| crypto_stream_keygen | Other XSalsa20 primitives are not available, so I'm leaving this out as well|   
 | 
			
		||||
| crypto_stream_xchacha20_keygen | not present in LazySodium Android | 
 | 
			
		||||
| crypto_stream_xchacha20_xor | not present in LazySodium Android|    
 | 
			
		||||
| crypto_stream_xchacha20_xor_ic | not present in LazySodium Android | 
 | 
			
		||||
| crypto_stream_xchacha20_keygen | Not at the moment | 
 | 
			
		||||
| crypto_stream_xchacha20_xor | Not at the moment |    
 | 
			
		||||
| crypto_stream_xchacha20_xor_ic | Not at the moment | 
 | 
			
		||||
| randombytes_buf | :heavy_check_mark: |    
 | 
			
		||||
| randombytes_buf_deterministic | :heavy_check_mark: |  
 | 
			
		||||
| randombytes_close | not present in LazySodium |  
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user