Update readme and changelog, as this is going into master so snapshots are available for experimenting

This commit is contained in:
Ugljesa Jovanovic 2020-08-08 22:22:38 +02:00 committed by Ugljesa Jovanovic
parent e997c18d1d
commit e6e7a7664c
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
13 changed files with 265 additions and 28 deletions

View File

@ -1,7 +1,12 @@
## Descriptive changelog ## Descriptive changelog
(All dates are DD.MM.YYYY) (All dates are DD.MM.YYYY)
#### AES - 0.0.3-SNAPSHOT - 25.9.2019 #### - 0.1.0 - SNAPSHOT
- Complete rework of the library
- Creating in parallel both Pure Kotlin and Delegated flavours (backed by libsodium)
- Introducing libsodium bindings generator
#### AES - 0.0.3 - 25.9.2019
- Added AES with CBC and CTR modes - Added AES with CBC and CTR modes
#### Updatable SHA hash implementation - 0.0.2 - 21.7.2019 #### Updatable SHA hash implementation - 0.0.2 - 21.7.2019

View File

@ -18,6 +18,11 @@ for prototyping or experimentation purposes.
APIs of both variants are identical. APIs of both variants are identical.
* `multiplatform-crypto-libsodium-bindings` is a generated bindings library using `kotlin-multiplatform-libsodium-generator`
* Under HEAVY development at the moment
### Table of contents ### Table of contents
1. [Supported platforms](#supported-platforms-by-variant) 1. [Supported platforms](#supported-platforms-by-variant)
2. [API](#api) 2. [API](#api)
@ -53,19 +58,15 @@ Next steps:
- Expand API (ECC, Signing ...) - Expand API (ECC, Signing ...)
## Should I use this in production? ## Should I use this in production?
**NO.**
No, until it is reviewed. The library is under HEAVY development.
## Should I use this in code that is *critical* in any way, shape or form?
No, but even if after being warned you decide to, then use `multiplatform-crypto-delegated` as it relies on reputable libraries.
## Why? ## Why?
This is an experimental implementation, mostly for expanding personal understanding of cryptography. This is an experimental implementation, mostly for expanding personal understanding of cryptography.
It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure. It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure.
## API ## API for Pure and Delegated flavourd
### Hashing functions ### Hashing functions
* Blake2b * Blake2b
@ -225,7 +226,7 @@ println("Tag: ${tagString}")
assertEquals(tagString, expectedTagString) assertEquals(tagString, expectedTagString)
``` ```
### Symmetric encryption (OUTDATED, won't be exposed in next release, no counterpart in delegated flavor - 0.10.1) ### Symmetric encryption (OUTDATED, won't be exposed in next release, no counterpart in delegated flavor - 0.1.1)
#### AES #### AES
@ -272,7 +273,8 @@ plainText == decrypted.toHexString()
``` ```
## Libsodium bindings ## Libsodium bindings
TODO
* Under development

View File

@ -0,0 +1,26 @@
package debug.test
import kotlin.Int
import kotlin.UByteArray
expect class Sha256State
expect class Sha512State
expect class GenericHashState
expect class Crypto internal constructor() {
fun crypto_hash_sha256_init(): Sha256State
fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray)
fun crypto_hash_sha256_final(state: Sha256State): UByteArray
fun crypto_hash_sha512_init(): Sha512State
fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray)
fun crypto_hash_sha512_final(state: Sha512State): UByteArray
fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState
}

View File

@ -0,0 +1,53 @@
package debug.test
import com.ionspin.kotlin.crypto.getSodium
import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray
import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array
import kotlin.Any
import kotlin.Int
import kotlin.UByteArray
actual typealias Sha256State = Any
actual typealias Sha512State = Any
actual typealias GenericHashState = Any
actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha256_init(): dynamic {
println("Debug")
val result = js("getSodium().crypto_hash_sha256_init()")
return result
}
actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
println("Debug")
getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), )
}
actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray {
println("Debug")
return getSodium().crypto_hash_sha256_final(state).toUByteArray()
}
actual fun crypto_hash_sha512_init(): dynamic {
println("Debug")
val result = js("getSodium().crypto_hash_sha512_init()")
return result
}
actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
println("Debug")
getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), )
}
actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray {
println("Debug")
return getSodium().crypto_hash_sha512_final(state).toUByteArray()
}
actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic {
println("Debug")
return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen)
}
}

View File

@ -0,0 +1,62 @@
package debug.test
import com.goterl.lazycode.lazysodium.SodiumJava
import com.goterl.lazycode.lazysodium.interfaces.Hash
import kotlin.ByteArray
import kotlin.Int
import kotlin.UByteArray
val sodium: SodiumJava = SodiumJava()
actual typealias Sha256State = Hash.State256
actual typealias Sha512State = Hash.State512
actual typealias GenericHashState = ByteArray
actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha256_init(): Sha256State {
val state = debug.test.Sha256State()
println("Debug")
sodium.crypto_hash_sha256_init(state)
return state
}
actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
println("Debug")
sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong())
}
actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray {
val out = UByteArray(32)
println("Debug")
sodium.crypto_hash_sha256_final(state, out.asByteArray())
return out
}
actual fun crypto_hash_sha512_init(): Sha512State {
val state = debug.test.Sha512State()
println("Debug")
sodium.crypto_hash_sha512_init(state)
return state
}
actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
println("Debug")
sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong())
}
actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray {
val out = UByteArray(64)
println("Debug")
sodium.crypto_hash_sha512_final(state, out.asByteArray())
return out
}
actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState {
val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes())
println("Debug")
sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen)
return state
}
}

View File

@ -0,0 +1,81 @@
package debug.test
import kotlin.Byte
import kotlin.ByteArray
import kotlin.Int
import kotlin.UByteArray
import kotlinx.cinterop.addressOf
import kotlinx.cinterop.convert
import kotlinx.cinterop.pin
import kotlinx.cinterop.pointed
import kotlinx.cinterop.ptr
import kotlinx.cinterop.reinterpret
import kotlinx.cinterop.toCValues
import libsodium.crypto_generichash_blake2b_state
import libsodium.crypto_hash_sha256_state
import libsodium.crypto_hash_sha512_state
import libsodium.sodium_malloc
actual typealias Sha256State = crypto_hash_sha256_state
actual typealias Sha512State = crypto_hash_sha512_state
actual typealias GenericHashState = crypto_generichash_blake2b_state
actual class Crypto internal actual constructor() {
val _emitByte: Byte = 0
val _emitByteArray: ByteArray = ByteArray(0)
actual fun crypto_hash_sha256_init(): Sha256State {
val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!!
val state = allocated.reinterpret<debug.test.Sha256State>().pointed
libsodium.crypto_hash_sha256_init(state.ptr)
return state
}
actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
val pinnedInput = input.pin()
libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert())
pinnedInput.unpin()
}
actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray {
val out = UByteArray(32)
val pinnedOut = out.pin()
libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0))
pinnedOut.unpin()
return out
}
actual fun crypto_hash_sha512_init(): Sha512State {
val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!!
val state = allocated.reinterpret<debug.test.Sha512State>().pointed
libsodium.crypto_hash_sha512_init(state.ptr)
return state
}
actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
val pinnedInput = input.pin()
libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert())
pinnedInput.unpin()
}
actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray {
val out = UByteArray(64)
val pinnedOut = out.pin()
libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0))
pinnedOut.unpin()
return out
}
actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState {
val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!!
val state = allocated.reinterpret<debug.test.GenericHashState>().pointed
val pinnedKey = key.pin()
libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(),
outlen.convert())
pinnedKey.unpin()
return state
}
}

View File

@ -69,7 +69,7 @@ object JsLibsodiumGenerator {
actualReturnType = paramDefinition.parameterType.typeName actualReturnType = paramDefinition.parameterType.typeName
} }
} }
methodBuilder.addStatement("println(\"Debug\")") methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")")
val constructJsCall = StringBuilder() val constructJsCall = StringBuilder()
when (methodDefinition.returnType) { when (methodDefinition.returnType) {
TypeDefinition.ARRAY_OF_UBYTES -> { TypeDefinition.ARRAY_OF_UBYTES -> {

View File

@ -101,7 +101,7 @@ object JvmLibsodiumGenerator {
) )
} }
} }
methodBuilder.addStatement("println(\"Debug\")") methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")")
val constructJvmCall = StringBuilder() val constructJvmCall = StringBuilder()
if (methodDefinition.isStateCreationFunction) { if (methodDefinition.isStateCreationFunction) {
constructJvmCall.append("sodium.${methodDefinition.nativeName}") constructJvmCall.append("sodium.${methodDefinition.nativeName}")

View File

@ -108,6 +108,7 @@ object NativeLibsodiumGenerator {
createOutputParam(actualReturnParameterDefinition, methodDefinition.outputLengthWhenArray.toString(), methodBuilder) createOutputParam(actualReturnParameterDefinition, methodDefinition.outputLengthWhenArray.toString(), methodBuilder)
} }
} }
methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")")
pinParams(methodDefinition, methodBuilder) pinParams(methodDefinition, methodBuilder)
val constructNativeCall = StringBuilder() val constructNativeCall = StringBuilder()
if (methodDefinition.isStateCreationFunction) { if (methodDefinition.isStateCreationFunction) {

View File

@ -21,7 +21,7 @@ class SmokeTest {
Initializer.initialize() Initializer.initialize()
val crypto = Crypto() val crypto = Crypto()
//TODO seems to be a bug in JS compiler, if we have the same method name in crypto an in JsSodiumInterface, method tries to call wrong method name (unneeded suffix _0) //TODO seems to be a bug in JS compiler, if we have the same method name in crypto an in JsSodiumInterface, method tries to call wrong method name (unneeded suffix _0)
//I've workaround this by making state functions with 1 parameter execute call with js("") wrap, but still might sail somewhere else //I've worked around this by making state functions with 1 parameter execute call with js("") wrap, but still might sail somewhere else
val state256 = crypto.crypto_hash_sha256_init() val state256 = crypto.crypto_hash_sha256_init()
crypto.crypto_hash_sha256_update(state256, "Hello".encodeToUByteArray()) crypto.crypto_hash_sha256_update(state256, "Hello".encodeToUByteArray())
val result = crypto.crypto_hash_sha256_final(state256) val result = crypto.crypto_hash_sha256_final(state256)

View File

@ -15,39 +15,39 @@ actual typealias GenericHashState = Any
actual class Crypto internal actual constructor() { actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha256_init(): dynamic { actual fun crypto_hash_sha256_init(): dynamic {
println("Debug") println("Debug crypto_hash_sha256_init")
val result = js("getSodium().crypto_hash_sha256_init()") val result = js("getSodium().crypto_hash_sha256_init()")
return result return result
} }
actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
println("Debug") println("Debug crypto_hash_sha256_update")
getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), ) getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), )
} }
actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray {
println("Debug") println("Debug crypto_hash_sha256_final")
return getSodium().crypto_hash_sha256_final(state).toUByteArray() return getSodium().crypto_hash_sha256_final(state).toUByteArray()
} }
actual fun crypto_hash_sha512_init(): dynamic { actual fun crypto_hash_sha512_init(): dynamic {
println("Debug") println("Debug crypto_hash_sha512_init")
val result = js("getSodium().crypto_hash_sha512_init()") val result = js("getSodium().crypto_hash_sha512_init()")
return result return result
} }
actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
println("Debug") println("Debug crypto_hash_sha512_update")
getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), ) getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), )
} }
actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray {
println("Debug") println("Debug crypto_hash_sha512_final")
return getSodium().crypto_hash_sha512_final(state).toUByteArray() return getSodium().crypto_hash_sha512_final(state).toUByteArray()
} }
actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic {
println("Debug") println("Debug crypto_generichash_init")
return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen)
} }
} }

View File

@ -17,45 +17,45 @@ actual typealias GenericHashState = ByteArray
actual class Crypto internal actual constructor() { actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha256_init(): Sha256State { actual fun crypto_hash_sha256_init(): Sha256State {
val state = debug.test.Sha256State() val state = debug.test.Sha256State()
println("Debug") println("Debug crypto_hash_sha256_init")
sodium.crypto_hash_sha256_init(state) sodium.crypto_hash_sha256_init(state)
return state return state
} }
actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
println("Debug") println("Debug crypto_hash_sha256_update")
sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong())
} }
actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray {
val out = UByteArray(32) val out = UByteArray(32)
println("Debug") println("Debug crypto_hash_sha256_final")
sodium.crypto_hash_sha256_final(state, out.asByteArray()) sodium.crypto_hash_sha256_final(state, out.asByteArray())
return out return out
} }
actual fun crypto_hash_sha512_init(): Sha512State { actual fun crypto_hash_sha512_init(): Sha512State {
val state = debug.test.Sha512State() val state = debug.test.Sha512State()
println("Debug") println("Debug crypto_hash_sha512_init")
sodium.crypto_hash_sha512_init(state) sodium.crypto_hash_sha512_init(state)
return state return state
} }
actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
println("Debug") println("Debug crypto_hash_sha512_update")
sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong())
} }
actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray {
val out = UByteArray(64) val out = UByteArray(64)
println("Debug") println("Debug crypto_hash_sha512_final")
sodium.crypto_hash_sha512_final(state, out.asByteArray()) sodium.crypto_hash_sha512_final(state, out.asByteArray())
return out return out
} }
actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState {
val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes())
println("Debug") println("Debug crypto_generichash_init")
sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen)
return state return state
} }

View File

@ -30,11 +30,13 @@ actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha256_init(): Sha256State { actual fun crypto_hash_sha256_init(): Sha256State {
val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!!
val state = allocated.reinterpret<debug.test.Sha256State>().pointed val state = allocated.reinterpret<debug.test.Sha256State>().pointed
println("Debug crypto_hash_sha256_init")
libsodium.crypto_hash_sha256_init(state.ptr) libsodium.crypto_hash_sha256_init(state.ptr)
return state return state
} }
actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) {
println("Debug crypto_hash_sha256_update")
val pinnedInput = input.pin() val pinnedInput = input.pin()
libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert())
pinnedInput.unpin() pinnedInput.unpin()
@ -42,6 +44,7 @@ actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray {
val out = UByteArray(32) val out = UByteArray(32)
println("Debug crypto_hash_sha256_final")
val pinnedOut = out.pin() val pinnedOut = out.pin()
libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0))
pinnedOut.unpin() pinnedOut.unpin()
@ -51,11 +54,13 @@ actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha512_init(): Sha512State { actual fun crypto_hash_sha512_init(): Sha512State {
val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!!
val state = allocated.reinterpret<debug.test.Sha512State>().pointed val state = allocated.reinterpret<debug.test.Sha512State>().pointed
println("Debug crypto_hash_sha512_init")
libsodium.crypto_hash_sha512_init(state.ptr) libsodium.crypto_hash_sha512_init(state.ptr)
return state return state
} }
actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) {
println("Debug crypto_hash_sha512_update")
val pinnedInput = input.pin() val pinnedInput = input.pin()
libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert())
pinnedInput.unpin() pinnedInput.unpin()
@ -63,6 +68,7 @@ actual class Crypto internal actual constructor() {
actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray {
val out = UByteArray(64) val out = UByteArray(64)
println("Debug crypto_hash_sha512_final")
val pinnedOut = out.pin() val pinnedOut = out.pin()
libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0))
pinnedOut.unpin() pinnedOut.unpin()
@ -72,6 +78,7 @@ actual class Crypto internal actual constructor() {
actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState {
val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!!
val state = allocated.reinterpret<debug.test.GenericHashState>().pointed val state = allocated.reinterpret<debug.test.GenericHashState>().pointed
println("Debug crypto_generichash_init")
val pinnedKey = key.pin() val pinnedKey = key.pin()
libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(),
outlen.convert()) outlen.convert())