diff --git a/README.md b/README.md index 4897b53..f1bc7da 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ # Libsodium bindings for Kotlin Multiplatform -Libsodium bindings project uses libsodium c sources and libsodium.js 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. The library is feature complete and usable. ## Warning While this library is just a wrapper around the well known Libsodium library it still comes with high potential of introducing new diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index 5d09a77..82c58b9 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -1,4 +1,4 @@ -/* + /* * Copyright 2019 Ugljesa Jovanovic * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,7 +40,6 @@ object Versions { object ReleaseInfo { val group = "com.ionspin.kotlin" - val version = "0.1.0-SNAPSHOT" val bindingsVersion = "0.8.5-SNAPSHOT" } diff --git a/multiplatform-crypto-api/README.md b/multiplatform-crypto-api/README.md index d65ec6a..30721d3 100644 --- a/multiplatform-crypto-api/README.md +++ b/multiplatform-crypto-api/README.md @@ -1,288 +1 @@ -[![Build Status](https://travis-ci.com/ionspin/kotlin-multiplatform-crypto.svg?branch=master)](https://travis-ci.com/ionspin/kotlin-multiplatform-crypto) -![Maven Central](https://img.shields.io/maven-central/v/com.ionspin.kotlin/multiplatform-crypto.svg) - -# Kotlin Multiplatform Crypto Library - - -Kotlin Multiplatform Crypto is a library for various cryptographic applications. - -The library comes in two flavors `multiplatform-crypto` and `multiplatform-crypto-delegated`. - -* `multiplatform-crypto` contains pure kotlin implementations, is not reviewed, should be considered unsafe and only -for prototyping or experimentation purposes. - -* `multiplatform-crypto-delegated` relies on platform specific implementations, mostly libsodium, but care should still be taken that the kotlin code is not reviewed or proven safe. - -APIs of both variants are identical. - - -### Table of contents -1. [Supported platforms](#supported-platforms-by-variant) -2. [API](#api) -3. TODO - -## Supported platforms by variant -|Platform|Pure variant| Delegated variant| -|--------|------------|------------------| -|Linux X86 64| :heavy_check_mark: | :heavy_check_mark: | -|Linux Arm 64| :heavy_check_mark: | :heavy_check_mark: | -|Linux Arm 32| :heavy_check_mark: | :x: | -|macOS X86 64| :heavy_check_mark: | :heavy_check_mark: | -|iOS x86 64 | :heavy_check_mark: | :heavy_check_mark: | -|iOS Arm 64 | :heavy_check_mark: | :heavy_check_mark: | -|iOS Arm 32 | :heavy_check_mark: | :heavy_check_mark: | -|watchOS X86 32 | :heavy_check_mark: | :heavy_check_mark: | -|watchOS Arm 64(_32) | :heavy_check_mark: | :heavy_check_mark: | -|watchos Arm 32 | :heavy_check_mark: | :heavy_check_mark: | -|tvOS X86 64 | :heavy_check_mark: | :heavy_check_mark: | -|tvOS Arm 64 | :heavy_check_mark: | :heavy_check_mark: | -|minGW X86 64| :heavy_check_mark: | :heavy_check_mark: | -|minGW X86 32| :x: | :x: | - -## Sample project -The library includes sample project that shows usage on different platforms -- NOTE: Currently only linux, macOs and windows are included. - -## Notes & Roadmap - -**The API will move fast and break often until v1.0** - -Next steps: -- Expand API (ECC, Signing ...) - -## Should I use this in production? -**NO.** -The library is under HEAVY development. Until development is done it will not be reviewed and therefore it shouldn't be used. -Contributions are still welcome! - -## Why? - -This is an experimental implementation, mostly for expanding personal understanding of cryptography. -It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure. - -## API for Pure and Delegated flavours - -### Hashing functions -* Blake2b -* SHA512 -* SHA256 - -### Key Derivation - -* Argon2 - -### Authenticated symmetric encryption (AEAD) - -* XChaCha20-Poly1305 - - -### Delegated flavor dependancy table -The following table describes which library is used for particular cryptographic primitive - -| Primitive | JVM | JS | Native | -| ----------|-----|----|--------| -| Blake2b | LazySodium | libsodium.js | libsodium | -| SHA256 | LazySodium | libsodium.js | libsodium | -| SHA512 | LazySodium | libsodium.js | libsodium | -| XChaCha20-Poly1305 | LazySodium | libsodium.js | libsodium | - - - -## Integration - -NOTE: Latest version of the library is built with Kotlin 1.4-M2 and therefore only SNAPSHOT variant is available. Next -stable version will be released when Kotlin 1.4. is released - -#### Gradle -Kotlin -```kotlin -implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0") - -or - -implementation("com.ionspin.kotlin:multiplatform-crypto-delegated:0.1.0") -``` - -#### Snapshot builds -```kotlin -repositories { - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - } -} -implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0-SNAPSHOT") - -``` - -## Usage - -### Helper functions - -All API take `UByteArray` as message/key/nonce/etc parameter. For convenience when working with strings we provide -`String.enocdeToUbyteArray()` extensions function, and `UByteArray.toHexString` extension function. - -More convenience functions will be added. - -### Hashes - -Hashes are provided in two versions, "stateless", usually the companion object of the hash, -which takes the data to be hashed in one go, and "updatable" which can be fed data in chunks. - - -#### Blake2b - -You can use Blake 2b in two modes - -##### Stateless version -You need to deliver the complete data that is to be hashed in one go - -```kotlin -val input = "abc" -val result = Crypto.Blake2b.stateless(input.encodeToUByteArray()) -``` - -Result is returned as a `UByteArray` - -##### Updatable instance version -You can create an instance and feed the data by using `update(input : UByteArray)` call. Once all data is supplied, -you should call `digest()`. - -If you want to use Blake2b with a key, you should supply it when creating the `Blake2b` instance. - -```kotlin -val test = "abc" -val key = "key" -val blake2b = Crypto.Blake2b.updateable(key.encodeToUByteArray()) -blake2b.update(test.encodeToUByteArray()) -val result = blake2b.digest().toHexString() -``` - -After digest is called, the instance is reset and can be reused (Keep in mind key stays the same for the particular instance). -#### SHA2 (SHA256 and SHA512) - -##### Stateless version - -You need to deliver the complete data that is to be hashed in one go. You can either provide the `UByteArray` as input -or `String`. Result is always returned as `UByteArray` (At least in verision 0.0.1) - -```kotlin -val input = "abc" -val result = Crypto.Sha256.stateless(input.encodeToUByteArray()) -``` - -```kotlin -val input ="abc" -val result = Crypto.Sha512.stateless(input.encodeToUByteArray()) -``` - -Result is returned as a `UByteArray` - -##### Updateable version - -Or you can use the updatable instance version - -```kotlin -val sha256 = Crypto.Sha256.updateable() -sha256.update("abc".encodeToUByteArray()) -val result = sha256.digest() -``` - -```kotlin -val sha512 = Crypto.Sha512.updateable() -sha512.update("abc".encodeToUByteArray()) -val result = sha512.digest() -``` - -### Key derivation - -#### Argon2 - -NOTE: This implementation is tested against KAT generated by reference Argon2 implementation, which does not follow -specification completely. See this issue https://github.com/P-H-C/phc-winner-argon2/issues/183 - -```kotlin -val argon2Instance = Argon2( - password = "Password", - salt = "RandomSalt", - parallelism = 8, - tagLength = 64U, - requestedMemorySize = 256U, //4GB - numberOfIterations = 4U, - key = "", - associatedData = "", - argonType = ArgonType.Argon2id - ) -val tag = argon2Instance.derive() -val tagString = tag.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") -val expectedTagString = "c255e3e94305817d5e09a7c771e574e3a81cc78fef5da4a9644b6df0" + - "0ba1c9b424e3dd0ce7e600b1269b14c84430708186a8a60403e1bfbda935991592b9ff37" -println("Tag: ${tagString}") -assertEquals(tagString, expectedTagString) -``` - -### Symmetric encryption (OUTDATED, won't be exposed in next release, no counterpart in delegated flavor - 0.1.1) - -#### AES - -Aes is available with CBC and CTR mode through `AesCbc` and `AesCtr` classes/objects. -Similarly to hashes you can either use stateless or updateable version. - -Initialization vector, or counter states are chosen by the SDK automaticaly, and returned alongside encrypted data - -##### Stateless AesCbc and AesCtr - -AesCtr - -```kotlin -val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" -val key = AesKey.Aes128Key(keyString) -val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" - -val encryptedDataAndInitializationVector = AesCtr.encrypt(key, plainText.hexStringToUByteArray()) -val decrypted = AesCtr.decrypt( - key, - encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initialCounter -) -plainText == decrypted.toHexString() -``` - -AesCbc - -```kotlin - -val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" -val key = AesKey.Aes128Key(keyString) - -val plainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" - -val encryptedDataAndInitializationVector = AesCbc.encrypt(key, plainText.hexStringToUByteArray()) -val decrypted = AesCbc.decrypt( - key, - encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initilizationVector -) -plainText == decrypted.toHexString() - -``` - -## Libsodium bindings - -* Under development - - - - - - - - - - - - - - - - - +This is just used to get kotlin to download appropriate konan tools. diff --git a/multiplatform-crypto-api/build.gradle.kts b/multiplatform-crypto-api/build.gradle.kts index aa0ecdf..cba2028 100644 --- a/multiplatform-crypto-api/build.gradle.kts +++ b/multiplatform-crypto-api/build.gradle.kts @@ -32,7 +32,7 @@ repositories { mavenCentral() } group = ReleaseInfo.group -version = ReleaseInfo.version +version = "0.1" //Irrelevant val ideaActive = System.getProperty("idea.active") == "true" @@ -83,105 +83,30 @@ kotlin { } - } - - runningOnLinuxArm64 { - - } - - runningOnLinuxArm32 { - } runningOnMacos { - iosX64() { - binaries { - framework { - optimized = true - } - } - } - iosArm64() { - binaries { - framework { - optimized = true - } - } - } - iosArm32() { - binaries { - framework { - optimized = true - } - } - } + iosX64() + iosArm64() + iosArm32() + iosSimulatorArm64() - macosX64() { - binaries { - framework { - optimized = true - } - } - } + macosX64() + macosArm64() - tvosX64() { - binaries { - framework { - optimized = true - } - } - } + tvosX64() + tvosArm64() + tvosSimulatorArm64() - tvosArm64() { - binaries { - framework { - optimized = true - } - } - } - - watchosArm64() { - binaries { - framework { - optimized = true - } - } - } - - watchosArm32() { - binaries { - framework { - optimized = true - } - } - } - - watchosX86() { - binaries { - framework { - optimized = true - } - } - } + watchosArm64() + watchosArm32() + watchosX86() + watchosSimulatorArm64() } runningOnWindows { - - mingwX64() { - binaries { - staticLib { - optimized = true - } - } - } - - mingwX86() { - binaries { - staticLib { - - } - } - } + mingwX64() + mingwX86() } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt index ca1c16d..c18773d 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt @@ -15,7 +15,7 @@ actual object LibsodiumInitializer { private fun loadLibrary() : JnaLibsodiumInterface { val libraryFile = when { Platform.isMac() -> { - SharedLibraryLoader.get().load("dynamic-macos-x86-64.dylib", JnaLibsodiumInterface::class.java) + SharedLibraryLoader.get().load("dynamic-macos.dylib", JnaLibsodiumInterface::class.java) } Platform.isLinux() -> { if (Platform.isARM()) { diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-arm64-libsodium.so b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-arm64-libsodium.so index 9b3ad8c..a2469ed 100755 Binary files a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-arm64-libsodium.so and b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-arm64-libsodium.so differ diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-x86-64-libsodium.so b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-x86-64-libsodium.so index 32662be..2209e04 100755 Binary files a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-x86-64-libsodium.so and b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-linux-x86-64-libsodium.so differ diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-macos-x86-64.dylib b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-macos-x86-64.dylib deleted file mode 100755 index e3c9766..0000000 Binary files a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-macos-x86-64.dylib and /dev/null differ diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-macos.dylib b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-macos.dylib new file mode 100755 index 0000000..3c50beb Binary files /dev/null and b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-macos.dylib differ diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-mingw-x86-64-libsodium.dll.a b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-mingw-x86-64-libsodium.dll.a index 0b251cd..f7ac5ac 100644 Binary files a/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-mingw-x86-64-libsodium.dll.a and b/multiplatform-crypto-libsodium-bindings/src/jvmMain/resources/dynamic-mingw-x86-64-libsodium.dll.a differ