From fcc4d8761012127579936815965b9d5d0707974f Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 14 Aug 2020 11:08:59 +0200 Subject: [PATCH 01/65] Add documentation to definitions --- .../commonMain/kotlin/debug/test/DebugTest.kt | 4 +++ .../src/jsMain/kotlin/debug/test/DebugTest.kt | 4 +++ .../jvmMain/kotlin/debug/test/DebugTest.kt | 4 +++ .../nativeMain/kotlin/debug/test/DebugTest.kt | 4 +++ .../libsodium/definitions/DefinitionTypes.kt | 25 ++++++++++++++-- .../LibsodiumGenericHashDefinitions.kt | 4 +-- .../definitions/LibsodiumHashDefinitions.kt | 18 ++++++----- .../LibsodiumSecretStreamDefinitions.kt | 30 +++++++++++++++++++ .../LibsodiumSecretstreamDefinitions.kt | 10 ------- .../generator/CommonLibsodiumGenerator.kt | 4 +-- .../generator/JsLibsodiumGenerator.kt | 4 +-- .../generator/JvmLibsodiumGenerator.kt | 4 +-- .../generator/NativeLibsodiumGenerator.kt | 4 +-- .../libsodium/generator/SharedCreators.kt | 10 +++++-- 14 files changed, 97 insertions(+), 32 deletions(-) create mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretstreamDefinitions.kt diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 6287381..c3ee8f9 100644 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -10,6 +10,10 @@ expect class Sha512State expect class GenericHashState expect class Crypto internal constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ fun crypto_hash_sha256_init(): Sha256State fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index 727d9c7..f9a210c 100644 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -14,6 +14,10 @@ actual typealias Sha512State = Any actual typealias GenericHashState = Any actual class Crypto internal actual constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): dynamic { println("Debug crypto_hash_sha256_init") val result = js("getSodium().crypto_hash_sha256_init()") diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index 1213842..c6fec61 100644 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -15,6 +15,10 @@ actual typealias Sha512State = Hash.State512 actual typealias GenericHashState = ByteArray actual class Crypto internal actual constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): Sha256State { val state = debug.test.Sha256State() println("Debug crypto_hash_sha256_init") diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 5224235..b987ebb 100644 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -27,6 +27,10 @@ actual class Crypto internal actual constructor() { val _emitByteArray: ByteArray = ByteArray(0) + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): Sha256State { val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! val state = allocated.reinterpret().pointed diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt index dfd1175..f2f2832 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -25,6 +25,7 @@ class KotlinFileDefinition( class ClassDefinition( val name: String, + val codeDocumentation: String = "", val innerClasses: MutableList = mutableListOf(), val methods: MutableList = mutableListOf() ) { @@ -46,6 +47,7 @@ class InnerClassDefinition( val javaName: String, val jsName: String, val nativeName: String, + val codeDocumentation: String = "", val functions: MutableList = mutableListOf() ) @@ -54,6 +56,7 @@ class FunctionDefinition( val javaName: String, val jsName: String, val nativeName: String, + val codeDocumentation: String = "", val parameterList: MutableList = mutableListOf(), val returnType: GeneralTypeDefinition, val dynamicJsReturn: Boolean = false, @@ -75,6 +78,10 @@ class ParameterDefinition( val specificJvmInitializer: String? = null, ) +class CodeBlockDefinition( + codeBlock: String +) + interface GeneralTypeDefinition { val typeName: TypeName } @@ -98,17 +105,24 @@ fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefi } -fun classDef(name: String, body: ClassDefinition.() -> Unit): ClassDefinition { - val commonClass = ClassDefinition(name) +fun classDef(name: String, codeDocumentation: String = "",body: ClassDefinition.() -> Unit): ClassDefinition { + val commonClass = ClassDefinition(name, codeDocumentation) commonClass.body() return commonClass } +fun codeBlock(codeBlock: String) : CodeBlockDefinition { + val codeBlockDefinition = CodeBlockDefinition(codeBlock) + return codeBlockDefinition + +} + fun innerClassDef( name: String, javaName: String, jsName: String, nativeName: String, + codeDocumentation: String = "", specificConstructor : String? = null, body: InnerClassDefinition.() -> Unit = {} ): InnerClassDefinition { @@ -116,7 +130,8 @@ fun innerClassDef( name, javaName, jsName, - nativeName + nativeName, + codeDocumentation ) genClass.body() return genClass @@ -127,6 +142,7 @@ fun funcDef( javaName: String, jsName: String, nativeName: String, + codeDocumentation: String = "", returnType: GeneralTypeDefinition, dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, @@ -138,6 +154,7 @@ fun funcDef( javaName, jsName, nativeName, + codeDocumentation, returnType = returnType, dynamicJsReturn = dynamicJsReturn, isStateCreationFunction = isStateCreationFunction, @@ -149,6 +166,7 @@ fun funcDef( fun funcDef( name: String, + codeDocumentation: String = "", returnType: GeneralTypeDefinition, dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, @@ -161,6 +179,7 @@ fun funcDef( name, name, name, + codeDocumentation, returnType = returnType, dynamicJsReturn = dynamicJsReturn, isStateCreationFunction = isStateCreationFunction, diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt index d6d47fd..751faed 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt @@ -21,8 +21,8 @@ fun ClassDefinition.defineGenericHashFunctions() { +funcDef( "crypto_generichash_init", - CustomTypeDefinition(ClassName(packageName, "GenericHashState")), - true, + returnType = CustomTypeDefinition(ClassName(packageName, "GenericHashState")), + dynamicJsReturn = true, isStateCreationFunction = true ) { +ParameterDefinition( diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt index b196ecf..531994e 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt @@ -19,7 +19,11 @@ fun ClassDefinition.defineHashFunctions() { ) +funcDef( "crypto_hash_sha256_init", - CustomTypeDefinition(ClassName(packageName, "Sha256State")), + codeDocumentation = """ + Initialize the SHA256 hash + returns sha 256 state + """.trimIndent(), + returnType = CustomTypeDefinition(ClassName(packageName, "Sha256State")), dynamicJsReturn = true, isStateCreationFunction = true ) { @@ -31,7 +35,7 @@ fun ClassDefinition.defineHashFunctions() { ) } - +funcDef("crypto_hash_sha256_update", TypeDefinition.UNIT) { + +funcDef("crypto_hash_sha256_update", returnType = TypeDefinition.UNIT) { +ParameterDefinition( "state", CustomTypeDefinition((withPackageName("Sha256State"))), @@ -40,7 +44,7 @@ fun ClassDefinition.defineHashFunctions() { +ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE) } - +funcDef("crypto_hash_sha256_final", TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 32) { + +funcDef("crypto_hash_sha256_final", returnType = TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 32) { +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State")))) +ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true) } @@ -56,8 +60,8 @@ fun ClassDefinition.defineHashFunctions() { ) +funcDef( "crypto_hash_sha512_init", - CustomTypeDefinition(ClassName(packageName, "Sha512State")), - true, + returnType = CustomTypeDefinition(ClassName(packageName, "Sha512State")), + dynamicJsReturn = true, isStateCreationFunction = true ) { +ParameterDefinition( @@ -68,12 +72,12 @@ fun ClassDefinition.defineHashFunctions() { ) } - +funcDef("crypto_hash_sha512_update", TypeDefinition.UNIT) { + +funcDef("crypto_hash_sha512_update", returnType = TypeDefinition.UNIT) { +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State")))) +ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE) } - +funcDef("crypto_hash_sha512_final", TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 64) { + +funcDef("crypto_hash_sha512_final", returnType = TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 64) { +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State")))) +ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true) } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt new file mode 100644 index 0000000..a632968 --- /dev/null +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -0,0 +1,30 @@ +package com.ionspin.kotlin.crypto.generator.libsodium.definitions + +import com.squareup.kotlinpoet.ClassName + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Aug/2020 + */ +fun ClassDefinition.defineSecretStreamFunctions() { + +innerClassDef( + "SecretStreamState", + "com.goterl.lazycode.lazysodium.interfaces.SecretStream.State", + "SecretStreamState", + "crypto_hash_sha256_state" + ) + +funcDef( + "crypto_secretstream_xchacha20poly1305_init_push", + returnType = TypeDefinition.ARRAY_OF_UBYTES, + dynamicJsReturn = true, + isStateCreationFunction = true + ) { + +ParameterDefinition( + "state", + CustomTypeDefinition((withPackageName("SecretStreamState"))), + dropParameterFromDefinition = true, + isActuallyAnOutputParam = true + ) + } + + +} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretstreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretstreamDefinitions.kt deleted file mode 100644 index 9854763..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretstreamDefinitions.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -/** - * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Aug/2020 - */ -fun ClassDefinition.defineSecretStreamFunctions() { - - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt index 1ff5af6..ea5af64 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt @@ -49,7 +49,7 @@ object CommonLibsodiumGenerator { return innerClassBuilder.build() } - fun createCommonMethodSpec(methodDefinition: FunctionDefinition): FunSpec { + fun createCommonMethodSpec(methodDefinition: FunctionDefinition): FunSpec.Builder { val methodBuilder = FunSpec.builder(methodDefinition.name) var actualReturnType : TypeName = Any::class.asTypeName() var actualReturnTypeFound : Boolean = false @@ -69,7 +69,7 @@ object CommonLibsodiumGenerator { } else { methodBuilder.returns(methodDefinition.returnType.typeName) } - return methodBuilder.build() + return methodBuilder } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt index 03f11b6..2255cb8 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -57,7 +57,7 @@ object JsLibsodiumGenerator { return innerClassBuilder.build() } - fun createJsFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec { + fun createJsFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec.Builder { val methodBuilder = FunSpec.builder(methodDefinition.name) var returnModifierFound = false @@ -121,7 +121,7 @@ object JsLibsodiumGenerator { } } methodBuilder.addStatement(constructJsCall.toString()) - return methodBuilder.build() + return methodBuilder } fun paramsToString(methodDefinition: FunctionDefinition): String { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index e303c2f..7283207 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -55,7 +55,7 @@ object JvmLibsodiumGenerator { return innerClassBuilder.build() } - fun createJvmFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec { + fun createJvmFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec.Builder { val methodBuilder = FunSpec.builder(methodDefinition.name) methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false @@ -141,7 +141,7 @@ object JvmLibsodiumGenerator { } } methodBuilder.returns(methodDefinition.returnType.typeName) - return methodBuilder.build() + return methodBuilder } fun createOutputParam(outputParam: ParameterDefinition, length: String?, methodBuilder: FunSpec.Builder) { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 46bcea0..74a8d88 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -70,7 +70,7 @@ object NativeLibsodiumGenerator { return innerClassBuilder.build() } - fun createNativeFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec { + fun createNativeFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec.Builder { val methodBuilder = FunSpec.builder(methodDefinition.name) methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false @@ -159,7 +159,7 @@ object NativeLibsodiumGenerator { methodBuilder.returns(methodDefinition.returnType.typeName) - return methodBuilder.build() + return methodBuilder } fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt index 189561b..d9b4986 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt @@ -15,7 +15,7 @@ import com.squareup.kotlinpoet.TypeSpec fun createClass( classDefinition: ClassDefinition, multiplatformModifier: MultiplatformModifier, - methodCreator: (FunctionDefinition) -> FunSpec + methodCreator: (FunctionDefinition) -> FunSpec.Builder ): TypeSpec.Builder { val commonClassBuilder = TypeSpec.classBuilder(classDefinition.name) // Ugly @@ -29,9 +29,15 @@ fun createClass( commonClassBuilder.primaryConstructor(primaryConstructor.build()) commonClassBuilder.modifiers += multiplatformModifier.modifierList for (methodDefinition in classDefinition.methods) { - commonClassBuilder.addFunction(methodCreator(methodDefinition)) + val builder = methodCreator(methodDefinition) + generateDocumentationForMethod(builder, methodDefinition) + commonClassBuilder.addFunction(builder.build()) } return commonClassBuilder } +fun generateDocumentationForMethod(builder: FunSpec.Builder, methodSpec: FunctionDefinition) { + builder.addKdoc(methodSpec.codeDocumentation) +} + From a5b20daf5a87f705709e30eb695da0683525797e Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 14 Aug 2020 12:39:27 +0200 Subject: [PATCH 02/65] Adding data classes --- .../commonMain/kotlin/debug/test/DebugTest.kt | 30 ------ .../src/jsMain/kotlin/debug/test/DebugTest.kt | 57 ----------- .../jvmMain/kotlin/debug/test/DebugTest.kt | 66 ------------- .../nativeMain/kotlin/debug/test/DebugTest.kt | 92 ------------------ .../libsodium/definitions/DefinitionTypes.kt | 63 +++++++++++-- .../definitions/LibsodiumDefinitions.kt | 1 + .../LibsodiumSecretStreamDefinitions.kt | 26 ++++- .../libsodium/generator/Coordinator.kt | 4 +- .../generator/JsLibsodiumGenerator.kt | 41 ++++---- .../generator/JvmLibsodiumGenerator.kt | 78 +++++++-------- .../generator/NativeLibsodiumGenerator.kt | 94 +++++++++---------- .../libsodium/generator/SharedCreators.kt | 27 +++++- .../kotlin/crypto/generator/DebugTest.kt | 8 +- .../commonMain/kotlin/debug/test/DebugTest.kt | 13 +++ .../src/jsMain/kotlin/debug/test/DebugTest.kt | 11 +++ .../jvmMain/kotlin/debug/test/DebugTest.kt | 13 +++ .../nativeMain/kotlin/debug/test/DebugTest.kt | 14 +++ 17 files changed, 263 insertions(+), 375 deletions(-) delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index c3ee8f9..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,30 +0,0 @@ -package debug.test - -import kotlin.Int -import kotlin.UByteArray - -expect class Sha256State - -expect class Sha512State - -expect class GenericHashState - -expect class Crypto internal constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - fun crypto_hash_sha256_init(): Sha256State - - fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) - - fun crypto_hash_sha256_final(state: Sha256State): UByteArray - - fun crypto_hash_sha512_init(): Sha512State - - fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) - - fun crypto_hash_sha512_final(state: Sha512State): UByteArray - - fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index f9a210c..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,57 +0,0 @@ -package debug.test - -import com.ionspin.kotlin.crypto.getSodium -import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray -import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array -import kotlin.Any -import kotlin.Int -import kotlin.UByteArray - -actual typealias Sha256State = Any - -actual typealias Sha512State = Any - -actual typealias GenericHashState = Any - -actual class Crypto internal actual constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): dynamic { - println("Debug crypto_hash_sha256_init") - val result = js("getSodium().crypto_hash_sha256_init()") - return result - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - getSodium().crypto_hash_sha256_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - println("Debug crypto_hash_sha256_final") - return getSodium().crypto_hash_sha256_final(state).toUByteArray() - } - - actual fun crypto_hash_sha512_init(): dynamic { - println("Debug crypto_hash_sha512_init") - val result = js("getSodium().crypto_hash_sha512_init()") - return result - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - getSodium().crypto_hash_sha512_update(state, input.toUInt8Array(), ) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - println("Debug crypto_hash_sha512_final") - return getSodium().crypto_hash_sha512_final(state).toUByteArray() - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { - println("Debug crypto_generichash_init") - return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) - } -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index c6fec61..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,66 +0,0 @@ -package debug.test - -import com.goterl.lazycode.lazysodium.SodiumJava -import com.goterl.lazycode.lazysodium.interfaces.Hash -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray - -val sodium: SodiumJava = SodiumJava() - -actual typealias Sha256State = Hash.State256 - -actual typealias Sha512State = Hash.State512 - -actual typealias GenericHashState = ByteArray - -actual class Crypto internal actual constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): Sha256State { - val state = debug.test.Sha256State() - println("Debug crypto_hash_sha256_init") - sodium.crypto_hash_sha256_init(state) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - sodium.crypto_hash_sha256_final(state, out.asByteArray()) - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val state = debug.test.Sha512State() - println("Debug crypto_hash_sha512_init") - sodium.crypto_hash_sha512_init(state) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - sodium.crypto_hash_sha512_final(state, out.asByteArray()) - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) - println("Debug crypto_generichash_init") - sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) - return state - } -} diff --git a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt deleted file mode 100644 index b987ebb..0000000 --- a/kotlin-multiplatform-libsodium-generator/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ /dev/null @@ -1,92 +0,0 @@ -package debug.test - -import kotlin.Byte -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByteArray -import kotlinx.cinterop.addressOf -import kotlinx.cinterop.convert -import kotlinx.cinterop.pin -import kotlinx.cinterop.pointed -import kotlinx.cinterop.ptr -import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.toCValues -import libsodium.crypto_generichash_blake2b_state -import libsodium.crypto_hash_sha256_state -import libsodium.crypto_hash_sha512_state -import libsodium.sodium_malloc - -actual typealias Sha256State = crypto_hash_sha256_state - -actual typealias Sha512State = crypto_hash_sha512_state - -actual typealias GenericHashState = crypto_generichash_blake2b_state - -actual class Crypto internal actual constructor() { - val _emitByte: Byte = 0 - - val _emitByteArray: ByteArray = ByteArray(0) - - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): Sha256State { - val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha256_init") - libsodium.crypto_hash_sha256_init(state.ptr) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha512_init") - libsodium.crypto_hash_sha512_init(state.ptr) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_generichash_init") - val pinnedKey = key.pin() - libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), - outlen.convert()) - pinnedKey.unpin() - return state - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt index f2f2832..fe7b003 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -27,7 +27,8 @@ class ClassDefinition( val name: String, val codeDocumentation: String = "", val innerClasses: MutableList = mutableListOf(), - val methods: MutableList = mutableListOf() + val methods: MutableList = mutableListOf(), + val dataClasses: MutableList = mutableListOf() ) { operator fun InnerClassDefinition.unaryPlus() { innerClasses.add(this) @@ -37,6 +38,10 @@ class ClassDefinition( methods.add(this) } + operator fun DataClassDefinition.unaryPlus() { + dataClasses.add(this) + } + operator fun List.unaryPlus() { methods.addAll(this) } @@ -51,6 +56,17 @@ class InnerClassDefinition( val functions: MutableList = mutableListOf() ) +class DataClassDefinition( + val name: String, + val codeDocumentation: String = "", + val parameters : List +) + +/** + * outputLengthWhenArray - if output is an a array and there is no parameter that modifies output length we need + * to tell the function what to expect (think SHA256 32byte output always, and Blake2 dynamic output controlled + * by outputLen parameter) + */ class FunctionDefinition( val name: String, val javaName: String, @@ -61,7 +77,8 @@ class FunctionDefinition( val returnType: GeneralTypeDefinition, val dynamicJsReturn: Boolean = false, val isStateCreationFunction: Boolean = false, - val outputLengthWhenArray: Int = -1 + val outputLengthWhenArray: Int = -1, + val customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null ) { operator fun ParameterDefinition.unaryPlus() { parameterList.add(this) @@ -79,7 +96,13 @@ class ParameterDefinition( ) class CodeBlockDefinition( - codeBlock: String + val codeBlock: String, + val applyOnTargets: Set = setOf( + TargetPlatform.COMMON, + TargetPlatform.JVM, + TargetPlatform.JS, + TargetPlatform.NATIVE + ) ) interface GeneralTypeDefinition { @@ -98,6 +121,10 @@ enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefiniti UNIT(Unit::class.asTypeName()) } +enum class TargetPlatform { + JVM, NATIVE, JS, COMMON +} + fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefinition { val commonKotlinFileInstance = KotlinFileDefinition(name) commonKotlinFileInstance.body() @@ -105,14 +132,26 @@ fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefi } -fun classDef(name: String, codeDocumentation: String = "",body: ClassDefinition.() -> Unit): ClassDefinition { +fun classDef(name: String, codeDocumentation: String = "", body: ClassDefinition.() -> Unit): ClassDefinition { val commonClass = ClassDefinition(name, codeDocumentation) commonClass.body() return commonClass } -fun codeBlock(codeBlock: String) : CodeBlockDefinition { - val codeBlockDefinition = CodeBlockDefinition(codeBlock) +fun dataClassDef(name : String, codeDocumentation: String = "", parameters: List) : DataClassDefinition { + return DataClassDefinition(name, codeDocumentation, parameters) +} + +fun codeBlock( + codeBlock: String, + applyOnTargets: Set = setOf( + TargetPlatform.COMMON, + TargetPlatform.JVM, + TargetPlatform.JS, + TargetPlatform.NATIVE + ) +): CodeBlockDefinition { + val codeBlockDefinition = CodeBlockDefinition(codeBlock, applyOnTargets) return codeBlockDefinition } @@ -123,7 +162,7 @@ fun innerClassDef( jsName: String, nativeName: String, codeDocumentation: String = "", - specificConstructor : String? = null, + specificConstructor: String? = null, body: InnerClassDefinition.() -> Unit = {} ): InnerClassDefinition { val genClass = InnerClassDefinition( @@ -147,6 +186,7 @@ fun funcDef( dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, outputLengthWhenArray: Int = -1, + customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, body: FunctionDefinition.() -> Unit ): FunctionDefinition { val function = FunctionDefinition( @@ -154,11 +194,12 @@ fun funcDef( javaName, jsName, nativeName, - codeDocumentation, + codeDocumentation = codeDocumentation, returnType = returnType, dynamicJsReturn = dynamicJsReturn, isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray + outputLengthWhenArray = outputLengthWhenArray, + customCodeBlockReplacesFunctionBody = customCodeBlockReplacesFunctionBody ) function.body() return function @@ -171,6 +212,7 @@ fun funcDef( dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, outputLengthWhenArray: Int = -1, + customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, body: FunctionDefinition.() -> Unit ): FunctionDefinition { val function = @@ -183,7 +225,8 @@ fun funcDef( returnType = returnType, dynamicJsReturn = dynamicJsReturn, isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray + outputLengthWhenArray = outputLengthWhenArray, + customCodeBlockReplacesFunctionBody = customCodeBlockReplacesFunctionBody ) function.body() return function diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt index 61cacf0..54d4fc0 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt @@ -10,6 +10,7 @@ object LibSodiumDefinitions { +classDef("Crypto") { defineHashFunctions() defineGenericHashFunctions() + defineSecretStreamFunctions() } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index a632968..e4c8935 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -12,17 +12,33 @@ fun ClassDefinition.defineSecretStreamFunctions() { "SecretStreamState", "crypto_hash_sha256_state" ) + +dataClassDef( + "SecretStreamStateAndHeader", + """ + This data class wraps the state and header objects returned when initializing secret stream encryption + """.trimIndent(), + listOf( + ParameterDefinition( + parameterName = "state", + parameterType = CustomTypeDefinition(withPackageName("SecretStreamState")) + ), + ParameterDefinition( + parameterName = "header", + parameterType = TypeDefinition.ARRAY_OF_UBYTES + ) + + ) + + ) +funcDef( "crypto_secretstream_xchacha20poly1305_init_push", - returnType = TypeDefinition.ARRAY_OF_UBYTES, + returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, dynamicJsReturn = true, isStateCreationFunction = true ) { +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("SecretStreamState"))), - dropParameterFromDefinition = true, - isActuallyAnOutputParam = true + "key", + parameterType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE ) } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt index c347f7c..946b03f 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt @@ -10,8 +10,8 @@ import java.io.File * on 31-Jul-2020 */ object Coordinator { - - fun run() { + @JvmStatic + fun main(args : Array) { val commonFileSpec = CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile) val jvmFileSpec = JvmLibsodiumGenerator.createJvmFile(packageName, LibSodiumDefinitions.testKotlinFile) diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt index 2255cb8..c2985b7 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -97,26 +97,31 @@ object JsLibsodiumGenerator { methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") val constructJsCall = StringBuilder() - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()") - } - TypeDefinition.INT -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - TypeDefinition.UNIT -> { - constructJsCall.append("getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - is CustomTypeDefinition -> { - if (methodDefinition.parameterList.filter { it.isStateType.not() }.size > 0) { + if (methodDefinition.customCodeBlockReplacesFunctionBody != null && + methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { + constructJsCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) + } else { + when (methodDefinition.returnType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + constructJsCall.append("return getSodium().${methodDefinition.jsName}") + constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()") + } + TypeDefinition.INT -> { constructJsCall.append("return getSodium().${methodDefinition.jsName}") constructJsCall.append(paramsToString(methodDefinition)) - } else { - constructJsCall.append("val result = js(\"getSodium().${methodDefinition.jsName}()\")") - constructJsCall.append("\nreturn result") + } + TypeDefinition.UNIT -> { + constructJsCall.append("getSodium().${methodDefinition.jsName}") + constructJsCall.append(paramsToString(methodDefinition)) + } + is CustomTypeDefinition -> { + if (methodDefinition.parameterList.filter { it.isStateType.not() }.size > 0) { + constructJsCall.append("return getSodium().${methodDefinition.jsName}") + constructJsCall.append(paramsToString(methodDefinition)) + } else { + constructJsCall.append("val result = js(\"getSodium().${methodDefinition.jsName}()\")") + constructJsCall.append("\nreturn result") + } } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index 7283207..bad4c91 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -1,11 +1,6 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition +import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec @@ -103,40 +98,45 @@ object JvmLibsodiumGenerator { } methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") val constructJvmCall = StringBuilder() - if (methodDefinition.isStateCreationFunction) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return out") + if (methodDefinition.customCodeBlockReplacesFunctionBody != null && + methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JVM)) { + constructJvmCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - } - is CustomTypeDefinition -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") + if (methodDefinition.isStateCreationFunction) { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return state") + } else if (actualReturnTypeFound) { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return out") + } else { + when (methodDefinition.returnType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return result") + } + TypeDefinition.INT -> { + constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return result") + } + TypeDefinition.UNIT -> { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + } + is CustomTypeDefinition -> { + constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return result") + } } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 74a8d88..3f22726 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -1,11 +1,6 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.CustomTypeDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ParameterDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition +import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* import com.squareup.kotlinpoet.ClassName import com.squareup.kotlinpoet.CodeBlock import com.squareup.kotlinpoet.FileSpec @@ -111,50 +106,55 @@ object NativeLibsodiumGenerator { methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") pinParams(methodDefinition, methodBuilder) val constructNativeCall = StringBuilder() - if (methodDefinition.isStateCreationFunction) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return out") + if (methodDefinition.customCodeBlockReplacesFunctionBody != null && + methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { + constructNativeCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - } - is CustomTypeDefinition -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") + if (methodDefinition.isStateCreationFunction) { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return state") + } else if (actualReturnTypeFound) { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return out") + } else { + when (methodDefinition.returnType) { + TypeDefinition.ARRAY_OF_UBYTES -> { + constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return result") + } + TypeDefinition.INT -> { + constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return result") + } + TypeDefinition.UNIT -> { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + } + is CustomTypeDefinition -> { + constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return result") + } } + + } - - } methodBuilder.returns(methodDefinition.returnType.typeName) diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt index d9b4986..3236be4 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt @@ -1,11 +1,10 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ClassDefinition +import com.ionspin.kotlin.crypto.generator.libsodium.definitions.DataClassDefinition import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.KModifier -import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.* /** * Created by Ugljesa Jovanovic @@ -22,6 +21,9 @@ fun createClass( val primaryConstructor = FunSpec.constructorBuilder() if (multiplatformModifier == MultiplatformModifier.EXPECT) { primaryConstructor.addModifiers(KModifier.INTERNAL) + for (dataClassDefinition in classDefinition.dataClasses) { + generateDataClass(commonClassBuilder, dataClassDefinition) + } } else { primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL) } @@ -36,6 +38,25 @@ fun createClass( return commonClassBuilder } +fun generateDataClass(classBuilder: TypeSpec.Builder, dataClassDefinition: DataClassDefinition) { + val dataClassBuilder = TypeSpec.classBuilder(dataClassDefinition.name) + dataClassBuilder.addModifiers(KModifier.DATA) + val dataClassConstructor = FunSpec.constructorBuilder() + for (parameter in dataClassDefinition.parameters) { + val parameterBuilder = ParameterSpec.builder(parameter.parameterName, parameter.parameterType.typeName) + dataClassConstructor.addParameter(parameterBuilder.build()) + } + dataClassBuilder.primaryConstructor(dataClassConstructor.build()) + for (parameter in dataClassDefinition.parameters) { + dataClassBuilder.addProperty( + PropertySpec.builder(parameter.parameterName, parameter.parameterType.typeName) + .initializer(parameter.parameterName) + .build() + ) + } + classBuilder.addType(dataClassBuilder.build()) +} + fun generateDocumentationForMethod(builder: FunSpec.Builder, methodSpec: FunctionDefinition) { builder.addKdoc(methodSpec.codeDocumentation) } diff --git a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt index 32aa3b2..65fa2d6 100644 --- a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt +++ b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt @@ -1,8 +1,7 @@ package com.ionspin.kotlin.crypto.generator -import com.ionspin.kotlin.crypto.generator.libsodium.generator.CommonLibsodiumGenerator -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefinitions import com.ionspin.kotlin.crypto.generator.libsodium.generator.Coordinator +import com.squareup.kotlinpoet.* import org.junit.Test /** @@ -11,8 +10,5 @@ import org.junit.Test * on 31-Jul-2020 */ class DebugTest { - @Test - fun debugTest() { - Coordinator.run() - } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 6287381..06ba9e5 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -9,7 +9,13 @@ expect class Sha512State expect class GenericHashState +expect class SecretStreamState + expect class Crypto internal constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ fun crypto_hash_sha256_init(): Sha256State fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) @@ -23,4 +29,11 @@ expect class Crypto internal constructor() { fun crypto_hash_sha512_final(state: Sha512State): UByteArray fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState + + fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray + + data class SecretStreamStateAndHeader( + val state: SecretStreamState, + val header: UByteArray + ) } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index 727d9c7..6585ac4 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -13,7 +13,13 @@ actual typealias Sha512State = Any actual typealias GenericHashState = Any +actual typealias SecretStreamState = Any + actual class Crypto internal actual constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): dynamic { println("Debug crypto_hash_sha256_init") val result = js("getSodium().crypto_hash_sha256_init()") @@ -50,4 +56,9 @@ actual class Crypto internal actual constructor() { println("Debug crypto_generichash_init") return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) } + + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { + println("Debug crypto_secretstream_xchacha20poly1305_init_push") + + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index 1213842..7d5c0a2 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -2,6 +2,7 @@ package debug.test import com.goterl.lazycode.lazysodium.SodiumJava import com.goterl.lazycode.lazysodium.interfaces.Hash +import com.goterl.lazycode.lazysodium.interfaces.SecretStream import kotlin.ByteArray import kotlin.Int import kotlin.UByteArray @@ -14,7 +15,13 @@ actual typealias Sha512State = Hash.State512 actual typealias GenericHashState = ByteArray +actual typealias SecretStreamState = SecretStream.State + actual class Crypto internal actual constructor() { + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): Sha256State { val state = debug.test.Sha256State() println("Debug crypto_hash_sha256_init") @@ -59,4 +66,10 @@ actual class Crypto internal actual constructor() { sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) return state } + + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { + println("Debug crypto_secretstream_xchacha20poly1305_init_push") + sodium.crypto_secretstream_xchacha20poly1305_init_push(key.asByteArray()) + return state + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 5224235..24ee29e 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -22,11 +22,17 @@ actual typealias Sha512State = crypto_hash_sha512_state actual typealias GenericHashState = crypto_generichash_blake2b_state +actual typealias SecretStreamState = crypto_hash_sha256_state + actual class Crypto internal actual constructor() { val _emitByte: Byte = 0 val _emitByteArray: ByteArray = ByteArray(0) + /** + * Initialize the SHA256 hash + * returns sha 256 state + */ actual fun crypto_hash_sha256_init(): Sha256State { val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! val state = allocated.reinterpret().pointed @@ -85,4 +91,12 @@ actual class Crypto internal actual constructor() { pinnedKey.unpin() return state } + + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { + println("Debug crypto_secretstream_xchacha20poly1305_init_push") + val pinnedKey = key.pin() + libsodium.crypto_secretstream_xchacha20poly1305_init_push(pinnedKey.addressOf(0)) + pinnedKey.unpin() + return state + } } From efe9661c30a1048a1124447228b3ee231788c68b Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 14 Aug 2020 14:25:26 +0200 Subject: [PATCH 03/65] Adding custom code blocks --- .../libsodium/definitions/DefinitionTypes.kt | 6 ++-- .../LibsodiumSecretStreamDefinitions.kt | 36 ++++++++++++++++++- .../generator/CommonLibsodiumGenerator.kt | 1 + .../generator/JsLibsodiumGenerator.kt | 9 +++-- .../generator/JvmLibsodiumGenerator.kt | 9 +++-- .../generator/NativeLibsodiumGenerator.kt | 9 +++-- .../libsodium/generator/SharedCreators.kt | 7 ++-- .../commonMain/kotlin/debug/test/DebugTest.kt | 10 +++--- .../src/jsMain/kotlin/debug/test/DebugTest.kt | 7 +++- .../jvmMain/kotlin/debug/test/DebugTest.kt | 7 ++-- .../nativeMain/kotlin/debug/test/DebugTest.kt | 13 +++++-- 11 files changed, 87 insertions(+), 27 deletions(-) diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt index fe7b003..9e1c9ed 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -78,7 +78,7 @@ class FunctionDefinition( val dynamicJsReturn: Boolean = false, val isStateCreationFunction: Boolean = false, val outputLengthWhenArray: Int = -1, - val customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null + val customCodeBlockReplacesFunctionBody: List? = null ) { operator fun ParameterDefinition.unaryPlus() { parameterList.add(this) @@ -186,7 +186,7 @@ fun funcDef( dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, outputLengthWhenArray: Int = -1, - customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, + customCodeBlockReplacesFunctionBody: List? = null, body: FunctionDefinition.() -> Unit ): FunctionDefinition { val function = FunctionDefinition( @@ -212,7 +212,7 @@ fun funcDef( dynamicJsReturn: Boolean = false, isStateCreationFunction: Boolean = false, outputLengthWhenArray: Int = -1, - customCodeBlockReplacesFunctionBody: CodeBlockDefinition? = null, + customCodeBlockReplacesFunctionBody: List? = null, body: FunctionDefinition.() -> Unit ): FunctionDefinition { val function = diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index e4c8935..4f3b10b 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -30,11 +30,45 @@ fun ClassDefinition.defineSecretStreamFunctions() { ) ) + val jsSecretStreamInit = CodeBlockDefinition( + """ + val stateAndHeader = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) + val state = stateAndHeader.state + val header = (stateAndHeader.header as Uint8Array).toUByteArray() + return SecretStreamStateAndHeader(state, header) + """.trimIndent(), + setOf(TargetPlatform.JS) + ) + + val jvmSecretStreamInit = CodeBlockDefinition( + """ + val header = UByteArray(24) + val state = SecretStream.State() + sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) + return SecretStreamStateAndHeader(state, header) + """.trimIndent(), + setOf(TargetPlatform.JVM) + ) + + val nativeSecretStreamInit = CodeBlockDefinition( + """ + val state = libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! + .reinterpret() + .pointed + val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } + val pinnedHeader = header.pin() + libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues()) + pinnedHeader.unpin() + return SecretStreamStateAndHeader(state, header) + """.trimIndent(), + setOf(TargetPlatform.NATIVE) + ) +funcDef( "crypto_secretstream_xchacha20poly1305_init_push", returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, dynamicJsReturn = true, - isStateCreationFunction = true + isStateCreationFunction = true, + customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit) ) { +ParameterDefinition( "key", diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt index ea5af64..d2142b8 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt @@ -28,6 +28,7 @@ object CommonLibsodiumGenerator { } val commonClassSpec = createClass( + fileBuilder, commonClassDefinition, MultiplatformModifier.EXPECT, ::createCommonMethodSpec diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt index c2985b7..b474068 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -18,6 +18,7 @@ object JsLibsodiumGenerator { fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUInt8Array") fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUByteArray") fileBuilder.addImport("com.ionspin.kotlin.crypto", "getSodium") + fileBuilder.addImport("org.khronos.webgl", "Uint8Array") for (commonClassDefinition in fileDefinition.commonClassList) { //Create type-aliases commonClassDefinition.innerClasses.forEach { @@ -25,6 +26,7 @@ object JsLibsodiumGenerator { } val commonClassSpec = createClass( + fileBuilder, commonClassDefinition, MultiplatformModifier.ACTUAL, ::createJsFunctionImplementation @@ -97,9 +99,10 @@ object JsLibsodiumGenerator { methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") val constructJsCall = StringBuilder() - if (methodDefinition.customCodeBlockReplacesFunctionBody != null && - methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { - constructJsCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) + if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { + for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.JS) }) { + constructJsCall.append(codeBlock.codeBlock) + } } else { when (methodDefinition.returnType) { TypeDefinition.ARRAY_OF_UBYTES -> { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index bad4c91..9e9304a 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -29,6 +29,7 @@ object JvmLibsodiumGenerator { } val commonClassSpec = createClass( + fileBuilder, commonClassDefinition, MultiplatformModifier.ACTUAL, ::createJvmFunctionImplementation @@ -98,9 +99,11 @@ object JvmLibsodiumGenerator { } methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") val constructJvmCall = StringBuilder() - if (methodDefinition.customCodeBlockReplacesFunctionBody != null && - methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JVM)) { - constructJvmCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) + if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { + for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.JVM) }) { + constructJvmCall.append(codeBlock.codeBlock) + } + methodBuilder.addStatement(constructJvmCall.toString()) } else { if (methodDefinition.isStateCreationFunction) { constructJvmCall.append("sodium.${methodDefinition.nativeName}") diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 3f22726..56a865a 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -36,6 +36,7 @@ object NativeLibsodiumGenerator { } val commonClassSpec = createClass( + fileBuilder, commonClassDefinition, MultiplatformModifier.ACTUAL, ::createNativeFunctionImplementation @@ -106,9 +107,11 @@ object NativeLibsodiumGenerator { methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") pinParams(methodDefinition, methodBuilder) val constructNativeCall = StringBuilder() - if (methodDefinition.customCodeBlockReplacesFunctionBody != null && - methodDefinition.customCodeBlockReplacesFunctionBody.applyOnTargets.contains(TargetPlatform.JS)) { - constructNativeCall.append(methodDefinition.customCodeBlockReplacesFunctionBody.codeBlock) + if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { + for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.NATIVE) }) { + constructNativeCall.append(codeBlock.codeBlock) + methodBuilder.addStatement(constructNativeCall.toString()) + } } else { if (methodDefinition.isStateCreationFunction) { constructNativeCall.append("libsodium.${methodDefinition.nativeName}") diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt index 3236be4..e35df01 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt @@ -12,6 +12,7 @@ import com.squareup.kotlinpoet.* * on 31-Jul-2020 */ fun createClass( + fileBuilder: FileSpec.Builder, classDefinition: ClassDefinition, multiplatformModifier: MultiplatformModifier, methodCreator: (FunctionDefinition) -> FunSpec.Builder @@ -22,7 +23,7 @@ fun createClass( if (multiplatformModifier == MultiplatformModifier.EXPECT) { primaryConstructor.addModifiers(KModifier.INTERNAL) for (dataClassDefinition in classDefinition.dataClasses) { - generateDataClass(commonClassBuilder, dataClassDefinition) + generateDataClass(fileBuilder, dataClassDefinition) } } else { primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL) @@ -38,7 +39,7 @@ fun createClass( return commonClassBuilder } -fun generateDataClass(classBuilder: TypeSpec.Builder, dataClassDefinition: DataClassDefinition) { +fun generateDataClass(fileBuilder: FileSpec.Builder, dataClassDefinition: DataClassDefinition) { val dataClassBuilder = TypeSpec.classBuilder(dataClassDefinition.name) dataClassBuilder.addModifiers(KModifier.DATA) val dataClassConstructor = FunSpec.constructorBuilder() @@ -54,7 +55,7 @@ fun generateDataClass(classBuilder: TypeSpec.Builder, dataClassDefinition: DataC .build() ) } - classBuilder.addType(dataClassBuilder.build()) + fileBuilder.addType(dataClassBuilder.build()) } fun generateDocumentationForMethod(builder: FunSpec.Builder, methodSpec: FunctionDefinition) { diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 06ba9e5..91fe139 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -11,6 +11,11 @@ expect class GenericHashState expect class SecretStreamState +data class SecretStreamStateAndHeader( + val state: SecretStreamState, + val header: UByteArray +) + expect class Crypto internal constructor() { /** * Initialize the SHA256 hash @@ -31,9 +36,4 @@ expect class Crypto internal constructor() { fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray - - data class SecretStreamStateAndHeader( - val state: SecretStreamState, - val header: UByteArray - ) } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index 6585ac4..9ad22de 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -6,6 +6,7 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array import kotlin.Any import kotlin.Int import kotlin.UByteArray +import org.khronos.webgl.Uint8Array actual typealias Sha256State = Any @@ -59,6 +60,10 @@ actual class Crypto internal actual constructor() { actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { println("Debug crypto_secretstream_xchacha20poly1305_init_push") - + val stateAndHeader = + getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) + val state = stateAndHeader.state + val header = (stateAndHeader.header as Uint8Array).toUByteArray() + return SecretStreamStateAndHeader(state, header) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index 7d5c0a2..5b917e5 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -69,7 +69,10 @@ actual class Crypto internal actual constructor() { actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { println("Debug crypto_secretstream_xchacha20poly1305_init_push") - sodium.crypto_secretstream_xchacha20poly1305_init_push(key.asByteArray()) - return state + val header = UByteArray(24) + val state = SecretStream.State() + sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), + key.asByteArray()) + return SecretStreamStateAndHeader(state, header) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 24ee29e..1d2dc33 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -95,8 +95,15 @@ actual class Crypto internal actual constructor() { actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { println("Debug crypto_secretstream_xchacha20poly1305_init_push") val pinnedKey = key.pin() - libsodium.crypto_secretstream_xchacha20poly1305_init_push(pinnedKey.addressOf(0)) - pinnedKey.unpin() - return state + val state = + libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! + .reinterpret() + .pointed + val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } + val pinnedHeader = header.pin() + libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, + pinnedHeader.addressOf(0), key.toCValues()) + pinnedHeader.unpin() + return SecretStreamStateAndHeader(state, header) } } From 28995c065fd7310adb69b2aff3a2f1e4ff6267d4 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 14 Aug 2020 16:00:30 +0200 Subject: [PATCH 04/65] Adding secretstream push definition and neccessary changes --- .../libsodium/definitions/DefinitionTypes.kt | 10 ++- .../LibsodiumSecretStreamDefinitions.kt | 65 +++++++++++++++---- .../generator/JsLibsodiumGenerator.kt | 12 +++- .../generator/JvmLibsodiumGenerator.kt | 16 ++++- .../generator/NativeLibsodiumGenerator.kt | 19 ++++-- .../commonMain/kotlin/debug/test/DebugTest.kt | 17 ++++- .../src/jsMain/kotlin/debug/test/DebugTest.kt | 19 ++++++ .../jvmMain/kotlin/debug/test/DebugTest.kt | 24 ++++++- .../nativeMain/kotlin/debug/test/DebugTest.kt | 44 +++++++++++-- 9 files changed, 195 insertions(+), 31 deletions(-) diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt index 9e1c9ed..a27533b 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -85,6 +85,13 @@ class FunctionDefinition( } } +/** + * + * isActuallyAnOutputParam - drop this parameter from the generated param list and provide it as output. Param + * will be automatically generated inside function body block + * isStateType - provides special handling when type is a non-primitive state type + * dropParameterFromDefinition - don't show this parameter in method definition + */ class ParameterDefinition( val parameterName: String, val parameterType: GeneralTypeDefinition, @@ -118,7 +125,8 @@ enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefiniti LONG(Long::class.asTypeName()), INT(Int::class.asTypeName()), STRING(String::class.asTypeName()), - UNIT(Unit::class.asTypeName()) + UNIT(Unit::class.asTypeName()), + UBYTE(UByte::class.asTypeName()) } enum class TargetPlatform { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index 4f3b10b..c4f16b1 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -10,7 +10,7 @@ fun ClassDefinition.defineSecretStreamFunctions() { "SecretStreamState", "com.goterl.lazycode.lazysodium.interfaces.SecretStream.State", "SecretStreamState", - "crypto_hash_sha256_state" + "crypto_secretstream_xchacha20poly1305_state" ) +dataClassDef( "SecretStreamStateAndHeader", @@ -42,30 +42,35 @@ fun ClassDefinition.defineSecretStreamFunctions() { val jvmSecretStreamInit = CodeBlockDefinition( """ - val header = UByteArray(24) - val state = SecretStream.State() - sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) - return SecretStreamStateAndHeader(state, header) + val header = UByteArray(24) + val state = SecretStream.State() + sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) + return SecretStreamStateAndHeader(state, header) """.trimIndent(), setOf(TargetPlatform.JVM) ) val nativeSecretStreamInit = CodeBlockDefinition( """ - val state = libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! - .reinterpret() - .pointed - val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } - val pinnedHeader = header.pin() - libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues()) - pinnedHeader.unpin() - return SecretStreamStateAndHeader(state, header) + val pinnedKey = key.pin() + val state = sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! + .reinterpret() + .pointed + val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } + val pinnedHeader = header.pin() + libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), pinnedKey.addressOf(0)) + pinnedHeader.unpin() + pinnedKey.unpin() + return SecretStreamStateAndHeader(state, header) """.trimIndent(), setOf(TargetPlatform.NATIVE) ) +funcDef( "crypto_secretstream_xchacha20poly1305_init_push", - returnType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, + codeDocumentation = """ + Initialize a state and generate a random header. Both are returned inside `SecretStreamStateAndHeader` object + """.trimIndent(), + returnType = CustomTypeDefinition(withPackageName("SecretStreamStateAndHeader")), dynamicJsReturn = true, isStateCreationFunction = true, customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit) @@ -76,5 +81,37 @@ fun ClassDefinition.defineSecretStreamFunctions() { ) } + +funcDef( + name = "crypto_secretstream_xchacha20poly1305_push", + codeDocumentation = """ + Encrypt next block of data using the previously initialized state. Returns encrypted block. + """.trimIndent(), + returnType = TypeDefinition.ARRAY_OF_UBYTES + ) { + +ParameterDefinition( + "state", + CustomTypeDefinition(withPackageName("SecretStreamState")) + ) + +ParameterDefinition( + "c", + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, + isActuallyAnOutputParam = true, + dropParameterFromDefinition = true + ) + +ParameterDefinition( + "m", + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, + modifiesReturn = true + ) + +ParameterDefinition( + "ad", + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE + ) + +ParameterDefinition( + "tag", + TypeDefinition.UBYTE + ) + } + } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt index b474068..9901e0d 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -77,7 +77,14 @@ object JsLibsodiumGenerator { throw RuntimeException("Return modifier already found") } returnModifierFound = true - returnModifierName = paramDefinition.parameterName + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierName = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierName = paramDefinition.parameterName + } + } } if (paramDefinition.isActuallyAnOutputParam) { actualReturnTypeFound = true @@ -165,6 +172,9 @@ object JsLibsodiumGenerator { TypeDefinition.STRING -> { paramsBuilder.append(paramDefinition.parameterName + separator) } + TypeDefinition.UBYTE -> { + paramsBuilder.append(paramDefinition.parameterName + separator) + } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index 9e9304a..06708bc 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -72,7 +72,14 @@ object JvmLibsodiumGenerator { throw RuntimeException("Return modifier already found") } returnModifierFound = true - returnModifierName = paramDefinition.parameterName + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierName = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierName = paramDefinition.parameterName + } + } } if (paramDefinition.isActuallyAnOutputParam) { actualReturnParameterDefinition = paramDefinition @@ -114,7 +121,7 @@ object JvmLibsodiumGenerator { constructJvmCall.append("sodium.${methodDefinition.nativeName}") constructJvmCall.append(paramsToString(methodDefinition)) methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return out") + methodBuilder.addStatement("return ${actualReturnParameterDefinition.parameterName}") } else { when (methodDefinition.returnType) { TypeDefinition.ARRAY_OF_UBYTES -> { @@ -155,7 +162,7 @@ object JvmLibsodiumGenerator { */ when (outputParam.parameterType) { TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val out = UByteArray($length)") + methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") } else -> { throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") @@ -205,6 +212,9 @@ object JvmLibsodiumGenerator { TypeDefinition.STRING -> { paramsBuilder.append(paramDefinition.parameterName + separator) } + TypeDefinition.UBYTE -> { + paramsBuilder.append(paramDefinition.parameterName + separator) + } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 56a865a..98261b6 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -87,7 +87,15 @@ object NativeLibsodiumGenerator { throw RuntimeException("Return modifier already found") } returnModifierFound = true - returnModifierName = paramDefinition.parameterName + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierName = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierName = paramDefinition.parameterName + } + } + } if (paramDefinition.isActuallyAnOutputParam) { actualReturnParameterDefinition = paramDefinition @@ -105,7 +113,6 @@ object NativeLibsodiumGenerator { } } methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") - pinParams(methodDefinition, methodBuilder) val constructNativeCall = StringBuilder() if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.NATIVE) }) { @@ -113,6 +120,7 @@ object NativeLibsodiumGenerator { methodBuilder.addStatement(constructNativeCall.toString()) } } else { + pinParams(methodDefinition, methodBuilder) if (methodDefinition.isStateCreationFunction) { constructNativeCall.append("libsodium.${methodDefinition.nativeName}") constructNativeCall.append(paramsToString(methodDefinition)) @@ -124,7 +132,7 @@ object NativeLibsodiumGenerator { constructNativeCall.append(paramsToString(methodDefinition)) methodBuilder.addStatement(constructNativeCall.toString()) unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return out") + methodBuilder.addStatement("return ${actualReturnParameterDefinition.parameterName}") } else { when (methodDefinition.returnType) { TypeDefinition.ARRAY_OF_UBYTES -> { @@ -184,7 +192,7 @@ object NativeLibsodiumGenerator { */ when (outputParam.parameterType) { TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val out = UByteArray($length)") + methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") } else -> { throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") @@ -282,6 +290,9 @@ object NativeLibsodiumGenerator { TypeDefinition.STRING -> { paramsBuilder.append(paramDefinition.parameterName + separator) } + TypeDefinition.UBYTE -> { + paramsBuilder.append(paramDefinition.parameterName + separator) + } } } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 91fe139..791885d 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -1,6 +1,7 @@ package debug.test import kotlin.Int +import kotlin.UByte import kotlin.UByteArray expect class Sha256State @@ -35,5 +36,19 @@ expect class Crypto internal constructor() { fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState - fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray + /** + * Initialize a state and generate a random header. Both are returned inside + * `SecretStreamStateAndHeader` object + */ + fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader + + /** + * Encrypt next block of data using the previously initialized state. Returns encrypted block. + */ + fun crypto_secretstream_xchacha20poly1305_push( + state: SecretStreamState, + m: UByteArray, + ad: UByteArray, + tag: UByte + ): UByteArray } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index 9ad22de..a3ebf86 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -5,6 +5,7 @@ import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array import kotlin.Any import kotlin.Int +import kotlin.UByte import kotlin.UByteArray import org.khronos.webgl.Uint8Array @@ -58,6 +59,10 @@ actual class Crypto internal actual constructor() { return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) } + /** + * Initialize a state and generate a random header. Both are returned inside + * `SecretStreamStateAndHeader` object + */ actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { println("Debug crypto_secretstream_xchacha20poly1305_init_push") val stateAndHeader = @@ -66,4 +71,18 @@ actual class Crypto internal actual constructor() { val header = (stateAndHeader.header as Uint8Array).toUByteArray() return SecretStreamStateAndHeader(state, header) } + + /** + * Encrypt next block of data using the previously initialized state. Returns encrypted block. + */ + actual fun crypto_secretstream_xchacha20poly1305_push( + state: SecretStreamState, + m: UByteArray, + ad: UByteArray, + tag: UByte + ): UByteArray { + println("Debug crypto_secretstream_xchacha20poly1305_push") + return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(), , + ad.toUInt8Array(), , tag).toUByteArray() + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index 5b917e5..efffbf4 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -5,6 +5,7 @@ import com.goterl.lazycode.lazysodium.interfaces.Hash import com.goterl.lazycode.lazysodium.interfaces.SecretStream import kotlin.ByteArray import kotlin.Int +import kotlin.UByte import kotlin.UByteArray val sodium: SodiumJava = SodiumJava() @@ -67,7 +68,12 @@ actual class Crypto internal actual constructor() { return state } - actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { + /** + * Initialize a state and generate a random header. Both are returned inside + * `SecretStreamStateAndHeader` object + */ + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): + SecretStreamStateAndHeader { println("Debug crypto_secretstream_xchacha20poly1305_init_push") val header = UByteArray(24) val state = SecretStream.State() @@ -75,4 +81,20 @@ actual class Crypto internal actual constructor() { key.asByteArray()) return SecretStreamStateAndHeader(state, header) } + + /** + * Encrypt next block of data using the previously initialized state. Returns encrypted block. + */ + actual fun crypto_secretstream_xchacha20poly1305_push( + state: SecretStreamState, + m: UByteArray, + ad: UByteArray, + tag: UByte + ): UByteArray { + val c = UByteArray(m.size) + println("Debug crypto_secretstream_xchacha20poly1305_push") + sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), c.size.toLong(), + m.asByteArray(), m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag) + return c + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 1d2dc33..933270f 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -3,6 +3,7 @@ package debug.test import kotlin.Byte import kotlin.ByteArray import kotlin.Int +import kotlin.UByte import kotlin.UByteArray import kotlinx.cinterop.addressOf import kotlinx.cinterop.convert @@ -14,6 +15,7 @@ import kotlinx.cinterop.toCValues import libsodium.crypto_generichash_blake2b_state import libsodium.crypto_hash_sha256_state import libsodium.crypto_hash_sha512_state +import libsodium.crypto_secretstream_xchacha20poly1305_state import libsodium.sodium_malloc actual typealias Sha256State = crypto_hash_sha256_state @@ -22,7 +24,7 @@ actual typealias Sha512State = crypto_hash_sha512_state actual typealias GenericHashState = crypto_generichash_blake2b_state -actual typealias SecretStreamState = crypto_hash_sha256_state +actual typealias SecretStreamState = crypto_secretstream_xchacha20poly1305_state actual class Crypto internal actual constructor() { val _emitByte: Byte = 0 @@ -92,18 +94,48 @@ actual class Crypto internal actual constructor() { return state } - actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): UByteArray { + /** + * Initialize a state and generate a random header. Both are returned inside + * `SecretStreamStateAndHeader` object + */ + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): + SecretStreamStateAndHeader { println("Debug crypto_secretstream_xchacha20poly1305_init_push") val pinnedKey = key.pin() - val state = - libsodium.sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! + val state = + sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! .reinterpret() .pointed - val header = UByteArray(crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } + val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) + { 0U } val pinnedHeader = header.pin() libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, - pinnedHeader.addressOf(0), key.toCValues()) + pinnedHeader.addressOf(0), pinnedKey.addressOf(0)) pinnedHeader.unpin() + pinnedKey.unpin() return SecretStreamStateAndHeader(state, header) } + + /** + * Encrypt next block of data using the previously initialized state. Returns encrypted block. + */ + actual fun crypto_secretstream_xchacha20poly1305_push( + state: SecretStreamState, + m: UByteArray, + ad: UByteArray, + tag: UByte + ): UByteArray { + val c = UByteArray(m.size) + println("Debug crypto_secretstream_xchacha20poly1305_push") + val pinnedC = c.pin() + val pinnedM = m.pin() + val pinnedAd = ad.pin() + libsodium.crypto_secretstream_xchacha20poly1305_push(state.ptr, pinnedC.addressOf(0), + c.size.convert(), pinnedM.addressOf(0), m.size.convert(), pinnedAd.addressOf(0), + ad.size.convert(), tag) + pinnedC.unpin() + pinnedM.unpin() + pinnedAd.unpin() + return c + } } From df87dae37611554e2eec4871a226d87911ee4b67 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 15 Aug 2020 11:53:11 +0200 Subject: [PATCH 05/65] Adding pull secretstream definition --- .../libsodium/definitions/DefinitionTypes.kt | 4 +- .../LibsodiumSecretStreamDefinitions.kt | 73 ++++++++++++++++++- .../generator/CommonLibsodiumGenerator.kt | 9 ++- .../generator/JsLibsodiumGenerator.kt | 14 +++- .../generator/JvmLibsodiumGenerator.kt | 13 +++- .../generator/NativeLibsodiumGenerator.kt | 11 ++- .../kotlin/crypto/generator/DebugTest.kt | 1 + .../commonMain/kotlin/debug/test/DebugTest.kt | 17 ++++- .../src/jsMain/kotlin/debug/test/DebugTest.kt | 33 +++++++-- .../jvmMain/kotlin/debug/test/DebugTest.kt | 33 ++++++++- .../nativeMain/kotlin/debug/test/DebugTest.kt | 45 +++++++++++- 11 files changed, 223 insertions(+), 30 deletions(-) diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt index a27533b..7fd0e90 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -126,7 +126,9 @@ enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefiniti INT(Int::class.asTypeName()), STRING(String::class.asTypeName()), UNIT(Unit::class.asTypeName()), - UBYTE(UByte::class.asTypeName()) + UBYTE(UByte::class.asTypeName()), + IRRELEVANT(Unit::class.asTypeName()), + NULL(Unit::class.asTypeName()) } enum class TargetPlatform { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index c4f16b1..c286144 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -68,7 +68,7 @@ fun ClassDefinition.defineSecretStreamFunctions() { +funcDef( "crypto_secretstream_xchacha20poly1305_init_push", codeDocumentation = """ - Initialize a state and generate a random header. Both are returned inside `SecretStreamStateAndHeader` object + Initialize a state and generate a random header. Both are returned inside `SecretStreamStateAndHeader` object. """.trimIndent(), returnType = CustomTypeDefinition(withPackageName("SecretStreamStateAndHeader")), dynamicJsReturn = true, @@ -81,6 +81,32 @@ fun ClassDefinition.defineSecretStreamFunctions() { ) } + + +funcDef( + "crypto_secretstream_xchacha20poly1305_init_pull", + codeDocumentation = """ + Initialize state from header and key. The state can then be used for decryption. + """.trimIndent(), + returnType = CustomTypeDefinition(withPackageName("SecretStreamState")), + dynamicJsReturn = true, + isStateCreationFunction = true, + ) { + +ParameterDefinition( + "state", + parameterType = CustomTypeDefinition(withPackageName("SecretStreamState")), + dropParameterFromDefinition = true, + isStateType = true + ) + +ParameterDefinition( + "header", + parameterType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE + ) + +ParameterDefinition( + "key", + parameterType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE + ) + } + +funcDef( name = "crypto_secretstream_xchacha20poly1305_push", codeDocumentation = """ @@ -94,10 +120,15 @@ fun ClassDefinition.defineSecretStreamFunctions() { ) +ParameterDefinition( "c", - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, + TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true ) + +ParameterDefinition( + "clen", + TypeDefinition.NULL, + dropParameterFromDefinition = true + ) +ParameterDefinition( "m", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, @@ -113,5 +144,43 @@ fun ClassDefinition.defineSecretStreamFunctions() { ) } + +funcDef( + name = "crypto_secretstream_xchacha20poly1305_pull", + codeDocumentation = """ + Decrypt next block of data using the previously initialized state. Returns decrypted block. + """.trimIndent(), + returnType = TypeDefinition.ARRAY_OF_UBYTES + ) { + +ParameterDefinition( + "state", + CustomTypeDefinition(withPackageName("SecretStreamState")) + ) + +ParameterDefinition( + "m", + TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, + isActuallyAnOutputParam = true, + dropParameterFromDefinition = true + ) + +ParameterDefinition( + "mlen", + TypeDefinition.NULL, + dropParameterFromDefinition = true + ) + +ParameterDefinition( + "tag_p", + TypeDefinition.NULL + ) + +ParameterDefinition( + "c", + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, + modifiesReturn = true + ) + +ParameterDefinition( + "ad", + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE + ) + + } + } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt index d2142b8..9027f38 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt @@ -3,6 +3,7 @@ package com.ionspin.kotlin.crypto.generator.libsodium.generator import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition +import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition import com.squareup.kotlinpoet.* /** @@ -56,9 +57,11 @@ object CommonLibsodiumGenerator { var actualReturnTypeFound : Boolean = false for (paramDefinition in methodDefinition.parameterList) { if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.dropParameterFromDefinition.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) + if (paramDefinition.parameterType != TypeDefinition.NULL) { + val parameterSpec = + ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) + methodBuilder.addParameter(parameterSpec.build()) + } } if (paramDefinition.isActuallyAnOutputParam) { actualReturnTypeFound = true diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt index 9901e0d..2aeb944 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -68,9 +68,11 @@ object JsLibsodiumGenerator { var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) + if (paramDefinition.parameterType != TypeDefinition.NULL) { + val parameterSpec = + ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) + methodBuilder.addParameter(parameterSpec.build()) + } } if (paramDefinition.modifiesReturn) { if (returnModifierFound == true) { @@ -158,7 +160,7 @@ object JsLibsodiumGenerator { paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) } TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array(), " + separator) + paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) } TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) @@ -175,6 +177,10 @@ object JsLibsodiumGenerator { TypeDefinition.UBYTE -> { paramsBuilder.append(paramDefinition.parameterName + separator) } + TypeDefinition.NULL -> { + println("Got null parameter in js") +// paramsBuilder.append("null" + separator) + } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index 06708bc..7e36e8c 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -63,9 +63,11 @@ object JvmLibsodiumGenerator { createStateParam(paramDefinition, methodBuilder) } if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) + if (paramDefinition.parameterType != TypeDefinition.NULL) { + val parameterSpec = + ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) + methodBuilder.addParameter(parameterSpec.build()) + } } if (paramDefinition.modifiesReturn) { if (returnModifierFound == true) { @@ -213,7 +215,10 @@ object JvmLibsodiumGenerator { paramsBuilder.append(paramDefinition.parameterName + separator) } TypeDefinition.UBYTE -> { - paramsBuilder.append(paramDefinition.parameterName + separator) + paramsBuilder.append(paramDefinition.parameterName + ".toByte()" + separator) + } + TypeDefinition.NULL -> { + paramsBuilder.append("null" + separator) } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 98261b6..7f8b552 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -78,9 +78,11 @@ object NativeLibsodiumGenerator { createStateParam(paramDefinition, methodBuilder) } if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) + if (paramDefinition.parameterType != TypeDefinition.NULL) { + val parameterSpec = + ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) + methodBuilder.addParameter(parameterSpec.build()) + } } if (paramDefinition.modifiesReturn) { if (returnModifierFound == true) { @@ -293,6 +295,9 @@ object NativeLibsodiumGenerator { TypeDefinition.UBYTE -> { paramsBuilder.append(paramDefinition.parameterName + separator) } + TypeDefinition.NULL -> { + paramsBuilder.append("null" + separator) + } } } diff --git a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt index 65fa2d6..033b196 100644 --- a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt +++ b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt @@ -12,3 +12,4 @@ import org.junit.Test class DebugTest { } + diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 791885d..e4694f6 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -38,10 +38,16 @@ expect class Crypto internal constructor() { /** * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object + * `SecretStreamStateAndHeader` object. */ fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader + /** + * Initialize state from header and key. The state can then be used for decryption. + */ + fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): + SecretStreamState + /** * Encrypt next block of data using the previously initialized state. Returns encrypted block. */ @@ -51,4 +57,13 @@ expect class Crypto internal constructor() { ad: UByteArray, tag: UByte ): UByteArray + + /** + * Decrypt next block of data using the previously initialized state. Returns decrypted block. + */ + fun crypto_secretstream_xchacha20poly1305_pull( + state: SecretStreamState, + c: UByteArray, + ad: UByteArray + ): UByteArray } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index a3ebf86..bd65e56 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -30,7 +30,7 @@ actual class Crypto internal actual constructor() { actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { 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 { @@ -46,7 +46,7 @@ actual class Crypto internal actual constructor() { actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { 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 { @@ -61,7 +61,7 @@ actual class Crypto internal actual constructor() { /** * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object + * `SecretStreamStateAndHeader` object. */ actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { println("Debug crypto_secretstream_xchacha20poly1305_init_push") @@ -72,6 +72,16 @@ actual class Crypto internal actual constructor() { return SecretStreamStateAndHeader(state, header) } + /** + * Initialize state from header and key. The state can then be used for decryption. + */ + actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): + dynamic { + println("Debug crypto_secretstream_xchacha20poly1305_init_pull") + return getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), + key.toUInt8Array()) + } + /** * Encrypt next block of data using the previously initialized state. Returns encrypted block. */ @@ -82,7 +92,20 @@ actual class Crypto internal actual constructor() { tag: UByte ): UByteArray { println("Debug crypto_secretstream_xchacha20poly1305_push") - return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(), , - ad.toUInt8Array(), , tag).toUByteArray() + return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(), + ad.toUInt8Array(), tag).toUByteArray() + } + + /** + * Decrypt next block of data using the previously initialized state. Returns decrypted block. + */ + actual fun crypto_secretstream_xchacha20poly1305_pull( + state: SecretStreamState, + c: UByteArray, + ad: UByteArray + ): UByteArray { + println("Debug crypto_secretstream_xchacha20poly1305_pull") + return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(), + ad.toUInt8Array()).toUByteArray() } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index efffbf4..e058319 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -70,7 +70,7 @@ actual class Crypto internal actual constructor() { /** * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object + * `SecretStreamStateAndHeader` object. */ actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader { @@ -82,6 +82,18 @@ actual class Crypto internal actual constructor() { return SecretStreamStateAndHeader(state, header) } + /** + * Initialize state from header and key. The state can then be used for decryption. + */ + actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): + SecretStreamState { + val state = debug.test.SecretStreamState() + println("Debug crypto_secretstream_xchacha20poly1305_init_pull") + sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), + key.asByteArray()) + return state + } + /** * Encrypt next block of data using the previously initialized state. Returns encrypted block. */ @@ -93,8 +105,23 @@ actual class Crypto internal actual constructor() { ): UByteArray { val c = UByteArray(m.size) println("Debug crypto_secretstream_xchacha20poly1305_push") - sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), c.size.toLong(), - m.asByteArray(), m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag) + sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(), + m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte()) return c } + + /** + * Decrypt next block of data using the previously initialized state. Returns decrypted block. + */ + actual fun crypto_secretstream_xchacha20poly1305_pull( + state: SecretStreamState, + c: UByteArray, + ad: UByteArray + ): UByteArray { + val m = UByteArray(c.size) + println("Debug crypto_secretstream_xchacha20poly1305_pull") + sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, null, + c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) + return m + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 933270f..95c3e20 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -96,7 +96,7 @@ actual class Crypto internal actual constructor() { /** * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object + * `SecretStreamStateAndHeader` object. */ actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader { @@ -116,6 +116,23 @@ actual class Crypto internal actual constructor() { return SecretStreamStateAndHeader(state, header) } + /** + * Initialize state from header and key. The state can then be used for decryption. + */ + actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): + SecretStreamState { + val allocated = sodium_malloc(debug.test.SecretStreamState.size.convert())!! + val state = allocated.reinterpret().pointed + println("Debug crypto_secretstream_xchacha20poly1305_init_pull") + val pinnedHeader = header.pin() + val pinnedKey = key.pin() + libsodium.crypto_secretstream_xchacha20poly1305_init_pull(state.ptr, pinnedHeader.addressOf(0), + pinnedKey.addressOf(0)) + pinnedHeader.unpin() + pinnedKey.unpin() + return state + } + /** * Encrypt next block of data using the previously initialized state. Returns encrypted block. */ @@ -130,12 +147,32 @@ actual class Crypto internal actual constructor() { val pinnedC = c.pin() val pinnedM = m.pin() val pinnedAd = ad.pin() - libsodium.crypto_secretstream_xchacha20poly1305_push(state.ptr, pinnedC.addressOf(0), - c.size.convert(), pinnedM.addressOf(0), m.size.convert(), pinnedAd.addressOf(0), - ad.size.convert(), tag) + libsodium.crypto_secretstream_xchacha20poly1305_push(state.ptr, pinnedC.addressOf(0), null, + pinnedM.addressOf(0), m.size.convert(), pinnedAd.addressOf(0), ad.size.convert(), tag) pinnedC.unpin() pinnedM.unpin() pinnedAd.unpin() return c } + + /** + * Decrypt next block of data using the previously initialized state. Returns decrypted block. + */ + actual fun crypto_secretstream_xchacha20poly1305_pull( + state: SecretStreamState, + c: UByteArray, + ad: UByteArray + ): UByteArray { + val m = UByteArray(c.size) + println("Debug crypto_secretstream_xchacha20poly1305_pull") + val pinnedM = m.pin() + val pinnedC = c.pin() + val pinnedAd = ad.pin() + libsodium.crypto_secretstream_xchacha20poly1305_pull(state.ptr, pinnedM.addressOf(0), null, + null, pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) + pinnedM.unpin() + pinnedC.unpin() + pinnedAd.unpin() + return m + } } From 0c098e57db2e841a2ba46b7eef0c103439002b79 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 15 Aug 2020 17:50:46 +0200 Subject: [PATCH 06/65] Test secret stream generated code --- .../libsodium/definitions/DefinitionTypes.kt | 3 +- .../LibsodiumGenericHashDefinitions.kt | 2 +- .../LibsodiumSecretStreamDefinitions.kt | 9 +-- .../generator/JsLibsodiumGenerator.kt | 20 +++--- .../generator/JvmLibsodiumGenerator.kt | 23 +++--- .../generator/NativeLibsodiumGenerator.kt | 22 +++--- .../com/ionspin/kotlin/crypto/util/Util.kt | 2 +- .../build.gradle.kts | 1 - .../com/ionspin/kotlin/crypto/SmokeTest.kt | 2 +- .../crypto/secretstream/SecretStreamTest.kt | 70 +++++++++++++++++++ .../ionspin/kotlin/crypto/util/TestUtil.kt | 14 ++++ .../jvmMain/kotlin/debug/test/DebugTest.kt | 4 +- .../nativeMain/kotlin/debug/test/DebugTest.kt | 4 +- 13 files changed, 137 insertions(+), 39 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt index 7fd0e90..94c730d 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt @@ -95,7 +95,8 @@ class FunctionDefinition( class ParameterDefinition( val parameterName: String, val parameterType: GeneralTypeDefinition, - val modifiesReturn: Boolean = false, + val modifiesReturnObjectSize: Boolean = false, + val specificReturnModification : String? = null, val isActuallyAnOutputParam: Boolean = false, val isStateType: Boolean = false, val dropParameterFromDefinition: Boolean = false, diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt index 751faed..9ce1678 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt @@ -33,6 +33,6 @@ fun ClassDefinition.defineGenericHashFunctions() { specificJvmInitializer = "sodium.crypto_generichash_statebytes()" ) +ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES) - +ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true) + +ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturnObjectSize = true) } } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index c286144..4801ab0 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -1,7 +1,5 @@ package com.ionspin.kotlin.crypto.generator.libsodium.definitions -import com.squareup.kotlinpoet.ClassName - /** * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Aug/2020 */ @@ -132,7 +130,8 @@ fun ClassDefinition.defineSecretStreamFunctions() { +ParameterDefinition( "m", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, - modifiesReturn = true + modifiesReturnObjectSize = true, + specificReturnModification = "m.size + 17" ) +ParameterDefinition( "ad", @@ -173,7 +172,8 @@ fun ClassDefinition.defineSecretStreamFunctions() { +ParameterDefinition( "c", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, - modifiesReturn = true + modifiesReturnObjectSize = true, + specificReturnModification = "c.size - 17" ) +ParameterDefinition( "ad", @@ -183,4 +183,5 @@ fun ClassDefinition.defineSecretStreamFunctions() { } + } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt index 2aeb944..fea8ca8 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt @@ -63,7 +63,7 @@ object JsLibsodiumGenerator { val methodBuilder = FunSpec.builder(methodDefinition.name) var returnModifierFound = false - var returnModifierName = "" + var returnModifierValue = "" var actualReturnType: TypeName = DYNAMIC var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { @@ -74,18 +74,22 @@ object JsLibsodiumGenerator { methodBuilder.addParameter(parameterSpec.build()) } } - if (paramDefinition.modifiesReturn) { + if (paramDefinition.modifiesReturnObjectSize) { if (returnModifierFound == true) { throw RuntimeException("Return modifier already found") } returnModifierFound = true - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierName = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierName = paramDefinition.parameterName + if (paramDefinition.specificReturnModification == null) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierValue = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierValue = paramDefinition.parameterName + } } + } else { + returnModifierValue = paramDefinition.specificReturnModification!! } } if (paramDefinition.isActuallyAnOutputParam) { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index 7e36e8c..0096f83 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -55,7 +55,7 @@ object JvmLibsodiumGenerator { val methodBuilder = FunSpec.builder(methodDefinition.name) methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false - var returnModifierName = "" + var returnModifierValue = "" lateinit var actualReturnParameterDefinition: ParameterDefinition var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { @@ -69,18 +69,23 @@ object JvmLibsodiumGenerator { methodBuilder.addParameter(parameterSpec.build()) } } - if (paramDefinition.modifiesReturn) { + if (paramDefinition.modifiesReturnObjectSize) { if (returnModifierFound == true) { throw RuntimeException("Return modifier already found") } returnModifierFound = true - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierName = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierName = paramDefinition.parameterName + + if (paramDefinition.specificReturnModification == null) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierValue = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierValue = paramDefinition.parameterName + } } + } else { + returnModifierValue = paramDefinition.specificReturnModification!! } } if (paramDefinition.isActuallyAnOutputParam) { @@ -92,7 +97,7 @@ object JvmLibsodiumGenerator { if (returnModifierFound) { createOutputParam( actualReturnParameterDefinition, - returnModifierName, + returnModifierValue, methodBuilder ) } else { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 7f8b552..14b9d0e 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -70,7 +70,7 @@ object NativeLibsodiumGenerator { val methodBuilder = FunSpec.builder(methodDefinition.name) methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false - var returnModifierName = "" + var returnModifierValue = "" lateinit var actualReturnParameterDefinition: ParameterDefinition var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { @@ -84,18 +84,22 @@ object NativeLibsodiumGenerator { methodBuilder.addParameter(parameterSpec.build()) } } - if (paramDefinition.modifiesReturn) { + if (paramDefinition.modifiesReturnObjectSize) { if (returnModifierFound == true) { throw RuntimeException("Return modifier already found") } returnModifierFound = true - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierName = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierName = paramDefinition.parameterName + if (paramDefinition.specificReturnModification == null) { + when (paramDefinition.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + returnModifierValue = "${paramDefinition.parameterName}.size" + } + TypeDefinition.INT -> { + returnModifierValue = paramDefinition.parameterName + } } + } else { + returnModifierValue = paramDefinition.specificReturnModification!! } } @@ -106,7 +110,7 @@ object NativeLibsodiumGenerator { } if (actualReturnTypeFound) { if (returnModifierFound) { - createOutputParam(actualReturnParameterDefinition, returnModifierName, methodBuilder) + createOutputParam(actualReturnParameterDefinition, returnModifierValue, methodBuilder) } else { if (methodDefinition.outputLengthWhenArray == -1) { throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt index 6b8eb10..b24e406 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/Util.kt @@ -213,4 +213,4 @@ fun Collection.flattenToUByteArray(): UByteArray { } } return result -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/build.gradle.kts b/multiplatform-crypto-libsodium-bindings/build.gradle.kts index fbd9577..6cbea96 100644 --- a/multiplatform-crypto-libsodium-bindings/build.gradle.kts +++ b/multiplatform-crypto-libsodium-bindings/build.gradle.kts @@ -249,7 +249,6 @@ kotlin { implementation(kotlin(Deps.Common.stdLib)) implementation(kotlin(Deps.Common.test)) implementation(Deps.Common.kotlinBigNum) - api(project(Deps.Common.apiProject)) } } val commonTest by getting { diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt index 905a71c..8eecfd5 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -1,7 +1,7 @@ package com.ionspin.kotlin.crypto import com.ionspin.kotlin.bignum.integer.BigInteger -import com.ionspin.kotlin.crypto.hash.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.toHexString import debug.test.Crypto diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt new file mode 100644 index 0000000..2b1cbaf --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -0,0 +1,70 @@ +package com.ionspin.kotlin.crypto.secretstream + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import debug.test.Crypto +import kotlin.math.exp +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 15-Aug-2020 + */ +class SecretStreamTest { + @Test + fun testSecretStream() { + assertTrue { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val additionalData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val expected = ubyteArrayOf( + 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, + 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, + 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, + 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, + 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, + 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, + 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, + 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, + 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, + 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, + 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, + 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, + 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, + 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, + 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, + 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, + 0xcfU, 0x49U + ) + message.hexColumsPrint() + val crypto = Crypto() + val stateAndHeader = crypto.crypto_secretstream_xchacha20poly1305_init_push(key) + val encrypted = crypto.crypto_secretstream_xchacha20poly1305_push(stateAndHeader.state, message, ubyteArrayOf(), 0U) + encrypted.hexColumsPrint() + val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) + val decrypted = crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) + decrypted.hexColumsPrint() + decrypted.contentEquals(message) + + } + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt index 3cb5304..da2e924 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt @@ -34,3 +34,17 @@ fun testBlocking(block : suspend () -> Unit) { } block.startCoroutine(continuation) } + +fun String.encodeToUByteArray() : UByteArray{ + return encodeToByteArray().asUByteArray() +} + +fun UByteArray.toHexString() : String { + return this.joinToString(separator = "") { + if (it <= 0x0FU) { + "0${it.toString(16)}" + } else { + it.toString(16) + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index e058319..b2b3082 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -103,7 +103,7 @@ actual class Crypto internal actual constructor() { ad: UByteArray, tag: UByte ): UByteArray { - val c = UByteArray(m.size) + val c = UByteArray(m.size + 17) println("Debug crypto_secretstream_xchacha20poly1305_push") sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(), m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte()) @@ -118,7 +118,7 @@ actual class Crypto internal actual constructor() { c: UByteArray, ad: UByteArray ): UByteArray { - val m = UByteArray(c.size) + val m = UByteArray(c.size - 17) println("Debug crypto_secretstream_xchacha20poly1305_pull") sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, null, c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 95c3e20..7bb9657 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -142,7 +142,7 @@ actual class Crypto internal actual constructor() { ad: UByteArray, tag: UByte ): UByteArray { - val c = UByteArray(m.size) + val c = UByteArray(m.size + 17) println("Debug crypto_secretstream_xchacha20poly1305_push") val pinnedC = c.pin() val pinnedM = m.pin() @@ -163,7 +163,7 @@ actual class Crypto internal actual constructor() { c: UByteArray, ad: UByteArray ): UByteArray { - val m = UByteArray(c.size) + val m = UByteArray(c.size - 17) println("Debug crypto_secretstream_xchacha20poly1305_pull") val pinnedM = m.pin() val pinnedC = c.pin() From cd90f964ab5526584960630780ed3e276849100b Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 18 Aug 2020 23:32:50 +0200 Subject: [PATCH 07/65] Update kotlin version, need to fix secretstream pull, at least in js if not everywhere --- buildSrc/src/main/kotlin/Deps.kt | 8 +- .../LibsodiumSecretStreamDefinitions.kt | 2 +- .../libsodium/generator/SharedCreators.kt | 4 + .../kotlin/crypto/JsSodiumInterface.kt | 2 +- .../commonMain/kotlin/debug/test/DebugTest.kt | 3 + .../crypto/secretstream/SecretStreamTest.kt | 98 ++++++++++--------- .../kotlin/crypto/JsSodiumInterface.kt | 2 +- .../com/ionspin/kotlin/crypto/JsUtil.kt | 3 + .../src/jsMain/kotlin/debug/test/DebugTest.kt | 9 +- 9 files changed, 74 insertions(+), 57 deletions(-) diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index a4617e6..8c65ccd 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -15,12 +15,12 @@ */ object Versions { - val kotlinCoroutines = "1.3.8-1.4.0-rc" - val kotlin = "1.4.0-rc" - val kotlinSerialization = "1.0-M1-1.4.0-rc" + val kotlinCoroutines = "1.3.9" + val kotlin = "1.4.0" + val kotlinSerialization = "1.0.0-RC" val atomicfu = "0.14.3-M2-2-SNAPSHOT" //NOTE: my linux arm32 and arm64 build val nodePlugin = "1.3.0" - val dokkaPlugin = "1.4.0-M3-dev-92" + val dokkaPlugin = "1.4.0-rc" val taskTreePlugin = "1.5" val kotlinBigNumVersion = "0.1.6-1.4.0-rc-SNAPSHOT" diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index 4801ab0..76d7037 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -69,7 +69,7 @@ fun ClassDefinition.defineSecretStreamFunctions() { Initialize a state and generate a random header. Both are returned inside `SecretStreamStateAndHeader` object. """.trimIndent(), returnType = CustomTypeDefinition(withPackageName("SecretStreamStateAndHeader")), - dynamicJsReturn = true, + dynamicJsReturn = false, isStateCreationFunction = true, customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit) ) { diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt index e35df01..0fd8c24 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt @@ -45,6 +45,10 @@ fun generateDataClass(fileBuilder: FileSpec.Builder, dataClassDefinition: DataCl val dataClassConstructor = FunSpec.constructorBuilder() for (parameter in dataClassDefinition.parameters) { val parameterBuilder = ParameterSpec.builder(parameter.parameterName, parameter.parameterType.typeName) + val annotationBuilder = + AnnotationSpec.builder(ClassName("kotlin.js", "JsName")) + .addMember("\"${parameter.parameterName}\"") + parameterBuilder.addAnnotation(annotationBuilder.build()) dataClassConstructor.addParameter(parameterBuilder.build()) } dataClassBuilder.primaryConstructor(dataClassConstructor.build()) diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 1934eb9..6694723 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -50,7 +50,7 @@ interface JsSodiumInterface { //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : Uint8Array //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index e4694f6..d1acc23 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -3,6 +3,7 @@ package debug.test import kotlin.Int import kotlin.UByte import kotlin.UByteArray +import kotlin.js.JsName expect class Sha256State @@ -13,7 +14,9 @@ expect class GenericHashState expect class SecretStreamState data class SecretStreamStateAndHeader( + @JsName("state") val state: SecretStreamState, + @JsName("header") val header: UByteArray ) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index 2b1cbaf..c9e3cf4 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -1,7 +1,9 @@ package com.ionspin.kotlin.crypto.secretstream import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.Initializer import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.testBlocking import debug.test.Crypto import kotlin.math.exp import kotlin.test.Test @@ -14,56 +16,60 @@ import kotlin.test.assertTrue */ class SecretStreamTest { @Test - fun testSecretStream() { - assertTrue { - val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + - "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + fun testSecretStream() = testBlocking { + Initializer.initializeWithCallback { + assertTrue { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( - 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U - ) - val key = ubyteArrayOf( - 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, - 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, - 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, - 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, - ) + val additionalData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) - val nonce = ubyteArrayOf( - 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, - 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, - 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, - ) + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) - val expected = ubyteArrayOf( - 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, - 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, - 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, - 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, - 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, - 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, - 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, - 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, - 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, - 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, - 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, - 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, - 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, - 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, - 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, - 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, - 0xcfU, 0x49U - ) - message.hexColumsPrint() - val crypto = Crypto() - val stateAndHeader = crypto.crypto_secretstream_xchacha20poly1305_init_push(key) - val encrypted = crypto.crypto_secretstream_xchacha20poly1305_push(stateAndHeader.state, message, ubyteArrayOf(), 0U) - encrypted.hexColumsPrint() - val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) - val decrypted = crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) - decrypted.hexColumsPrint() - decrypted.contentEquals(message) + val expected = ubyteArrayOf( + 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, + 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, + 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, + 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, + 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, + 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, + 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, + 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, + 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, + 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, + 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, + 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, + 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, + 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, + 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, + 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, + 0xcfU, 0x49U + ) + message.hexColumsPrint() + val crypto = Crypto() + val stateAndHeader = crypto.crypto_secretstream_xchacha20poly1305_init_push(key) + val encrypted = + crypto.crypto_secretstream_xchacha20poly1305_push(stateAndHeader.state, message, ubyteArrayOf(), 0U) + encrypted.hexColumsPrint() + val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) + val decrypted = + crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) //TODO JS pull returns a tag and a message!!! + decrypted.hexColumsPrint() + decrypted.contentEquals(message) + } } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 1934eb9..6694723 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -50,7 +50,7 @@ interface JsSodiumInterface { //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : Uint8Array //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt index 9cecbbd..ec40078 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsUtil.kt @@ -15,6 +15,9 @@ fun UByteArray.toUInt8Array() : Uint8Array { fun Uint8Array.toUByteArray() : UByteArray { + if (length.asDynamic() == undefined) { + println("Error") + } val result = UByteArray(length) for (i in 0 until length) { result[i] = get(i).toUByte() diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index bd65e56..cb820c3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -63,23 +63,24 @@ actual class Crypto internal actual constructor() { * Initialize a state and generate a random header. Both are returned inside * `SecretStreamStateAndHeader` object. */ - actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): dynamic { + actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): + SecretStreamStateAndHeader { println("Debug crypto_secretstream_xchacha20poly1305_init_push") val stateAndHeader = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) val state = stateAndHeader.state val header = (stateAndHeader.header as Uint8Array).toUByteArray() - return SecretStreamStateAndHeader(state, header) + return SecretStreamStateAndHeader(state, header) } /** * Initialize state from header and key. The state can then be used for decryption. */ actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): - dynamic { + SecretStreamState { println("Debug crypto_secretstream_xchacha20poly1305_init_pull") return getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), - key.toUInt8Array()) + key.toUInt8Array()) as SecretStreamState } /** From be4468785d8102bda936ee119916ceeb7f574a7f Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 21 Aug 2020 18:55:17 +0200 Subject: [PATCH 08/65] Slow progress. --- .../LibsodiumSecretStreamDefinitions.kt | 27 ++++++++- .../generator/CommonLibsodiumGenerator.kt | 8 +-- .../generator/JvmLibsodiumGenerator.kt | 50 +++++++++++------ .../generator/NativeLibsodiumGenerator.kt | 56 +++++++++++++------ .../commonMain/kotlin/debug/test/DebugTest.kt | 9 ++- .../crypto/secretstream/SecretStreamTest.kt | 2 +- .../src/jsMain/kotlin/debug/test/DebugTest.kt | 10 ++-- .../jvmMain/kotlin/debug/test/DebugTest.kt | 7 ++- .../nativeMain/kotlin/debug/test/DebugTest.kt | 7 ++- 9 files changed, 122 insertions(+), 54 deletions(-) diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt index 76d7037..7e452bf 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt @@ -28,6 +28,27 @@ fun ClassDefinition.defineSecretStreamFunctions() { ) ) + + +dataClassDef( + "DecryptedDataAndTag", + """ + This data class wraps the decrypted data and tag returned when decrypting + """.trimIndent(), + listOf( + ParameterDefinition( + parameterName = "decrypted", + parameterType = TypeDefinition.ARRAY_OF_UBYTES + ), + ParameterDefinition( + parameterName = "tag", + parameterType = TypeDefinition.UBYTE + ) + + ) + + ) + + val jsSecretStreamInit = CodeBlockDefinition( """ val stateAndHeader = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) @@ -148,7 +169,7 @@ fun ClassDefinition.defineSecretStreamFunctions() { codeDocumentation = """ Decrypt next block of data using the previously initialized state. Returns decrypted block. """.trimIndent(), - returnType = TypeDefinition.ARRAY_OF_UBYTES + returnType = CustomTypeDefinition(withPackageName("DecryptedDataAndTag")) ) { +ParameterDefinition( "state", @@ -167,7 +188,9 @@ fun ClassDefinition.defineSecretStreamFunctions() { ) +ParameterDefinition( "tag_p", - TypeDefinition.NULL + TypeDefinition.UBYTE, + dropParameterFromDefinition = true, + isActuallyAnOutputParam = true ) +ParameterDefinition( "c", diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt index 9027f38..53b5eed 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt @@ -53,7 +53,7 @@ object CommonLibsodiumGenerator { fun createCommonMethodSpec(methodDefinition: FunctionDefinition): FunSpec.Builder { val methodBuilder = FunSpec.builder(methodDefinition.name) - var actualReturnType : TypeName = Any::class.asTypeName() + val actualReturnTypes = mutableListOf() var actualReturnTypeFound : Boolean = false for (paramDefinition in methodDefinition.parameterList) { if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.dropParameterFromDefinition.not()) { @@ -65,11 +65,11 @@ object CommonLibsodiumGenerator { } if (paramDefinition.isActuallyAnOutputParam) { actualReturnTypeFound = true - actualReturnType = paramDefinition.parameterType.typeName + actualReturnTypes += paramDefinition.parameterType.typeName } } - if (actualReturnTypeFound) { - methodBuilder.returns(actualReturnType) + if (actualReturnTypeFound && actualReturnTypes.size == 1) { + methodBuilder.returns(actualReturnTypes[0]) } else { methodBuilder.returns(methodDefinition.returnType.typeName) } diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt index 0096f83..10ddb0c 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt @@ -8,6 +8,7 @@ import com.squareup.kotlinpoet.FunSpec import com.squareup.kotlinpoet.ParameterSpec import com.squareup.kotlinpoet.PropertySpec import com.squareup.kotlinpoet.TypeAliasSpec +import com.squareup.kotlinpoet.TypeName /** * Created by Ugljesa Jovanovic @@ -56,7 +57,7 @@ object JvmLibsodiumGenerator { methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false var returnModifierValue = "" - lateinit var actualReturnParameterDefinition: ParameterDefinition + val actualReturnTypes = mutableListOf() var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) { @@ -89,14 +90,14 @@ object JvmLibsodiumGenerator { } } if (paramDefinition.isActuallyAnOutputParam) { - actualReturnParameterDefinition = paramDefinition + actualReturnTypes += paramDefinition actualReturnTypeFound = true } } if (actualReturnTypeFound) { if (returnModifierFound) { createOutputParam( - actualReturnParameterDefinition, + actualReturnTypes, returnModifierValue, methodBuilder ) @@ -105,7 +106,7 @@ object JvmLibsodiumGenerator { throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") } createOutputParam( - actualReturnParameterDefinition, + actualReturnTypes, methodDefinition.outputLengthWhenArray.toString(), methodBuilder ) @@ -125,10 +126,18 @@ object JvmLibsodiumGenerator { methodBuilder.addStatement(constructJvmCall.toString()) methodBuilder.addStatement("return state") } else if (actualReturnTypeFound) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return ${actualReturnParameterDefinition.parameterName}") + if (actualReturnTypes.size == 1) { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement("return ${actualReturnTypes[0].parameterName}") + } else { + constructJvmCall.append("sodium.${methodDefinition.nativeName}") + constructJvmCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructJvmCall.toString()) + methodBuilder.addStatement( + "return ${methodDefinition.returnType.typeName}(${createTupleOutputParams(actualReturnTypes)})") + } } else { when (methodDefinition.returnType) { TypeDefinition.ARRAY_OF_UBYTES -> { @@ -161,24 +170,31 @@ object JvmLibsodiumGenerator { return methodBuilder } - fun createOutputParam(outputParam: ParameterDefinition, length: String?, methodBuilder: FunSpec.Builder) { + fun createOutputParam(outputParams: List, length: String?, methodBuilder: FunSpec.Builder) { /* val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES) sodium.crypto_hash_sha256_final(state, hashed) return hashed.asUByteArray() */ - when (outputParam.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") + for (outputParam in outputParams) { + when (outputParam.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") + } + TypeDefinition.UBYTE -> { + methodBuilder.addStatement("var ${outputParam.parameterName} : UByte = 0U") + } + else -> { + throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") + } } - else -> { - throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") - } - - } } + fun createTupleOutputParams(outputParams: List) : String { + return outputParams.map { it.parameterName }.joinToString (separator = ", ") + } + fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) { /* val state = Hash.State256() diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt index 14b9d0e..629db0e 100644 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt @@ -71,7 +71,7 @@ object NativeLibsodiumGenerator { methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList var returnModifierFound = false var returnModifierValue = "" - lateinit var actualReturnParameterDefinition: ParameterDefinition + val actualReturnTypes = mutableListOf() var actualReturnTypeFound: Boolean = false for (paramDefinition in methodDefinition.parameterList) { if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) { @@ -104,18 +104,18 @@ object NativeLibsodiumGenerator { } if (paramDefinition.isActuallyAnOutputParam) { - actualReturnParameterDefinition = paramDefinition + actualReturnTypes += paramDefinition actualReturnTypeFound = true } } if (actualReturnTypeFound) { if (returnModifierFound) { - createOutputParam(actualReturnParameterDefinition, returnModifierValue, methodBuilder) + createOutputParam(actualReturnTypes, returnModifierValue, methodBuilder) } else { if (methodDefinition.outputLengthWhenArray == -1) { throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") } - createOutputParam(actualReturnParameterDefinition, methodDefinition.outputLengthWhenArray.toString(), methodBuilder) + createOutputParam(actualReturnTypes, methodDefinition.outputLengthWhenArray.toString(), methodBuilder) } } methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") @@ -134,11 +134,24 @@ object NativeLibsodiumGenerator { unpinParams(methodDefinition, methodBuilder) methodBuilder.addStatement("return state") } else if (actualReturnTypeFound) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return ${actualReturnParameterDefinition.parameterName}") + if (actualReturnTypes.size == 1) { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement("return ${actualReturnTypes[0].parameterName}") + } else { + constructNativeCall.append("libsodium.${methodDefinition.nativeName}") + constructNativeCall.append(paramsToString(methodDefinition)) + methodBuilder.addStatement(constructNativeCall.toString()) + unpinParams(methodDefinition, methodBuilder) + methodBuilder.addStatement( + "return ${methodDefinition.returnType.typeName}(${ + JvmLibsodiumGenerator.createTupleOutputParams( + actualReturnTypes + ) + })") + } } else { when (methodDefinition.returnType) { TypeDefinition.ARRAY_OF_UBYTES -> { @@ -188,7 +201,7 @@ object NativeLibsodiumGenerator { methodBuilder.addStatement("val state = allocated.reinterpret<${stateParameterDefinition.parameterType.typeName}>().pointed") } - fun createOutputParam(outputParam: ParameterDefinition, length: String?, methodBuilder: FunSpec.Builder) { + fun createOutputParam(outputParams: List, length: String?, methodBuilder: FunSpec.Builder) { /* val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() @@ -196,18 +209,25 @@ object NativeLibsodiumGenerator { sodium_free(state.ptr) return hashResult */ - when (outputParam.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") + for (outputParam in outputParams) { + when (outputParam.parameterType) { + TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { + methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") + } + TypeDefinition.UBYTE -> { + methodBuilder.addStatement("var ${outputParam.parameterName} : UByte = 0U") + } + else -> { + throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") + } } - else -> { - throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") - } - - } } + fun createTupleOutputParams(outputParams: List) : String { + return outputParams.map { it.parameterName }.joinToString (separator = ", ") + } + fun pinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) { methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> if (paramDefinition.parameterType is TypeDefinition) { diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index d1acc23..763ea38 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -20,6 +20,13 @@ data class SecretStreamStateAndHeader( val header: UByteArray ) +data class DecryptedDataAndTag( + @JsName("decrypted") + val decrypted: UByteArray, + @JsName("tag") + val tag: UByte +) + expect class Crypto internal constructor() { /** * Initialize the SHA256 hash @@ -68,5 +75,5 @@ expect class Crypto internal constructor() { state: SecretStreamState, c: UByteArray, ad: UByteArray - ): UByteArray + ): DecryptedDataAndTag } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index c9e3cf4..e477f41 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -65,7 +65,7 @@ class SecretStreamTest { encrypted.hexColumsPrint() val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) val decrypted = - crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) //TODO JS pull returns a tag and a message!!! + crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) decrypted.hexColumsPrint() decrypted.contentEquals(message) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index cb820c3..2c462b6 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -70,17 +70,17 @@ actual class Crypto internal actual constructor() { getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) val state = stateAndHeader.state val header = (stateAndHeader.header as Uint8Array).toUByteArray() - return SecretStreamStateAndHeader(state, header) + return SecretStreamStateAndHeader(state, header) } /** * Initialize state from header and key. The state can then be used for decryption. */ actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): - SecretStreamState { + dynamic { println("Debug crypto_secretstream_xchacha20poly1305_init_pull") return getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), - key.toUInt8Array()) as SecretStreamState + key.toUInt8Array()) } /** @@ -104,9 +104,9 @@ actual class Crypto internal actual constructor() { state: SecretStreamState, c: UByteArray, ad: UByteArray - ): UByteArray { + ): UByte { println("Debug crypto_secretstream_xchacha20poly1305_pull") return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(), - ad.toUInt8Array()).toUByteArray() + ad.toUInt8Array()) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index b2b3082..17529ec 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -117,11 +117,12 @@ actual class Crypto internal actual constructor() { state: SecretStreamState, c: UByteArray, ad: UByteArray - ): UByteArray { + ): DecryptedDataAndTag { val m = UByteArray(c.size - 17) + var tag_p : UByte = 0U println("Debug crypto_secretstream_xchacha20poly1305_pull") - sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, null, + sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, tag_p.toByte(), c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) - return m + return debug.test.DecryptedDataAndTag(m, tag_p) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 7bb9657..52cc5fa 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -162,17 +162,18 @@ actual class Crypto internal actual constructor() { state: SecretStreamState, c: UByteArray, ad: UByteArray - ): UByteArray { + ): DecryptedDataAndTag { val m = UByteArray(c.size - 17) + var tag_p : UByte = 0U println("Debug crypto_secretstream_xchacha20poly1305_pull") val pinnedM = m.pin() val pinnedC = c.pin() val pinnedAd = ad.pin() libsodium.crypto_secretstream_xchacha20poly1305_pull(state.ptr, pinnedM.addressOf(0), null, - null, pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) + tag_p, pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) pinnedM.unpin() pinnedC.unpin() pinnedAd.unpin() - return m + return debug.test.DecryptedDataAndTag(m, tag_p) } } From 6a6119dec19160833d83b8191399fa6ba1886914 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 21 Aug 2020 18:57:20 +0200 Subject: [PATCH 09/65] Abandon generator approach --- .../build.gradle.kts | 36 -- .../kotlin/crypto/generator/Launcher.kt | 13 - .../generator/libsodium/CInteropParser.kt | 10 - .../libsodium/definitions/DefinitionTypes.kt | 247 ------------- .../definitions/LibsodiumDefinitions.kt | 16 - .../LibsodiumGenericHashDefinitions.kt | 38 -- .../definitions/LibsodiumHashDefinitions.kt | 84 ----- .../LibsodiumSecretStreamDefinitions.kt | 210 ----------- .../generator/CommonLibsodiumGenerator.kt | 93 ----- .../libsodium/generator/Coordinator.kt | 31 -- .../generator/JsLibsodiumGenerator.kt | 198 ----------- .../generator/JvmLibsodiumGenerator.kt | 254 ------------- .../generator/NativeLibsodiumGenerator.kt | 334 ------------------ .../libsodium/generator/SharedCreators.kt | 69 ---- .../cinteropDecompiled/0_libsodium.dknm | 101 ------ .../cinteropDecompiled/1_libsodium.dknm | 261 -------------- .../cinteropDecompiled/2_libsodium.dknm | 261 -------------- .../cinteropDecompiled/3_libsodium.dknm | 261 -------------- .../cinteropDecompiled/4_libsodium.dknm | 261 -------------- .../cinteropDecompiled/5_libsodium.dknm | 261 -------------- .../cinteropDecompiled/6_libsodium.dknm | 261 -------------- .../cinteropDecompiled/7_libsodium.dknm | 261 -------------- .../cinteropDecompiled/8_libsodium.dknm | 145 -------- .../kotlin/crypto/generator/DebugTest.kt | 15 - settings.gradle.kts | 1 - 25 files changed, 3722 deletions(-) delete mode 100644 kotlin-multiplatform-libsodium-generator/build.gradle.kts delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm delete mode 100644 kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt diff --git a/kotlin-multiplatform-libsodium-generator/build.gradle.kts b/kotlin-multiplatform-libsodium-generator/build.gradle.kts deleted file mode 100644 index 934c736..0000000 --- a/kotlin-multiplatform-libsodium-generator/build.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -plugins { - kotlin -} - -group = "com.ionspin.kotlin.crypto" -version = "0.0.1" - -repositories { - mavenCentral() - google() - maven ("https://kotlin.bintray.com/kotlinx") - maven ("https://dl.bintray.com/kotlin/kotlin-eap") - maven ("https://dl.bintray.com/kotlin/kotlin-dev") - jcenter() - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - } -} - -dependencies { - implementation (kotlin(Deps.Jvm.stdLib)) - implementation("com.squareup:kotlinpoet:1.6.0") - testImplementation(kotlin(Deps.Jvm.test)) - testImplementation(kotlin(Deps.Jvm.testJUnit)) -} - -tasks.withType().all { - kotlinOptions.freeCompilerArgs += listOf( - "-Xuse-experimental=kotlin.ExperimentalUnsignedTypes" - ) -} - - - - - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt deleted file mode 100644 index f20abfc..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/Launcher.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.ionspin.kotlin.crypto.generator - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 18-Jul-2020 - */ -object Launcher { - @JvmStatic - fun main(args : Array) { - println("Ok") - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt deleted file mode 100644 index 9bcf7ff..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/CInteropParser.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 18-Jul-2020 - */ -class CInteropParser { - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt deleted file mode 100644 index 94c730d..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/DefinitionTypes.kt +++ /dev/null @@ -1,247 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.TypeName -import com.squareup.kotlinpoet.asTypeName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 28-Jul-2020 - */ - -val packageName = "debug.test" - -fun withPackageName(name: String) = ClassName(packageName, name) - -class KotlinFileDefinition( - val name: String, - val commonClassList: MutableList = mutableListOf() -) { - operator fun ClassDefinition.unaryPlus() { - commonClassList.add(this) - } -} - -class ClassDefinition( - val name: String, - val codeDocumentation: String = "", - val innerClasses: MutableList = mutableListOf(), - val methods: MutableList = mutableListOf(), - val dataClasses: MutableList = mutableListOf() -) { - operator fun InnerClassDefinition.unaryPlus() { - innerClasses.add(this) - } - - operator fun FunctionDefinition.unaryPlus() { - methods.add(this) - } - - operator fun DataClassDefinition.unaryPlus() { - dataClasses.add(this) - } - - operator fun List.unaryPlus() { - methods.addAll(this) - } -} - -class InnerClassDefinition( - val name: String, - val javaName: String, - val jsName: String, - val nativeName: String, - val codeDocumentation: String = "", - val functions: MutableList = mutableListOf() -) - -class DataClassDefinition( - val name: String, - val codeDocumentation: String = "", - val parameters : List -) - -/** - * outputLengthWhenArray - if output is an a array and there is no parameter that modifies output length we need - * to tell the function what to expect (think SHA256 32byte output always, and Blake2 dynamic output controlled - * by outputLen parameter) - */ -class FunctionDefinition( - val name: String, - val javaName: String, - val jsName: String, - val nativeName: String, - val codeDocumentation: String = "", - val parameterList: MutableList = mutableListOf(), - val returnType: GeneralTypeDefinition, - val dynamicJsReturn: Boolean = false, - val isStateCreationFunction: Boolean = false, - val outputLengthWhenArray: Int = -1, - val customCodeBlockReplacesFunctionBody: List? = null -) { - operator fun ParameterDefinition.unaryPlus() { - parameterList.add(this) - } -} - -/** - * - * isActuallyAnOutputParam - drop this parameter from the generated param list and provide it as output. Param - * will be automatically generated inside function body block - * isStateType - provides special handling when type is a non-primitive state type - * dropParameterFromDefinition - don't show this parameter in method definition - */ -class ParameterDefinition( - val parameterName: String, - val parameterType: GeneralTypeDefinition, - val modifiesReturnObjectSize: Boolean = false, - val specificReturnModification : String? = null, - val isActuallyAnOutputParam: Boolean = false, - val isStateType: Boolean = false, - val dropParameterFromDefinition: Boolean = false, - val specificJvmInitializer: String? = null, -) - -class CodeBlockDefinition( - val codeBlock: String, - val applyOnTargets: Set = setOf( - TargetPlatform.COMMON, - TargetPlatform.JVM, - TargetPlatform.JS, - TargetPlatform.NATIVE - ) -) - -interface GeneralTypeDefinition { - val typeName: TypeName -} - -data class CustomTypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition - -enum class TypeDefinition(override val typeName: TypeName) : GeneralTypeDefinition { - ARRAY_OF_UBYTES(UByteArray::class.asTypeName()), - ARRAY_OF_UBYTES_LONG_SIZE(UByteArray::class.asTypeName()), - ARRAY_OF_UBYTES_NO_SIZE(UByteArray::class.asTypeName()), - LONG(Long::class.asTypeName()), - INT(Int::class.asTypeName()), - STRING(String::class.asTypeName()), - UNIT(Unit::class.asTypeName()), - UBYTE(UByte::class.asTypeName()), - IRRELEVANT(Unit::class.asTypeName()), - NULL(Unit::class.asTypeName()) -} - -enum class TargetPlatform { - JVM, NATIVE, JS, COMMON -} - -fun fileDef(name: String, body: KotlinFileDefinition.() -> Unit): KotlinFileDefinition { - val commonKotlinFileInstance = KotlinFileDefinition(name) - commonKotlinFileInstance.body() - return commonKotlinFileInstance -} - - -fun classDef(name: String, codeDocumentation: String = "", body: ClassDefinition.() -> Unit): ClassDefinition { - val commonClass = ClassDefinition(name, codeDocumentation) - commonClass.body() - return commonClass -} - -fun dataClassDef(name : String, codeDocumentation: String = "", parameters: List) : DataClassDefinition { - return DataClassDefinition(name, codeDocumentation, parameters) -} - -fun codeBlock( - codeBlock: String, - applyOnTargets: Set = setOf( - TargetPlatform.COMMON, - TargetPlatform.JVM, - TargetPlatform.JS, - TargetPlatform.NATIVE - ) -): CodeBlockDefinition { - val codeBlockDefinition = CodeBlockDefinition(codeBlock, applyOnTargets) - return codeBlockDefinition - -} - -fun innerClassDef( - name: String, - javaName: String, - jsName: String, - nativeName: String, - codeDocumentation: String = "", - specificConstructor: String? = null, - body: InnerClassDefinition.() -> Unit = {} -): InnerClassDefinition { - val genClass = InnerClassDefinition( - name, - javaName, - jsName, - nativeName, - codeDocumentation - ) - genClass.body() - return genClass -} - -fun funcDef( - name: String, - javaName: String, - jsName: String, - nativeName: String, - codeDocumentation: String = "", - returnType: GeneralTypeDefinition, - dynamicJsReturn: Boolean = false, - isStateCreationFunction: Boolean = false, - outputLengthWhenArray: Int = -1, - customCodeBlockReplacesFunctionBody: List? = null, - body: FunctionDefinition.() -> Unit -): FunctionDefinition { - val function = FunctionDefinition( - name, - javaName, - jsName, - nativeName, - codeDocumentation = codeDocumentation, - returnType = returnType, - dynamicJsReturn = dynamicJsReturn, - isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray, - customCodeBlockReplacesFunctionBody = customCodeBlockReplacesFunctionBody - ) - function.body() - return function -} - -fun funcDef( - name: String, - codeDocumentation: String = "", - returnType: GeneralTypeDefinition, - dynamicJsReturn: Boolean = false, - isStateCreationFunction: Boolean = false, - outputLengthWhenArray: Int = -1, - customCodeBlockReplacesFunctionBody: List? = null, - body: FunctionDefinition.() -> Unit -): FunctionDefinition { - val function = - FunctionDefinition( - name, - name, - name, - name, - codeDocumentation, - returnType = returnType, - dynamicJsReturn = dynamicJsReturn, - isStateCreationFunction = isStateCreationFunction, - outputLengthWhenArray = outputLengthWhenArray, - customCodeBlockReplacesFunctionBody = customCodeBlockReplacesFunctionBody - ) - function.body() - return function -} - - - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt deleted file mode 100644 index 54d4fc0..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumDefinitions.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 01-Aug-2020 - */ -object LibSodiumDefinitions { - val testKotlinFile = fileDef("DebugTest") { - +classDef("Crypto") { - defineHashFunctions() - defineGenericHashFunctions() - defineSecretStreamFunctions() - } - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt deleted file mode 100644 index 9ce1678..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumGenericHashDefinitions.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -import com.squareup.kotlinpoet.ClassName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 04-Aug-2020 - */ -fun ClassDefinition.defineGenericHashFunctions() { - /* - * ------------- GENERIC HASH (BLAKE2B) - */ - - +innerClassDef( - "GenericHashState", - "kotlin.ByteArray", - "Uint8Array", - "crypto_generichash_blake2b_state" - ) - - +funcDef( - "crypto_generichash_init", - returnType = CustomTypeDefinition(ClassName(packageName, "GenericHashState")), - dynamicJsReturn = true, - isStateCreationFunction = true - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("GenericHashState"))), - isStateType = true, - dropParameterFromDefinition = true, - specificJvmInitializer = "sodium.crypto_generichash_statebytes()" - ) - +ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES) - +ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturnObjectSize = true) - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt deleted file mode 100644 index 531994e..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumHashDefinitions.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -import com.squareup.kotlinpoet.ClassName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 04-Aug-2020 - */ -fun ClassDefinition.defineHashFunctions() { - /* - --------------- SHA256 - */ - +innerClassDef( - "Sha256State", - "com.goterl.lazycode.lazysodium.interfaces.Hash.State256", - "Sha256State", - "crypto_hash_sha256_state" - ) - +funcDef( - "crypto_hash_sha256_init", - codeDocumentation = """ - Initialize the SHA256 hash - returns sha 256 state - """.trimIndent(), - returnType = CustomTypeDefinition(ClassName(packageName, "Sha256State")), - dynamicJsReturn = true, - isStateCreationFunction = true - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("Sha256State"))), - dropParameterFromDefinition = true, - isStateType = true - ) - } - - +funcDef("crypto_hash_sha256_update", returnType = TypeDefinition.UNIT) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("Sha256State"))), - isStateType = true - ) - +ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE) - } - - +funcDef("crypto_hash_sha256_final", returnType = TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 32) { - +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha256State")))) - +ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true) - } - - /* - --------------- SHA512 - */ - +innerClassDef( - "Sha512State", - "com.goterl.lazycode.lazysodium.interfaces.Hash.State512", - "Sha512State", - "crypto_hash_sha512_state" - ) - +funcDef( - "crypto_hash_sha512_init", - returnType = CustomTypeDefinition(ClassName(packageName, "Sha512State")), - dynamicJsReturn = true, - isStateCreationFunction = true - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition((withPackageName("Sha512State"))), - dropParameterFromDefinition = true, - isStateType = true - ) - } - - +funcDef("crypto_hash_sha512_update", returnType = TypeDefinition.UNIT) { - +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State")))) - +ParameterDefinition("input", TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE) - } - - +funcDef("crypto_hash_sha512_final", returnType = TypeDefinition.ARRAY_OF_UBYTES, outputLengthWhenArray = 64) { - +ParameterDefinition("state", CustomTypeDefinition((withPackageName("Sha512State")))) - +ParameterDefinition("out", TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, isActuallyAnOutputParam = true, dropParameterFromDefinition = true) - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt deleted file mode 100644 index 7e452bf..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/definitions/LibsodiumSecretStreamDefinitions.kt +++ /dev/null @@ -1,210 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.definitions - -/** - * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Aug/2020 - */ -fun ClassDefinition.defineSecretStreamFunctions() { - +innerClassDef( - "SecretStreamState", - "com.goterl.lazycode.lazysodium.interfaces.SecretStream.State", - "SecretStreamState", - "crypto_secretstream_xchacha20poly1305_state" - ) - +dataClassDef( - "SecretStreamStateAndHeader", - """ - This data class wraps the state and header objects returned when initializing secret stream encryption - """.trimIndent(), - listOf( - ParameterDefinition( - parameterName = "state", - parameterType = CustomTypeDefinition(withPackageName("SecretStreamState")) - ), - ParameterDefinition( - parameterName = "header", - parameterType = TypeDefinition.ARRAY_OF_UBYTES - ) - - ) - - ) - - +dataClassDef( - "DecryptedDataAndTag", - """ - This data class wraps the decrypted data and tag returned when decrypting - """.trimIndent(), - listOf( - ParameterDefinition( - parameterName = "decrypted", - parameterType = TypeDefinition.ARRAY_OF_UBYTES - ), - ParameterDefinition( - parameterName = "tag", - parameterType = TypeDefinition.UBYTE - ) - - ) - - ) - - - val jsSecretStreamInit = CodeBlockDefinition( - """ - val stateAndHeader = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) - val state = stateAndHeader.state - val header = (stateAndHeader.header as Uint8Array).toUByteArray() - return SecretStreamStateAndHeader(state, header) - """.trimIndent(), - setOf(TargetPlatform.JS) - ) - - val jvmSecretStreamInit = CodeBlockDefinition( - """ - val header = UByteArray(24) - val state = SecretStream.State() - sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) - return SecretStreamStateAndHeader(state, header) - """.trimIndent(), - setOf(TargetPlatform.JVM) - ) - - val nativeSecretStreamInit = CodeBlockDefinition( - """ - val pinnedKey = key.pin() - val state = sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! - .reinterpret() - .pointed - val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) { 0U } - val pinnedHeader = header.pin() - libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), pinnedKey.addressOf(0)) - pinnedHeader.unpin() - pinnedKey.unpin() - return SecretStreamStateAndHeader(state, header) - """.trimIndent(), - setOf(TargetPlatform.NATIVE) - ) - +funcDef( - "crypto_secretstream_xchacha20poly1305_init_push", - codeDocumentation = """ - Initialize a state and generate a random header. Both are returned inside `SecretStreamStateAndHeader` object. - """.trimIndent(), - returnType = CustomTypeDefinition(withPackageName("SecretStreamStateAndHeader")), - dynamicJsReturn = false, - isStateCreationFunction = true, - customCodeBlockReplacesFunctionBody = listOf(jsSecretStreamInit, jvmSecretStreamInit, nativeSecretStreamInit) - ) { - +ParameterDefinition( - "key", - parameterType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE - ) - } - - - +funcDef( - "crypto_secretstream_xchacha20poly1305_init_pull", - codeDocumentation = """ - Initialize state from header and key. The state can then be used for decryption. - """.trimIndent(), - returnType = CustomTypeDefinition(withPackageName("SecretStreamState")), - dynamicJsReturn = true, - isStateCreationFunction = true, - ) { - +ParameterDefinition( - "state", - parameterType = CustomTypeDefinition(withPackageName("SecretStreamState")), - dropParameterFromDefinition = true, - isStateType = true - ) - +ParameterDefinition( - "header", - parameterType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE - ) - +ParameterDefinition( - "key", - parameterType = TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE - ) - } - - +funcDef( - name = "crypto_secretstream_xchacha20poly1305_push", - codeDocumentation = """ - Encrypt next block of data using the previously initialized state. Returns encrypted block. - """.trimIndent(), - returnType = TypeDefinition.ARRAY_OF_UBYTES - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition(withPackageName("SecretStreamState")) - ) - +ParameterDefinition( - "c", - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, - isActuallyAnOutputParam = true, - dropParameterFromDefinition = true - ) - +ParameterDefinition( - "clen", - TypeDefinition.NULL, - dropParameterFromDefinition = true - ) - +ParameterDefinition( - "m", - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, - modifiesReturnObjectSize = true, - specificReturnModification = "m.size + 17" - ) - +ParameterDefinition( - "ad", - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE - ) - +ParameterDefinition( - "tag", - TypeDefinition.UBYTE - ) - } - - +funcDef( - name = "crypto_secretstream_xchacha20poly1305_pull", - codeDocumentation = """ - Decrypt next block of data using the previously initialized state. Returns decrypted block. - """.trimIndent(), - returnType = CustomTypeDefinition(withPackageName("DecryptedDataAndTag")) - ) { - +ParameterDefinition( - "state", - CustomTypeDefinition(withPackageName("SecretStreamState")) - ) - +ParameterDefinition( - "m", - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, - isActuallyAnOutputParam = true, - dropParameterFromDefinition = true - ) - +ParameterDefinition( - "mlen", - TypeDefinition.NULL, - dropParameterFromDefinition = true - ) - +ParameterDefinition( - "tag_p", - TypeDefinition.UBYTE, - dropParameterFromDefinition = true, - isActuallyAnOutputParam = true - ) - +ParameterDefinition( - "c", - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, - modifiesReturnObjectSize = true, - specificReturnModification = "c.size - 17" - ) - +ParameterDefinition( - "ad", - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE - ) - - } - - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt deleted file mode 100644 index 53b5eed..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/CommonLibsodiumGenerator.kt +++ /dev/null @@ -1,93 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.KotlinFileDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.TypeDefinition -import com.squareup.kotlinpoet.* - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ - -enum class MultiplatformModifier(val modifierList: List) { - EXPECT(listOf(KModifier.EXPECT)), - ACTUAL(listOf(KModifier.ACTUAL)), - NONE(listOf()) -} - -object CommonLibsodiumGenerator { - - fun createCommonFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create expected inner classes that will be represented by type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addType(createCommonInnerClassSpec(it, MultiplatformModifier.EXPECT)) - } - val commonClassSpec = - createClass( - fileBuilder, - commonClassDefinition, - MultiplatformModifier.EXPECT, - ::createCommonMethodSpec - ) - fileBuilder.addType(commonClassSpec.build()) - } - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - fun createCommonInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeSpec { - val innerClassBuilder = TypeSpec.classBuilder(innerClassDefinition.name) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createCommonMethodSpec(methodDefinition: FunctionDefinition): FunSpec.Builder { - val methodBuilder = FunSpec.builder(methodDefinition.name) - val actualReturnTypes = mutableListOf() - var actualReturnTypeFound : Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.dropParameterFromDefinition.not()) { - if (paramDefinition.parameterType != TypeDefinition.NULL) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnTypeFound = true - actualReturnTypes += paramDefinition.parameterType.typeName - } - } - if (actualReturnTypeFound && actualReturnTypes.size == 1) { - methodBuilder.returns(actualReturnTypes[0]) - } else { - methodBuilder.returns(methodDefinition.returnType.typeName) - } - return methodBuilder - } - -} - - - - - - - - - - - - - - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt deleted file mode 100644 index 946b03f..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/Coordinator.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.LibSodiumDefinitions -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.packageName -import java.io.File - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object Coordinator { - @JvmStatic - fun main(args : Array) { - - val commonFileSpec = CommonLibsodiumGenerator.createCommonFile(packageName, LibSodiumDefinitions.testKotlinFile) - val jvmFileSpec = JvmLibsodiumGenerator.createJvmFile(packageName, LibSodiumDefinitions.testKotlinFile) - val nativeFileSpec = NativeLibsodiumGenerator.createNativeFile(packageName, LibSodiumDefinitions.testKotlinFile) - val jsFileSpec = JsLibsodiumGenerator.createJsFile(packageName, LibSodiumDefinitions.testKotlinFile) - - val commonFile = File("multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/") - commonFileSpec.writeTo(commonFile) - val jvmFile = File("multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/") - jvmFileSpec.writeTo(jvmFile) - val nativeFile = File("multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/") - nativeFileSpec.writeTo(nativeFile) - val jsFile = File("multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/") - jsFileSpec.writeTo(jsFile) - - } -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt deleted file mode 100644 index fea8ca8..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JsLibsodiumGenerator.kt +++ /dev/null @@ -1,198 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* -import com.squareup.kotlinpoet.* - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object JsLibsodiumGenerator { - - val jsInterfaceFunctionDefinitions : MutableList = mutableListOf() - - - fun createJsFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUInt8Array") - fileBuilder.addImport("ext.libsodium.com.ionspin.kotlin.crypto", "toUByteArray") - fileBuilder.addImport("com.ionspin.kotlin.crypto", "getSodium") - fileBuilder.addImport("org.khronos.webgl", "Uint8Array") - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addTypeAlias(createJsInnerClassSpec(it, MultiplatformModifier.ACTUAL)) - } - - val commonClassSpec = createClass( - fileBuilder, - commonClassDefinition, - MultiplatformModifier.ACTUAL, - ::createJsFunctionImplementation - ) - fileBuilder.addType(commonClassSpec.build()) - } - createJsInterfaceFile() - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - // This helps with static typing in js target - fun createJsInterfaceFile() { - val fileBuilder = FileSpec.builder(packageName, "JsSodiumInterfaceDebug") - val jsInterface = TypeSpec.interfaceBuilder("JsSodiumInterfaceDebug") - jsInterface.addFunctions(jsInterfaceFunctionDefinitions) - fileBuilder.addType(jsInterface.build()) - val file = fileBuilder.build() - file.writeTo(System.out) - } - - fun createJsInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeAliasSpec { - val innerClassBuilder = TypeAliasSpec.builder(innerClassDefinition.name, Any::class.asTypeName()) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createJsFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec.Builder { - val methodBuilder = FunSpec.builder(methodDefinition.name) - - var returnModifierFound = false - var returnModifierValue = "" - var actualReturnType: TypeName = DYNAMIC - var actualReturnTypeFound: Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - if (paramDefinition.parameterType != TypeDefinition.NULL) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - } - if (paramDefinition.modifiesReturnObjectSize) { - if (returnModifierFound == true) { - throw RuntimeException("Return modifier already found") - } - returnModifierFound = true - if (paramDefinition.specificReturnModification == null) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierValue = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierValue = paramDefinition.parameterName - } - } - } else { - returnModifierValue = paramDefinition.specificReturnModification!! - } - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnTypeFound = true - actualReturnType = paramDefinition.parameterType.typeName - } - } - if (actualReturnTypeFound) { - methodBuilder.returns(actualReturnType) - } else if (methodDefinition.dynamicJsReturn) { - methodBuilder.returns(Dynamic) - } else { - methodBuilder.returns(methodDefinition.returnType.typeName) - } - //Create a spec for interface - methodBuilder.addModifiers(KModifier.ABSTRACT) - jsInterfaceFunctionDefinitions.add(methodBuilder.build()) - //continue with normal func spec for implementation - methodBuilder.modifiers.clear() - methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList - methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") - val constructJsCall = StringBuilder() - if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { - for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.JS) }) { - constructJsCall.append(codeBlock.codeBlock) - } - } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition) + ".toUByteArray()") - } - TypeDefinition.INT -> { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - TypeDefinition.UNIT -> { - constructJsCall.append("getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } - is CustomTypeDefinition -> { - if (methodDefinition.parameterList.filter { it.isStateType.not() }.size > 0) { - constructJsCall.append("return getSodium().${methodDefinition.jsName}") - constructJsCall.append(paramsToString(methodDefinition)) - } else { - constructJsCall.append("val result = js(\"getSodium().${methodDefinition.jsName}()\")") - constructJsCall.append("\nreturn result") - } - } - } - } - methodBuilder.addStatement(constructJsCall.toString()) - return methodBuilder - } - - fun paramsToString(methodDefinition: FunctionDefinition): String { - val paramsBuilder = StringBuilder() - paramsBuilder.append("(") - val jsParams = methodDefinition.parameterList.filter { it.dropParameterFromDefinition.not() } - jsParams.forEachIndexed { index, paramDefinition -> - val separator = if (index == jsParams.size - 1) { - "" - } else { - ", " - } - if (paramDefinition.parameterType is CustomTypeDefinition) { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toUInt8Array()" + separator) - } - TypeDefinition.LONG -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.INT -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.STRING -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.UBYTE -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.NULL -> { - println("Got null parameter in js") -// paramsBuilder.append("null" + separator) - } - } - } - - - } - paramsBuilder.append(')') - return paramsBuilder.toString() - } - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt deleted file mode 100644 index 10ddb0c..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/JvmLibsodiumGenerator.kt +++ /dev/null @@ -1,254 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.CodeBlock -import com.squareup.kotlinpoet.FileSpec -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.ParameterSpec -import com.squareup.kotlinpoet.PropertySpec -import com.squareup.kotlinpoet.TypeAliasSpec -import com.squareup.kotlinpoet.TypeName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object JvmLibsodiumGenerator { - - - fun createJvmFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - val sodiumProperty = PropertySpec.builder("sodium", ClassName.bestGuess("com.goterl.lazycode.lazysodium.SodiumJava")) - sodiumProperty.initializer(CodeBlock.of("SodiumJava()")) - fileBuilder.addProperty(sodiumProperty.build()) - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addTypeAlias(createJvmInnerClassSpec(it, MultiplatformModifier.ACTUAL)) - } - - val commonClassSpec = createClass( - fileBuilder, - commonClassDefinition, - MultiplatformModifier.ACTUAL, - ::createJvmFunctionImplementation - ) - fileBuilder.addType(commonClassSpec.build()) - } - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - fun createJvmInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeAliasSpec { - val innerClassBuilder = TypeAliasSpec.builder(innerClassDefinition.name, ClassName.bestGuess(innerClassDefinition.javaName)) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createJvmFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec.Builder { - val methodBuilder = FunSpec.builder(methodDefinition.name) - methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList - var returnModifierFound = false - var returnModifierValue = "" - val actualReturnTypes = mutableListOf() - var actualReturnTypeFound: Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) { - createStateParam(paramDefinition, methodBuilder) - } - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - if (paramDefinition.parameterType != TypeDefinition.NULL) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - } - if (paramDefinition.modifiesReturnObjectSize) { - if (returnModifierFound == true) { - throw RuntimeException("Return modifier already found") - } - returnModifierFound = true - - if (paramDefinition.specificReturnModification == null) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierValue = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierValue = paramDefinition.parameterName - } - } - } else { - returnModifierValue = paramDefinition.specificReturnModification!! - } - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnTypes += paramDefinition - actualReturnTypeFound = true - } - } - if (actualReturnTypeFound) { - if (returnModifierFound) { - createOutputParam( - actualReturnTypes, - returnModifierValue, - methodBuilder - ) - } else { - if (methodDefinition.outputLengthWhenArray == -1) { - throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") - } - createOutputParam( - actualReturnTypes, - methodDefinition.outputLengthWhenArray.toString(), - methodBuilder - ) - } - } - methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") - val constructJvmCall = StringBuilder() - if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { - for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.JVM) }) { - constructJvmCall.append(codeBlock.codeBlock) - } - methodBuilder.addStatement(constructJvmCall.toString()) - } else { - if (methodDefinition.isStateCreationFunction) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - if (actualReturnTypes.size == 1) { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return ${actualReturnTypes[0].parameterName}") - } else { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement( - "return ${methodDefinition.returnType.typeName}(${createTupleOutputParams(actualReturnTypes)})") - } - } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructJvmCall.append("sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - } - is CustomTypeDefinition -> { - constructJvmCall.append("val result = sodium.${methodDefinition.nativeName}") - constructJvmCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructJvmCall.toString()) - methodBuilder.addStatement("return result") - } - } - } - } - methodBuilder.returns(methodDefinition.returnType.typeName) - return methodBuilder - } - - fun createOutputParam(outputParams: List, length: String?, methodBuilder: FunSpec.Builder) { - /* - val hashed = ByteArray(Sha256Properties.MAX_HASH_BYTES) - sodium.crypto_hash_sha256_final(state, hashed) - return hashed.asUByteArray() - */ - for (outputParam in outputParams) { - when (outputParam.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") - } - TypeDefinition.UBYTE -> { - methodBuilder.addStatement("var ${outputParam.parameterName} : UByte = 0U") - } - else -> { - throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") - } - } - } - } - - fun createTupleOutputParams(outputParams: List) : String { - return outputParams.map { it.parameterName }.joinToString (separator = ", ") - } - - fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) { - /* - val state = Hash.State256() - */ - val specificInitializer = stateParameterDefinition.specificJvmInitializer ?: "" - methodBuilder.addStatement("val state = ${stateParameterDefinition.parameterType.typeName}($specificInitializer)") - } - - fun paramsToString(methodDefinition: FunctionDefinition) : String { - val paramsBuilder = StringBuilder() - paramsBuilder.append("(") - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - val separator = if (index == methodDefinition.parameterList.size - 1) { - "" - } else { - ", " - } - if (paramDefinition.parameterType is CustomTypeDefinition) { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - if (paramDefinition.parameterType is TypeDefinition) { - when(paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".asByteArray(), " + paramDefinition.parameterName + ".size.toLong()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - paramsBuilder.append(paramDefinition.parameterName + ".asByteArray()" + separator) - } - TypeDefinition.LONG -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.INT -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.STRING -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.UBYTE -> { - paramsBuilder.append(paramDefinition.parameterName + ".toByte()" + separator) - } - TypeDefinition.NULL -> { - paramsBuilder.append("null" + separator) - } - } - } - - } - paramsBuilder.append(')') - return paramsBuilder.toString() - } - - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt deleted file mode 100644 index 629db0e..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/NativeLibsodiumGenerator.kt +++ /dev/null @@ -1,334 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.* -import com.squareup.kotlinpoet.ClassName -import com.squareup.kotlinpoet.CodeBlock -import com.squareup.kotlinpoet.FileSpec -import com.squareup.kotlinpoet.FunSpec -import com.squareup.kotlinpoet.ParameterSpec -import com.squareup.kotlinpoet.PropertySpec -import com.squareup.kotlinpoet.TypeAliasSpec -import com.squareup.kotlinpoet.asTypeName - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -object NativeLibsodiumGenerator { - - - fun createNativeFile(packageName: String, fileDefinition: KotlinFileDefinition): FileSpec { - val fileBuilder = FileSpec.builder(packageName, fileDefinition.name) - fileBuilder.addImport("kotlinx.cinterop", "toCValues") - fileBuilder.addImport("kotlinx.cinterop", "convert") - fileBuilder.addImport("kotlinx.cinterop", "ptr") - fileBuilder.addImport("kotlinx.cinterop", "pin") - fileBuilder.addImport("kotlinx.cinterop", "addressOf") - fileBuilder.addImport("kotlinx.cinterop", "reinterpret") - fileBuilder.addImport("kotlinx.cinterop", "pointed") - fileBuilder.addImport("libsodium", "sodium_malloc") - - for (commonClassDefinition in fileDefinition.commonClassList) { - //Create type-aliases - commonClassDefinition.innerClasses.forEach { - fileBuilder.addTypeAlias(createNativeInnerClassSpec(it, MultiplatformModifier.ACTUAL)) - } - - val commonClassSpec = createClass( - fileBuilder, - commonClassDefinition, - MultiplatformModifier.ACTUAL, - ::createNativeFunctionImplementation - ) - //Workarounds for native not emitting types - val byteEmitter = PropertySpec.builder("_emitByte", Byte::class.asTypeName()) - byteEmitter.initializer(CodeBlock.of("0")) - val byteArrayEmitter = PropertySpec.builder("_emitByteArray", ByteArray::class.asTypeName()) - byteArrayEmitter.initializer(CodeBlock.of("ByteArray(0)")) - commonClassSpec.addProperty(byteEmitter.build()) - commonClassSpec.addProperty(byteArrayEmitter.build()) - fileBuilder.addType(commonClassSpec.build()) - } - val file = fileBuilder.build() - file.writeTo(System.out) - return file - } - - fun createNativeInnerClassSpec( - innerClassDefinition: InnerClassDefinition, - multiplatformModifier: MultiplatformModifier - ): TypeAliasSpec { - val innerClassBuilder = - TypeAliasSpec.builder(innerClassDefinition.name, ClassName("libsodium", innerClassDefinition.nativeName)) - innerClassBuilder.modifiers += multiplatformModifier.modifierList - - return innerClassBuilder.build() - } - - fun createNativeFunctionImplementation(methodDefinition: FunctionDefinition): FunSpec.Builder { - val methodBuilder = FunSpec.builder(methodDefinition.name) - methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList - var returnModifierFound = false - var returnModifierValue = "" - val actualReturnTypes = mutableListOf() - var actualReturnTypeFound: Boolean = false - for (paramDefinition in methodDefinition.parameterList) { - if (paramDefinition.isStateType && methodDefinition.isStateCreationFunction) { - createStateParam(paramDefinition, methodBuilder) - } - if ((paramDefinition.isStateType.not() || methodDefinition.isStateCreationFunction.not()) && paramDefinition.isActuallyAnOutputParam.not()) { - if (paramDefinition.parameterType != TypeDefinition.NULL) { - val parameterSpec = - ParameterSpec.builder(paramDefinition.parameterName, paramDefinition.parameterType.typeName) - methodBuilder.addParameter(parameterSpec.build()) - } - } - if (paramDefinition.modifiesReturnObjectSize) { - if (returnModifierFound == true) { - throw RuntimeException("Return modifier already found") - } - returnModifierFound = true - if (paramDefinition.specificReturnModification == null) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - returnModifierValue = "${paramDefinition.parameterName}.size" - } - TypeDefinition.INT -> { - returnModifierValue = paramDefinition.parameterName - } - } - } else { - returnModifierValue = paramDefinition.specificReturnModification!! - } - - } - if (paramDefinition.isActuallyAnOutputParam) { - actualReturnTypes += paramDefinition - actualReturnTypeFound = true - } - } - if (actualReturnTypeFound) { - if (returnModifierFound) { - createOutputParam(actualReturnTypes, returnModifierValue, methodBuilder) - } else { - if (methodDefinition.outputLengthWhenArray == -1) { - throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") - } - createOutputParam(actualReturnTypes, methodDefinition.outputLengthWhenArray.toString(), methodBuilder) - } - } - methodBuilder.addStatement("println(\"Debug ${methodDefinition.name}\")") - val constructNativeCall = StringBuilder() - if (methodDefinition.customCodeBlockReplacesFunctionBody != null) { - for (codeBlock in methodDefinition.customCodeBlockReplacesFunctionBody.filter { it.applyOnTargets.contains(TargetPlatform.NATIVE) }) { - constructNativeCall.append(codeBlock.codeBlock) - methodBuilder.addStatement(constructNativeCall.toString()) - } - } else { - pinParams(methodDefinition, methodBuilder) - if (methodDefinition.isStateCreationFunction) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return state") - } else if (actualReturnTypeFound) { - if (actualReturnTypes.size == 1) { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return ${actualReturnTypes[0].parameterName}") - } else { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement( - "return ${methodDefinition.returnType.typeName}(${ - JvmLibsodiumGenerator.createTupleOutputParams( - actualReturnTypes - ) - })") - } - } else { - when (methodDefinition.returnType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.INT -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - TypeDefinition.UNIT -> { - constructNativeCall.append("libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - } - is CustomTypeDefinition -> { - constructNativeCall.append("val result = libsodium.${methodDefinition.nativeName}") - constructNativeCall.append(paramsToString(methodDefinition)) - methodBuilder.addStatement(constructNativeCall.toString()) - unpinParams(methodDefinition, methodBuilder) - methodBuilder.addStatement("return result") - } - } - - - } - } - - methodBuilder.returns(methodDefinition.returnType.typeName) - - return methodBuilder - } - - fun createStateParam(stateParameterDefinition: ParameterDefinition, methodBuilder: FunSpec.Builder) { - /* - val allocated = sodium_malloc(crypto_hash_sha256_state.size.convert())!! - state = allocated.reinterpret().pointed - */ - methodBuilder.addStatement("val allocated = sodium_malloc(${stateParameterDefinition.parameterType.typeName}.size.convert())!!") - methodBuilder.addStatement("val state = allocated.reinterpret<${stateParameterDefinition.parameterType.typeName}>().pointed") - } - - fun createOutputParam(outputParams: List, length: String?, methodBuilder: FunSpec.Builder) { - /* - val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES) - val hashResultPinned = hashResult.pin() - crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0)) - sodium_free(state.ptr) - return hashResult - */ - for (outputParam in outputParams) { - when (outputParam.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES, TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val ${outputParam.parameterName} = UByteArray($length)") - } - TypeDefinition.UBYTE -> { - methodBuilder.addStatement("var ${outputParam.parameterName} : UByte = 0U") - } - else -> { - throw RuntimeException("Unhandled native output param type: ${outputParam.parameterType.typeName}") - } - } - } - } - - fun createTupleOutputParams(outputParams: List) : String { - return outputParams.map { it.parameterName }.joinToString (separator = ", ") - } - - fun pinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) { - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - methodBuilder.addStatement("val pinned${paramDefinition.parameterName.capitalize()} = ${paramDefinition.parameterName}.pin()") - } - TypeDefinition.LONG -> { - - } - TypeDefinition.INT -> { - - } - TypeDefinition.STRING -> { - - } - } - } - - } - } - - fun unpinParams(methodDefinition: FunctionDefinition, methodBuilder: FunSpec.Builder) { - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - methodBuilder.addStatement("pinned${paramDefinition.parameterName.capitalize()}.unpin()") - } - TypeDefinition.LONG -> { - - } - TypeDefinition.INT -> { - - } - TypeDefinition.STRING -> { - - } - } - } - - } - } - - fun paramsToString(methodDefinition: FunctionDefinition): String { - val paramsBuilder = StringBuilder() - paramsBuilder.append("(") - methodDefinition.parameterList.forEachIndexed { index, paramDefinition -> - val separator = if (index == methodDefinition.parameterList.size - 1) { - "" - } else { - ", " - } - if (paramDefinition.parameterType is CustomTypeDefinition) { - paramsBuilder.append(paramDefinition.parameterName + ".ptr" + separator) - } - if (paramDefinition.parameterType is TypeDefinition) { - when (paramDefinition.parameterType) { - TypeDefinition.ARRAY_OF_UBYTES -> { - paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), " + paramDefinition.parameterName + ".size.convert()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { - paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0), " + paramDefinition.parameterName + ".size.convert()" + separator) - } - TypeDefinition.ARRAY_OF_UBYTES_NO_SIZE -> { - paramsBuilder.append("pinned" + paramDefinition.parameterName.capitalize() + ".addressOf(0)" + separator) - } - TypeDefinition.LONG -> { - paramsBuilder.append(paramDefinition.parameterName + ".convert()" + separator) - } - TypeDefinition.INT -> { - paramsBuilder.append(paramDefinition.parameterName + ".convert()" + separator) - } - TypeDefinition.STRING -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.UBYTE -> { - paramsBuilder.append(paramDefinition.parameterName + separator) - } - TypeDefinition.NULL -> { - paramsBuilder.append("null" + separator) - } - } - } - - } - paramsBuilder.append(')') - return paramsBuilder.toString() - } - - -} diff --git a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt b/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt deleted file mode 100644 index 0fd8c24..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/kotlin/com/ionspin/kotlin/crypto/generator/libsodium/generator/SharedCreators.kt +++ /dev/null @@ -1,69 +0,0 @@ -package com.ionspin.kotlin.crypto.generator.libsodium.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.ClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.DataClassDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.FunctionDefinition -import com.ionspin.kotlin.crypto.generator.libsodium.definitions.InnerClassDefinition -import com.squareup.kotlinpoet.* - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -fun createClass( - fileBuilder: FileSpec.Builder, - classDefinition: ClassDefinition, - multiplatformModifier: MultiplatformModifier, - methodCreator: (FunctionDefinition) -> FunSpec.Builder -): TypeSpec.Builder { - val commonClassBuilder = TypeSpec.classBuilder(classDefinition.name) - // Ugly - val primaryConstructor = FunSpec.constructorBuilder() - if (multiplatformModifier == MultiplatformModifier.EXPECT) { - primaryConstructor.addModifiers(KModifier.INTERNAL) - for (dataClassDefinition in classDefinition.dataClasses) { - generateDataClass(fileBuilder, dataClassDefinition) - } - } else { - primaryConstructor.addModifiers(KModifier.INTERNAL, KModifier.ACTUAL) - } - - commonClassBuilder.primaryConstructor(primaryConstructor.build()) - commonClassBuilder.modifiers += multiplatformModifier.modifierList - for (methodDefinition in classDefinition.methods) { - val builder = methodCreator(methodDefinition) - generateDocumentationForMethod(builder, methodDefinition) - commonClassBuilder.addFunction(builder.build()) - } - return commonClassBuilder -} - -fun generateDataClass(fileBuilder: FileSpec.Builder, dataClassDefinition: DataClassDefinition) { - val dataClassBuilder = TypeSpec.classBuilder(dataClassDefinition.name) - dataClassBuilder.addModifiers(KModifier.DATA) - val dataClassConstructor = FunSpec.constructorBuilder() - for (parameter in dataClassDefinition.parameters) { - val parameterBuilder = ParameterSpec.builder(parameter.parameterName, parameter.parameterType.typeName) - val annotationBuilder = - AnnotationSpec.builder(ClassName("kotlin.js", "JsName")) - .addMember("\"${parameter.parameterName}\"") - parameterBuilder.addAnnotation(annotationBuilder.build()) - dataClassConstructor.addParameter(parameterBuilder.build()) - } - dataClassBuilder.primaryConstructor(dataClassConstructor.build()) - for (parameter in dataClassDefinition.parameters) { - dataClassBuilder.addProperty( - PropertySpec.builder(parameter.parameterName, parameter.parameterType.typeName) - .initializer(parameter.parameterName) - .build() - ) - } - fileBuilder.addType(dataClassBuilder.build()) -} - -fun generateDocumentationForMethod(builder: FunSpec.Builder, methodSpec: FunctionDefinition) { - builder.addKdoc(methodSpec.codeDocumentation) -} - - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm deleted file mode 100644 index 74f517f..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/0_libsodium.dknm +++ /dev/null @@ -1,101 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CStruct public final class crypto_aead_aes256gcm_state_ public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val opaque: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_hash_sha512_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val buf: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val count: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val state: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_auth_hmacsha512_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val ictx: libsodium.crypto_hash_sha512_state /* compiled code */ - - public final val octx: libsodium.crypto_hash_sha512_state /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_hash_sha256_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val buf: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final var count: platform.posix.uint64_t /* = kotlin.ULong */ /* compiled code */ - - public final val state: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_auth_hmacsha256_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val ictx: libsodium.crypto_hash_sha256_state /* compiled code */ - - public final val octx: libsodium.crypto_hash_sha256_state /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_generichash_blake2b_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val opaque: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_onetimeauth_poly1305_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val opaque: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_secretstream_xchacha20poly1305_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val _pad: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val k: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ - - public final val nonce: kotlinx.cinterop.CArrayPointer */> /* = kotlinx.cinterop.CPointer */> */ /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class crypto_sign_ed25519ph_state public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final val hs: libsodium.crypto_hash_sha512_state /* compiled code */ -} - -@kotlinx.cinterop.internal.CStruct public final class randombytes_implementation public constructor(rawPtr: kotlinx.cinterop.NativePtr /* = kotlin.native.internal.NativePtr */) : kotlinx.cinterop.CStructVar { - @kotlinx.cinterop.internal.CStruct.VarType public companion object : kotlinx.cinterop.CStructVar.Type { - } - - public final var buf: kotlinx.cinterop.CPointer? */, platform.posix.size_t /* = kotlin.ULong */) -> kotlin.Unit>>? /* compiled code */ - - public final var close: kotlinx.cinterop.CPointer kotlin.Int>>? /* compiled code */ - - public final var implementation_name: kotlinx.cinterop.CPointer kotlinx.cinterop.CPointer */>?>>? /* compiled code */ - - public final var random: kotlinx.cinterop.CPointer platform.posix.uint32_t /* = kotlin.UInt */>>? /* compiled code */ - - public final var stir: kotlinx.cinterop.CPointer kotlin.Unit>>? /* compiled code */ - - public final var uniform: kotlinx.cinterop.CPointer platform.posix.uint32_t /* = kotlin.UInt */>>? /* compiled code */ -} - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm deleted file mode 100644 index d9073d2..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/1_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_is_available(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis128l_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_is_available(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aegis256_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_beforenm(ctx_: kotlinx.cinterop.CValuesRef?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt_afternm(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_decrypt_detached_afternm(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt_afternm(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_encrypt_detached_afternm(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, ctx_: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_is_available(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_aes256gcm_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_ietf_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_chacha20poly1305_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_decrypt(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_decrypt_detached(m: kotlinx.cinterop.CValuesRef */>?, nsec: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, mac: kotlinx.cinterop.CValuesRef */>?, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_encrypt(c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_encrypt_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, maclen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, nsec: kotlinx.cinterop.CValuesRef */>?, npub: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_npubbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_aead_xchacha20poly1305_ietf_nsecbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha256_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512256_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_hmacsha512_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_auth_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha256_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_sha512_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xsalsa20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_init(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_library_minimal(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_library_version_major(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_library_version_minor(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_misuse(): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_set_misuse_handler(handler: kotlinx.cinterop.CPointer kotlin.Unit>>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_version_string(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm deleted file mode 100644 index 55096ca..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/2_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun crypto_box(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_beforenm(k: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_beforenmbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_beforenm(k: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_beforenmbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_open_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xsalsa20poly1305_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_detached_afternm(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_easy_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_detached_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_open_easy_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seal(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seal_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_sealbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hchacha20_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_hsalsa20_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa2012_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa208_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_constbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_inputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_salsa20_outputbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash(out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b(out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_init_salt_personal(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, outlen: platform.posix.size_t /* = kotlin.ULong */, salt: kotlinx.cinterop.CValuesRef */>?, personal: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keybytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keybytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_personalbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_salt_personal(out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, salt: kotlinx.cinterop.CValuesRef */>?, personal: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_blake2b_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?, keylen: platform.posix.size_t /* = kotlin.ULong */, outlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keybytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keybytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_generichash_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_hash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_contextbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_derive_from_key(subkey: kotlinx.cinterop.CValuesRef */>?, subkey_len: platform.posix.size_t /* = kotlin.ULong */, subkey_id: platform.posix.uint64_t /* = kotlin.ULong */, ctx: kotlinx.cinterop.CValuesRef */>?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_blake2b_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_contextbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_derive_from_key(subkey: kotlinx.cinterop.CValuesRef */>?, subkey_len: platform.posix.size_t /* = kotlin.ULong */, subkey_id: platform.posix.uint64_t /* = kotlin.ULong */, ctx: kotlinx.cinterop.CValuesRef */>?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_client_session_keys(rx: kotlinx.cinterop.CValuesRef */>?, tx: kotlinx.cinterop.CValuesRef */>?, client_pk: kotlinx.cinterop.CValuesRef */>?, client_sk: kotlinx.cinterop.CValuesRef */>?, server_pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_server_session_keys(rx: kotlinx.cinterop.CValuesRef */>?, tx: kotlinx.cinterop.CValuesRef */>?, server_pk: kotlinx.cinterop.CValuesRef */>?, server_sk: kotlinx.cinterop.CValuesRef */>?, client_pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kx_sessionkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm deleted file mode 100644 index 926379c..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/3_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_init(state: kotlinx.cinterop.CValuesRef?, key: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_final(state: kotlinx.cinterop.CValuesRef?, out: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_poly1305_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_update(state: kotlinx.cinterop.CValuesRef?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_onetimeauth_verify(h: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_alg_argon2i13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_alg_argon2id13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_alg_default(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_alg_argon2i13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2i_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_alg_argon2id13(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_argon2id_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_moderate(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str_alg(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */, alg: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_curve25519_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_boxzerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xsalsa20poly1305_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_zerobytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint32_t /* = kotlin.UInt */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm deleted file mode 100644 index 2d912db..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/4_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun _sodium_runtime_get_cpu_features(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_abytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_headerbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_init_pull(state: kotlinx.cinterop.CValuesRef?, header: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_init_push(state: kotlinx.cinterop.CValuesRef?, header: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_pull(state: kotlinx.cinterop.CValuesRef?, m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, tag_p: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_push(state: kotlinx.cinterop.CValuesRef?, c: kotlinx.cinterop.CValuesRef */>?, clen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, ad: kotlinx.cinterop.CValuesRef */>?, adlen: kotlin.ULong, tag: kotlin.UByte): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_rekey(state: kotlinx.cinterop.CValuesRef?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_final(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_message(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_push(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretstream_xchacha20poly1305_tag_rekey(): kotlin.UByte { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphash24(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphash24_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphash24_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphashx24(out: kotlinx.cinterop.CValuesRef */>?, `in`: kotlinx.cinterop.CValuesRef */>?, inlen: kotlin.ULong, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphashx24_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_shorthash_siphashx24_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign(sm: kotlinx.cinterop.CValuesRef */>?, smlen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_detached(sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519(sm: kotlinx.cinterop.CValuesRef */>?, smlen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_detached(sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_open(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, sm: kotlinx.cinterop.CValuesRef */>?, smlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_pk_to_curve25519(curve25519_pk: kotlinx.cinterop.CValuesRef */>?, ed25519_pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_sk_to_curve25519(curve25519_sk: kotlinx.cinterop.CValuesRef */>?, ed25519_sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_sk_to_pk(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_sk_to_seed(seed: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519_verify_detached(sig: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_final_create(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_final_verify(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_ed25519ph_update(state: kotlinx.cinterop.CValuesRef?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_final_create(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, siglen_p: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_final_verify(state: kotlinx.cinterop.CValuesRef?, sig: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_init(state: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_open(m: kotlinx.cinterop.CValuesRef */>?, mlen_p: kotlinx.cinterop.CValuesRef */>?, sm: kotlinx.cinterop.CValuesRef */>?, smlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_statebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_update(state: kotlinx.cinterop.CValuesRef?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_sign_verify_detached(sig: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_chacha20_ietf_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_primitive(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_16(x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_16_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_32(x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_32_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_64(x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_verify_64_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes(buf: kotlinx.cinterop.CValuesRef */>?, buf_len: kotlin.ULong): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_buf(buf: kotlinx.cinterop.CValuesRef<*>?, size: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_buf_deterministic(buf: kotlinx.cinterop.CValuesRef<*>?, size: platform.posix.size_t /* = kotlin.ULong */, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_close(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_implementation_name(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_random(): platform.posix.uint32_t /* = kotlin.UInt */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_set_implementation(impl: kotlinx.cinterop.CValuesRef?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_stir(): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun randombytes_uniform(upper_bound: platform.posix.uint32_t /* = kotlin.UInt */): platform.posix.uint32_t /* = kotlin.UInt */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_add(a: kotlinx.cinterop.CValuesRef */>?, b: kotlinx.cinterop.CValuesRef */>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_allocarray(count: platform.posix.size_t /* = kotlin.ULong */, size: platform.posix.size_t /* = kotlin.ULong */): kotlinx.cinterop.COpaquePointer? /* = kotlinx.cinterop.CPointer? */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_base642bin(bin: kotlinx.cinterop.CValuesRef */>?, bin_maxlen: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString b64: kotlin.String?, b64_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ignore: kotlin.String?, bin_len: kotlinx.cinterop.CValuesRef */>?, b64_end: kotlinx.cinterop.CValuesRef */> /* = kotlinx.cinterop.CPointerVarOf */>> */>?, variant: kotlin.Int): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_base64_encoded_len(bin_len: platform.posix.size_t /* = kotlin.ULong */, variant: kotlin.Int): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_bin2base64(b64: kotlinx.cinterop.CValuesRef */>?, b64_maxlen: platform.posix.size_t /* = kotlin.ULong */, bin: kotlinx.cinterop.CValuesRef */>?, bin_len: platform.posix.size_t /* = kotlin.ULong */, variant: kotlin.Int): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_bin2hex(hex: kotlinx.cinterop.CValuesRef */>?, hex_maxlen: platform.posix.size_t /* = kotlin.ULong */, bin: kotlinx.cinterop.CValuesRef */>?, bin_len: platform.posix.size_t /* = kotlin.ULong */): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_compare(b1_: kotlinx.cinterop.CValuesRef */>?, b2_: kotlinx.cinterop.CValuesRef */>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_free(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_hex2bin(bin: kotlinx.cinterop.CValuesRef */>?, bin_maxlen: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString hex: kotlin.String?, hex_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ignore: kotlin.String?, bin_len: kotlinx.cinterop.CValuesRef */>?, hex_end: kotlinx.cinterop.CValuesRef */> /* = kotlinx.cinterop.CPointerVarOf */>> */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_increment(n: kotlinx.cinterop.CValuesRef */>?, nlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_is_zero(n: kotlinx.cinterop.CValuesRef */>?, nlen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_malloc(size: platform.posix.size_t /* = kotlin.ULong */): kotlinx.cinterop.COpaquePointer? /* = kotlinx.cinterop.CPointer? */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_memcmp(b1_: kotlinx.cinterop.CValuesRef<*>?, b2_: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_memzero(pnt: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mlock(addr: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mprotect_noaccess(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mprotect_readonly(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_mprotect_readwrite(ptr: kotlinx.cinterop.CValuesRef<*>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_munlock(addr: kotlinx.cinterop.CValuesRef<*>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_aesni(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_armcrypto(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_avx(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_avx2(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_avx512f(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_neon(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_pclmul(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_rdrand(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_sse2(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_sse3(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_sse41(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_runtime_has_ssse3(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_stackzero(len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_sub(a: kotlinx.cinterop.CValuesRef */>?, b: kotlinx.cinterop.CValuesRef */>?, len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Unit { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm deleted file mode 100644 index dbcc66b..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/5_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -@kotlinx.cinterop.internal.CCall public external fun _sodium_alloc_init(): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_beforenm(k: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_beforenmbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_detached_afternm(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_easy_afternm(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_detached_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_open_easy_afternm(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_publickeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seal(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seal_open(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_sealbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_secretkeybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seed_keypair(pk: kotlinx.cinterop.CValuesRef */>?, sk: kotlinx.cinterop.CValuesRef */>?, seed: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_box_curve25519xchacha20poly1305_seedbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_add(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_from_string(p: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, msg: kotlinx.cinterop.CValuesRef */>?, msg_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_from_string_ro(p: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, msg: kotlinx.cinterop.CValuesRef */>?, msg_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_from_uniform(p: kotlinx.cinterop.CValuesRef */>?, r: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_hashbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_is_valid_point(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_nonreducedscalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_random(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_add(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_complement(comp: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_invert(recip: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_is_canonical(s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_mul(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_negate(neg: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_random(r: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_reduce(r: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalar_sub(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_sub(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ed25519_uniformbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_add(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_from_hash(p: kotlinx.cinterop.CValuesRef */>?, r: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_hashbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_is_valid_point(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_nonreducedscalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_random(p: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_add(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_complement(comp: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_invert(recip: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_is_canonical(s: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_mul(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_negate(neg: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_random(r: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_reduce(r: kotlinx.cinterop.CValuesRef */>?, s: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalar_sub(z: kotlinx.cinterop.CValuesRef */>?, x: kotlinx.cinterop.CValuesRef */>?, y: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_core_ristretto255_sub(r: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?, q: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_expand(out: kotlinx.cinterop.CValuesRef */>?, out_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, ctx_len: platform.posix.size_t /* = kotlin.ULong */, prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_extract(prk: kotlinx.cinterop.CValuesRef */>?, salt: kotlinx.cinterop.CValuesRef */>?, salt_len: platform.posix.size_t /* = kotlin.ULong */, ikm: kotlinx.cinterop.CValuesRef */>?, ikm_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha256_keygen(prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_expand(out: kotlinx.cinterop.CValuesRef */>?, out_len: platform.posix.size_t /* = kotlin.ULong */, @kotlinx.cinterop.internal.CCall.CString ctx: kotlin.String?, ctx_len: platform.posix.size_t /* = kotlin.ULong */, prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_extract(prk: kotlinx.cinterop.CValuesRef */>?, salt: kotlinx.cinterop.CValuesRef */>?, salt_len: platform.posix.size_t /* = kotlin.ULong */, ikm: kotlinx.cinterop.CValuesRef */>?, ikm_len: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_kdf_hkdf_sha512_keygen(prk: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256(out: kotlinx.cinterop.CValuesRef */>?, outlen: kotlin.ULong, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, salt: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_bytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_bytes_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_ll(passwd: kotlinx.cinterop.CValuesRef */>?, passwdlen: platform.posix.size_t /* = kotlin.ULong */, salt: kotlinx.cinterop.CValuesRef */>?, saltlen: platform.posix.size_t /* = kotlin.ULong */, N: platform.posix.uint64_t /* = kotlin.ULong */, r: platform.posix.uint32_t /* = kotlin.UInt */, p: platform.posix.uint32_t /* = kotlin.UInt */, buf: kotlinx.cinterop.CValuesRef */>?, buflen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_passwd_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_passwd_min(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_saltbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_str(out: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(str: kotlinx.cinterop.CValuesRef */>?, opslimit: kotlin.ULong, memlimit: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_str_verify(str: kotlinx.cinterop.CValuesRef */>?, @kotlinx.cinterop.internal.CCall.CString passwd: kotlin.String?, passwdlen: kotlin.ULong): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_strbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_pwhash_scryptsalsa208sha256_strprefix(): kotlinx.cinterop.CPointer */>? { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_base_noclamp(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_noclamp(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ed25519_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?, p: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255_base(q: kotlinx.cinterop.CValuesRef */>?, n: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255_bytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_scalarmult_ristretto255_scalarbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_detached(c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_easy(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_macbytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_open_detached(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, mac: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_secretbox_xchacha20poly1305_open_easy(m: kotlinx.cinterop.CValuesRef */>?, c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa2012_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_keybytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_noncebytes(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_xchacha20_xor_ic(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, ic: platform.posix.uint64_t /* = kotlin.ULong */, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_pad(padded_buflen_p: kotlinx.cinterop.CValuesRef */>?, buf: kotlinx.cinterop.CValuesRef */>?, unpadded_buflen: platform.posix.size_t /* = kotlin.ULong */, blocksize: platform.posix.size_t /* = kotlin.ULong */, max_buflen: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun sodium_unpad(unpadded_buflen_p: kotlinx.cinterop.CValuesRef */>?, buf: kotlinx.cinterop.CValuesRef */>?, padded_buflen: platform.posix.size_t /* = kotlin.ULong */, blocksize: platform.posix.size_t /* = kotlin.ULong */): kotlin.Int { /* compiled code */ } - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm deleted file mode 100644 index 7a15690..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/6_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -public const val SODIUM_LIBRARY_VERSION_MAJOR: kotlin.Int /* compiled code */ - -public const val SODIUM_LIBRARY_VERSION_MINOR: kotlin.Int /* compiled code */ - -public const val SODIUM_SIZE_MAX: kotlin.ULong /* compiled code */ - -public const val SODIUM_VERSION_STRING: kotlin.String /* compiled code */ - -public const val crypto_aead_aegis128l_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis128l_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis128l_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_aegis128l_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis128l_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_aegis256_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aegis256_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_aes256gcm_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_aes256gcm_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_IETF_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_chacha20poly1305_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_chacha20poly1305_ietf_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_IETF_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_NPUBBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_aead_xchacha20poly1305_ietf_NSECBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_auth_hmacsha256_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512256_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_auth_hmacsha512_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_BEFORENMBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_box_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_box_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_SEALBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xsalsa20poly1305_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hchacha20_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_hsalsa20_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa2012_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa208_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_CONSTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_INPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_salsa20_OUTPUTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_KEYBYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_KEYBYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_generichash_blake2b_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_KEYBYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_KEYBYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_PERSONALBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_generichash_blake2b_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_hash_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_hash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_hash_sha256_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_hash_sha512_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_blake2b_BYTES_MAX: kotlin.Int /* compiled code */ - -public const val crypto_kdf_blake2b_BYTES_MIN: kotlin.Int /* compiled code */ - -public const val crypto_stream_xsalsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_xsalsa20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_xsalsa20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public val randombytes_internal_implementation: libsodium.randombytes_implementation /* compiled code */ - -public val randombytes_sysrandom_implementation: libsodium.randombytes_implementation /* compiled code */ - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208(c: kotlinx.cinterop.CValuesRef */>?, clen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_keygen(k: kotlinx.cinterop.CValuesRef */>?): kotlin.Unit { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_messagebytes_max(): platform.posix.size_t /* = kotlin.ULong */ { /* compiled code */ } - -@kotlinx.cinterop.internal.CCall public external fun crypto_stream_salsa208_xor(c: kotlinx.cinterop.CValuesRef */>?, m: kotlinx.cinterop.CValuesRef */>?, mlen: kotlin.ULong, n: kotlinx.cinterop.CValuesRef */>?, k: kotlinx.cinterop.CValuesRef */>?): kotlin.Int { /* compiled code */ } - -public typealias crypto_aead_aes256gcm_state = libsodium.crypto_aead_aes256gcm_state_ - -public typealias crypto_auth_hmacsha512256_state = libsodium.crypto_auth_hmacsha512_state - -public typealias crypto_generichash_state = libsodium.crypto_generichash_blake2b_state - -public typealias crypto_onetimeauth_state = libsodium.crypto_onetimeauth_poly1305_state - -public typealias crypto_sign_state = libsodium.crypto_sign_ed25519ph_state - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm deleted file mode 100644 index eb6a78a..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/7_libsodium.dknm +++ /dev/null @@ -1,261 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -public const val crypto_kdf_BYTES_MAX: kotlin.Int /* compiled code */ - -public const val crypto_kdf_BYTES_MIN: kotlin.Int /* compiled code */ - -public const val crypto_kdf_CONTEXTBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_KEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_kdf_blake2b_CONTEXTBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_blake2b_KEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_kx_PUBLICKEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_SECRETKEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_SEEDBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kx_SESSIONKEYBYTES: kotlin.Int /* compiled code */ - -public const val crypto_onetimeauth_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_onetimeauth_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_onetimeauth_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_onetimeauth_poly1305_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_onetimeauth_poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_ALG_ARGON2I13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_ALG_ARGON2ID13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_ALG_DEFAULT: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_PASSWD_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_pwhash_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_pwhash_argon2i_ALG_ARGON2I13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_argon2i_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2i_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_PASSWD_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2i_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_pwhash_argon2id_ALG_ARGON2ID13: kotlin.Int /* compiled code */ - -public const val crypto_pwhash_argon2id_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2id_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_MODERATE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_PASSWD_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_argon2id_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_scalarmult_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_scalarmult_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_curve25519_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_curve25519_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretbox_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_secretbox_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xsalsa20poly1305_ZEROBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_ABYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_HEADERBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_FINAL: kotlin.Int /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_MESSAGE: kotlin.Int /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_PUSH: kotlin.Int /* compiled code */ - -public const val crypto_secretstream_xchacha20poly1305_TAG_REKEY: kotlin.Int /* compiled code */ - -public const val crypto_shorthash_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_shorthash_siphash24_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_siphash24_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_siphashx24_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_shorthash_siphashx24_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_sign_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_sign_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_sign_ed25519_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_sign_ed25519_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_IETF_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_chacha20_IETF_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_chacha20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_ietf_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_chacha20_ietf_NONCEBYTES: kotlin.UInt /* compiled code */ - diff --git a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm b/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm deleted file mode 100644 index 60ee5dc..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/main/resources/cinteropDecompiled/8_libsodium.dknm +++ /dev/null @@ -1,145 +0,0 @@ -// IntelliJ API Decompiler stub source generated from a class file -// Implementation of methods is not available - -package libsodium - -public const val crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_SEALBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_box_curve25519xchacha20poly1305_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_core_ed25519_BYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_HASHBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_NONREDUCEDSCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_SCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ed25519_UNIFORMBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_BYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_HASHBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_NONREDUCEDSCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_core_ristretto255_SCALARBYTES: kotlin.Int /* compiled code */ - -public const val crypto_kdf_hkdf_sha256_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha256_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha256_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha512_BYTES_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha512_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_kdf_hkdf_sha512_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_BYTES_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_SALTBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_STRBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_pwhash_scryptsalsa208sha256_STRPREFIX: kotlin.String /* compiled code */ - -public const val crypto_scalarmult_ed25519_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_ed25519_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_ristretto255_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_scalarmult_ristretto255_SCALARBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_MACBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_secretbox_xchacha20poly1305_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_PRIMITIVE: kotlin.String /* compiled code */ - -public const val crypto_stream_salsa2012_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa2012_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_salsa2012_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa208_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa208_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_salsa208_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_salsa20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_salsa20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_xchacha20_KEYBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_stream_xchacha20_MESSAGEBYTES_MAX: kotlin.ULong /* compiled code */ - -public const val crypto_stream_xchacha20_NONCEBYTES: kotlin.UInt /* compiled code */ - -public const val crypto_verify_16_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_verify_32_BYTES: kotlin.UInt /* compiled code */ - -public const val crypto_verify_64_BYTES: kotlin.UInt /* compiled code */ - -public const val randombytes_BYTES_MAX: kotlin.ULong /* compiled code */ - -public const val randombytes_SEEDBYTES: kotlin.UInt /* compiled code */ - -public const val sodium_base64_VARIANT_ORIGINAL: kotlin.Int /* compiled code */ - -public const val sodium_base64_VARIANT_ORIGINAL_NO_PADDING: kotlin.Int /* compiled code */ - -public const val sodium_base64_VARIANT_URLSAFE: kotlin.Int /* compiled code */ - -public const val sodium_base64_VARIANT_URLSAFE_NO_PADDING: kotlin.Int /* compiled code */ - diff --git a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt b/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt deleted file mode 100644 index 033b196..0000000 --- a/kotlin-multiplatform-libsodium-generator/src/test/kotlin/com/ionspin/kotlin/crypto/generator/DebugTest.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.ionspin.kotlin.crypto.generator - -import com.ionspin.kotlin.crypto.generator.libsodium.generator.Coordinator -import com.squareup.kotlinpoet.* -import org.junit.Test - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 31-Jul-2020 - */ -class DebugTest { - -} - diff --git a/settings.gradle.kts b/settings.gradle.kts index e201525..085d14b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -40,5 +40,4 @@ include("multiplatform-crypto") include("multiplatform-crypto-delegated") include("multiplatform-crypto-libsodium-bindings") include("sample") -include("kotlin-multiplatform-libsodium-generator") From 92058a7ba57aedfdfe905d04578a1fc8d838e5aa Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 21 Aug 2020 19:21:40 +0200 Subject: [PATCH 10/65] Added generic hash --- .../generichash/GenericHashing.kt | 10 ++ .../shortinputhash/ShortInputHashing.kt | 10 ++ .../com/ionspin/kotlin/crypto/SmokeTest.kt | 24 ++- .../crypto/secretstream/SecretStreamTest.kt | 152 +++++++++--------- .../kotlin/crypto/JsSodiumInterface.kt | 3 +- .../crypto/generichash/GenericHashing.kt | 25 +++ .../src/jsMain/kotlin/debug/test/DebugTest.kt | 9 +- .../crypto/generichash/GenericHashing.kt | 27 ++++ .../jvmMain/kotlin/debug/test/DebugTest.kt | 2 +- .../crypto/generichash/GenericHashing.kt | 45 ++++++ .../nativeMain/kotlin/debug/test/DebugTest.kt | 2 +- 11 files changed, 218 insertions(+), 91 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt new file mode 100644 index 0000000..85aac10 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt @@ -0,0 +1,10 @@ +package com.ionspin.kotlin.crypto.generichash + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +expect object GenericHashing { + fun genericHash(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt new file mode 100644 index 0000000..4f51c24 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt @@ -0,0 +1,10 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +object ShortInputHashing { + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt index 8eecfd5..8033e07 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -1,6 +1,7 @@ package com.ionspin.kotlin.crypto import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.crypto.generichash.GenericHashing import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.toHexString @@ -20,17 +21,24 @@ class SmokeTest { testBlocking { Initializer.initialize() val crypto = Crypto() - //TODO seems to be a bug in JS compiler, if we have the same method name in crypto an in JsSodiumInterface, method tries to call wrong method name (unneeded suffix _0) - //I've worked around this by making state functions with 1 parameter execute call with js("") wrap, but still might sail somewhere else - val state256 = crypto.crypto_hash_sha256_init() - crypto.crypto_hash_sha256_update(state256, "Hello".encodeToUByteArray()) - val result = crypto.crypto_hash_sha256_final(state256) - val resultString = result.toHexString() - println("Result: $resultString") +// //TODO seems to be a bug in JS compiler, if we have the same method name in crypto an in JsSodiumInterface, method tries to call wrong method name (unneeded suffix _0) +// //I've worked around this by making state functions with 1 parameter execute call with js("") wrap, but still might sail somewhere else +// val state256 = crypto.crypto_hash_sha256_init() +// crypto.crypto_hash_sha256_update(state256, "Hello".encodeToUByteArray()) +// val result = crypto.crypto_hash_sha256_final(state256) +// val resultString = result.toHexString() +// println("Result: $resultString") +// assertTrue { +// "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969" == resultString +// } + //Blake512 Hello - EF15EAF92D5E335345A3E1D977BC7D8797C3D275717CC1B10AF79C93CDA01AEB2A0C59BC02E2BDF9380FD1B54EB9E1669026930CCC24BD49748E65F9A6B2EE68 + val hashResult = GenericHashing.genericHash("Hello".encodeToUByteArray(), 64) + println(hashResult.toHexString()) assertTrue { - "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969" == resultString + "EF15EAF92D5E335345A3E1D977BC7D8797C3D275717CC1B10AF79C93CDA01AEB2A0C59BC02E2BDF9380FD1B54EB9E1669026930CCC24BD49748E65F9A6B2EE68".toLowerCase() == hashResult.toHexString() } + } } } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index e477f41..41837de 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -1,76 +1,76 @@ -package com.ionspin.kotlin.crypto.secretstream - -import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint -import com.ionspin.kotlin.crypto.Initializer -import com.ionspin.kotlin.crypto.util.encodeToUByteArray -import com.ionspin.kotlin.crypto.util.testBlocking -import debug.test.Crypto -import kotlin.math.exp -import kotlin.test.Test -import kotlin.test.assertTrue - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 15-Aug-2020 - */ -class SecretStreamTest { - @Test - fun testSecretStream() = testBlocking { - Initializer.initializeWithCallback { - assertTrue { - val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + - "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - - val additionalData = ubyteArrayOf( - 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U - ) - val key = ubyteArrayOf( - 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, - 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, - 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, - 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, - ) - - val nonce = ubyteArrayOf( - 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, - 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, - 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, - ) - - val expected = ubyteArrayOf( - 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, - 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, - 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, - 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, - 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, - 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, - 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, - 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, - 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, - 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, - 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, - 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, - 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, - 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, - 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, - 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, - 0xcfU, 0x49U - ) - message.hexColumsPrint() - val crypto = Crypto() - val stateAndHeader = crypto.crypto_secretstream_xchacha20poly1305_init_push(key) - val encrypted = - crypto.crypto_secretstream_xchacha20poly1305_push(stateAndHeader.state, message, ubyteArrayOf(), 0U) - encrypted.hexColumsPrint() - val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) - val decrypted = - crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) - decrypted.hexColumsPrint() - decrypted.contentEquals(message) - - } - } - } - -} +//package com.ionspin.kotlin.crypto.secretstream +// +//import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +//import com.ionspin.kotlin.crypto.Initializer +//import com.ionspin.kotlin.crypto.util.encodeToUByteArray +//import com.ionspin.kotlin.crypto.util.testBlocking +//import debug.test.Crypto +//import kotlin.math.exp +//import kotlin.test.Test +//import kotlin.test.assertTrue +// +///** +// * Created by Ugljesa Jovanovic +// * ugljesa.jovanovic@ionspin.com +// * on 15-Aug-2020 +// */ +//class SecretStreamTest { +// @Test +// fun testSecretStream() = testBlocking { +// Initializer.initializeWithCallback { +// assertTrue { +// val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + +// "only one tip for the future, sunscreen would be it.").encodeToUByteArray() +// +// val additionalData = ubyteArrayOf( +// 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U +// ) +// val key = ubyteArrayOf( +// 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, +// 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, +// 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, +// 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, +// ) +// +// val nonce = ubyteArrayOf( +// 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, +// 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, +// 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, +// ) +// +// val expected = ubyteArrayOf( +// 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, +// 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, +// 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, +// 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, +// 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, +// 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, +// 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, +// 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, +// 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, +// 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, +// 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, +// 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, +// 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, +// 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, +// 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, +// 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, +// 0xcfU, 0x49U +// ) +// message.hexColumsPrint() +// val crypto = Crypto() +// val stateAndHeader = crypto.crypto_secretstream_xchacha20poly1305_init_push(key) +// val encrypted = +// crypto.crypto_secretstream_xchacha20poly1305_push(stateAndHeader.state, message, ubyteArrayOf(), 0U) +// encrypted.hexColumsPrint() +// val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) +// val decrypted = +// crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) +// decrypted.hexColumsPrint() +// decrypted.contentEquals(message) +// +// } +// } +// } +// +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 6694723..cb5c6b6 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -12,7 +12,7 @@ interface JsSodiumInterface { fun randombytes_buf(numberOfBytes: Int): Uint8Array - fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array,): Uint8Array + fun crypto_generichash(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array): Uint8Array fun crypto_hash_sha256(message: Uint8Array): Uint8Array @@ -57,4 +57,5 @@ interface JsSodiumInterface { + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt new file mode 100644 index 0000000..8cbc72b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt @@ -0,0 +1,25 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual object GenericHashing { + actual fun genericHash( + message: UByteArray, + requestedHashLength: Int, + key: UByteArray? + ): UByteArray { + return getSodium().crypto_generichash( + requestedHashLength, + message.toUInt8Array(), + key?.toUInt8Array() ?: Uint8Array(0) + ).toUByteArray() + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index 2c462b6..f5b75ff 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -70,7 +70,7 @@ actual class Crypto internal actual constructor() { getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) val state = stateAndHeader.state val header = (stateAndHeader.header as Uint8Array).toUByteArray() - return SecretStreamStateAndHeader(state, header) + return SecretStreamStateAndHeader(state, header) } /** @@ -104,9 +104,10 @@ actual class Crypto internal actual constructor() { state: SecretStreamState, c: UByteArray, ad: UByteArray - ): UByte { + ): DecryptedDataAndTag { println("Debug crypto_secretstream_xchacha20poly1305_pull") - return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(), - ad.toUInt8Array()) +// return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(), +// ad.toUInt8Array()) + return DecryptedDataAndTag(ubyteArrayOf(), 0U) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt new file mode 100644 index 0000000..90dd443 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt @@ -0,0 +1,27 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.Initializer.sodium + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual object GenericHashing { + actual fun genericHash( + message: UByteArray, + requestedHashLength: Int, + key: UByteArray? + ): UByteArray { + val hash = UByteArray(requestedHashLength) + sodium.crypto_generichash( + hash.asByteArray(), + requestedHashLength, + message.asByteArray(), + message.size.toLong(), + key?.asByteArray(), + (key?.size ?: 0) + ) + return hash + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index 17529ec..f970b12 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -121,7 +121,7 @@ actual class Crypto internal actual constructor() { val m = UByteArray(c.size - 17) var tag_p : UByte = 0U println("Debug crypto_secretstream_xchacha20poly1305_pull") - sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, tag_p.toByte(), + sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, byteArrayOf(), c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) return debug.test.DecryptedDataAndTag(m, tag_p) } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt new file mode 100644 index 0000000..265ec22 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt @@ -0,0 +1,45 @@ +package com.ionspin.kotlin.crypto.generichash + +import kotlin.Byte +import kotlin.ByteArray +import kotlin.Int +import kotlin.UByte +import kotlin.UByteArray +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.pointed +import kotlinx.cinterop.ptr +import kotlinx.cinterop.reinterpret +import kotlinx.cinterop.toCValues +import libsodium.crypto_generichash +import libsodium.crypto_generichash_blake2b_state +import libsodium.crypto_hash_sha256_state +import libsodium.crypto_hash_sha512_state +import libsodium.crypto_secretstream_xchacha20poly1305_state +import libsodium.sodium_malloc +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual object GenericHashing { + actual fun genericHash(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray { + val hash = UByteArray(requestedHashLength) + val pinnedHash = hash.pin() + val pinnedKey = key?.pin() + val pinnedMessage = message.pin() + crypto_generichash( + pinnedHash.addressOf(0), + requestedHashLength.convert(), + pinnedMessage.addressOf(0), + message.size.convert(), + pinnedKey?.addressOf(0), + (key?.size ?: 0).convert() + ) + pinnedHash.unpin() + pinnedKey?.unpin() + pinnedMessage.unpin() + return hash + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index 52cc5fa..dd148b9 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -170,7 +170,7 @@ actual class Crypto internal actual constructor() { val pinnedC = c.pin() val pinnedAd = ad.pin() libsodium.crypto_secretstream_xchacha20poly1305_pull(state.ptr, pinnedM.addressOf(0), null, - tag_p, pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) + ubyteArrayOf().toCValues(), pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) pinnedM.unpin() pinnedC.unpin() pinnedAd.unpin() From f060d2298da1841d584edef64d799921540c2d98 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 22 Aug 2020 00:43:22 +0200 Subject: [PATCH 11/65] Added android plugin, need to sort out shared jvm code next --- buildSrc/build.gradle.kts | 2 ++ buildSrc/src/main/kotlin/Deps.kt | 2 ++ gradle.properties | 2 ++ .../build.gradle.kts | 25 ++++++++++++++++++- .../src/main/AndroidManifest.xml | 2 ++ 5 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/main/AndroidManifest.xml diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6b9af03..2658b0f 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -25,10 +25,12 @@ repositories { maven ("https://dl.bintray.com/kotlin/kotlin-eap") maven("https://dl.bintray.com/kotlin/kotlin-dev") jcenter() + google() } dependencies { implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.0-rc") + implementation("com.android.tools.build:gradle:4.0.1") } System.setProperty("PROJECT_PATH", project.projectDir.parentFile.toString()) diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index 8c65ccd..c98ede8 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -107,5 +107,7 @@ object PluginsDeps { val signing = "signing" val dokka = "org.jetbrains.dokka" val taskTree = "com.dorongold.task-tree" + val androidLibrary = "com.android.library" + val kotlinAndroidExtensions = "kotlin-android-extensions" } diff --git a/gradle.properties b/gradle.properties index 9296ffa..51da301 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,3 +23,5 @@ kotlin.js.compiler=ir kotlin.native.disableCompilerDaemon=true org.gradle.jvmargs=-Xmx4g -XX:MaxPermSize=4096m + +android.useAndroidX=true diff --git a/multiplatform-crypto-libsodium-bindings/build.gradle.kts b/multiplatform-crypto-libsodium-bindings/build.gradle.kts index 6cbea96..4d29078 100644 --- a/multiplatform-crypto-libsodium-bindings/build.gradle.kts +++ b/multiplatform-crypto-libsodium-bindings/build.gradle.kts @@ -28,6 +28,9 @@ plugins { id(PluginsDeps.node) version Versions.nodePlugin id(PluginsDeps.dokka) id(PluginsDeps.taskTree) version Versions.taskTreePlugin + id(PluginsDeps.androidLibrary) + id(PluginsDeps.kotlinAndroidExtensions) + } val sonatypeStaging = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" @@ -51,13 +54,27 @@ version = ReleaseInfo.version val ideaActive = isInIdea() println("Idea active: $ideaActive") - +android { + compileSdkVersion(29) + defaultConfig { + minSdkVersion(24) + targetSdkVersion(29) + versionCode = 1 + versionName = "1.0" + } + buildTypes { + getByName("release") { + isMinifyEnabled = false + } + } +} kotlin { val hostOsName = getHostOsName() runningOnLinuxx86_64 { println("Configuring Linux X86-64 targets") jvm() + android() js { browser { testTask { @@ -428,6 +445,12 @@ kotlin { implementation(kotlin(Deps.Jvm.reflection)) } } + val androidMain by getting { + dependencies { + implementation("androidx.core:core-ktx:1.2.0") + } + } + val jsMain by getting { dependencies { implementation(kotlin(Deps.Js.stdLib)) diff --git a/multiplatform-crypto-libsodium-bindings/src/main/AndroidManifest.xml b/multiplatform-crypto-libsodium-bindings/src/main/AndroidManifest.xml new file mode 100644 index 0000000..0b4b599 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + From 9962198aadb1f1a77f85565273c24d25effc5dd5 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 22 Aug 2020 13:53:01 +0200 Subject: [PATCH 12/65] Comment out old debug generated code, but keep for short term reference, add android/jvm wrappers, seemingly solve android unit test problems --- .../ionspin/kotlin/crypto/AndroidSodiumWrapper.kt | 11 +++++++++++ .../{Initializer.kt => LibsodiumInitializer.kt} | 0 .../{Initializer.kt => LibsodiumInitializer.kt} | 0 .../{Initializer.kt => LibsodiumInitializer.kt} | 0 .../com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt | 13 +++++++++++++ .../{Initializer.kt => LibsodiumInitializer.kt} | 0 6 files changed, 24 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt rename multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/{Initializer.kt => LibsodiumInitializer.kt} (100%) rename multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/{Initializer.kt => LibsodiumInitializer.kt} (100%) rename multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/{Initializer.kt => LibsodiumInitializer.kt} (100%) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt rename multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/{Initializer.kt => LibsodiumInitializer.kt} (100%) diff --git a/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt b/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt new file mode 100644 index 0000000..af80862 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt @@ -0,0 +1,11 @@ +package com.ionspin.kotlin.crypto + + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 22-Aug-2020 + */ +class SodiumWrapper : LazySodiumAndroid { + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt similarity index 100% rename from multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt similarity index 100% rename from multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt similarity index 100% rename from multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt b/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt new file mode 100644 index 0000000..7c84820 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt @@ -0,0 +1,13 @@ +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 + */ +class ASodiumWrapper : SodiumJava() { + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt similarity index 100% rename from multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/Initializer.kt rename to multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt From 231a84af67e44d948f0f275e9d9aa0007defff22 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 23 Aug 2020 13:39:59 +0200 Subject: [PATCH 13/65] Comment out old debug generated code, but keep for short term reference, add android/jvm wrappers, seemingly solve android unit test problems --- .../build.gradle.kts | 48 ++- .../kotlin/crypto/AndroidSodiumWrapper.kt | 7 +- .../LibsodiumInitializer.kt | 4 +- .../commonMain/kotlin/debug/test/DebugTest.kt | 158 ++++---- .../com/ionspin/kotlin/crypto/SmokeTest.kt | 17 +- .../kotlin/crypto/LibsodiumInitializer.kt | 4 +- .../src/jsMain/kotlin/debug/test/DebugTest.kt | 226 +++++------ .../kotlin/crypto/LibsodiumInitializer.kt | 12 +- .../crypto/generichash/GenericHashing.kt | 2 +- .../jvmMain/kotlin/debug/test/DebugTest.kt | 256 ++++++------- .../ionspin/kotlin/crypto/JvmSodiumWrapper.kt | 4 +- .../kotlin/crypto/LibsodiumInitializer.kt | 2 +- .../crypto/generichash/GenericHashing.kt | 18 +- .../nativeMain/kotlin/debug/test/DebugTest.kt | 358 +++++++++--------- 14 files changed, 549 insertions(+), 567 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/build.gradle.kts b/multiplatform-crypto-libsodium-bindings/build.gradle.kts index 4d29078..91ed8ac 100644 --- a/multiplatform-crypto-libsodium-bindings/build.gradle.kts +++ b/multiplatform-crypto-libsodium-bindings/build.gradle.kts @@ -46,6 +46,7 @@ val sonatypeUsernameEnv: String? = System.getenv()["SONATYPE_USERNAME"] repositories { mavenCentral() jcenter() + maven("https://dl.bintray.com/terl/lazysodium-maven") } group = ReleaseInfo.group @@ -61,6 +62,7 @@ android { targetSdkVersion(29) versionCode = 1 versionName = "1.0" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { getByName("release") { @@ -69,6 +71,7 @@ android { } } + kotlin { val hostOsName = getHostOsName() runningOnLinuxx86_64 { @@ -128,26 +131,8 @@ kotlin { // >>> referenced by randombytes_sysrandom.c // >>> libsodium_la-randombytes_sysrandom.o:(_randombytes_linux_getrandom) in archive /tmp/included11051337748775083797/libsodium.a -// linuxArm32Hfp() { -// binaries { -// staticLib { -// } -// } -// compilations.getByName("main") { -// val libsodiumCinterop by cinterops.creating { -// defFile(project.file("src/nativeInterop/cinterop/libsodium.def")) -// compilerOpts.add("-I${project.rootDir}/sodiumWrapper/static-arm32/include/") -// } -// kotlinOptions.freeCompilerArgs = listOf( -// "-include-binary", "${project.rootDir}/sodiumWrapper/static-arm32/lib/libsodium.a" -// ) -// } -// } - - } - runningOnLinuxArm64 { println("Configuring Linux Arm 64 targets") @@ -428,6 +413,7 @@ kotlin { runningOnLinuxx86_64 { println("Configuring Linux 64 Bit source sets") val jvmMain by getting { + kotlin.srcDirs("src/jvmSpecific", "src/jvmMain/kotlin") dependencies { implementation(kotlin(Deps.Jvm.stdLib)) implementation(kotlin(Deps.Jvm.test)) @@ -446,8 +432,24 @@ kotlin { } } val androidMain by getting { + isNotRunningInIdea { + kotlin.srcDirs("src/androidSpecific", "src/jvmMain/kotlin") + } + isRunningInIdea { + kotlin.srcDirs("src/androidSpecific") + } dependencies { - implementation("androidx.core:core-ktx:1.2.0") + implementation("com.goterl.lazycode:lazysodium-android:4.2.0@aar") + implementation("net.java.dev.jna:jna:5.5.0@aar") + } + } + + val androidTest by getting { + dependencies { + implementation(kotlin(Deps.Jvm.test)) + implementation(kotlin(Deps.Jvm.testJUnit)) + implementation("androidx.test:runner:1.2.0") + implementation("androidx.test:rules:1.2.0") } } @@ -544,7 +546,11 @@ kotlin { } - +tasks.whenTaskAdded { + if("DebugUnitTest" in name || "ReleaseUnitTest" in name) { + enabled = false // https://youtrack.jetbrains.com/issue/KT-34662 otherwise common tests fail, because we require native android libs to be loaded + } +} tasks { @@ -588,6 +594,8 @@ tasks { } } + + // val legacyjsNodeTest by getting(KotlinJsTest::class) { // // testLogging { diff --git a/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt b/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt index af80862..b537c33 100644 --- a/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt +++ b/multiplatform-crypto-libsodium-bindings/src/androidSpecific/com/ionspin/kotlin/crypto/AndroidSodiumWrapper.kt @@ -1,11 +1,12 @@ package com.ionspin.kotlin.crypto +import com.goterl.lazycode.lazysodium.LazySodiumAndroid +import com.goterl.lazycode.lazysodium.SodiumAndroid + /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 22-Aug-2020 */ -class SodiumWrapper : LazySodiumAndroid { - -} +typealias SodiumWrapper = SodiumAndroid diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt index 2ea2e2f..9313ca7 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/LibsodiumInitializer.kt @@ -3,10 +3,10 @@ package com.ionspin.kotlin.crypto /** * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020 */ -expect object Initializer { +expect object LibsodiumInitializer { fun isInitialized() : Boolean suspend fun initialize() fun initializeWithCallback(done: () -> (Unit)) -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt index 763ea38..5d4c83c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/debug/test/DebugTest.kt @@ -1,79 +1,79 @@ -package debug.test - -import kotlin.Int -import kotlin.UByte -import kotlin.UByteArray -import kotlin.js.JsName - -expect class Sha256State - -expect class Sha512State - -expect class GenericHashState - -expect class SecretStreamState - -data class SecretStreamStateAndHeader( - @JsName("state") - val state: SecretStreamState, - @JsName("header") - val header: UByteArray -) - -data class DecryptedDataAndTag( - @JsName("decrypted") - val decrypted: UByteArray, - @JsName("tag") - val tag: UByte -) - -expect class Crypto internal constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - fun crypto_hash_sha256_init(): Sha256State - - fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) - - fun crypto_hash_sha256_final(state: Sha256State): UByteArray - - fun crypto_hash_sha512_init(): Sha512State - - fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) - - fun crypto_hash_sha512_final(state: Sha512State): UByteArray - - fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState - - /** - * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object. - */ - fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader - - /** - * Initialize state from header and key. The state can then be used for decryption. - */ - fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): - SecretStreamState - - /** - * Encrypt next block of data using the previously initialized state. Returns encrypted block. - */ - fun crypto_secretstream_xchacha20poly1305_push( - state: SecretStreamState, - m: UByteArray, - ad: UByteArray, - tag: UByte - ): UByteArray - - /** - * Decrypt next block of data using the previously initialized state. Returns decrypted block. - */ - fun crypto_secretstream_xchacha20poly1305_pull( - state: SecretStreamState, - c: UByteArray, - ad: UByteArray - ): DecryptedDataAndTag -} +//package debug.test +// +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +//import kotlin.js.JsName +// +//expect class Sha256State +// +//expect class Sha512State +// +//expect class GenericHashState +// +//expect class SecretStreamState +// +//data class SecretStreamStateAndHeader( +// @JsName("state") +// val state: SecretStreamState, +// @JsName("header") +// val header: UByteArray +//) +// +//data class DecryptedDataAndTag( +// @JsName("decrypted") +// val decrypted: UByteArray, +// @JsName("tag") +// val tag: UByte +//) +// +//expect class Crypto internal constructor() { +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// fun crypto_hash_sha256_init(): Sha256State +// +// fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) +// +// fun crypto_hash_sha256_final(state: Sha256State): UByteArray +// +// fun crypto_hash_sha512_init(): Sha512State +// +// fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) +// +// fun crypto_hash_sha512_final(state: Sha512State): UByteArray +// +// fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): SecretStreamStateAndHeader +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// SecretStreamState +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt index 8033e07..52e1d15 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -1,11 +1,9 @@ package com.ionspin.kotlin.crypto -import com.ionspin.kotlin.bignum.integer.BigInteger import com.ionspin.kotlin.crypto.generichash.GenericHashing import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.toHexString -import debug.test.Crypto import kotlin.test.Test import kotlin.test.assertTrue @@ -19,19 +17,7 @@ class SmokeTest { @Test fun testIfLibraryIsNotOnFire() { testBlocking { - Initializer.initialize() - val crypto = Crypto() -// //TODO seems to be a bug in JS compiler, if we have the same method name in crypto an in JsSodiumInterface, method tries to call wrong method name (unneeded suffix _0) -// //I've worked around this by making state functions with 1 parameter execute call with js("") wrap, but still might sail somewhere else -// val state256 = crypto.crypto_hash_sha256_init() -// crypto.crypto_hash_sha256_update(state256, "Hello".encodeToUByteArray()) -// val result = crypto.crypto_hash_sha256_final(state256) -// val resultString = result.toHexString() -// println("Result: $resultString") -// assertTrue { -// "185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969" == resultString -// } - //Blake512 Hello - EF15EAF92D5E335345A3E1D977BC7D8797C3D275717CC1B10AF79C93CDA01AEB2A0C59BC02E2BDF9380FD1B54EB9E1669026930CCC24BD49748E65F9A6B2EE68 + LibsodiumInitializer.initialize() val hashResult = GenericHashing.genericHash("Hello".encodeToUByteArray(), 64) println(hashResult.toHexString()) assertTrue { @@ -41,4 +27,5 @@ class SmokeTest { } } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt index 9567243..437304a 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt @@ -20,7 +20,7 @@ fun setSodiumLoaded(loaded: Boolean) { js("sodiumLoaded = loaded") } -actual object Initializer { +actual object LibsodiumInitializer { private var isPlatformInitialized = false actual suspend fun initialize() { @@ -40,4 +40,4 @@ actual object Initializer { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt index f5b75ff..43b49bc 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/debug/test/DebugTest.kt @@ -1,113 +1,113 @@ -package debug.test - -import com.ionspin.kotlin.crypto.getSodium -import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray -import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array -import kotlin.Any -import kotlin.Int -import kotlin.UByte -import kotlin.UByteArray -import org.khronos.webgl.Uint8Array - -actual typealias Sha256State = Any - -actual typealias Sha512State = Any - -actual typealias GenericHashState = Any - -actual typealias SecretStreamState = Any - -actual class Crypto internal actual constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): dynamic { - println("Debug crypto_hash_sha256_init") - val result = js("getSodium().crypto_hash_sha256_init()") - return result - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - getSodium().crypto_hash_sha256_update(state, input.toUInt8Array()) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - println("Debug crypto_hash_sha256_final") - return getSodium().crypto_hash_sha256_final(state).toUByteArray() - } - - actual fun crypto_hash_sha512_init(): dynamic { - println("Debug crypto_hash_sha512_init") - val result = js("getSodium().crypto_hash_sha512_init()") - return result - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - getSodium().crypto_hash_sha512_update(state, input.toUInt8Array()) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - println("Debug crypto_hash_sha512_final") - return getSodium().crypto_hash_sha512_final(state).toUByteArray() - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { - println("Debug crypto_generichash_init") - return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) - } - - /** - * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object. - */ - actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): - SecretStreamStateAndHeader { - println("Debug crypto_secretstream_xchacha20poly1305_init_push") - val stateAndHeader = - getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) - val state = stateAndHeader.state - val header = (stateAndHeader.header as Uint8Array).toUByteArray() - return SecretStreamStateAndHeader(state, header) - } - - /** - * Initialize state from header and key. The state can then be used for decryption. - */ - actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): - dynamic { - println("Debug crypto_secretstream_xchacha20poly1305_init_pull") - return getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), - key.toUInt8Array()) - } - - /** - * Encrypt next block of data using the previously initialized state. Returns encrypted block. - */ - actual fun crypto_secretstream_xchacha20poly1305_push( - state: SecretStreamState, - m: UByteArray, - ad: UByteArray, - tag: UByte - ): UByteArray { - println("Debug crypto_secretstream_xchacha20poly1305_push") - return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(), - ad.toUInt8Array(), tag).toUByteArray() - } - - /** - * Decrypt next block of data using the previously initialized state. Returns decrypted block. - */ - actual fun crypto_secretstream_xchacha20poly1305_pull( - state: SecretStreamState, - c: UByteArray, - ad: UByteArray - ): DecryptedDataAndTag { - println("Debug crypto_secretstream_xchacha20poly1305_pull") -// return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(), -// ad.toUInt8Array()) - return DecryptedDataAndTag(ubyteArrayOf(), 0U) - } -} +//package debug.test +// +//import com.ionspin.kotlin.crypto.getSodium +//import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +//import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +//import kotlin.Any +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +//import org.khronos.webgl.Uint8Array +// +//actual typealias Sha256State = Any +// +//actual typealias Sha512State = Any +// +//actual typealias GenericHashState = Any +// +//actual typealias SecretStreamState = Any +// +//actual class Crypto internal actual constructor() { +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// actual fun crypto_hash_sha256_init(): dynamic { +// println("Debug crypto_hash_sha256_init") +// val result = js("getSodium().crypto_hash_sha256_init()") +// return result +// } +// +// actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { +// println("Debug crypto_hash_sha256_update") +// getSodium().crypto_hash_sha256_update(state, input.toUInt8Array()) +// } +// +// actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { +// println("Debug crypto_hash_sha256_final") +// return getSodium().crypto_hash_sha256_final(state).toUByteArray() +// } +// +// actual fun crypto_hash_sha512_init(): dynamic { +// println("Debug crypto_hash_sha512_init") +// val result = js("getSodium().crypto_hash_sha512_init()") +// return result +// } +// +// actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { +// println("Debug crypto_hash_sha512_update") +// getSodium().crypto_hash_sha512_update(state, input.toUInt8Array()) +// } +// +// actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { +// println("Debug crypto_hash_sha512_final") +// return getSodium().crypto_hash_sha512_final(state).toUByteArray() +// } +// +// actual fun crypto_generichash_init(key: UByteArray, outlen: Int): dynamic { +// println("Debug crypto_generichash_init") +// return getSodium().crypto_generichash_init(key.toUInt8Array(), outlen) +// } +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): +// SecretStreamStateAndHeader { +// println("Debug crypto_secretstream_xchacha20poly1305_init_push") +// val stateAndHeader = +// getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) +// val state = stateAndHeader.state +// val header = (stateAndHeader.header as Uint8Array).toUByteArray() +// return SecretStreamStateAndHeader(state, header) +// } +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// dynamic { +// println("Debug crypto_secretstream_xchacha20poly1305_init_pull") +// return getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), +// key.toUInt8Array()) +// } +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray { +// println("Debug crypto_secretstream_xchacha20poly1305_push") +// return getSodium().crypto_secretstream_xchacha20poly1305_push(state, m.toUInt8Array(), +// ad.toUInt8Array(), tag).toUByteArray() +// } +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag { +// println("Debug crypto_secretstream_xchacha20poly1305_pull") +//// return getSodium().crypto_secretstream_xchacha20poly1305_pull(state, c.toUInt8Array(), +//// ad.toUInt8Array()) +// return DecryptedDataAndTag(ubyteArrayOf(), 0U) +// } +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt index 2af22a3..0f72b4b 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt @@ -1,21 +1,19 @@ package com.ionspin.kotlin.crypto -import com.goterl.lazycode.lazysodium.SodiumJava - /** * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 02/Aug/2020 */ -actual object Initializer { +actual object LibsodiumInitializer { private var isPlatformInitialized = false - lateinit var sodium : SodiumJava + lateinit var sodium : SodiumWrapper actual suspend fun initialize() { - sodium = SodiumJava() + sodium = SodiumWrapper() isPlatformInitialized = true } actual fun initializeWithCallback(done: () -> Unit) { - sodium = SodiumJava() + sodium = SodiumWrapper() isPlatformInitialized = true done() } @@ -24,4 +22,4 @@ actual object Initializer { return isPlatformInitialized } -} \ No newline at end of file +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt index 90dd443..c54dfc1 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt @@ -1,6 +1,6 @@ package com.ionspin.kotlin.crypto.generichash -import com.ionspin.kotlin.crypto.Initializer.sodium +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium /** * Created by Ugljesa Jovanovic diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt index f970b12..178c9c3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/debug/test/DebugTest.kt @@ -1,128 +1,128 @@ -package debug.test - -import com.goterl.lazycode.lazysodium.SodiumJava -import com.goterl.lazycode.lazysodium.interfaces.Hash -import com.goterl.lazycode.lazysodium.interfaces.SecretStream -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByte -import kotlin.UByteArray - -val sodium: SodiumJava = SodiumJava() - -actual typealias Sha256State = Hash.State256 - -actual typealias Sha512State = Hash.State512 - -actual typealias GenericHashState = ByteArray - -actual typealias SecretStreamState = SecretStream.State - -actual class Crypto internal actual constructor() { - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): Sha256State { - val state = debug.test.Sha256State() - println("Debug crypto_hash_sha256_init") - sodium.crypto_hash_sha256_init(state) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - sodium.crypto_hash_sha256_final(state, out.asByteArray()) - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val state = debug.test.Sha512State() - println("Debug crypto_hash_sha512_init") - sodium.crypto_hash_sha512_init(state) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - sodium.crypto_hash_sha512_final(state, out.asByteArray()) - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) - println("Debug crypto_generichash_init") - sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) - return state - } - - /** - * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object. - */ - actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): - SecretStreamStateAndHeader { - println("Debug crypto_secretstream_xchacha20poly1305_init_push") - val header = UByteArray(24) - val state = SecretStream.State() - sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), - key.asByteArray()) - return SecretStreamStateAndHeader(state, header) - } - - /** - * Initialize state from header and key. The state can then be used for decryption. - */ - actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): - SecretStreamState { - val state = debug.test.SecretStreamState() - println("Debug crypto_secretstream_xchacha20poly1305_init_pull") - sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), - key.asByteArray()) - return state - } - - /** - * Encrypt next block of data using the previously initialized state. Returns encrypted block. - */ - actual fun crypto_secretstream_xchacha20poly1305_push( - state: SecretStreamState, - m: UByteArray, - ad: UByteArray, - tag: UByte - ): UByteArray { - val c = UByteArray(m.size + 17) - println("Debug crypto_secretstream_xchacha20poly1305_push") - sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(), - m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte()) - return c - } - - /** - * Decrypt next block of data using the previously initialized state. Returns decrypted block. - */ - actual fun crypto_secretstream_xchacha20poly1305_pull( - state: SecretStreamState, - c: UByteArray, - ad: UByteArray - ): DecryptedDataAndTag { - val m = UByteArray(c.size - 17) - var tag_p : UByte = 0U - println("Debug crypto_secretstream_xchacha20poly1305_pull") - sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, byteArrayOf(), - c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) - return debug.test.DecryptedDataAndTag(m, tag_p) - } -} +//package debug.test +// +//import com.goterl.lazycode.lazysodium.SodiumJava +//import com.goterl.lazycode.lazysodium.interfaces.Hash +//import com.goterl.lazycode.lazysodium.interfaces.SecretStream +//import kotlin.ByteArray +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +// +//val sodium: SodiumJava = SodiumJava() +// +//actual typealias Sha256State = Hash.State256 +// +//actual typealias Sha512State = Hash.State512 +// +//actual typealias GenericHashState = ByteArray +// +//actual typealias SecretStreamState = SecretStream.State +// +//actual class Crypto internal actual constructor() { +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// actual fun crypto_hash_sha256_init(): Sha256State { +// val state = debug.test.Sha256State() +// println("Debug crypto_hash_sha256_init") +// sodium.crypto_hash_sha256_init(state) +// return state +// } +// +// actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { +// println("Debug crypto_hash_sha256_update") +// sodium.crypto_hash_sha256_update(state, input.asByteArray(), input.size.toLong()) +// } +// +// actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { +// val out = UByteArray(32) +// println("Debug crypto_hash_sha256_final") +// sodium.crypto_hash_sha256_final(state, out.asByteArray()) +// return out +// } +// +// actual fun crypto_hash_sha512_init(): Sha512State { +// val state = debug.test.Sha512State() +// println("Debug crypto_hash_sha512_init") +// sodium.crypto_hash_sha512_init(state) +// return state +// } +// +// actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { +// println("Debug crypto_hash_sha512_update") +// sodium.crypto_hash_sha512_update(state, input.asByteArray(), input.size.toLong()) +// } +// +// actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { +// val out = UByteArray(64) +// println("Debug crypto_hash_sha512_final") +// sodium.crypto_hash_sha512_final(state, out.asByteArray()) +// return out +// } +// +// actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { +// val state = debug.test.GenericHashState(sodium.crypto_generichash_statebytes()) +// println("Debug crypto_generichash_init") +// sodium.crypto_generichash_init(state, key.asByteArray(), key.size, outlen) +// return state +// } +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): +// SecretStreamStateAndHeader { +// println("Debug crypto_secretstream_xchacha20poly1305_init_push") +// val header = UByteArray(24) +// val state = SecretStream.State() +// sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), +// key.asByteArray()) +// return SecretStreamStateAndHeader(state, header) +// } +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// SecretStreamState { +// val state = debug.test.SecretStreamState() +// println("Debug crypto_secretstream_xchacha20poly1305_init_pull") +// sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), +// key.asByteArray()) +// return state +// } +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray { +// val c = UByteArray(m.size + 17) +// println("Debug crypto_secretstream_xchacha20poly1305_push") +// sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(), +// m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte()) +// return c +// } +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag { +// val m = UByteArray(c.size - 17) +// var tag_p : UByte = 0U +// println("Debug crypto_secretstream_xchacha20poly1305_pull") +// sodium.crypto_secretstream_xchacha20poly1305_pull(state, m.asByteArray(), null, byteArrayOf(), +// c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) +// return debug.test.DecryptedDataAndTag(m, tag_p) +// } +//} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt b/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt index 7c84820..eb62fc6 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmSpecific/com/ionspin/kotlin/crypto/JvmSodiumWrapper.kt @@ -8,6 +8,4 @@ import com.goterl.lazycode.lazysodium.SodiumJava * ugljesa.jovanovic@ionspin.com * on 22-Aug-2020 */ -class ASodiumWrapper : SodiumJava() { - -} +typealias SodiumWrapper = SodiumJava diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt index 944c199..5f6ae73 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/LibsodiumInitializer.kt @@ -5,7 +5,7 @@ package com.ionspin.kotlin.crypto import libsodium.sodium_init import kotlin.native.concurrent.AtomicInt -actual object Initializer { +actual object LibsodiumInitializer { private var isPlatformInitialized : AtomicInt = AtomicInt(0) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt index 265ec22..4d54d53 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt @@ -1,29 +1,19 @@ package com.ionspin.kotlin.crypto.generichash -import kotlin.Byte -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByte -import kotlin.UByteArray import kotlinx.cinterop.addressOf import kotlinx.cinterop.convert import kotlinx.cinterop.pin -import kotlinx.cinterop.pointed -import kotlinx.cinterop.ptr -import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.toCValues import libsodium.crypto_generichash -import libsodium.crypto_generichash_blake2b_state -import libsodium.crypto_hash_sha256_state -import libsodium.crypto_hash_sha512_state -import libsodium.crypto_secretstream_xchacha20poly1305_state -import libsodium.sodium_malloc + /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 21-Aug-2020 */ actual object GenericHashing { + val _emitByte: Byte = 0 + val _emitByteArray: ByteArray = ByteArray(0) + actual fun genericHash(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray { val hash = UByteArray(requestedHashLength) val pinnedHash = hash.pin() diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt index dd148b9..7496ed9 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/debug/test/DebugTest.kt @@ -1,179 +1,179 @@ -package debug.test - -import kotlin.Byte -import kotlin.ByteArray -import kotlin.Int -import kotlin.UByte -import kotlin.UByteArray -import kotlinx.cinterop.addressOf -import kotlinx.cinterop.convert -import kotlinx.cinterop.pin -import kotlinx.cinterop.pointed -import kotlinx.cinterop.ptr -import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.toCValues -import libsodium.crypto_generichash_blake2b_state -import libsodium.crypto_hash_sha256_state -import libsodium.crypto_hash_sha512_state -import libsodium.crypto_secretstream_xchacha20poly1305_state -import libsodium.sodium_malloc - -actual typealias Sha256State = crypto_hash_sha256_state - -actual typealias Sha512State = crypto_hash_sha512_state - -actual typealias GenericHashState = crypto_generichash_blake2b_state - -actual typealias SecretStreamState = crypto_secretstream_xchacha20poly1305_state - -actual class Crypto internal actual constructor() { - val _emitByte: Byte = 0 - - val _emitByteArray: ByteArray = ByteArray(0) - - /** - * Initialize the SHA256 hash - * returns sha 256 state - */ - actual fun crypto_hash_sha256_init(): Sha256State { - val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha256_init") - libsodium.crypto_hash_sha256_init(state.ptr) - return state - } - - actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { - println("Debug crypto_hash_sha256_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { - val out = UByteArray(32) - println("Debug crypto_hash_sha256_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_hash_sha512_init(): Sha512State { - val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_hash_sha512_init") - libsodium.crypto_hash_sha512_init(state.ptr) - return state - } - - actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { - println("Debug crypto_hash_sha512_update") - val pinnedInput = input.pin() - libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) - pinnedInput.unpin() - } - - actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { - val out = UByteArray(64) - println("Debug crypto_hash_sha512_final") - val pinnedOut = out.pin() - libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) - pinnedOut.unpin() - return out - } - - actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { - val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_generichash_init") - val pinnedKey = key.pin() - libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), - outlen.convert()) - pinnedKey.unpin() - return state - } - - /** - * Initialize a state and generate a random header. Both are returned inside - * `SecretStreamStateAndHeader` object. - */ - actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): - SecretStreamStateAndHeader { - println("Debug crypto_secretstream_xchacha20poly1305_init_push") - val pinnedKey = key.pin() - val state = - sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! - .reinterpret() - .pointed - val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) - { 0U } - val pinnedHeader = header.pin() - libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, - pinnedHeader.addressOf(0), pinnedKey.addressOf(0)) - pinnedHeader.unpin() - pinnedKey.unpin() - return SecretStreamStateAndHeader(state, header) - } - - /** - * Initialize state from header and key. The state can then be used for decryption. - */ - actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): - SecretStreamState { - val allocated = sodium_malloc(debug.test.SecretStreamState.size.convert())!! - val state = allocated.reinterpret().pointed - println("Debug crypto_secretstream_xchacha20poly1305_init_pull") - val pinnedHeader = header.pin() - val pinnedKey = key.pin() - libsodium.crypto_secretstream_xchacha20poly1305_init_pull(state.ptr, pinnedHeader.addressOf(0), - pinnedKey.addressOf(0)) - pinnedHeader.unpin() - pinnedKey.unpin() - return state - } - - /** - * Encrypt next block of data using the previously initialized state. Returns encrypted block. - */ - actual fun crypto_secretstream_xchacha20poly1305_push( - state: SecretStreamState, - m: UByteArray, - ad: UByteArray, - tag: UByte - ): UByteArray { - val c = UByteArray(m.size + 17) - println("Debug crypto_secretstream_xchacha20poly1305_push") - val pinnedC = c.pin() - val pinnedM = m.pin() - val pinnedAd = ad.pin() - libsodium.crypto_secretstream_xchacha20poly1305_push(state.ptr, pinnedC.addressOf(0), null, - pinnedM.addressOf(0), m.size.convert(), pinnedAd.addressOf(0), ad.size.convert(), tag) - pinnedC.unpin() - pinnedM.unpin() - pinnedAd.unpin() - return c - } - - /** - * Decrypt next block of data using the previously initialized state. Returns decrypted block. - */ - actual fun crypto_secretstream_xchacha20poly1305_pull( - state: SecretStreamState, - c: UByteArray, - ad: UByteArray - ): DecryptedDataAndTag { - val m = UByteArray(c.size - 17) - var tag_p : UByte = 0U - println("Debug crypto_secretstream_xchacha20poly1305_pull") - val pinnedM = m.pin() - val pinnedC = c.pin() - val pinnedAd = ad.pin() - libsodium.crypto_secretstream_xchacha20poly1305_pull(state.ptr, pinnedM.addressOf(0), null, - ubyteArrayOf().toCValues(), pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) - pinnedM.unpin() - pinnedC.unpin() - pinnedAd.unpin() - return debug.test.DecryptedDataAndTag(m, tag_p) - } -} +//package debug.test +// +//import kotlin.Byte +//import kotlin.ByteArray +//import kotlin.Int +//import kotlin.UByte +//import kotlin.UByteArray +//import kotlinx.cinterop.addressOf +//import kotlinx.cinterop.convert +//import kotlinx.cinterop.pin +//import kotlinx.cinterop.pointed +//import kotlinx.cinterop.ptr +//import kotlinx.cinterop.reinterpret +//import kotlinx.cinterop.toCValues +//import libsodium.crypto_generichash_blake2b_state +//import libsodium.crypto_hash_sha256_state +//import libsodium.crypto_hash_sha512_state +//import libsodium.crypto_secretstream_xchacha20poly1305_state +//import libsodium.sodium_malloc +// +//actual typealias Sha256State = crypto_hash_sha256_state +// +//actual typealias Sha512State = crypto_hash_sha512_state +// +//actual typealias GenericHashState = crypto_generichash_blake2b_state +// +//actual typealias SecretStreamState = crypto_secretstream_xchacha20poly1305_state +// +//actual class Crypto internal actual constructor() { +// val _emitByte: Byte = 0 +// +// val _emitByteArray: ByteArray = ByteArray(0) +// +// /** +// * Initialize the SHA256 hash +// * returns sha 256 state +// */ +// actual fun crypto_hash_sha256_init(): Sha256State { +// val allocated = sodium_malloc(debug.test.Sha256State.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_hash_sha256_init") +// libsodium.crypto_hash_sha256_init(state.ptr) +// return state +// } +// +// actual fun crypto_hash_sha256_update(state: Sha256State, input: UByteArray) { +// println("Debug crypto_hash_sha256_update") +// val pinnedInput = input.pin() +// libsodium.crypto_hash_sha256_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) +// pinnedInput.unpin() +// } +// +// actual fun crypto_hash_sha256_final(state: Sha256State): UByteArray { +// val out = UByteArray(32) +// println("Debug crypto_hash_sha256_final") +// val pinnedOut = out.pin() +// libsodium.crypto_hash_sha256_final(state.ptr, pinnedOut.addressOf(0)) +// pinnedOut.unpin() +// return out +// } +// +// actual fun crypto_hash_sha512_init(): Sha512State { +// val allocated = sodium_malloc(debug.test.Sha512State.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_hash_sha512_init") +// libsodium.crypto_hash_sha512_init(state.ptr) +// return state +// } +// +// actual fun crypto_hash_sha512_update(state: Sha512State, input: UByteArray) { +// println("Debug crypto_hash_sha512_update") +// val pinnedInput = input.pin() +// libsodium.crypto_hash_sha512_update(state.ptr, pinnedInput.addressOf(0), input.size.convert()) +// pinnedInput.unpin() +// } +// +// actual fun crypto_hash_sha512_final(state: Sha512State): UByteArray { +// val out = UByteArray(64) +// println("Debug crypto_hash_sha512_final") +// val pinnedOut = out.pin() +// libsodium.crypto_hash_sha512_final(state.ptr, pinnedOut.addressOf(0)) +// pinnedOut.unpin() +// return out +// } +// +// actual fun crypto_generichash_init(key: UByteArray, outlen: Int): GenericHashState { +// val allocated = sodium_malloc(debug.test.GenericHashState.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_generichash_init") +// val pinnedKey = key.pin() +// libsodium.crypto_generichash_init(state.ptr, pinnedKey.addressOf(0), key.size.convert(), +// outlen.convert()) +// pinnedKey.unpin() +// return state +// } +// +// /** +// * Initialize a state and generate a random header. Both are returned inside +// * `SecretStreamStateAndHeader` object. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_push(key: UByteArray): +// SecretStreamStateAndHeader { +// println("Debug crypto_secretstream_xchacha20poly1305_init_push") +// val pinnedKey = key.pin() +// val state = +// sodium_malloc(libsodium.crypto_secretstream_xchacha20poly1305_state.size.convert())!! +// .reinterpret() +// .pointed +// val header = UByteArray(libsodium.crypto_secretstream_xchacha20poly1305_HEADERBYTES.toInt()) +// { 0U } +// val pinnedHeader = header.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_init_push(state.ptr, +// pinnedHeader.addressOf(0), pinnedKey.addressOf(0)) +// pinnedHeader.unpin() +// pinnedKey.unpin() +// return SecretStreamStateAndHeader(state, header) +// } +// +// /** +// * Initialize state from header and key. The state can then be used for decryption. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_init_pull(header: UByteArray, key: UByteArray): +// SecretStreamState { +// val allocated = sodium_malloc(debug.test.SecretStreamState.size.convert())!! +// val state = allocated.reinterpret().pointed +// println("Debug crypto_secretstream_xchacha20poly1305_init_pull") +// val pinnedHeader = header.pin() +// val pinnedKey = key.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_init_pull(state.ptr, pinnedHeader.addressOf(0), +// pinnedKey.addressOf(0)) +// pinnedHeader.unpin() +// pinnedKey.unpin() +// return state +// } +// +// /** +// * Encrypt next block of data using the previously initialized state. Returns encrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_push( +// state: SecretStreamState, +// m: UByteArray, +// ad: UByteArray, +// tag: UByte +// ): UByteArray { +// val c = UByteArray(m.size + 17) +// println("Debug crypto_secretstream_xchacha20poly1305_push") +// val pinnedC = c.pin() +// val pinnedM = m.pin() +// val pinnedAd = ad.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_push(state.ptr, pinnedC.addressOf(0), null, +// pinnedM.addressOf(0), m.size.convert(), pinnedAd.addressOf(0), ad.size.convert(), tag) +// pinnedC.unpin() +// pinnedM.unpin() +// pinnedAd.unpin() +// return c +// } +// +// /** +// * Decrypt next block of data using the previously initialized state. Returns decrypted block. +// */ +// actual fun crypto_secretstream_xchacha20poly1305_pull( +// state: SecretStreamState, +// c: UByteArray, +// ad: UByteArray +// ): DecryptedDataAndTag { +// val m = UByteArray(c.size - 17) +// var tag_p : UByte = 0U +// println("Debug crypto_secretstream_xchacha20poly1305_pull") +// val pinnedM = m.pin() +// val pinnedC = c.pin() +// val pinnedAd = ad.pin() +// libsodium.crypto_secretstream_xchacha20poly1305_pull(state.ptr, pinnedM.addressOf(0), null, +// ubyteArrayOf().toCValues(), pinnedC.addressOf(0), c.size.convert(), pinnedAd.addressOf(0), ad.size.convert()) +// pinnedM.unpin() +// pinnedC.unpin() +// pinnedAd.unpin() +// return debug.test.DecryptedDataAndTag(m, tag_p) +// } +//} From 6f38a01195e38765e277489805a4ea9bd9d8b06e Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Wed, 26 Aug 2020 19:58:57 +0200 Subject: [PATCH 14/65] Fixed some of the errors spotted in various aes implementation while doing cryptopals challenge, anyways they were unused. Added multipart generic hash (blake2b) native implementation --- .../kotlin/crypto/JsSodiumInterface.kt | 2 +- .../generichash/GenericHashing.kt | 16 ++++++ .../crypto/generichash/GenericHashing.kt | 57 +++++++++++++++++++ .../kotlin/crypto/symmetric/AesCbcPure.kt | 10 ++-- .../kotlin/crypto/symmetric/AesCtrPure.kt | 8 +-- .../kotlin/crypto/symmetric/AesCbcTest.kt | 6 +- 6 files changed, 88 insertions(+), 11 deletions(-) diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 6694723..1934eb9 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -50,7 +50,7 @@ interface JsSodiumInterface { //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : Uint8Array + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt index 85aac10..4d3373d 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt @@ -5,6 +5,22 @@ package com.ionspin.kotlin.crypto.generichash * ugljesa.jovanovic@ionspin.com * on 21-Aug-2020 */ + +data class GenericHashState(val hashLength: Int, val state: GenericHashStateInternal) + +expect class GenericHashStateInternal + expect object GenericHashing { + + + + fun genericHash(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray + + fun genericHashInit(requestedHashLength: Int, key : UByteArray? = null) : GenericHashState + fun genericHashUpdate(state: GenericHashState, messagePart : UByteArray) + fun genericHashFinal(state : GenericHashState) : UByteArray + } + + diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt index 4d54d53..ac7f26e 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt @@ -3,17 +3,30 @@ package com.ionspin.kotlin.crypto.generichash import kotlinx.cinterop.addressOf import kotlinx.cinterop.convert import kotlinx.cinterop.pin +import kotlinx.cinterop.pointed +import kotlinx.cinterop.ptr +import kotlinx.cinterop.reinterpret import libsodium.crypto_generichash +import libsodium.crypto_generichash_final +import libsodium.crypto_generichash_init +import libsodium.crypto_generichash_state +import libsodium.crypto_generichash_update +import platform.posix.malloc /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 21-Aug-2020 */ + +actual typealias GenericHashStateInternal = libsodium.crypto_generichash_blake2b_state + actual object GenericHashing { val _emitByte: Byte = 0 val _emitByteArray: ByteArray = ByteArray(0) + + actual fun genericHash(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray { val hash = UByteArray(requestedHashLength) val pinnedHash = hash.pin() @@ -32,4 +45,48 @@ actual object GenericHashing { pinnedMessage.unpin() return hash } + + actual fun genericHashInit( + requestedHashLength: Int, + key: UByteArray? + ): GenericHashState { + val stateAllocated = malloc(GenericHashStateInternal.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + val pinnedKey = key?.pin() + crypto_generichash_init( + statePointed.ptr, + pinnedKey?.addressOf(0), + (key?.size ?: 0).convert(), + requestedHashLength.convert() + ) + pinnedKey?.unpin() + return GenericHashState(requestedHashLength, statePointed) + } + + actual fun genericHashUpdate( + state: GenericHashState, + messagePart: UByteArray + ) { + val pinnedMessage = messagePart.pin() + crypto_generichash_update( + state.state.ptr, + pinnedMessage.addressOf(0), + messagePart.size.convert() + ) + pinnedMessage.unpin() + } + + actual fun genericHashFinal(state: GenericHashState): UByteArray { + val hashResult = UByteArray(state.hashLength) + val hashResultPinned = hashResult.pin() + crypto_generichash_final( + state.state.ptr, + hashResultPinned.addressOf(0), + state.hashLength.convert() + ) + hashResultPinned.unpin() + return hashResult + } + + } diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt index 94cbf76..ae9acbd 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcPure.kt @@ -145,7 +145,8 @@ internal class AesCbcPure internal constructor(val aesKey: InternalAesKey, val m } /** - * Encrypt fed data and return it alongside the randomly chosen initialization vector + * Encrypt fed data and return it alongside the randomly chosen initialization vector. + * This also applies correct PKCS#7 padding * @return Encrypted data and initialization vector */ fun encrypt(): EncryptedDataAndInitializationVector { @@ -158,6 +159,8 @@ internal class AesCbcPure internal constructor(val aesKey: InternalAesKey, val m } else { output += consumeBlock(lastBlockPadded) } + } else { + output += consumeBlock(UByteArray(BLOCK_BYTES) { BLOCK_BYTES.toUByte()}) } return EncryptedDataAndInitializationVector( output.reversed().foldRight(UByteArray(0) { 0U }) { arrayOfUBytes, acc -> acc + arrayOfUBytes }, @@ -172,11 +175,10 @@ internal class AesCbcPure internal constructor(val aesKey: InternalAesKey, val m fun decrypt(): UByteArray { val removePaddingCount = output.last().last() - val removedPadding = if (removePaddingCount > 0U && removePaddingCount < 16U) { output.last().dropLast(removePaddingCount.toInt() and 0x7F) } else { - output.last().toList() + ubyteArrayOf() }.toUByteArray() val preparedOutput = (output.dropLast(1) + listOf(removedPadding)) //JS compiler freaks out here if we don't supply exact type @@ -238,4 +240,4 @@ data class EncryptedDataAndInitializationVector(val encryptedData : UByteArray, result = 31 * result + initializationVector.contentHashCode() return result } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt index e477d39..b9f4ff9 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt @@ -54,8 +54,8 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m * Creates and returns AesCtr instance that can be fed data using [addData]. Once you have submitted all * data call [decrypt] */ - fun createDecryptor(aesKey : InternalAesKey) : AesCtrPure { - return AesCtrPure(aesKey, Mode.DECRYPT) + fun createDecryptor(aesKey : InternalAesKey, initialCounter: UByteArray) : AesCtrPure { + return AesCtrPure(aesKey, Mode.DECRYPT, initialCounter = initialCounter) } /** * Bulk encryption, returns encrypted data and a random initial counter @@ -68,8 +68,8 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m /** * Bulk decryption, returns decrypted data */ - fun decrypt(aesKey: InternalAesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { - val aesCtr = AesCtrPure(aesKey, Mode.DECRYPT, initialCounter) + fun decrypt(aesKey: InternalAesKey, data: UByteArray, initialCounter: UByteArray): UByteArray { + val aesCtr = AesCtrPure(aesKey, Mode.DECRYPT, initialCounter = initialCounter) aesCtr.addData(data) return aesCtr.decrypt() } diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt index 8a6af88..7b86d77 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt @@ -35,7 +35,9 @@ class AesCbcTest { val key = "4278b840fb44aaa757c1bf04acbe1a3e" val iv = "57f02a5c5339daeb0a2908a06ac6393f" val plaintext = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" - val expectedCipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" + val expectedCipherText = "479c89ec14bc98994e62b2c705b5014e" + + "175bd7832e7e60a1e92aac568a861eb7" + + "fc2dc2f4a527ce39f79c56b31432c779" val aesCbc = AesCbcPure(InternalAesKey.Aes128Key(key), mode = Mode.ENCRYPT, initializationVector = iv.hexStringToUByteArray()) aesCbc.addData(plaintext.hexStringToUByteArray()) @@ -104,4 +106,4 @@ class AesCbcTest { -} \ No newline at end of file +} From 39f08173082abb688f27db1e4683d268066b2004 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Wed, 26 Aug 2020 22:15:03 +0200 Subject: [PATCH 15/65] Adding secret stream impl, completed generichash impl --- .../{GenericHashing.kt => GenericHash.kt} | 7 +-- .../secretstream/SecretStream.kt | 21 ++++++++ .../com/ionspin/kotlin/crypto/SmokeTest.kt | 4 +- .../kotlin/crypto/generichash/GenericHash.kt | 47 ++++++++++++++++ .../crypto/generichash/GenericHashing.kt | 25 --------- .../kotlin/crypto/generichash/GenericHash.kt | 53 +++++++++++++++++++ .../crypto/generichash/GenericHashing.kt | 27 ---------- .../{GenericHashing.kt => GenericHash.kt} | 7 ++- .../crypto/secretstream/SecretStream.kt | 34 ++++++++++++ 9 files changed, 162 insertions(+), 63 deletions(-) rename multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/{GenericHashing.kt => GenericHash.kt} (81%) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt delete mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt delete mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt rename multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/{GenericHashing.kt => GenericHash.kt} (95%) create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt similarity index 81% rename from multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt rename to multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt index 4d3373d..b66c2d1 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHashing.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt @@ -6,14 +6,11 @@ package com.ionspin.kotlin.crypto.generichash * on 21-Aug-2020 */ -data class GenericHashState(val hashLength: Int, val state: GenericHashStateInternal) +data class GenericHashState(val hashLength: Int, val internalState: GenericHashStateInternal) expect class GenericHashStateInternal -expect object GenericHashing { - - - +expect object GenericHash { fun genericHash(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt new file mode 100644 index 0000000..847298f --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt @@ -0,0 +1,21 @@ +package com.ionspin.kotlin.crypto.secretstream + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 26-Aug-2020 + */ +expect class SecretStreamState + +data class SecretStreamStateAndHeader(val state: SecretStreamState, val header : UByteArray) + +data class DecryptedDataAndTag(val decryptedData : UByteArray, val tag : UByte) + +expect object SecretStream { + + fun xChaCha20Poly1305InitPush(key: UByteArray) : SecretStreamStateAndHeader + fun xChaCha20Poly1305Push(state : SecretStreamState, message: UByteArray, additionalData : UByteArray = ubyteArrayOf(), tag: UByte) : UByteArray + fun xChaCha20Poly1305InitPull(key: UByteArray, header: UByteArray) : SecretStreamStateAndHeader + fun xChaCha20Poly1305Pull(state : SecretStreamState, ciphertext: UByteArray, additionalData : UByteArray = ubyteArrayOf()) : DecryptedDataAndTag + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt index 52e1d15..e9aca50 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -1,6 +1,6 @@ package com.ionspin.kotlin.crypto -import com.ionspin.kotlin.crypto.generichash.GenericHashing +import com.ionspin.kotlin.crypto.generichash.GenericHash import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import com.ionspin.kotlin.crypto.util.toHexString @@ -18,7 +18,7 @@ class SmokeTest { fun testIfLibraryIsNotOnFire() { testBlocking { LibsodiumInitializer.initialize() - val hashResult = GenericHashing.genericHash("Hello".encodeToUByteArray(), 64) + val hashResult = GenericHash.genericHash("Hello".encodeToUByteArray(), 64) println(hashResult.toHexString()) assertTrue { "EF15EAF92D5E335345A3E1D977BC7D8797C3D275717CC1B10AF79C93CDA01AEB2A0C59BC02E2BDF9380FD1B54EB9E1669026930CCC24BD49748E65F9A6B2EE68".toLowerCase() == hashResult.toHexString() diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt new file mode 100644 index 0000000..7a91cc1 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -0,0 +1,47 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ + +actual typealias GenericHashStateInternal = Any + +actual object GenericHash { + actual fun genericHash( + message: UByteArray, + requestedHashLength: Int, + key: UByteArray? + ): UByteArray { + return getSodium().crypto_generichash( + requestedHashLength, + message.toUInt8Array(), + key?.toUInt8Array() ?: Uint8Array(0) + ).toUByteArray() + } + + actual fun genericHashInit( + requestedHashLength: Int, + key: UByteArray? + ): GenericHashState { + val state = getSodium().crypto_generichash_init(key.toUInt8Array(), requestedHashLength) + return GenericHashState(requestedHashLength, state) + } + + actual fun genericHashUpdate( + state: GenericHashState, + messagePart: UByteArray + ) { + getSodium().crypto_generichash_update(state.internalState, messagePart.toUInt8Array()) + } + + actual fun genericHashFinal(state: GenericHashState): UByteArray { + return getSodium().crypto_generichash_final(state.internalState, state.hashLength).toUByteArray() + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt deleted file mode 100644 index 8cbc72b..0000000 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.ionspin.kotlin.crypto.generichash - -import com.ionspin.kotlin.crypto.getSodium -import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray -import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array -import org.khronos.webgl.Uint8Array - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 21-Aug-2020 - */ -actual object GenericHashing { - actual fun genericHash( - message: UByteArray, - requestedHashLength: Int, - key: UByteArray? - ): UByteArray { - return getSodium().crypto_generichash( - requestedHashLength, - message.toUInt8Array(), - key?.toUInt8Array() ?: Uint8Array(0) - ).toUByteArray() - } -} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt new file mode 100644 index 0000000..f94586c --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -0,0 +1,53 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual class GenericHashStateInternal(internal val data: ByteArray) + +actual object GenericHash { + actual fun genericHash( + message: UByteArray, + requestedHashLength: Int, + key: UByteArray? + ): UByteArray { + val hash = UByteArray(requestedHashLength) + sodium.crypto_generichash( + hash.asByteArray(), + requestedHashLength, + message.asByteArray(), + message.size.toLong(), + key?.asByteArray(), + (key?.size ?: 0) + ) + return hash + } + + actual fun genericHashInit( + requestedHashLength: Int, + key: UByteArray? + ): GenericHashState { + val state = GenericHashStateInternal(ByteArray(sodium.crypto_generichash_statebytes())) + sodium.crypto_generichash_init(state.data, key?.asByteArray(), key?.size ?: 0, requestedHashLength) + return GenericHashState(requestedHashLength, state) + } + + actual fun genericHashUpdate( + state: GenericHashState, + messagePart: UByteArray + ) { + sodium.crypto_generichash_update(state.internalState.data, messagePart.asByteArray(), messagePart.size.toLong()) + } + + actual fun genericHashFinal(state: GenericHashState): UByteArray { + val hashResult = ByteArray(state.hashLength) + sodium.crypto_generichash_final(state.internalState.data, hashResult, state.hashLength) + return hashResult.asUByteArray() + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt deleted file mode 100644 index c54dfc1..0000000 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.ionspin.kotlin.crypto.generichash - -import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 21-Aug-2020 - */ -actual object GenericHashing { - actual fun genericHash( - message: UByteArray, - requestedHashLength: Int, - key: UByteArray? - ): UByteArray { - val hash = UByteArray(requestedHashLength) - sodium.crypto_generichash( - hash.asByteArray(), - requestedHashLength, - message.asByteArray(), - message.size.toLong(), - key?.asByteArray(), - (key?.size ?: 0) - ) - return hash - } -} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt similarity index 95% rename from multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt rename to multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt index ac7f26e..c10ac4f 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashing.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -9,7 +9,6 @@ import kotlinx.cinterop.reinterpret import libsodium.crypto_generichash import libsodium.crypto_generichash_final import libsodium.crypto_generichash_init -import libsodium.crypto_generichash_state import libsodium.crypto_generichash_update import platform.posix.malloc @@ -21,7 +20,7 @@ import platform.posix.malloc actual typealias GenericHashStateInternal = libsodium.crypto_generichash_blake2b_state -actual object GenericHashing { +actual object GenericHash { val _emitByte: Byte = 0 val _emitByteArray: ByteArray = ByteArray(0) @@ -69,7 +68,7 @@ actual object GenericHashing { ) { val pinnedMessage = messagePart.pin() crypto_generichash_update( - state.state.ptr, + state.internalState.ptr, pinnedMessage.addressOf(0), messagePart.size.convert() ) @@ -80,7 +79,7 @@ actual object GenericHashing { val hashResult = UByteArray(state.hashLength) val hashResultPinned = hashResult.pin() crypto_generichash_final( - state.state.ptr, + state.internalState.ptr, hashResultPinned.addressOf(0), state.hashLength.convert() ) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt new file mode 100644 index 0000000..3b38152 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -0,0 +1,34 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual typealias SecretStreamState = libsodium.crypto_secretstream_xchacha20poly1305_state + +actual object SecretStream { + actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305Push( + state: SecretStreamState, + message: UByteArray, + additionalData: UByteArray, + tag: UByte + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305InitPull( + key: UByteArray, + header: UByteArray + ): SecretStreamStateAndHeader { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305Pull( + state: SecretStreamState, + ciphertext: UByteArray, + additionalData: UByteArray + ): DecryptedDataAndTag { + TODO("not implemented yet") + } + +} From 2c92a8142fbe2e5ec304cb9db68f01934d7f9bc5 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Wed, 26 Aug 2020 22:33:55 +0200 Subject: [PATCH 16/65] Add generic hash tests, add templates for secret stream jvm and js --- .../com/ionspin/kotlin/crypto/SmokeTest.kt | 2 +- .../crypto/generichash/GenericHashTest.kt | 74 +++++++++++++++++++ .../kotlin/crypto/generichash/GenericHash.kt | 2 +- .../crypto/secretstream/SecretStream.kt | 34 +++++++++ .../crypto/secretstream/SecretStream.kt | 38 ++++++++++ 5 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt index e9aca50..28c1665 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/SmokeTest.kt @@ -19,7 +19,7 @@ class SmokeTest { testBlocking { LibsodiumInitializer.initialize() val hashResult = GenericHash.genericHash("Hello".encodeToUByteArray(), 64) - println(hashResult.toHexString()) + println("Smoke test: ${hashResult.toHexString()}") assertTrue { "EF15EAF92D5E335345A3E1D977BC7D8797C3D275717CC1B10AF79C93CDA01AEB2A0C59BC02E2BDF9380FD1B54EB9E1669026930CCC24BD49748E65F9A6B2EE68".toLowerCase() == hashResult.toHexString() } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashTest.kt new file mode 100644 index 0000000..d39c387 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHashTest.kt @@ -0,0 +1,74 @@ +package com.ionspin.kotlin.crypto.generichash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.testBlocking +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 26-Aug-2020 + */ +class GenericHashTest { + + + @Test + fun testGenericHash() { + LibsodiumInitializer.initializeWithCallback { + val inputString = "1234567890" + val inputStringBuilder = StringBuilder() + for (i in 0 until 14) { + inputStringBuilder.append(inputString) + } + val input = inputStringBuilder.toString().encodeToUByteArray() + val expectedResult = ubyteArrayOf( + //@formatter:off + 0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, + 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU, + 0x2fU, 0x0dU, 0x2fU, 0xb4U, 0xc0U, 0x7dU, 0x7eU, 0x4aU, 0x72U, 0x40U, 0x46U, 0x12U, 0xd9U, 0x28U, 0x99U, + 0xafU, 0x8aU, 0x32U, 0x8fU, 0x3bU, 0x61U, 0x4eU, 0xd7U, 0x72U, 0x44U, 0xb4U, 0x81U, 0x15U, 0x1dU, 0x40U, + 0xb1U, 0x1eU, 0x32U, 0xa4U + //@formatter:on + ) + + + val result = GenericHash.genericHash(input, 64) + println("GenericHash result: ${result.toHexString()}") + assertTrue { + result.contentEquals(expectedResult) + } + } + + } + + @Test + fun testGenericHashMultipart() { + LibsodiumInitializer.initializeWithCallback { + val updates = 14 + val input = "1234567890" + val expectedResult = ubyteArrayOf( + //@formatter:off + 0x2fU, 0x49U, 0xaeU, 0xb6U, 0x13U, 0xe3U, 0x4eU, 0x92U, 0x4eU, 0x17U, 0x5aU, 0x6aU, 0xf2U, 0xfaU, 0xadU, + 0x7bU, 0xc7U, 0x82U, 0x35U, 0xf9U, 0xc5U, 0xe4U, 0x61U, 0xc6U, 0x8fU, 0xd5U, 0xb4U, 0x07U, 0xeeU, 0x8eU, + 0x2fU, 0x0dU, 0x2fU, 0xb4U, 0xc0U, 0x7dU, 0x7eU, 0x4aU, 0x72U, 0x40U, 0x46U, 0x12U, 0xd9U, 0x28U, 0x99U, + 0xafU, 0x8aU, 0x32U, 0x8fU, 0x3bU, 0x61U, 0x4eU, 0xd7U, 0x72U, 0x44U, 0xb4U, 0x81U, 0x15U, 0x1dU, 0x40U, + 0xb1U, 0x1eU, 0x32U, 0xa4U + //@formatter:on + ) + + val genericHashState = GenericHash.genericHashInit(64) + for (i in 0 until updates) { + GenericHash.genericHashUpdate(genericHashState, input.encodeToUByteArray()) + } + val result = GenericHash.genericHashFinal(genericHashState) + println("GenericHash result: ${result.toHexString()}") + assertTrue { + result.contentEquals(expectedResult) + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt index 7a91cc1..8055387 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -30,7 +30,7 @@ actual object GenericHash { requestedHashLength: Int, key: UByteArray? ): GenericHashState { - val state = getSodium().crypto_generichash_init(key.toUInt8Array(), requestedHashLength) + val state = getSodium().crypto_generichash_init(key?.toUInt8Array() ?: Uint8Array(0), requestedHashLength) return GenericHashState(requestedHashLength, state) } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt new file mode 100644 index 0000000..8d9974e --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -0,0 +1,34 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual typealias SecretStreamState = Any + +actual object SecretStream { + actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305Push( + state: SecretStreamState, + message: UByteArray, + additionalData: UByteArray, + tag: UByte + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305InitPull( + key: UByteArray, + header: UByteArray + ): SecretStreamStateAndHeader { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305Pull( + state: SecretStreamState, + ciphertext: UByteArray, + additionalData: UByteArray + ): DecryptedDataAndTag { + TODO("not implemented yet") + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt new file mode 100644 index 0000000..e03d3ad --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -0,0 +1,38 @@ +package com.ionspin.kotlin.crypto.secretstream + +import com.goterl.lazycode.lazysodium.interfaces.SecretStream +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual typealias SecretStreamState = SecretStream.State + +actual object SecretStream { + actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { + TODO("not implemented yet") +// sodium.crypto_secretstream_xchacha20poly1305_init_push() + } + + actual fun xChaCha20Poly1305Push( + state: SecretStreamState, + message: UByteArray, + additionalData: UByteArray, + tag: UByte + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305InitPull( + key: UByteArray, + header: UByteArray + ): SecretStreamStateAndHeader { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305Pull( + state: SecretStreamState, + ciphertext: UByteArray, + additionalData: UByteArray + ): DecryptedDataAndTag { + TODO("not implemented yet") + } + +} From 9e10677165758d1cb79b5ad684f2939e063ea010 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Thu, 27 Aug 2020 19:27:46 +0200 Subject: [PATCH 17/65] ADded helper extension toPtr instead of addressOf(0), implemented jvm and native secret stream --- .../XChaCha20Poly1305Delegated.kt | 11 +-- .../crypto/hash/blake2b/Blake2bDelegated.kt | 5 +- .../kotlin/crypto/hash/sha/Sha256Delegated.kt | 5 +- .../kotlin/crypto/hash/sha/Sha512Delegated.kt | 5 +- .../kotlin/crypto/util/ConversionUtil.kt | 13 +++ .../com/ionspin/kotlin/crypto/HelperTest.kt | 5 +- .../crypto/secretstream/SecretStream.kt | 37 ++++++-- .../kotlin/crypto/generichash/GenericHash.kt | 13 +-- .../crypto/secretstream/SecretStream.kt | 86 ++++++++++++++++++- .../kotlin/crypto/util/ConversionUtil.kt | 13 +++ 10 files changed, 165 insertions(+), 28 deletions(-) create mode 100644 multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt index 0d60110..e83dd43 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto.authenticated import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint import com.ionspin.kotlin.crypto.InvalidTagException +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* @@ -22,7 +23,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { val ciphertext = UByteArray(ciphertextLength) val ciphertextPinned = ciphertext.pin() crypto_aead_xchacha20poly1305_ietf_encrypt( - ciphertextPinned.addressOf(0), + ciphertextPinned.toPtr(), ulongArrayOf(ciphertextLength.convert()).toCValues(), message.toCValues(), message.size.convert(), @@ -46,7 +47,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { val message = UByteArray(messageLength) val messagePinned = message.pin() crypto_aead_xchacha20poly1305_ietf_decrypt( - messagePinned.addressOf(0), + messagePinned.toPtr(), ulongArrayOf(messageLength.convert()).toCValues(), null, ciphertext.toCValues(), @@ -95,7 +96,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { actual fun initializeForEncryption(key: UByteArray) : UByteArray { val pinnedHeader = header.pin() - crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.addressOf(0), key.toCValues()) + crypto_secretstream_xchacha20poly1305_init_push(state.ptr, pinnedHeader.toPtr(), key.toCValues()) println("state-----------") state.ptr.readBytes(crypto_secretstream_xchacha20poly1305_state.size.toInt()).asUByteArray().hexColumsPrint() println("state-----------") @@ -116,7 +117,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { val ciphertextWithTagPinned = ciphertextWithTag.pin() crypto_secretstream_xchacha20poly1305_push( state.ptr, - ciphertextWithTagPinned.addressOf(0), + ciphertextWithTagPinned.toPtr(), null, data.toCValues(), data.size.convert(), @@ -136,7 +137,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { val plaintextPinned = plaintext.pin() val validTag = crypto_secretstream_xchacha20poly1305_pull( state.ptr, - plaintextPinned.addressOf(0), + plaintextPinned.toPtr(), null, null, data.toCValues(), diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt index a72383b..d819606 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/blake2b/Blake2bDelegated.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.hash.blake2b import com.ionspin.kotlin.crypto.util.toHexString +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -30,7 +31,7 @@ actual class Blake2bDelegated actual constructor(key: UByteArray?, hashLength: I override fun digest(): UByteArray { val hashResult = UByteArray(requestedHashLength) val hashResultPinned = hashResult.pin() - crypto_generichash_final(state.ptr, hashResultPinned.addressOf(0), requestedHashLength.convert()) + crypto_generichash_final(state.ptr, hashResultPinned.toPtr(), requestedHashLength.convert()) free(state.ptr) return hashResult } @@ -44,7 +45,7 @@ actual object Blake2bDelegatedStateless : Blake2b { val hashResult = UByteArray(MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() crypto_generichash( - hashResultPinned.addressOf(0), + hashResultPinned.toPtr(), hashLength.convert(), inputMessage.toCValues(), inputMessage.size.convert(), diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt index 0663629..32c1e5d 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha256Delegated.kt @@ -1,6 +1,7 @@ package com.ionspin.kotlin.crypto.hash.sha import com.ionspin.kotlin.crypto.hash.blake2b.Blake2bDelegatedStateless +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -32,7 +33,7 @@ actual class Sha256Delegated : Sha256 { override fun digest(): UByteArray { val hashResult = UByteArray(Sha256Properties.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha256_final(state.ptr, hashResultPinned.addressOf(0)) + crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr()) sodium_free(state.ptr) return hashResult } @@ -46,7 +47,7 @@ actual object Sha256StatelessDelegated : StatelessSha256 { override fun digest(inputMessage: UByteArray): UByteArray { val hashResult = UByteArray(MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha256(hashResultPinned.addressOf(0), inputMessage.toCValues(), inputMessage.size.convert()) + crypto_hash_sha256(hashResultPinned.toPtr(), inputMessage.toCValues(), inputMessage.size.convert()) hashResultPinned.unpin() return hashResult } diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt index f4b80a6..a700b04 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/sha/Sha512Delegated.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.hash.sha +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -30,7 +31,7 @@ actual class Sha512Delegated : Sha512Multipart { override fun digest(): UByteArray { val hashResult = UByteArray(Sha512Properties.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha512_final(state.ptr, hashResultPinned.addressOf(0)) + crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr()) free(state.ptr) return hashResult } @@ -42,7 +43,7 @@ actual object Sha512StatelessDelegated : Sha512 { override fun digest(inputMessage: UByteArray): UByteArray { val hashResult = UByteArray(Sha512StatelessDelegated.MAX_HASH_BYTES) val hashResultPinned = hashResult.pin() - crypto_hash_sha512(hashResultPinned.addressOf(0), inputMessage.toCValues(), inputMessage.size.convert()) + crypto_hash_sha512(hashResultPinned.toPtr(), inputMessage.toCValues(), inputMessage.size.convert()) hashResultPinned.unpin() return hashResult } diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt new file mode 100644 index 0000000..7a0d892 --- /dev/null +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt @@ -0,0 +1,13 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.Pinned +import kotlinx.cinterop.UByteVar +import kotlinx.cinterop.addressOf + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Aug-2020 + */ +fun Pinned.toPtr() : CPointer = addressOf(0) diff --git a/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt b/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt index fd6827e..4bc8bcd 100644 --- a/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt +++ b/multiplatform-crypto-delegated/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/HelperTest.kt @@ -2,6 +2,7 @@ package com.ionspin.kotlin.crypto import com.ionspin.kotlin.crypto.hash.encodeToUByteArray import com.ionspin.kotlin.crypto.util.toHexString +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.* import libsodium.* import platform.posix.free @@ -39,7 +40,7 @@ class HelperTest { } val result = UByteArray(32) val resultPinned = result.pin() - crypto_hash_sha256_final(state, resultPinned.addressOf(0)) + crypto_hash_sha256_final(state, resultPinned.toPtr()) println("$target to \"${result.toHexString()}\",") free(state) } @@ -69,7 +70,7 @@ class HelperTest { } val result = UByteArray(32) val resultPinned = result.pin() - crypto_hash_sha512_final(state, resultPinned.addressOf(0)) + crypto_hash_sha512_final(state, resultPinned.toPtr()) println("$target to \"${result.toHexString()}\",") free(state) } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index e03d3ad..b92eb63 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -7,8 +7,10 @@ actual typealias SecretStreamState = SecretStream.State actual object SecretStream { actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { - TODO("not implemented yet") -// sodium.crypto_secretstream_xchacha20poly1305_init_push() + val state = SecretStreamState() + val header = UByteArray(sodium.crypto_secretstream_xchacha20poly1305_headerbytes()) + sodium.crypto_secretstream_xchacha20poly1305_init_push(state, header.asByteArray(), key.asByteArray()) + return SecretStreamStateAndHeader(state, header) } actual fun xChaCha20Poly1305Push( @@ -17,14 +19,27 @@ actual object SecretStream { additionalData: UByteArray, tag: UByte ): UByteArray { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size) + sodium.crypto_secretstream_xchacha20poly1305_push( + state, + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + additionalData.asByteArray(), + additionalData.size.toLong(), + tag.toByte() + ) + return ciphertext } actual fun xChaCha20Poly1305InitPull( key: UByteArray, header: UByteArray ): SecretStreamStateAndHeader { - TODO("not implemented yet") + val state = SecretStreamState() + sodium.crypto_secretstream_xchacha20poly1305_init_pull(state, header.asByteArray(), key.asByteArray()) + return SecretStreamStateAndHeader(state, header) } actual fun xChaCha20Poly1305Pull( @@ -32,7 +47,19 @@ actual object SecretStream { ciphertext: UByteArray, additionalData: UByteArray ): DecryptedDataAndTag { - TODO("not implemented yet") + val result = UByteArray(ciphertext.size) + val tagArray = UByteArray(1) { 0U } + sodium.crypto_secretstream_xchacha20poly1305_pull( + state, + result.asByteArray(), + null, + tagArray.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + additionalData.asByteArray(), + additionalData.size.toLong() + ) + return DecryptedDataAndTag(result, tagArray[0]) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt index c10ac4f..e8c9742 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.generichash +import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.addressOf import kotlinx.cinterop.convert import kotlinx.cinterop.pin @@ -32,11 +33,11 @@ actual object GenericHash { val pinnedKey = key?.pin() val pinnedMessage = message.pin() crypto_generichash( - pinnedHash.addressOf(0), + pinnedHash.toPtr(), requestedHashLength.convert(), - pinnedMessage.addressOf(0), + pinnedMessage.toPtr(), message.size.convert(), - pinnedKey?.addressOf(0), + pinnedKey?.toPtr(), (key?.size ?: 0).convert() ) pinnedHash.unpin() @@ -54,7 +55,7 @@ actual object GenericHash { val pinnedKey = key?.pin() crypto_generichash_init( statePointed.ptr, - pinnedKey?.addressOf(0), + pinnedKey?.toPtr(), (key?.size ?: 0).convert(), requestedHashLength.convert() ) @@ -69,7 +70,7 @@ actual object GenericHash { val pinnedMessage = messagePart.pin() crypto_generichash_update( state.internalState.ptr, - pinnedMessage.addressOf(0), + pinnedMessage.toPtr(), messagePart.size.convert() ) pinnedMessage.unpin() @@ -80,7 +81,7 @@ actual object GenericHash { val hashResultPinned = hashResult.pin() crypto_generichash_final( state.internalState.ptr, - hashResultPinned.addressOf(0), + hashResultPinned.toPtr(), state.hashLength.convert() ) hashResultPinned.unpin() diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 3b38152..11e15ba 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -1,10 +1,39 @@ package com.ionspin.kotlin.crypto.secretstream +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.UByteVar +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.pointed +import kotlinx.cinterop.ptr +import kotlinx.cinterop.reinterpret +import kotlinx.cinterop.toCPointer +import libsodium.crypto_secretstream_xchacha20poly1305_headerbytes +import libsodium.crypto_secretstream_xchacha20poly1305_init_pull +import libsodium.crypto_secretstream_xchacha20poly1305_init_push +import libsodium.crypto_secretstream_xchacha20poly1305_pull +import libsodium.crypto_secretstream_xchacha20poly1305_push +import platform.posix.malloc + actual typealias SecretStreamState = libsodium.crypto_secretstream_xchacha20poly1305_state actual object SecretStream { actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { - TODO("not implemented yet") + val stateAllocated = malloc(SecretStreamState.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + + val header = UByteArray(crypto_secretstream_xchacha20poly1305_headerbytes().convert()) { 0U } + val headerPinned = header.pin() + val keyPinned = key.pin() + crypto_secretstream_xchacha20poly1305_init_push( + statePointed.ptr, + headerPinned.toPtr(), + keyPinned.toPtr() + ) + headerPinned.unpin() + keyPinned.unpin() + return SecretStreamStateAndHeader(statePointed, header) + } actual fun xChaCha20Poly1305Push( @@ -13,14 +42,42 @@ actual object SecretStream { additionalData: UByteArray, tag: UByte ): UByteArray { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size) + val ciphertextPinned = ciphertext.pin() + val messagePinned = message.pin() + val additionalDataPinned = additionalData.pin() + crypto_secretstream_xchacha20poly1305_push( + state.ptr, + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + additionalDataPinned.toPtr(), + additionalData.size.convert(), + tag + ) + ciphertextPinned.unpin() + messagePinned.unpin() + additionalDataPinned.unpin() + return ciphertext } actual fun xChaCha20Poly1305InitPull( key: UByteArray, header: UByteArray ): SecretStreamStateAndHeader { - TODO("not implemented yet") + val stateAllocated = malloc(SecretStreamState.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + val keyPinned = key.pin() + val headerPinned = header.pin() + crypto_secretstream_xchacha20poly1305_init_pull( + statePointed.ptr, + headerPinned.toPtr(), + keyPinned.toPtr() + ) + headerPinned.unpin() + keyPinned.unpin() + return SecretStreamStateAndHeader(statePointed, header) } actual fun xChaCha20Poly1305Pull( @@ -28,7 +85,28 @@ actual object SecretStream { ciphertext: UByteArray, additionalData: UByteArray ): DecryptedDataAndTag { - TODO("not implemented yet") + val message = UByteArray(ciphertext.size) + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val additionalDataPinned = additionalData.pin() + val tag = UByteArray(1) { 0U } + val tagPinned = tag.pin() + crypto_secretstream_xchacha20poly1305_pull( + state.ptr, + messagePinned.toPtr(), + null, + tagPinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + additionalDataPinned.toPtr(), + additionalData.size.convert(), + + ) + ciphertextPinned.unpin() + messagePinned.unpin() + additionalDataPinned.unpin() + tagPinned.unpin() + return DecryptedDataAndTag(message, tag[0]) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt new file mode 100644 index 0000000..7a0d892 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt @@ -0,0 +1,13 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.Pinned +import kotlinx.cinterop.UByteVar +import kotlinx.cinterop.addressOf + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Aug-2020 + */ +fun Pinned.toPtr() : CPointer = addressOf(0) From 89e5ae62e4a5f88eae4d765461ae6fb26bce8c09 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Thu, 27 Aug 2020 22:07:03 +0200 Subject: [PATCH 18/65] Fixed native (i forgot to account for tag length. Added debug list of js functions, can be usefull when defining interface --- libsodium_js_debug_list.txt | 395 ++++++++++++++++++ .../crypto/secretstream/SecretStreamTest.kt | 165 ++++---- .../kotlin/crypto/JsSodiumInterface.kt | 4 +- .../crypto/secretstream/SecretStream.kt | 21 +- .../kotlin/crypto/secretstream/modifyState.kt | 4 + .../kotlin/crypto/secretstream/modifyState.kt | 6 + .../crypto/secretstream/SecretStream.kt | 38 +- .../kotlin/crypto/util/ConversionUtil.kt | 3 +- .../kotlin/crypto/secretstream/modifyState.kt | 4 + 9 files changed, 543 insertions(+), 97 deletions(-) create mode 100644 libsodium_js_debug_list.txt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt diff --git a/libsodium_js_debug_list.txt b/libsodium_js_debug_list.txt new file mode 100644 index 0000000..01d4ff7 --- /dev/null +++ b/libsodium_js_debug_list.txt @@ -0,0 +1,395 @@ +add = function(e,t){if(!(e instanceof Uint8Array&&t instanceof Uint8Array))throw new TypeError("Only Uint8Array instances can added");var r=e.length,a=0,_=0;if(t.length!=e.length)throw new TypeError("Arguments must have the same length");for(_=0;_>=8,a+=e[_]+t[_],e[_]=255&a} +base64_variants = Object {ORIGINAL: 1, +ORIGINAL_NO_PADDING: 3, +URLSAFE: 5, +URLSAFE_NO_PADDING: 7} +compare = function(e,t){if(!(e instanceof Uint8Array&&t instanceof Uint8Array))throw new TypeError("Only Uint8Array instances can be compared");if(e.length!==t.length)throw new TypeError("Only instances of identical length can be compared");for(var r=0,a=1,_=e.length;_-- >0;)r|=t[_]-e[_]>>8&a,a&=(t[_]^e[_])-1>>8;return r+r+a-1} +from_base64 = function(e,t){t=o(t);var a,_=[],n=new l(3*(e=m(_,e,"input")).length/4),s=u(e),c=d(4),h=d(4);return _.push(s),_.push(n.address),_.push(n.result_bin_len_p),_.push(n.b64_end_p),0!==r._sodium_base642bin(n.address,n.length,s,e.length,0,c,h,t)&&g(_,"invalid input"),r.getValue(h,"i32")-s!==e.length&&g(_,"incomplete input"),n.length=r.getValue(c,"i32"),a=n.to_Uint8Array(),v(_),a} +from_hex = function(e){var t,a=[],_=new l((e=m(a,e,"input")).length/2),n=u(e),s=d(4);return a.push(n),a.push(_.address),a.push(_.hex_end_p),0!==r._sodium_hex2bin(_.address,_.length,n,e.length,0,0,s)&&g(a,"invalid input"),r.getValue(s,"i32")-n!==e.length&&g(a,"incomplete input"),t=_.to_Uint8Array(),v(a),t} +from_string = function _(e){if("function"==typeof TextEncoder)return(new TextEncoder).encode(e);e=unescape(encodeURIComponent(e));for(var t=new Uint8Array(e.length),r=0,a=e.length;r>=8,t+=e[r],e[r]=255&t} +is_zero = function(e){if(!(e instanceof Uint8Array))throw new TypeError("Only Uint8Array instances can be checked");for(var t=0,r=0,a=e.length;r 0");var a,_=[],n=d(4),s=1,c=0,o=0|e.length,h=new l(o+t);_.push(n),_.push(h.address);for(var p=h.address,y=h.address+o+t;p>>48|o>>>32|o>>>16|o))-1>>16);return 0!==r._sodium_pad(n,h.address,e.length,t,h.length)&&g(_,"internal error"),h.length=r.getValue(n,"i32"),a=h.to_Uint8Array(),v(_),a} +unpad = function(e,t){if(!(e instanceof Uint8Array))throw new TypeError("buffer must be a Uint8Array");if((t|=0)<=0)throw new Error("block size must be > 0");var a=[],_=u(e),n=d(4);return a.push(_),a.push(n),0!==r._sodium_unpad(n,_,e.length,t)&&g(a,"unsupported/invalid padding"),e=(e=new Uint8Array(e)).subarray(0,r.getValue(n,"i32")),v(a),e} +ready = Promise {[[PromiseStatus]]: "resolved", +[[PromiseValue]]: undefined} +symbols = function(){return Object.keys(e).sort()} +to_base64 = function h(e,t){t=o(t),e=m(_,e,"input");var a,_=[],s=0|Math.floor(e.length/3),c=e.length-3*s,h=4*s+(0!==c?0==(2&t)?4:2+(c>>>1):0),p=new l(h+1),y=u(e);return _.push(y),_.push(p.address),0===r._sodium_bin2base64(p.address,p.length,y,e.length,t)&&g(_,"conversion failed"),p.length=h,a=n(p.to_Uint8Array()),v(_),a} +to_hex = function s(e){e=m(null,e,"input");for(var t,r,a,_="",n=0;n>8&-39)<<8|87+(t=e[n]>>>4)+(t-10>>8&-39),_+=String.fromCharCode(255&a)+String.fromCharCode(a>>>8);return _} +to_string = function n(e){if("function"==typeof TextDecoder)return new TextDecoder("utf-8",{fatal:!0}).decode(e);var t=Math.ceil(e.length/8192);if(t<=1)try{return decodeURIComponent(escape(String.fromCharCode.apply(null,e)))}catch(e){throw new TypeError("The encoded data was not valid.")}for(var r="",a=0,_=0;_=240?(h=4,c=!0):p>=224?(h=3,c=!0):p>=192?(h=2,c=!0):p<128&&(h=1,c=!0)}while(!c);for(var y=h-(s.length-o),i=0;i>>24>>>8,o,y);var x=p(g,s);return v(c),x} +crypto_kdf_keygen = function Le(e){var t=[];i(e);var a=new l(0|r._crypto_kdf_keybytes()),_=a.address;t.push(_),r._crypto_kdf_keygen(_);var n=p(a,e);return v(t),n} +crypto_kx_client_session_keys = function Ue(e,t,a,_){var n=[];i(_),e=m(n,e,"clientPublicKey");var s,c=0|r._crypto_kx_publickeybytes();e.length!==c&&b(n,"invalid clientPublicKey length"),s=u(e),n.push(s),t=m(n,t,"clientSecretKey");var o,h=0|r._crypto_kx_secretkeybytes();t.length!==h&&b(n,"invalid clientSecretKey length"),o=u(t),n.push(o),a=m(n,a,"serverPublicKey");var y,d=0|r._crypto_kx_publickeybytes();a.length!==d&&b(n,"invalid serverPublicKey length"),y=u(a),n.push(y);var f=new l(0|r._crypto_kx_sessionkeybytes()),E=f.address;n.push(E);var x=new l(0|r._crypto_kx_sessionkeybytes()),k=x.address;if(n.push(k),0==(0|r._crypto_kx_client_session_keys(E,k,s,o,y))){var S=p({sharedRx:f,sharedTx:x},_);return v(n),S}g(n,"invalid usage")} +crypto_kx_keypair = function Oe(e){var t=[];i(e);var a=new l(0|r._crypto_kx_publickeybytes()),_=a.address;t.push(_);var n=new l(0|r._crypto_kx_secretkeybytes()),s=n.address;if(t.push(s),0==(0|r._crypto_kx_keypair(_,s))){var c={publicKey:p(a,e),privateKey:p(n,e),keyType:"x25519"};return v(t),c}g(t,"internal error")} +crypto_kx_seed_keypair = function Ce(e,t){var a=[];i(t),e=m(a,e,"seed");var _,n=0|r._crypto_kx_seedbytes();e.length!==n&&b(a,"invalid seed length"),_=u(e),a.push(_);var s=new l(0|r._crypto_kx_publickeybytes()),c=s.address;a.push(c);var o=new l(0|r._crypto_kx_secretkeybytes()),h=o.address;if(a.push(h),0==(0|r._crypto_kx_seed_keypair(c,h,_))){var y={publicKey:p(s,t),privateKey:p(o,t),keyType:"x25519"};return v(a),y}g(a,"internal error")} +crypto_kx_server_session_keys = function Re(e,t,a,_){var n=[];i(_),e=m(n,e,"serverPublicKey");var s,c=0|r._crypto_kx_publickeybytes();e.length!==c&&b(n,"invalid serverPublicKey length"),s=u(e),n.push(s),t=m(n,t,"serverSecretKey");var o,h=0|r._crypto_kx_secretkeybytes();t.length!==h&&b(n,"invalid serverSecretKey length"),o=u(t),n.push(o),a=m(n,a,"clientPublicKey");var y,d=0|r._crypto_kx_publickeybytes();a.length!==d&&b(n,"invalid clientPublicKey length"),y=u(a),n.push(y);var f=new l(0|r._crypto_kx_sessionkeybytes()),E=f.address;n.push(E);var x=new l(0|r._crypto_kx_sessionkeybytes()),k=x.address;if(n.push(k),0==(0|r._crypto_kx_server_session_keys(E,k,s,o,y))){var S=p({sharedRx:f,sharedTx:x},_);return v(n),S}g(n,"invalid usage")} +crypto_onetimeauth = function Pe(e,t,a){var _=[];i(a);var n=u(e=m(_,e,"message")),s=e.length;_.push(n),t=m(_,t,"key");var c,o=0|r._crypto_onetimeauth_keybytes();t.length!==o&&b(_,"invalid key length"),c=u(t),_.push(c);var h=new l(0|r._crypto_onetimeauth_bytes()),y=h.address;if(_.push(y),0==(0|r._crypto_onetimeauth(y,n,s,0,c))){var d=p(h,a);return v(_),d}g(_,"invalid usage")} +crypto_onetimeauth_final = function Ge(e,t){var a=[];i(t),f(a,e,"state_address");var _=new l(0|r._crypto_onetimeauth_bytes()),n=_.address;if(a.push(n),0==(0|r._crypto_onetimeauth_final(e,n))){var s=(r._free(e),p(_,t));return v(a),s}g(a,"invalid usage")} +crypto_onetimeauth_init = function Xe(e,t){var a=[];i(t);var _=null;null!=e&&(_=u(e=m(a,e,"key")),e.length,a.push(_));var n=new l(144).address;if(0==(0|r._crypto_onetimeauth_init(n,_))){var s=n;return v(a),s}g(a,"invalid usage")} +crypto_onetimeauth_keygen = function De(e){var t=[];i(e);var a=new l(0|r._crypto_onetimeauth_keybytes()),_=a.address;t.push(_),r._crypto_onetimeauth_keygen(_);var n=p(a,e);return v(t),n} +crypto_onetimeauth_update = function Fe(e,t,a){var _=[];i(a),f(_,e,"state_address");var n=u(t=m(_,t,"message_chunk")),s=t.length;_.push(n),0!=(0|r._crypto_onetimeauth_update(e,n,s))&&g(_,"invalid usage"),v(_)} +crypto_onetimeauth_verify = function Ve(e,t,a){var _=[];e=m(_,e,"hash");var n,s=0|r._crypto_onetimeauth_bytes();e.length!==s&&b(_,"invalid hash length"),n=u(e),_.push(n);var c=u(t=m(_,t,"message")),o=t.length;_.push(c),a=m(_,a,"key");var h,p=0|r._crypto_onetimeauth_keybytes();a.length!==p&&b(_,"invalid key length"),h=u(a),_.push(h);var y=0==(0|r._crypto_onetimeauth_verify(n,c,o,0,h));return v(_),y} +crypto_pwhash = function He(e,t,a,_,n,s,c){var o=[];i(c),f(o,e,"keyLength"),("number"!=typeof e||(0|e)!==e||e<0)&&b(o,"keyLength must be an unsigned integer");var h=u(t=m(o,t,"password")),y=t.length;o.push(h),a=m(o,a,"salt");var d,E=0|r._crypto_pwhash_saltbytes();a.length!==E&&b(o,"invalid salt length"),d=u(a),o.push(d),f(o,_,"opsLimit"),("number"!=typeof _||(0|_)!==_||_<0)&&b(o,"opsLimit must be an unsigned integer"),f(o,n,"memLimit"),("number"!=typeof n||(0|n)!==n||n<0)&&b(o,"memLimit must be an unsigned integer"),f(o,s,"algorithm"),("number"!=typeof s||(0|s)!==s||s<0)&&b(o,"algorithm must be an unsigned integer");var x=new l(0|e),k=x.address;if(o.push(k),0==(0|r._crypto_pwhash(k,e,0,h,y,0,d,_,0,n,s))){var S=p(x,c);return v(o),S}g(o,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256 = function ze(e,t,a,_,n,s){var c=[];i(s),f(c,e,"keyLength"),("number"!=typeof e||(0|e)!==e||e<0)&&b(c,"keyLength must be an unsigned integer");var o=u(t=m(c,t,"password")),h=t.length;c.push(o),a=m(c,a,"salt");var y,d=0|r._crypto_pwhash_scryptsalsa208sha256_saltbytes();a.length!==d&&b(c,"invalid salt length"),y=u(a),c.push(y),f(c,_,"opsLimit"),("number"!=typeof _||(0|_)!==_||_<0)&&b(c,"opsLimit must be an unsigned integer"),f(c,n,"memLimit"),("number"!=typeof n||(0|n)!==n||n<0)&&b(c,"memLimit must be an unsigned integer");var E=new l(0|e),x=E.address;if(c.push(x),0==(0|r._crypto_pwhash_scryptsalsa208sha256(x,e,0,o,h,0,y,_,0,n))){var k=p(E,s);return v(c),k}g(c,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256_ll = function je(e,t,a,_,n,s,c){var o=[];i(c);var h=u(e=m(o,e,"password")),y=e.length;o.push(h);var d=u(t=m(o,t,"salt")),E=t.length;o.push(d),f(o,a,"opsLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(o,"opsLimit must be an unsigned integer"),f(o,_,"r"),("number"!=typeof _||(0|_)!==_||_<0)&&b(o,"r must be an unsigned integer"),f(o,n,"p"),("number"!=typeof n||(0|n)!==n||n<0)&&b(o,"p must be an unsigned integer"),f(o,s,"keyLength"),("number"!=typeof s||(0|s)!==s||s<0)&&b(o,"keyLength must be an unsigned integer");var x=new l(0|s),k=x.address;if(o.push(k),0==(0|r._crypto_pwhash_scryptsalsa208sha256_ll(h,y,d,E,a,0,_,n,k,s))){var S=p(x,c);return v(o),S}g(o,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256_str = function qe(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"password")),c=e.length;n.push(s),f(n,t,"opsLimit"),("number"!=typeof t||(0|t)!==t||t<0)&&b(n,"opsLimit must be an unsigned integer"),f(n,a,"memLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(n,"memLimit must be an unsigned integer");var o=new l(0|r._crypto_pwhash_scryptsalsa208sha256_strbytes()).address;if(n.push(o),0==(0|r._crypto_pwhash_scryptsalsa208sha256_str(o,s,c,0,t,0,a))){var h=r.UTF8ToString(o);return v(n),h}g(n,"invalid usage")} +crypto_pwhash_scryptsalsa208sha256_str_verify = function We(e,t,a){var n=[];i(a),"string"!=typeof e&&b(n,"hashed_password must be a string"),e=_(e+"\0"),null!=c&&e.length-1!==c&&b(n,"invalid hashed_password length");var s=u(e),c=e.length-1;n.push(s);var o=u(t=m(n,t,"password")),h=t.length;n.push(o);var p=0==(0|r._crypto_pwhash_scryptsalsa208sha256_str_verify(s,o,h,0));return v(n),p} +crypto_pwhash_str = function Je(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"password")),c=e.length;n.push(s),f(n,t,"opsLimit"),("number"!=typeof t||(0|t)!==t||t<0)&&b(n,"opsLimit must be an unsigned integer"),f(n,a,"memLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(n,"memLimit must be an unsigned integer");var o=new l(0|r._crypto_pwhash_strbytes()).address;if(n.push(o),0==(0|r._crypto_pwhash_str(o,s,c,0,t,0,a))){var h=r.UTF8ToString(o);return v(n),h}g(n,"invalid usage")} +crypto_pwhash_str_needs_rehash = function Qe(e,t,a,n){var s=[];i(n),"string"!=typeof e&&b(s,"hashed_password must be a string"),e=_(e+"\0"),null!=o&&e.length-1!==o&&b(s,"invalid hashed_password length");var c=u(e),o=e.length-1;s.push(c),f(s,t,"opsLimit"),("number"!=typeof t||(0|t)!==t||t<0)&&b(s,"opsLimit must be an unsigned integer"),f(s,a,"memLimit"),("number"!=typeof a||(0|a)!==a||a<0)&&b(s,"memLimit must be an unsigned integer");var h=0!=(0|r._crypto_pwhash_str_needs_rehash(c,t,0,a));return v(s),h} +crypto_pwhash_str_verify = function Ze(e,t,a){var n=[];i(a),"string"!=typeof e&&b(n,"hashed_password must be a string"),e=_(e+"\0"),null!=c&&e.length-1!==c&&b(n,"invalid hashed_password length");var s=u(e),c=e.length-1;n.push(s);var o=u(t=m(n,t,"password")),h=t.length;n.push(o);var p=0==(0|r._crypto_pwhash_str_verify(s,o,h,0));return v(n),p} +crypto_scalarmult = function $e(e,t,a){var _=[];i(a),e=m(_,e,"privateKey");var n,s=0|r._crypto_scalarmult_scalarbytes();e.length!==s&&b(_,"invalid privateKey length"),n=u(e),_.push(n),t=m(_,t,"publicKey");var c,o=0|r._crypto_scalarmult_scalarbytes();t.length!==o&&b(_,"invalid publicKey length"),c=u(t),_.push(c);var h=new l(0|r._crypto_scalarmult_bytes()),y=h.address;if(_.push(y),0==(0|r._crypto_scalarmult(y,n,c))){var d=p(h,a);return v(_),d}g(_,"weak public key")} +crypto_scalarmult_base = function et(e,t){var a=[];i(t),e=m(a,e,"privateKey");var _,n=0|r._crypto_scalarmult_scalarbytes();e.length!==n&&b(a,"invalid privateKey length"),_=u(e),a.push(_);var s=new l(0|r._crypto_scalarmult_scalarbytes()),c=s.address;if(a.push(c),0==(0|r._crypto_scalarmult_base(c,_))){var o=p(s,t);return v(a),o}g(a,"insecure scalar")} +crypto_scalarmult_ristretto255 = function tt(e,t,a){var _=[];i(a),e=m(_,e,"scalar");var n,s=0|r._crypto_scalarmult_ristretto255_scalarbytes();e.length!==s&&b(_,"invalid scalar length"),n=u(e),_.push(n),t=m(_,t,"privateKey");var c,o=0|r._crypto_scalarmult_ristretto255_bytes();t.length!==o&&b(_,"invalid privateKey length"),c=u(t),_.push(c);var h=new l(0|r._crypto_scalarmult_ristretto255_bytes()),y=h.address;if(_.push(y),0==(0|r._crypto_scalarmult_ristretto255(y,n,c))){var d=p(h,a);return v(_),d}g(_,"input is zero element")} +crypto_scalarmult_ristretto255_base = function rt(e,t){var a=[];i(t);var _=u(e=m(a,e,"scalar"));e.length,a.push(_);var n=new l(0|r._crypto_core_ristretto255_bytes()),s=n.address;if(a.push(s),0==(0|r._crypto_scalarmult_ristretto255_base(s,_))){var c=p(n,t);return v(a),c}g(a,"scalar is 0")} +crypto_secretbox_detached = function at(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"message")),c=e.length;n.push(s),t=m(n,t,"nonce");var o,h=0|r._crypto_secretbox_noncebytes();t.length!==h&&b(n,"invalid nonce length"),o=u(t),n.push(o),a=m(n,a,"key");var y,d=0|r._crypto_secretbox_keybytes();a.length!==d&&b(n,"invalid key length"),y=u(a),n.push(y);var f=new l(0|c),E=f.address;n.push(E);var x=new l(0|r._crypto_secretbox_macbytes()),k=x.address;if(n.push(k),0==(0|r._crypto_secretbox_detached(E,k,s,c,0,o,y))){var S=p({mac:x,cipher:f},_);return v(n),S}g(n,"invalid usage")} +crypto_secretbox_easy = function _t(e,t,a,_){var n=[];i(_);var s=u(e=m(n,e,"message")),c=e.length;n.push(s),t=m(n,t,"nonce");var o,h=0|r._crypto_secretbox_noncebytes();t.length!==h&&b(n,"invalid nonce length"),o=u(t),n.push(o),a=m(n,a,"key");var y,d=0|r._crypto_secretbox_keybytes();a.length!==d&&b(n,"invalid key length"),y=u(a),n.push(y);var f=new l(c+r._crypto_secretbox_macbytes()|0),E=f.address;if(n.push(E),0==(0|r._crypto_secretbox_easy(E,s,c,0,o,y))){var x=p(f,_);return v(n),x}g(n,"invalid usage")} +crypto_secretbox_keygen = function nt(e){var t=[];i(e);var a=new l(0|r._crypto_secretbox_keybytes()),_=a.address;t.push(_),r._crypto_secretbox_keygen(_);var n=p(a,e);return v(t),n} +crypto_secretbox_open_detached = function st(e,t,a,_,n){var s=[];i(n);var c=u(e=m(s,e,"ciphertext")),o=e.length;s.push(c),t=m(s,t,"mac");var h,y=0|r._crypto_secretbox_macbytes();t.length!==y&&b(s,"invalid mac length"),h=u(t),s.push(h),a=m(s,a,"nonce");var d,f=0|r._crypto_secretbox_noncebytes();a.length!==f&&b(s,"invalid nonce length"),d=u(a),s.push(d),_=m(s,_,"key");var E,x=0|r._crypto_secretbox_keybytes();_.length!==x&&b(s,"invalid key length"),E=u(_),s.push(E);var k=new l(0|o),S=k.address;if(s.push(S),0==(0|r._crypto_secretbox_open_detached(S,c,h,o,0,d,E))){var T=p(k,n);return v(s),T}g(s,"wrong secret key for the given ciphertext")} +crypto_secretbox_open_easy = function ct(e,t,a,_){var n=[];i(_),e=m(n,e,"ciphertext");var s,c=r._crypto_secretbox_macbytes(),o=e.length;o>>0;return v([]),t} +randombytes_stir = function zt(e){i(e),r._randombytes_stir()} +randombytes_uniform = function jt(e,t){var a=[];i(t),f(a,e,"upper_bound"),("number"!=typeof e||(0|e)!==e||e<0)&&b(a,"upper_bound must be an unsigned integer");var _=r._randombytes_uniform(e)>>>0;return v(a),_} +sodium_version_string = function qt(){var e=r._sodium_version_string(),t=r.UTF8ToString(e);return v([]),t} +SODIUM_LIBRARY_VERSION_MAJOR = 10 +SODIUM_LIBRARY_VERSION_MINOR = 3 +crypto_aead_chacha20poly1305_ABYTES = 16 +crypto_aead_chacha20poly1305_IETF_ABYTES = 16 +crypto_aead_chacha20poly1305_IETF_KEYBYTES = 32 +crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX = -17 +crypto_aead_chacha20poly1305_IETF_NPUBBYTES = 12 +crypto_aead_chacha20poly1305_IETF_NSECBYTES = 0 +crypto_aead_chacha20poly1305_KEYBYTES = 32 +crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX = -17 +crypto_aead_chacha20poly1305_NPUBBYTES = 8 +crypto_aead_chacha20poly1305_NSECBYTES = 0 +crypto_aead_chacha20poly1305_ietf_ABYTES = 16 +crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32 +crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX = -17 +crypto_aead_chacha20poly1305_ietf_NPUBBYTES = 12 +crypto_aead_chacha20poly1305_ietf_NSECBYTES = 0 +crypto_aead_xchacha20poly1305_IETF_ABYTES = 16 +crypto_aead_xchacha20poly1305_IETF_KEYBYTES = 32 +crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX = -17 +crypto_aead_xchacha20poly1305_IETF_NPUBBYTES = 24 +crypto_aead_xchacha20poly1305_IETF_NSECBYTES = 0 +crypto_aead_xchacha20poly1305_ietf_ABYTES = 16 +crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32 +crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX = -17 +crypto_aead_xchacha20poly1305_ietf_NPUBBYTES = 24 +crypto_aead_xchacha20poly1305_ietf_NSECBYTES = 0 +crypto_auth_BYTES = 32 +crypto_auth_KEYBYTES = 32 +crypto_auth_hmacsha256_BYTES = 32 +crypto_auth_hmacsha256_KEYBYTES = 32 +crypto_auth_hmacsha512256_BYTES = 32 +crypto_auth_hmacsha512256_KEYBYTES = 32 +crypto_auth_hmacsha512_BYTES = 64 +crypto_auth_hmacsha512_KEYBYTES = 32 +crypto_box_BEFORENMBYTES = 32 +crypto_box_MACBYTES = 16 +crypto_box_MESSAGEBYTES_MAX = -17 +crypto_box_NONCEBYTES = 24 +crypto_box_PUBLICKEYBYTES = 32 +crypto_box_SEALBYTES = 48 +crypto_box_SECRETKEYBYTES = 32 +crypto_box_SEEDBYTES = 32 +crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES = 32 +crypto_box_curve25519xchacha20poly1305_MACBYTES = 16 +crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX = -17 +crypto_box_curve25519xchacha20poly1305_NONCEBYTES = 24 +crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES = 32 +crypto_box_curve25519xchacha20poly1305_SEALBYTES = 48 +crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES = 32 +crypto_box_curve25519xchacha20poly1305_SEEDBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_MACBYTES = 16 +crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX = -17 +crypto_box_curve25519xsalsa20poly1305_NONCEBYTES = 24 +crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES = 32 +crypto_box_curve25519xsalsa20poly1305_SEEDBYTES = 32 +crypto_core_ed25519_BYTES = 32 +crypto_core_ed25519_HASHBYTES = 64 +crypto_core_ed25519_NONREDUCEDSCALARBYTES = 64 +crypto_core_ed25519_SCALARBYTES = 32 +crypto_core_ed25519_UNIFORMBYTES = 32 +crypto_core_hchacha20_CONSTBYTES = 16 +crypto_core_hchacha20_INPUTBYTES = 16 +crypto_core_hchacha20_KEYBYTES = 32 +crypto_core_hchacha20_OUTPUTBYTES = 32 +crypto_core_hsalsa20_CONSTBYTES = 16 +crypto_core_hsalsa20_INPUTBYTES = 16 +crypto_core_hsalsa20_KEYBYTES = 32 +crypto_core_hsalsa20_OUTPUTBYTES = 32 +crypto_core_ristretto255_BYTES = 32 +crypto_core_ristretto255_HASHBYTES = 64 +crypto_core_ristretto255_NONREDUCEDSCALARBYTES = 64 +crypto_core_ristretto255_SCALARBYTES = 32 +crypto_core_salsa2012_CONSTBYTES = 16 +crypto_core_salsa2012_INPUTBYTES = 16 +crypto_core_salsa2012_KEYBYTES = 32 +crypto_core_salsa2012_OUTPUTBYTES = 64 +crypto_core_salsa20_CONSTBYTES = 16 +crypto_core_salsa20_INPUTBYTES = 16 +crypto_core_salsa20_KEYBYTES = 32 +crypto_core_salsa20_OUTPUTBYTES = 64 +crypto_generichash_BYTES = 32 +crypto_generichash_BYTES_MAX = 64 +crypto_generichash_BYTES_MIN = 16 +crypto_generichash_KEYBYTES = 32 +crypto_generichash_KEYBYTES_MAX = 64 +crypto_generichash_KEYBYTES_MIN = 16 +crypto_generichash_blake2b_BYTES = 32 +crypto_generichash_blake2b_BYTES_MAX = 64 +crypto_generichash_blake2b_BYTES_MIN = 16 +crypto_generichash_blake2b_KEYBYTES = 32 +crypto_generichash_blake2b_KEYBYTES_MAX = 64 +crypto_generichash_blake2b_KEYBYTES_MIN = 16 +crypto_generichash_blake2b_PERSONALBYTES = 16 +crypto_generichash_blake2b_SALTBYTES = 16 +crypto_hash_BYTES = 64 +crypto_hash_sha256_BYTES = 32 +crypto_hash_sha512_BYTES = 64 +crypto_kdf_BYTES_MAX = 64 +crypto_kdf_BYTES_MIN = 16 +crypto_kdf_CONTEXTBYTES = 8 +crypto_kdf_KEYBYTES = 32 +crypto_kdf_blake2b_BYTES_MAX = 64 +crypto_kdf_blake2b_BYTES_MIN = 16 +crypto_kdf_blake2b_CONTEXTBYTES = 8 +crypto_kdf_blake2b_KEYBYTES = 32 +crypto_kx_PUBLICKEYBYTES = 32 +crypto_kx_SECRETKEYBYTES = 32 +crypto_kx_SEEDBYTES = 32 +crypto_kx_SESSIONKEYBYTES = 32 +crypto_onetimeauth_BYTES = 16 +crypto_onetimeauth_KEYBYTES = 32 +crypto_onetimeauth_poly1305_BYTES = 16 +crypto_onetimeauth_poly1305_KEYBYTES = 32 +crypto_pwhash_ALG_ARGON2I13 = 1 +crypto_pwhash_ALG_ARGON2ID13 = 2 +crypto_pwhash_ALG_DEFAULT = 2 +crypto_pwhash_BYTES_MAX = -1 +crypto_pwhash_BYTES_MIN = 16 +crypto_pwhash_MEMLIMIT_INTERACTIVE = 67108864 +crypto_pwhash_MEMLIMIT_MAX = -2147483648 +crypto_pwhash_MEMLIMIT_MIN = 8192 +crypto_pwhash_MEMLIMIT_MODERATE = 268435456 +crypto_pwhash_MEMLIMIT_SENSITIVE = 1073741824 +crypto_pwhash_OPSLIMIT_INTERACTIVE = 2 +crypto_pwhash_OPSLIMIT_MAX = -1 +crypto_pwhash_OPSLIMIT_MIN = 1 +crypto_pwhash_OPSLIMIT_MODERATE = 3 +crypto_pwhash_OPSLIMIT_SENSITIVE = 4 +crypto_pwhash_PASSWD_MAX = -1 +crypto_pwhash_PASSWD_MIN = 0 +crypto_pwhash_SALTBYTES = 16 +crypto_pwhash_STRBYTES = 128 +crypto_pwhash_argon2i_BYTES_MAX = -1 +crypto_pwhash_argon2i_BYTES_MIN = 16 +crypto_pwhash_argon2i_SALTBYTES = 16 +crypto_pwhash_argon2i_STRBYTES = 128 +crypto_pwhash_argon2id_BYTES_MAX = -1 +crypto_pwhash_argon2id_BYTES_MIN = 16 +crypto_pwhash_argon2id_SALTBYTES = 16 +crypto_pwhash_argon2id_STRBYTES = 128 +crypto_pwhash_scryptsalsa208sha256_BYTES_MAX = -1 +crypto_pwhash_scryptsalsa208sha256_BYTES_MIN = 16 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE = 16777216 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX = -1 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN = 16777216 +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE = 1073741824 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE = 524288 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX = -1 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN = 32768 +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE = 33554432 +crypto_pwhash_scryptsalsa208sha256_SALTBYTES = 32 +crypto_pwhash_scryptsalsa208sha256_STRBYTES = 102 +crypto_scalarmult_BYTES = 32 +crypto_scalarmult_SCALARBYTES = 32 +crypto_scalarmult_curve25519_BYTES = 32 +crypto_scalarmult_curve25519_SCALARBYTES = 32 +crypto_scalarmult_ed25519_BYTES = 32 +crypto_scalarmult_ed25519_SCALARBYTES = 32 +crypto_scalarmult_ristretto255_BYTES = 32 +crypto_scalarmult_ristretto255_SCALARBYTES = 32 +crypto_secretbox_KEYBYTES = 32 +crypto_secretbox_MACBYTES = 16 +crypto_secretbox_MESSAGEBYTES_MAX = -17 +crypto_secretbox_NONCEBYTES = 24 +crypto_secretbox_xchacha20poly1305_KEYBYTES = 32 +crypto_secretbox_xchacha20poly1305_MACBYTES = 16 +crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX = -17 +crypto_secretbox_xchacha20poly1305_NONCEBYTES = 24 +crypto_secretbox_xsalsa20poly1305_KEYBYTES = 32 +crypto_secretbox_xsalsa20poly1305_MACBYTES = 16 +crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX = -17 +crypto_secretbox_xsalsa20poly1305_NONCEBYTES = 24 +crypto_secretstream_xchacha20poly1305_ABYTES = 17 +crypto_secretstream_xchacha20poly1305_HEADERBYTES = 24 +crypto_secretstream_xchacha20poly1305_KEYBYTES = 32 +crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = -18 +crypto_secretstream_xchacha20poly1305_TAG_FINAL = 3 +crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = 0 +crypto_secretstream_xchacha20poly1305_TAG_PUSH = 1 +crypto_secretstream_xchacha20poly1305_TAG_REKEY = 2 +crypto_shorthash_BYTES = 8 +crypto_shorthash_KEYBYTES = 16 +crypto_shorthash_siphash24_BYTES = 8 +crypto_shorthash_siphash24_KEYBYTES = 16 +crypto_shorthash_siphashx24_BYTES = 16 +crypto_shorthash_siphashx24_KEYBYTES = 16 +crypto_sign_BYTES = 64 +crypto_sign_MESSAGEBYTES_MAX = -65 +crypto_sign_PUBLICKEYBYTES = 32 +crypto_sign_SECRETKEYBYTES = 64 +crypto_sign_SEEDBYTES = 32 +crypto_sign_ed25519_BYTES = 64 +crypto_sign_ed25519_MESSAGEBYTES_MAX = -65 +crypto_sign_ed25519_PUBLICKEYBYTES = 32 +crypto_sign_ed25519_SECRETKEYBYTES = 64 +crypto_sign_ed25519_SEEDBYTES = 32 +crypto_stream_KEYBYTES = 32 +crypto_stream_MESSAGEBYTES_MAX = -1 +crypto_stream_NONCEBYTES = 24 +crypto_stream_chacha20_IETF_KEYBYTES = 32 +crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX = -1 +crypto_stream_chacha20_IETF_NONCEBYTES = 12 +crypto_stream_chacha20_KEYBYTES = 32 +crypto_stream_chacha20_MESSAGEBYTES_MAX = -1 +crypto_stream_chacha20_NONCEBYTES = 8 +crypto_stream_chacha20_ietf_KEYBYTES = 32 +crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX = -1 +crypto_stream_chacha20_ietf_NONCEBYTES = 12 +crypto_stream_salsa2012_KEYBYTES = 32 +crypto_stream_salsa2012_MESSAGEBYTES_MAX = -1 +crypto_stream_salsa2012_NONCEBYTES = 8 +crypto_stream_salsa208_KEYBYTES = 32 +crypto_stream_salsa208_MESSAGEBYTES_MAX = -1 +crypto_stream_salsa208_NONCEBYTES = 8 +crypto_stream_salsa20_KEYBYTES = 32 +crypto_stream_salsa20_MESSAGEBYTES_MAX = -1 +crypto_stream_salsa20_NONCEBYTES = 8 +crypto_stream_xchacha20_KEYBYTES = 32 +crypto_stream_xchacha20_MESSAGEBYTES_MAX = -1 +crypto_stream_xchacha20_NONCEBYTES = 24 +crypto_stream_xsalsa20_KEYBYTES = 32 +crypto_stream_xsalsa20_MESSAGEBYTES_MAX = -1 +crypto_stream_xsalsa20_NONCEBYTES = 24 +crypto_verify_16_BYTES = 16 +crypto_verify_32_BYTES = 32 +crypto_verify_64_BYTES = 64 +SODIUM_VERSION_STRING = "1.0.18" +crypto_pwhash_STRPREFIX = "$argon2id$" +crypto_pwhash_scryptsalsa208sha256_STRPREFIX = "$7$" diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index 41837de..31a1706 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -1,76 +1,89 @@ -//package com.ionspin.kotlin.crypto.secretstream -// -//import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint -//import com.ionspin.kotlin.crypto.Initializer -//import com.ionspin.kotlin.crypto.util.encodeToUByteArray -//import com.ionspin.kotlin.crypto.util.testBlocking -//import debug.test.Crypto -//import kotlin.math.exp -//import kotlin.test.Test -//import kotlin.test.assertTrue -// -///** -// * Created by Ugljesa Jovanovic -// * ugljesa.jovanovic@ionspin.com -// * on 15-Aug-2020 -// */ -//class SecretStreamTest { -// @Test -// fun testSecretStream() = testBlocking { -// Initializer.initializeWithCallback { -// assertTrue { -// val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + -// "only one tip for the future, sunscreen would be it.").encodeToUByteArray() -// -// val additionalData = ubyteArrayOf( -// 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U -// ) -// val key = ubyteArrayOf( -// 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, -// 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, -// 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, -// 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, -// ) -// -// val nonce = ubyteArrayOf( -// 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, -// 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, -// 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, -// ) -// -// val expected = ubyteArrayOf( -// 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, -// 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, -// 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, -// 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, -// 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, -// 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, -// 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, -// 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, -// 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, -// 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, -// 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, -// 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, -// 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, -// 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, -// 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, -// 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, -// 0xcfU, 0x49U -// ) -// message.hexColumsPrint() -// val crypto = Crypto() -// val stateAndHeader = crypto.crypto_secretstream_xchacha20poly1305_init_push(key) -// val encrypted = -// crypto.crypto_secretstream_xchacha20poly1305_push(stateAndHeader.state, message, ubyteArrayOf(), 0U) -// encrypted.hexColumsPrint() -// val decryptState = crypto.crypto_secretstream_xchacha20poly1305_init_pull(stateAndHeader.header, key) -// val decrypted = -// crypto.crypto_secretstream_xchacha20poly1305_pull(decryptState, encrypted, ubyteArrayOf()) -// decrypted.hexColumsPrint() -// decrypted.contentEquals(message) -// -// } -// } -// } -// -//} +package com.ionspin.kotlin.crypto.secretstream + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.testBlocking +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 15-Aug-2020 + */ +class SecretStreamTest { + + @BeforeTest + fun initialize() = testBlocking { + LibsodiumInitializer.initialize() + } + + @Test + fun testSecretStream() = testBlocking { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val additionalData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val expected = ubyteArrayOf( + 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, + 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, + 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, + 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, + 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, + 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, + 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, + 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, + 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, + 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, + 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, + 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, + 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, + 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, + 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, + 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, + 0xcfU, 0x49U + ) + message.hexColumsPrint() + println("---- init enc ----") + val stateAndHeader = SecretStream.xChaCha20Poly1305InitPush(key) + println("---- encrypt ----") + val encrypted = + SecretStream.xChaCha20Poly1305Push(stateAndHeader.state, message, ubyteArrayOf(), 0U) + encrypted.hexColumsPrint() + println("---- init dec ----") + val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header) + println("---- decrypt ----") + val decrypted = + SecretStream.xChaCha20Poly1305Pull(decryptState.state, encrypted, ubyteArrayOf()) + decrypted.decryptedData.hexColumsPrint() + assertTrue { + decrypted.decryptedData.contentEquals(message) + + } + + + } + + +} + +expect fun modifyState(state: SecretStreamState, forceNonce: UByteArray) + + diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index cb5c6b6..646e0ad 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -45,12 +45,12 @@ interface JsSodiumInterface { //XChaCha20Poly1305 //encrypt - fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_init_push(key: Uint8Array) : dynamic fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: Uint8Array, tag: UByte) : Uint8Array //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : Uint8Array + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 8d9974e..b1daf7e 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -1,10 +1,16 @@ package com.ionspin.kotlin.crypto.secretstream +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + actual typealias SecretStreamState = Any actual object SecretStream { actual fun xChaCha20Poly1305InitPush(key: UByteArray): SecretStreamStateAndHeader { - TODO("not implemented yet") + val state = getSodium().crypto_secretstream_xchacha20poly1305_init_push(key.toUInt8Array()) + return SecretStreamStateAndHeader(state.state, (state.header as Uint8Array).toUByteArray()) } actual fun xChaCha20Poly1305Push( @@ -13,14 +19,17 @@ actual object SecretStream { additionalData: UByteArray, tag: UByte ): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_secretstream_xchacha20poly1305_push( + state, message.toUInt8Array(), additionalData.toUInt8Array(), tag + ).toUByteArray() } actual fun xChaCha20Poly1305InitPull( key: UByteArray, header: UByteArray ): SecretStreamStateAndHeader { - TODO("not implemented yet") + val state = getSodium().crypto_secretstream_xchacha20poly1305_init_pull(header.toUInt8Array(), key.toUInt8Array()) + return SecretStreamStateAndHeader(state, header) } actual fun xChaCha20Poly1305Pull( @@ -28,7 +37,11 @@ actual object SecretStream { ciphertext: UByteArray, additionalData: UByteArray ): DecryptedDataAndTag { - TODO("not implemented yet") + val dataAndTag = getSodium().crypto_secretstream_xchacha20poly1305_pull( + state, ciphertext.toUInt8Array(), additionalData.toUInt8Array() + ) + return DecryptedDataAndTag((dataAndTag.message as Uint8Array).toUByteArray(), dataAndTag.tag) + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt b/multiplatform-crypto-libsodium-bindings/src/jsTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt new file mode 100644 index 0000000..27130e3 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt @@ -0,0 +1,4 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual fun modifyState(state: SecretStreamState, forceNonce: UByteArray) { +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt b/multiplatform-crypto-libsodium-bindings/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt new file mode 100644 index 0000000..46ec50b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt @@ -0,0 +1,6 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual fun modifyState(state: SecretStreamState, forceNonce: UByteArray) { + state.nonce = forceNonce.sliceArray(12 until 24).asByteArray() + println("Nonce modified ${state.nonce}") +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 11e15ba..af9f2e5 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -1,13 +1,12 @@ package com.ionspin.kotlin.crypto.secretstream import com.ionspin.kotlin.crypto.util.toPtr -import kotlinx.cinterop.UByteVar import kotlinx.cinterop.convert import kotlinx.cinterop.pin import kotlinx.cinterop.pointed import kotlinx.cinterop.ptr import kotlinx.cinterop.reinterpret -import kotlinx.cinterop.toCPointer +import libsodium.crypto_secretstream_xchacha20poly1305_ABYTES import libsodium.crypto_secretstream_xchacha20poly1305_headerbytes import libsodium.crypto_secretstream_xchacha20poly1305_init_pull import libsodium.crypto_secretstream_xchacha20poly1305_init_push @@ -42,23 +41,28 @@ actual object SecretStream { additionalData: UByteArray, tag: UByte ): UByteArray { - val ciphertext = UByteArray(message.size) + val ciphertext = UByteArray(message.size + crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) { 0U } val ciphertextPinned = ciphertext.pin() val messagePinned = message.pin() - val additionalDataPinned = additionalData.pin() + val additionalDataPinned = if (additionalData.isNotEmpty()) { + additionalData.pin() + } else { + null + } crypto_secretstream_xchacha20poly1305_push( state.ptr, ciphertextPinned.toPtr(), null, messagePinned.toPtr(), message.size.convert(), - additionalDataPinned.toPtr(), + additionalDataPinned?.toPtr(), additionalData.size.convert(), tag ) + ciphertextPinned.unpin() messagePinned.unpin() - additionalDataPinned.unpin() + additionalDataPinned?.unpin() return ciphertext } @@ -85,27 +89,33 @@ actual object SecretStream { ciphertext: UByteArray, additionalData: UByteArray ): DecryptedDataAndTag { - val message = UByteArray(ciphertext.size) + val message = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) val messagePinned = message.pin() val ciphertextPinned = ciphertext.pin() - val additionalDataPinned = additionalData.pin() + val additionalDataPinned = if (additionalData.isNotEmpty()) { + additionalData.pin() + } else { + null + } val tag = UByteArray(1) { 0U } val tagPinned = tag.pin() - crypto_secretstream_xchacha20poly1305_pull( + val validTag = crypto_secretstream_xchacha20poly1305_pull( state.ptr, messagePinned.toPtr(), null, tagPinned.toPtr(), ciphertextPinned.toPtr(), ciphertext.size.convert(), - additionalDataPinned.toPtr(), - additionalData.size.convert(), - - ) + additionalDataPinned?.toPtr(), + additionalData.size.convert() + ) ciphertextPinned.unpin() messagePinned.unpin() - additionalDataPinned.unpin() + additionalDataPinned?.unpin() tagPinned.unpin() + if (validTag != 0) { + throw RuntimeException("Invalid tag") + } return DecryptedDataAndTag(message, tag[0]) } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt index 7a0d892..8964c2b 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/ConversionUtil.kt @@ -4,10 +4,11 @@ import kotlinx.cinterop.CPointer import kotlinx.cinterop.Pinned import kotlinx.cinterop.UByteVar import kotlinx.cinterop.addressOf +import kotlinx.cinterop.toCPointer /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 27-Aug-2020 */ -fun Pinned.toPtr() : CPointer = addressOf(0) +fun Pinned.toPtr() : CPointer? = addressOf(0) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt b/multiplatform-crypto-libsodium-bindings/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt new file mode 100644 index 0000000..27130e3 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeTest/kotlin/com/ionspin/kotlin/crypto/secretstream/modifyState.kt @@ -0,0 +1,4 @@ +package com.ionspin.kotlin.crypto.secretstream + +actual fun modifyState(state: SecretStreamState, forceNonce: UByteArray) { +} From 86611453eae1e4db114a370c75950a27258848d8 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Thu, 27 Aug 2020 22:09:42 +0200 Subject: [PATCH 19/65] Same thing for JVM, forgot about tag length --- .../crypto/secretstream/SecretStreamTest.kt | 111 +++++++++--------- .../crypto/secretstream/SecretStream.kt | 4 +- 2 files changed, 56 insertions(+), 59 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index 31a1706..7fc9226 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -4,7 +4,6 @@ import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint import com.ionspin.kotlin.crypto.LibsodiumInitializer import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking -import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertTrue @@ -15,70 +14,68 @@ import kotlin.test.assertTrue */ class SecretStreamTest { - @BeforeTest - fun initialize() = testBlocking { - LibsodiumInitializer.initialize() - } @Test fun testSecretStream() = testBlocking { - val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + - "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( - 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U - ) - val key = ubyteArrayOf( - 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, - 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, - 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, - 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, - ) + val additionalData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) - val nonce = ubyteArrayOf( - 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, - 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, - 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, - ) + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val expected = ubyteArrayOf( + 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, + 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, + 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, + 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, + 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, + 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, + 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, + 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, + 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, + 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, + 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, + 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, + 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, + 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, + 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, + 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, + 0xcfU, 0x49U + ) + message.hexColumsPrint() + println("---- init enc ----") + val stateAndHeader = SecretStream.xChaCha20Poly1305InitPush(key) + println("---- encrypt ----") + val encrypted = + SecretStream.xChaCha20Poly1305Push(stateAndHeader.state, message, ubyteArrayOf(), 0U) + encrypted.hexColumsPrint() + println("---- init dec ----") + val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header) + println("---- decrypt ----") + val decrypted = + SecretStream.xChaCha20Poly1305Pull(decryptState.state, encrypted, ubyteArrayOf()) + decrypted.decryptedData.hexColumsPrint() + assertTrue { + decrypted.decryptedData.contentEquals(message) + + } - val expected = ubyteArrayOf( - 0xbdU, 0x6dU, 0x17U, 0x9dU, 0x3eU, 0x83U, 0xd4U, 0x3bU, - 0x95U, 0x76U, 0x57U, 0x94U, 0x93U, 0xc0U, 0xe9U, 0x39U, - 0x57U, 0x2aU, 0x17U, 0x00U, 0x25U, 0x2bU, 0xfaU, 0xccU, - 0xbeU, 0xd2U, 0x90U, 0x2cU, 0x21U, 0x39U, 0x6cU, 0xbbU, - 0x73U, 0x1cU, 0x7fU, 0x1bU, 0x0bU, 0x4aU, 0xa6U, 0x44U, - 0x0bU, 0xf3U, 0xa8U, 0x2fU, 0x4eU, 0xdaU, 0x7eU, 0x39U, - 0xaeU, 0x64U, 0xc6U, 0x70U, 0x8cU, 0x54U, 0xc2U, 0x16U, - 0xcbU, 0x96U, 0xb7U, 0x2eU, 0x12U, 0x13U, 0xb4U, 0x52U, - 0x2fU, 0x8cU, 0x9bU, 0xa4U, 0x0dU, 0xb5U, 0xd9U, 0x45U, - 0xb1U, 0x1bU, 0x69U, 0xb9U, 0x82U, 0xc1U, 0xbbU, 0x9eU, - 0x3fU, 0x3fU, 0xacU, 0x2bU, 0xc3U, 0x69U, 0x48U, 0x8fU, - 0x76U, 0xb2U, 0x38U, 0x35U, 0x65U, 0xd3U, 0xffU, 0xf9U, - 0x21U, 0xf9U, 0x66U, 0x4cU, 0x97U, 0x63U, 0x7dU, 0xa9U, - 0x76U, 0x88U, 0x12U, 0xf6U, 0x15U, 0xc6U, 0x8bU, 0x13U, - 0xb5U, 0x2eU, 0xc0U, 0x87U, 0x59U, 0x24U, 0xc1U, 0xc7U, - 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, - 0xcfU, 0x49U - ) - message.hexColumsPrint() - println("---- init enc ----") - val stateAndHeader = SecretStream.xChaCha20Poly1305InitPush(key) - println("---- encrypt ----") - val encrypted = - SecretStream.xChaCha20Poly1305Push(stateAndHeader.state, message, ubyteArrayOf(), 0U) - encrypted.hexColumsPrint() - println("---- init dec ----") - val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header) - println("---- decrypt ----") - val decrypted = - SecretStream.xChaCha20Poly1305Pull(decryptState.state, encrypted, ubyteArrayOf()) - decrypted.decryptedData.hexColumsPrint() - assertTrue { - decrypted.decryptedData.contentEquals(message) } - - } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index b92eb63..96e1e65 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -19,7 +19,7 @@ actual object SecretStream { additionalData: UByteArray, tag: UByte ): UByteArray { - val ciphertext = UByteArray(message.size) + val ciphertext = UByteArray(message.size + 17) sodium.crypto_secretstream_xchacha20poly1305_push( state, ciphertext.asByteArray(), @@ -47,7 +47,7 @@ actual object SecretStream { ciphertext: UByteArray, additionalData: UByteArray ): DecryptedDataAndTag { - val result = UByteArray(ciphertext.size) + val result = UByteArray(ciphertext.size - 17) val tagArray = UByteArray(1) { 0U } sodium.crypto_secretstream_xchacha20poly1305_pull( state, From 91cd41c8c1ae780065774e52e620b6d6a6f665ee Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 28 Aug 2020 22:35:33 +0200 Subject: [PATCH 20/65] Short hash implementation and test, updated cbc tests as they ignored padding --- js_checklist.txt | 395 ++++++++++++++++++ .../shortinputhash/ShortHash.kt | 15 + .../shortinputhash/ShortInputHashing.kt | 10 - .../com.ionspin.kotlin.crypto/util/Util.kt | 24 ++ .../kotlin/crypto/shorthash/ShortHashTest.kt | 41 ++ .../ionspin/kotlin/crypto/util/TestUtil.kt | 12 - .../kotlin/crypto/JsSodiumInterface.kt | 5 + .../kotlin/crypto/shortinputhash/ShortHash.kt | 21 + .../kotlin/crypto/shortinputhash/ShortHash.kt | 25 ++ .../kotlin/crypto/shortinputhash/ShortHash.kt | 35 ++ .../kotlin/crypto/symmetric/AesCtrPure.kt | 6 +- .../kotlin/crypto/symmetric/AesCbcTest.kt | 8 +- 12 files changed, 570 insertions(+), 27 deletions(-) create mode 100644 js_checklist.txt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortHash.kt delete mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/Util.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/shorthash/ShortHashTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt diff --git a/js_checklist.txt b/js_checklist.txt new file mode 100644 index 0000000..8c2bdc3 --- /dev/null +++ b/js_checklist.txt @@ -0,0 +1,395 @@ +add +base64_variants +ORIGINAL_NO_PADDING +URLSAFE +URLSAFE_NO_PADDING +compare +from_base64 +from_hex +from_string +increment +is_zero +libsodium +print +printErr +onRuntimeInitialized +useBackupModule +... +memcmp +memzero +output_formats +pad +unpad +ready +[[ +symbols +to_base64 +to_hex +to_string +crypto_aead_chacha20poly1305_decrypt +crypto_aead_chacha20poly1305_decrypt_detached +crypto_aead_chacha20poly1305_encrypt +crypto_aead_chacha20poly1305_encrypt_detached +crypto_aead_chacha20poly1305_ietf_decrypt +crypto_aead_chacha20poly1305_ietf_decrypt_detached +crypto_aead_chacha20poly1305_ietf_encrypt +crypto_aead_chacha20poly1305_ietf_encrypt_detached +crypto_aead_chacha20poly1305_ietf_keygen +crypto_aead_chacha20poly1305_keygen +crypto_aead_xchacha20poly1305_ietf_decrypt +crypto_aead_xchacha20poly1305_ietf_decrypt_detached +crypto_aead_xchacha20poly1305_ietf_encrypt +crypto_aead_xchacha20poly1305_ietf_encrypt_detached +crypto_aead_xchacha20poly1305_ietf_keygen +crypto_auth +crypto_auth_hmacsha256 +crypto_auth_hmacsha256_keygen +crypto_auth_hmacsha256_verify +crypto_auth_hmacsha512 +crypto_auth_hmacsha512_keygen +crypto_auth_hmacsha512_verify +crypto_auth_keygen +crypto_auth_verify +crypto_box_beforenm +crypto_box_curve25519xchacha20poly1305_keypair +crypto_box_curve25519xchacha20poly1305_seal +crypto_box_curve25519xchacha20poly1305_seal_open +crypto_box_detached +crypto_box_easy +crypto_box_easy_afternm +crypto_box_keypair +crypto_box_open_detached +crypto_box_open_easy +crypto_box_open_easy_afternm +crypto_box_seal +crypto_box_seal_open +crypto_box_seed_keypair +crypto_core_ristretto255_add +crypto_core_ristretto255_from_hash +crypto_core_ristretto255_is_valid_point +crypto_core_ristretto255_random +crypto_core_ristretto255_scalar_add +crypto_core_ristretto255_scalar_complement +crypto_core_ristretto255_scalar_invert +crypto_core_ristretto255_scalar_mul +crypto_core_ristretto255_scalar_negate +crypto_core_ristretto255_scalar_random +crypto_core_ristretto255_scalar_reduce +crypto_core_ristretto255_scalar_sub +crypto_core_ristretto255_sub +crypto_generichash DONE +crypto_generichash_blake2b_salt_personal +crypto_generichash_final DONE +crypto_generichash_init DONE +crypto_generichash_keygen +crypto_generichash_update DONE +crypto_hash +crypto_hash_sha256 +crypto_hash_sha256_final +crypto_hash_sha256_init +crypto_hash_sha256_update +crypto_hash_sha512 +crypto_hash_sha512_final +crypto_hash_sha512_init +crypto_hash_sha512_update +crypto_kdf_derive_from_key +crypto_kdf_keygen +crypto_kx_client_session_keys +crypto_kx_keypair +crypto_kx_seed_keypair +crypto_kx_server_session_keys +crypto_onetimeauth +crypto_onetimeauth_final +crypto_onetimeauth_init +crypto_onetimeauth_keygen +crypto_onetimeauth_update +crypto_onetimeauth_verify +crypto_pwhash +crypto_pwhash_scryptsalsa208sha256 +crypto_pwhash_scryptsalsa208sha256_ll +crypto_pwhash_scryptsalsa208sha256_str +crypto_pwhash_scryptsalsa208sha256_str_verify +crypto_pwhash_str +crypto_pwhash_str_needs_rehash +crypto_pwhash_str_verify +crypto_scalarmult +crypto_scalarmult_base +crypto_scalarmult_ristretto255 +crypto_scalarmult_ristretto255_base +crypto_secretbox_detached +crypto_secretbox_easy +crypto_secretbox_keygen +crypto_secretbox_open_detached +crypto_secretbox_open_easy +crypto_secretstream_xchacha20poly1305_init_pull DONE +crypto_secretstream_xchacha20poly1305_init_push DONE +crypto_secretstream_xchacha20poly1305_keygen +crypto_secretstream_xchacha20poly1305_pull DONE +crypto_secretstream_xchacha20poly1305_push DONE +crypto_secretstream_xchacha20poly1305_rekey +crypto_shorthash DONE +crypto_shorthash_keygen DONE +crypto_shorthash_siphashx24 +crypto_sign +crypto_sign_detached +crypto_sign_ed25519_pk_to_curve25519 +crypto_sign_ed25519_sk_to_curve25519 +crypto_sign_ed25519_sk_to_pk +crypto_sign_ed25519_sk_to_seed +crypto_sign_final_create +crypto_sign_final_verify +crypto_sign_init +crypto_sign_keypair +crypto_sign_open +crypto_sign_seed_keypair +crypto_sign_update +crypto_sign_verify_detached +crypto_stream_chacha20 +crypto_stream_chacha20_ietf_xor +crypto_stream_chacha20_ietf_xor_ic +crypto_stream_chacha20_keygen +crypto_stream_chacha20_xor +crypto_stream_chacha20_xor_ic +crypto_stream_keygen +crypto_stream_xchacha20_keygen +crypto_stream_xchacha20_xor +crypto_stream_xchacha20_xor_ic +randombytes_buf +randombytes_buf_deterministic +randombytes_close +randombytes_random +randombytes_stir +randombytes_uniform +sodium_version_string +SODIUM_LIBRARY_VERSION_MAJOR +SODIUM_LIBRARY_VERSION_MINOR +crypto_aead_chacha20poly1305_ABYTES +crypto_aead_chacha20poly1305_IETF_ABYTES +crypto_aead_chacha20poly1305_IETF_KEYBYTES +crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX +crypto_aead_chacha20poly1305_IETF_NPUBBYTES +crypto_aead_chacha20poly1305_IETF_NSECBYTES +crypto_aead_chacha20poly1305_KEYBYTES +crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX +crypto_aead_chacha20poly1305_NPUBBYTES +crypto_aead_chacha20poly1305_NSECBYTES +crypto_aead_chacha20poly1305_ietf_ABYTES +crypto_aead_chacha20poly1305_ietf_KEYBYTES +crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX +crypto_aead_chacha20poly1305_ietf_NPUBBYTES +crypto_aead_chacha20poly1305_ietf_NSECBYTES +crypto_aead_xchacha20poly1305_IETF_ABYTES +crypto_aead_xchacha20poly1305_IETF_KEYBYTES +crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX +crypto_aead_xchacha20poly1305_IETF_NPUBBYTES +crypto_aead_xchacha20poly1305_IETF_NSECBYTES +crypto_aead_xchacha20poly1305_ietf_ABYTES +crypto_aead_xchacha20poly1305_ietf_KEYBYTES +crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX +crypto_aead_xchacha20poly1305_ietf_NPUBBYTES +crypto_aead_xchacha20poly1305_ietf_NSECBYTES +crypto_auth_BYTES +crypto_auth_KEYBYTES +crypto_auth_hmacsha256_BYTES +crypto_auth_hmacsha256_KEYBYTES +crypto_auth_hmacsha512256_BYTES +crypto_auth_hmacsha512256_KEYBYTES +crypto_auth_hmacsha512_BYTES +crypto_auth_hmacsha512_KEYBYTES +crypto_box_BEFORENMBYTES +crypto_box_MACBYTES +crypto_box_MESSAGEBYTES_MAX +crypto_box_NONCEBYTES +crypto_box_PUBLICKEYBYTES +crypto_box_SEALBYTES +crypto_box_SECRETKEYBYTES +crypto_box_SEEDBYTES +crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES +crypto_box_curve25519xchacha20poly1305_MACBYTES +crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX +crypto_box_curve25519xchacha20poly1305_NONCEBYTES +crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES +crypto_box_curve25519xchacha20poly1305_SEALBYTES +crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES +crypto_box_curve25519xchacha20poly1305_SEEDBYTES +crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES +crypto_box_curve25519xsalsa20poly1305_MACBYTES +crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX +crypto_box_curve25519xsalsa20poly1305_NONCEBYTES +crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES +crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES +crypto_box_curve25519xsalsa20poly1305_SEEDBYTES +crypto_core_ed25519_BYTES +crypto_core_ed25519_HASHBYTES +crypto_core_ed25519_NONREDUCEDSCALARBYTES +crypto_core_ed25519_SCALARBYTES +crypto_core_ed25519_UNIFORMBYTES +crypto_core_hchacha20_CONSTBYTES +crypto_core_hchacha20_INPUTBYTES +crypto_core_hchacha20_KEYBYTES +crypto_core_hchacha20_OUTPUTBYTES +crypto_core_hsalsa20_CONSTBYTES +crypto_core_hsalsa20_INPUTBYTES +crypto_core_hsalsa20_KEYBYTES +crypto_core_hsalsa20_OUTPUTBYTES +crypto_core_ristretto255_BYTES +crypto_core_ristretto255_HASHBYTES +crypto_core_ristretto255_NONREDUCEDSCALARBYTES +crypto_core_ristretto255_SCALARBYTES +crypto_core_salsa2012_CONSTBYTES +crypto_core_salsa2012_INPUTBYTES +crypto_core_salsa2012_KEYBYTES +crypto_core_salsa2012_OUTPUTBYTES +crypto_core_salsa20_CONSTBYTES +crypto_core_salsa20_INPUTBYTES +crypto_core_salsa20_KEYBYTES +crypto_core_salsa20_OUTPUTBYTES +crypto_generichash_BYTES +crypto_generichash_BYTES_MAX +crypto_generichash_BYTES_MIN +crypto_generichash_KEYBYTES +crypto_generichash_KEYBYTES_MAX +crypto_generichash_KEYBYTES_MIN +crypto_generichash_blake2b_BYTES +crypto_generichash_blake2b_BYTES_MAX +crypto_generichash_blake2b_BYTES_MIN +crypto_generichash_blake2b_KEYBYTES +crypto_generichash_blake2b_KEYBYTES_MAX +crypto_generichash_blake2b_KEYBYTES_MIN +crypto_generichash_blake2b_PERSONALBYTES +crypto_generichash_blake2b_SALTBYTES +crypto_hash_BYTES +crypto_hash_sha256_BYTES +crypto_hash_sha512_BYTES +crypto_kdf_BYTES_MAX +crypto_kdf_BYTES_MIN +crypto_kdf_CONTEXTBYTES +crypto_kdf_KEYBYTES +crypto_kdf_blake2b_BYTES_MAX +crypto_kdf_blake2b_BYTES_MIN +crypto_kdf_blake2b_CONTEXTBYTES +crypto_kdf_blake2b_KEYBYTES +crypto_kx_PUBLICKEYBYTES +crypto_kx_SECRETKEYBYTES +crypto_kx_SEEDBYTES +crypto_kx_SESSIONKEYBYTES +crypto_onetimeauth_BYTES +crypto_onetimeauth_KEYBYTES +crypto_onetimeauth_poly1305_BYTES +crypto_onetimeauth_poly1305_KEYBYTES +crypto_pwhash_ALG_ARGON2I13 +crypto_pwhash_ALG_ARGON2ID13 +crypto_pwhash_ALG_DEFAULT +crypto_pwhash_BYTES_MAX +crypto_pwhash_BYTES_MIN +crypto_pwhash_MEMLIMIT_INTERACTIVE +crypto_pwhash_MEMLIMIT_MAX +crypto_pwhash_MEMLIMIT_MIN +crypto_pwhash_MEMLIMIT_MODERATE +crypto_pwhash_MEMLIMIT_SENSITIVE +crypto_pwhash_OPSLIMIT_INTERACTIVE +crypto_pwhash_OPSLIMIT_MAX +crypto_pwhash_OPSLIMIT_MIN +crypto_pwhash_OPSLIMIT_MODERATE +crypto_pwhash_OPSLIMIT_SENSITIVE +crypto_pwhash_PASSWD_MAX +crypto_pwhash_PASSWD_MIN +crypto_pwhash_SALTBYTES +crypto_pwhash_STRBYTES +crypto_pwhash_argon2i_BYTES_MAX +crypto_pwhash_argon2i_BYTES_MIN +crypto_pwhash_argon2i_SALTBYTES +crypto_pwhash_argon2i_STRBYTES +crypto_pwhash_argon2id_BYTES_MAX +crypto_pwhash_argon2id_BYTES_MIN +crypto_pwhash_argon2id_SALTBYTES +crypto_pwhash_argon2id_STRBYTES +crypto_pwhash_scryptsalsa208sha256_BYTES_MAX +crypto_pwhash_scryptsalsa208sha256_BYTES_MIN +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN +crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN +crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE +crypto_pwhash_scryptsalsa208sha256_SALTBYTES +crypto_pwhash_scryptsalsa208sha256_STRBYTES +crypto_scalarmult_BYTES +crypto_scalarmult_SCALARBYTES +crypto_scalarmult_curve25519_BYTES +crypto_scalarmult_curve25519_SCALARBYTES +crypto_scalarmult_ed25519_BYTES +crypto_scalarmult_ed25519_SCALARBYTES +crypto_scalarmult_ristretto255_BYTES +crypto_scalarmult_ristretto255_SCALARBYTES +crypto_secretbox_KEYBYTES +crypto_secretbox_MACBYTES +crypto_secretbox_MESSAGEBYTES_MAX +crypto_secretbox_NONCEBYTES +crypto_secretbox_xchacha20poly1305_KEYBYTES +crypto_secretbox_xchacha20poly1305_MACBYTES +crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX +crypto_secretbox_xchacha20poly1305_NONCEBYTES +crypto_secretbox_xsalsa20poly1305_KEYBYTES +crypto_secretbox_xsalsa20poly1305_MACBYTES +crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX +crypto_secretbox_xsalsa20poly1305_NONCEBYTES +crypto_secretstream_xchacha20poly1305_ABYTES +crypto_secretstream_xchacha20poly1305_HEADERBYTES +crypto_secretstream_xchacha20poly1305_KEYBYTES +crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX +crypto_secretstream_xchacha20poly1305_TAG_FINAL +crypto_secretstream_xchacha20poly1305_TAG_MESSAGE +crypto_secretstream_xchacha20poly1305_TAG_PUSH +crypto_secretstream_xchacha20poly1305_TAG_REKEY +crypto_shorthash_BYTES +crypto_shorthash_KEYBYTES +crypto_shorthash_siphash24_BYTES +crypto_shorthash_siphash24_KEYBYTES +crypto_shorthash_siphashx24_BYTES +crypto_shorthash_siphashx24_KEYBYTES +crypto_sign_BYTES +crypto_sign_MESSAGEBYTES_MAX +crypto_sign_PUBLICKEYBYTES +crypto_sign_SECRETKEYBYTES +crypto_sign_SEEDBYTES +crypto_sign_ed25519_BYTES +crypto_sign_ed25519_MESSAGEBYTES_MAX +crypto_sign_ed25519_PUBLICKEYBYTES +crypto_sign_ed25519_SECRETKEYBYTES +crypto_sign_ed25519_SEEDBYTES +crypto_stream_KEYBYTES +crypto_stream_MESSAGEBYTES_MAX +crypto_stream_NONCEBYTES +crypto_stream_chacha20_IETF_KEYBYTES +crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX +crypto_stream_chacha20_IETF_NONCEBYTES +crypto_stream_chacha20_KEYBYTES +crypto_stream_chacha20_MESSAGEBYTES_MAX +crypto_stream_chacha20_NONCEBYTES +crypto_stream_chacha20_ietf_KEYBYTES +crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX +crypto_stream_chacha20_ietf_NONCEBYTES +crypto_stream_salsa2012_KEYBYTES +crypto_stream_salsa2012_MESSAGEBYTES_MAX +crypto_stream_salsa2012_NONCEBYTES +crypto_stream_salsa208_KEYBYTES +crypto_stream_salsa208_MESSAGEBYTES_MAX +crypto_stream_salsa208_NONCEBYTES +crypto_stream_salsa20_KEYBYTES +crypto_stream_salsa20_MESSAGEBYTES_MAX +crypto_stream_salsa20_NONCEBYTES +crypto_stream_xchacha20_KEYBYTES +crypto_stream_xchacha20_MESSAGEBYTES_MAX +crypto_stream_xchacha20_NONCEBYTES +crypto_stream_xsalsa20_KEYBYTES +crypto_stream_xsalsa20_MESSAGEBYTES_MAX +crypto_stream_xsalsa20_NONCEBYTES +crypto_verify_16_BYTES +crypto_verify_32_BYTES +crypto_verify_64_BYTES +SODIUM_VERSION_STRING +crypto_pwhash_STRPREFIX +crypto_pwhash_scryptsalsa208sha256_STRPREFIX diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..cc9b927 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,15 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +const val crypto_shorthash_KEYBYTES = 16 +const val crypto_shorthash_BYTES = 8 + +expect object ShortHash { + + fun shortHash(data : UByteArray, key: UByteArray) : UByteArray + fun shortHashKeygen() : UByteArray +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt deleted file mode 100644 index 4f51c24..0000000 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/shortinputhash/ShortInputHashing.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.ionspin.kotlin.crypto.shortinputhash - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 21-Aug-2020 - */ -object ShortInputHashing { - -} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/Util.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/Util.kt new file mode 100644 index 0000000..b3034e7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/Util.kt @@ -0,0 +1,24 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 28-Aug-2020 + */ +fun String.hexStringToUByteArray() : UByteArray { + return this.chunked(2).map { it.toUByte(16) }.toUByteArray() +} + +fun String.encodeToUByteArray() : UByteArray{ + return encodeToByteArray().asUByteArray() +} + +fun UByteArray.toHexString() : String { + return this.joinToString(separator = "") { + if (it <= 0x0FU) { + "0${it.toString(16)}" + } else { + it.toString(16) + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/shorthash/ShortHashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/shorthash/ShortHashTest.kt new file mode 100644 index 0000000..cae34ca --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/shorthash/ShortHashTest.kt @@ -0,0 +1,41 @@ +package com.ionspin.kotlin.crypto.shorthash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.shortinputhash.ShortHash +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 28-Aug-2020 + */ +class ShortHashTest { + + @Test + fun testShortHash() { + LibsodiumInitializer.initializeWithCallback { + val expected = "00e5d509c14e81bb".hexStringToUByteArray() + val input = "Libsodium test" + val key = "key1key1key1key1" + val hash = ShortHash.shortHash(input.encodeToUByteArray(), key.encodeToUByteArray()) + println(hash.toHexString()) + assertTrue { + expected.contentEquals(hash) + } + } + } + + @Test + fun testKeygen() { + LibsodiumInitializer.initializeWithCallback { + assertTrue { + val key = ShortHash.shortHashKeygen() + key.size == 16 + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt index da2e924..6358a90 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/TestUtil.kt @@ -35,16 +35,4 @@ fun testBlocking(block : suspend () -> Unit) { block.startCoroutine(continuation) } -fun String.encodeToUByteArray() : UByteArray{ - return encodeToByteArray().asUByteArray() -} -fun UByteArray.toHexString() : String { - return this.joinToString(separator = "") { - if (it <= 0x0FU) { - "0${it.toString(16)}" - } else { - it.toString(16) - } - } -} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 646e0ad..a811559 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -26,6 +26,11 @@ interface JsSodiumInterface { fun crypto_generichash_final(state: dynamic, hashLength: Int) : Uint8Array + //Short hash + fun crypto_shorthash(data : Uint8Array, key: Uint8Array) : Uint8Array + + fun crypto_shorthash_keygen() : Uint8Array + fun crypto_hash_sha256_init() : dynamic diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..df47ed7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,21 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual object ShortHash { + actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray { + return getSodium().crypto_shorthash(data.toUInt8Array(), key.toUInt8Array()).toUByteArray() + } + + actual fun shortHashKeygen(): UByteArray { + return getSodium().crypto_shorthash_keygen().toUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..f915ef7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,25 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ + + +actual object ShortHash { + actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_shorthash_BYTES) + sodium.crypto_shorthash(hashResult.asByteArray(), data.asByteArray(), data.size.toLong(), key.asByteArray()) + return hashResult + } + + actual fun shortHashKeygen(): UByteArray { + val key = UByteArray(crypto_shorthash_KEYBYTES) + sodium.crypto_shorthash_keygen(key.asByteArray()) + return key + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt new file mode 100644 index 0000000..852f043 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/shortinputhash/ShortHash.kt @@ -0,0 +1,35 @@ +package com.ionspin.kotlin.crypto.shortinputhash + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_shorthash +import libsodium.crypto_shorthash_keygen + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Aug-2020 + */ +actual object ShortHash { + actual fun shortHash(data: UByteArray, key: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_shorthash_BYTES) + val hashResultPinned = hashResult.pin() + val dataPinned = data.pin() + val keyPinned = key.pin() + crypto_shorthash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert(), keyPinned.toPtr()) + hashResultPinned.unpin() + dataPinned.unpin() + keyPinned.unpin() + return hashResult + } + + actual fun shortHashKeygen(): UByteArray { + val keyResult = UByteArray(crypto_shorthash_KEYBYTES) + val keyResultPinned = keyResult.pin() + crypto_shorthash_keygen(keyResultPinned.toPtr()) + keyResultPinned.unpin() + return keyResult + } + +} diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt index b9f4ff9..6b62b14 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCtrPure.kt @@ -55,7 +55,7 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m * data call [decrypt] */ fun createDecryptor(aesKey : InternalAesKey, initialCounter: UByteArray) : AesCtrPure { - return AesCtrPure(aesKey, Mode.DECRYPT, initialCounter = initialCounter) + return AesCtrPure(aesKey, Mode.DECRYPT, initialCounter) } /** * Bulk encryption, returns encrypted data and a random initial counter @@ -68,8 +68,8 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m /** * Bulk decryption, returns decrypted data */ - fun decrypt(aesKey: InternalAesKey, data: UByteArray, initialCounter: UByteArray): UByteArray { - val aesCtr = AesCtrPure(aesKey, Mode.DECRYPT, initialCounter = initialCounter) + fun decrypt(aesKey: InternalAesKey, data: UByteArray, initialCounter: UByteArray? = null): UByteArray { + val aesCtr = AesCtrPure(aesKey = aesKey, mode = Mode.DECRYPT, initialCounter = initialCounter) aesCtr.addData(data) return aesCtr.decrypt() } diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt index 7b86d77..c84a345 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/AesCbcTest.kt @@ -75,7 +75,9 @@ class AesCbcTest { assertTrue { val key = "4278b840fb44aaa757c1bf04acbe1a3e" val iv = "57f02a5c5339daeb0a2908a06ac6393f" - val cipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" + val cipherText = "479c89ec14bc98994e62b2c705b5014e" + + "175bd7832e7e60a1e92aac568a861eb7" + + "fc2dc2f4a527ce39f79c56b31432c779" val expectedPlainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" val aesCbc = AesCbcPure(InternalAesKey.Aes128Key(key), mode = Mode.DECRYPT, initializationVector = iv.hexStringToUByteArray()) @@ -95,7 +97,9 @@ class AesCbcTest { assertTrue { val key = "4278b840fb44aaa757c1bf04acbe1a3e" val iv = "57f02a5c5339daeb0a2908a06ac6393f" - val cipherText = "479c89ec14bc98994e62b2c705b5014e175bd7832e7e60a1e92aac568a861eb7" + val cipherText = "479c89ec14bc98994e62b2c705b5014e" + + "175bd7832e7e60a1e92aac568a861eb7" + + "fc2dc2f4a527ce39f79c56b31432c779" val expectedPlainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" val decrypted = AesCbcPure.decrypt(InternalAesKey.Aes128Key(key), cipherText.hexStringToUByteArray(), iv.hexStringToUByteArray()) println("Decrypted: ${decrypted.toHexString()}") From d5b1e7f7f3e771e71ab3fc5d52626f10d18809f4 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 29 Aug 2020 17:25:59 +0200 Subject: [PATCH 21/65] Added rekey and keygen to secretstream --- .../secretstream/SecretStream.kt | 11 +++++++++++ .../com/ionspin/kotlin/crypto/JsSodiumInterface.kt | 4 ++++ .../kotlin/crypto/secretstream/SecretStream.kt | 8 ++++++++ .../kotlin/crypto/secretstream/SecretStream.kt | 14 ++++++++++++-- .../kotlin/crypto/secretstream/SecretStream.kt | 14 ++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt index 847298f..24811d4 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt @@ -11,11 +11,22 @@ data class SecretStreamStateAndHeader(val state: SecretStreamState, val header : data class DecryptedDataAndTag(val decryptedData : UByteArray, val tag : UByte) +val crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = 0 +val crypto_secretstream_xchacha20poly1305_TAG_PUSH = 1 +val crypto_secretstream_xchacha20poly1305_TAG_REKEY = 2 +val crypto_secretstream_xchacha20poly1305_TAG_FINAL = 3 + +val crypto_secretstream_xchacha20poly1305_HEADERBYTES = 24 +val crypto_secretstream_xchacha20poly1305_KEYBYTES = 32 +val crypto_secretstream_xchacha20poly1305_ABYTES = 17 + expect object SecretStream { fun xChaCha20Poly1305InitPush(key: UByteArray) : SecretStreamStateAndHeader fun xChaCha20Poly1305Push(state : SecretStreamState, message: UByteArray, additionalData : UByteArray = ubyteArrayOf(), tag: UByte) : UByteArray fun xChaCha20Poly1305InitPull(key: UByteArray, header: UByteArray) : SecretStreamStateAndHeader fun xChaCha20Poly1305Pull(state : SecretStreamState, ciphertext: UByteArray, additionalData : UByteArray = ubyteArrayOf()) : DecryptedDataAndTag + fun xChaCha20Poly1305Keygen() : UByteArray + fun xChaCha20Poly1305Rekey(state: SecretStreamState) } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index a811559..aa1711f 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -57,6 +57,10 @@ interface JsSodiumInterface { fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic + //keygen and rekey + fun crypto_secretstream_xchacha20poly1305_keygen() : Uint8Array + fun crypto_secretstream_xchacha20poly1305_rekey(state: dynamic) + //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index b1daf7e..82b0a7c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -44,4 +44,12 @@ actual object SecretStream { } + actual fun xChaCha20Poly1305Keygen(): UByteArray { + return getSodium().crypto_shorthash_keygen().toUByteArray() + } + + actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) { + getSodium().crypto_secretstream_xchacha20poly1305_rekey(state) + } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 96e1e65..ab32a6e 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -19,7 +19,7 @@ actual object SecretStream { additionalData: UByteArray, tag: UByte ): UByteArray { - val ciphertext = UByteArray(message.size + 17) + val ciphertext = UByteArray(message.size + crypto_secretstream_xchacha20poly1305_ABYTES) sodium.crypto_secretstream_xchacha20poly1305_push( state, ciphertext.asByteArray(), @@ -47,7 +47,7 @@ actual object SecretStream { ciphertext: UByteArray, additionalData: UByteArray ): DecryptedDataAndTag { - val result = UByteArray(ciphertext.size - 17) + val result = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES) val tagArray = UByteArray(1) { 0U } sodium.crypto_secretstream_xchacha20poly1305_pull( state, @@ -62,4 +62,14 @@ actual object SecretStream { return DecryptedDataAndTag(result, tagArray[0]) } + actual fun xChaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_xchacha20poly1305_ietf_KEYBYTES) + sodium.crypto_secretstream_xchacha20poly1305_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) { + sodium.crypto_secretstream_xchacha20poly1305_rekey(state) + } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index af9f2e5..529c1be 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -10,8 +10,10 @@ import libsodium.crypto_secretstream_xchacha20poly1305_ABYTES import libsodium.crypto_secretstream_xchacha20poly1305_headerbytes import libsodium.crypto_secretstream_xchacha20poly1305_init_pull import libsodium.crypto_secretstream_xchacha20poly1305_init_push +import libsodium.crypto_secretstream_xchacha20poly1305_keygen import libsodium.crypto_secretstream_xchacha20poly1305_pull import libsodium.crypto_secretstream_xchacha20poly1305_push +import libsodium.crypto_secretstream_xchacha20poly1305_rekey import platform.posix.malloc actual typealias SecretStreamState = libsodium.crypto_secretstream_xchacha20poly1305_state @@ -119,4 +121,16 @@ actual object SecretStream { return DecryptedDataAndTag(message, tag[0]) } + actual fun xChaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_secretstream_xchacha20poly1305_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_secretstream_xchacha20poly1305_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun xChaCha20Poly1305Rekey(state: SecretStreamState) { + crypto_secretstream_xchacha20poly1305_rekey(state.ptr) + } + } From 387b827aef361813bb09f0f23b64cf3af45b4ca3 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 29 Aug 2020 17:26:47 +0200 Subject: [PATCH 22/65] Updated checklist --- js_checklist.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js_checklist.txt b/js_checklist.txt index 8c2bdc3..811bcd6 100644 --- a/js_checklist.txt +++ b/js_checklist.txt @@ -123,10 +123,10 @@ crypto_secretbox_open_detached crypto_secretbox_open_easy crypto_secretstream_xchacha20poly1305_init_pull DONE crypto_secretstream_xchacha20poly1305_init_push DONE -crypto_secretstream_xchacha20poly1305_keygen +crypto_secretstream_xchacha20poly1305_keygen DONE crypto_secretstream_xchacha20poly1305_pull DONE crypto_secretstream_xchacha20poly1305_push DONE -crypto_secretstream_xchacha20poly1305_rekey +crypto_secretstream_xchacha20poly1305_rekey DONE crypto_shorthash DONE crypto_shorthash_keygen DONE crypto_shorthash_siphashx24 From 555b69f15c8371665dcbdeb3a3bd9efe068bd402 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 29 Aug 2020 17:34:24 +0200 Subject: [PATCH 23/65] Binding implementation tracking list --- js_checklist.txt | 395 ------------------------------------- supported_bindings_list.md | 381 +++++++++++++++++++++++++++++++++++ 2 files changed, 381 insertions(+), 395 deletions(-) delete mode 100644 js_checklist.txt create mode 100644 supported_bindings_list.md diff --git a/js_checklist.txt b/js_checklist.txt deleted file mode 100644 index 811bcd6..0000000 --- a/js_checklist.txt +++ /dev/null @@ -1,395 +0,0 @@ -add -base64_variants -ORIGINAL_NO_PADDING -URLSAFE -URLSAFE_NO_PADDING -compare -from_base64 -from_hex -from_string -increment -is_zero -libsodium -print -printErr -onRuntimeInitialized -useBackupModule -... -memcmp -memzero -output_formats -pad -unpad -ready -[[ -symbols -to_base64 -to_hex -to_string -crypto_aead_chacha20poly1305_decrypt -crypto_aead_chacha20poly1305_decrypt_detached -crypto_aead_chacha20poly1305_encrypt -crypto_aead_chacha20poly1305_encrypt_detached -crypto_aead_chacha20poly1305_ietf_decrypt -crypto_aead_chacha20poly1305_ietf_decrypt_detached -crypto_aead_chacha20poly1305_ietf_encrypt -crypto_aead_chacha20poly1305_ietf_encrypt_detached -crypto_aead_chacha20poly1305_ietf_keygen -crypto_aead_chacha20poly1305_keygen -crypto_aead_xchacha20poly1305_ietf_decrypt -crypto_aead_xchacha20poly1305_ietf_decrypt_detached -crypto_aead_xchacha20poly1305_ietf_encrypt -crypto_aead_xchacha20poly1305_ietf_encrypt_detached -crypto_aead_xchacha20poly1305_ietf_keygen -crypto_auth -crypto_auth_hmacsha256 -crypto_auth_hmacsha256_keygen -crypto_auth_hmacsha256_verify -crypto_auth_hmacsha512 -crypto_auth_hmacsha512_keygen -crypto_auth_hmacsha512_verify -crypto_auth_keygen -crypto_auth_verify -crypto_box_beforenm -crypto_box_curve25519xchacha20poly1305_keypair -crypto_box_curve25519xchacha20poly1305_seal -crypto_box_curve25519xchacha20poly1305_seal_open -crypto_box_detached -crypto_box_easy -crypto_box_easy_afternm -crypto_box_keypair -crypto_box_open_detached -crypto_box_open_easy -crypto_box_open_easy_afternm -crypto_box_seal -crypto_box_seal_open -crypto_box_seed_keypair -crypto_core_ristretto255_add -crypto_core_ristretto255_from_hash -crypto_core_ristretto255_is_valid_point -crypto_core_ristretto255_random -crypto_core_ristretto255_scalar_add -crypto_core_ristretto255_scalar_complement -crypto_core_ristretto255_scalar_invert -crypto_core_ristretto255_scalar_mul -crypto_core_ristretto255_scalar_negate -crypto_core_ristretto255_scalar_random -crypto_core_ristretto255_scalar_reduce -crypto_core_ristretto255_scalar_sub -crypto_core_ristretto255_sub -crypto_generichash DONE -crypto_generichash_blake2b_salt_personal -crypto_generichash_final DONE -crypto_generichash_init DONE -crypto_generichash_keygen -crypto_generichash_update DONE -crypto_hash -crypto_hash_sha256 -crypto_hash_sha256_final -crypto_hash_sha256_init -crypto_hash_sha256_update -crypto_hash_sha512 -crypto_hash_sha512_final -crypto_hash_sha512_init -crypto_hash_sha512_update -crypto_kdf_derive_from_key -crypto_kdf_keygen -crypto_kx_client_session_keys -crypto_kx_keypair -crypto_kx_seed_keypair -crypto_kx_server_session_keys -crypto_onetimeauth -crypto_onetimeauth_final -crypto_onetimeauth_init -crypto_onetimeauth_keygen -crypto_onetimeauth_update -crypto_onetimeauth_verify -crypto_pwhash -crypto_pwhash_scryptsalsa208sha256 -crypto_pwhash_scryptsalsa208sha256_ll -crypto_pwhash_scryptsalsa208sha256_str -crypto_pwhash_scryptsalsa208sha256_str_verify -crypto_pwhash_str -crypto_pwhash_str_needs_rehash -crypto_pwhash_str_verify -crypto_scalarmult -crypto_scalarmult_base -crypto_scalarmult_ristretto255 -crypto_scalarmult_ristretto255_base -crypto_secretbox_detached -crypto_secretbox_easy -crypto_secretbox_keygen -crypto_secretbox_open_detached -crypto_secretbox_open_easy -crypto_secretstream_xchacha20poly1305_init_pull DONE -crypto_secretstream_xchacha20poly1305_init_push DONE -crypto_secretstream_xchacha20poly1305_keygen DONE -crypto_secretstream_xchacha20poly1305_pull DONE -crypto_secretstream_xchacha20poly1305_push DONE -crypto_secretstream_xchacha20poly1305_rekey DONE -crypto_shorthash DONE -crypto_shorthash_keygen DONE -crypto_shorthash_siphashx24 -crypto_sign -crypto_sign_detached -crypto_sign_ed25519_pk_to_curve25519 -crypto_sign_ed25519_sk_to_curve25519 -crypto_sign_ed25519_sk_to_pk -crypto_sign_ed25519_sk_to_seed -crypto_sign_final_create -crypto_sign_final_verify -crypto_sign_init -crypto_sign_keypair -crypto_sign_open -crypto_sign_seed_keypair -crypto_sign_update -crypto_sign_verify_detached -crypto_stream_chacha20 -crypto_stream_chacha20_ietf_xor -crypto_stream_chacha20_ietf_xor_ic -crypto_stream_chacha20_keygen -crypto_stream_chacha20_xor -crypto_stream_chacha20_xor_ic -crypto_stream_keygen -crypto_stream_xchacha20_keygen -crypto_stream_xchacha20_xor -crypto_stream_xchacha20_xor_ic -randombytes_buf -randombytes_buf_deterministic -randombytes_close -randombytes_random -randombytes_stir -randombytes_uniform -sodium_version_string -SODIUM_LIBRARY_VERSION_MAJOR -SODIUM_LIBRARY_VERSION_MINOR -crypto_aead_chacha20poly1305_ABYTES -crypto_aead_chacha20poly1305_IETF_ABYTES -crypto_aead_chacha20poly1305_IETF_KEYBYTES -crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX -crypto_aead_chacha20poly1305_IETF_NPUBBYTES -crypto_aead_chacha20poly1305_IETF_NSECBYTES -crypto_aead_chacha20poly1305_KEYBYTES -crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX -crypto_aead_chacha20poly1305_NPUBBYTES -crypto_aead_chacha20poly1305_NSECBYTES -crypto_aead_chacha20poly1305_ietf_ABYTES -crypto_aead_chacha20poly1305_ietf_KEYBYTES -crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX -crypto_aead_chacha20poly1305_ietf_NPUBBYTES -crypto_aead_chacha20poly1305_ietf_NSECBYTES -crypto_aead_xchacha20poly1305_IETF_ABYTES -crypto_aead_xchacha20poly1305_IETF_KEYBYTES -crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX -crypto_aead_xchacha20poly1305_IETF_NPUBBYTES -crypto_aead_xchacha20poly1305_IETF_NSECBYTES -crypto_aead_xchacha20poly1305_ietf_ABYTES -crypto_aead_xchacha20poly1305_ietf_KEYBYTES -crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX -crypto_aead_xchacha20poly1305_ietf_NPUBBYTES -crypto_aead_xchacha20poly1305_ietf_NSECBYTES -crypto_auth_BYTES -crypto_auth_KEYBYTES -crypto_auth_hmacsha256_BYTES -crypto_auth_hmacsha256_KEYBYTES -crypto_auth_hmacsha512256_BYTES -crypto_auth_hmacsha512256_KEYBYTES -crypto_auth_hmacsha512_BYTES -crypto_auth_hmacsha512_KEYBYTES -crypto_box_BEFORENMBYTES -crypto_box_MACBYTES -crypto_box_MESSAGEBYTES_MAX -crypto_box_NONCEBYTES -crypto_box_PUBLICKEYBYTES -crypto_box_SEALBYTES -crypto_box_SECRETKEYBYTES -crypto_box_SEEDBYTES -crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES -crypto_box_curve25519xchacha20poly1305_MACBYTES -crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX -crypto_box_curve25519xchacha20poly1305_NONCEBYTES -crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES -crypto_box_curve25519xchacha20poly1305_SEALBYTES -crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES -crypto_box_curve25519xchacha20poly1305_SEEDBYTES -crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES -crypto_box_curve25519xsalsa20poly1305_MACBYTES -crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX -crypto_box_curve25519xsalsa20poly1305_NONCEBYTES -crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES -crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES -crypto_box_curve25519xsalsa20poly1305_SEEDBYTES -crypto_core_ed25519_BYTES -crypto_core_ed25519_HASHBYTES -crypto_core_ed25519_NONREDUCEDSCALARBYTES -crypto_core_ed25519_SCALARBYTES -crypto_core_ed25519_UNIFORMBYTES -crypto_core_hchacha20_CONSTBYTES -crypto_core_hchacha20_INPUTBYTES -crypto_core_hchacha20_KEYBYTES -crypto_core_hchacha20_OUTPUTBYTES -crypto_core_hsalsa20_CONSTBYTES -crypto_core_hsalsa20_INPUTBYTES -crypto_core_hsalsa20_KEYBYTES -crypto_core_hsalsa20_OUTPUTBYTES -crypto_core_ristretto255_BYTES -crypto_core_ristretto255_HASHBYTES -crypto_core_ristretto255_NONREDUCEDSCALARBYTES -crypto_core_ristretto255_SCALARBYTES -crypto_core_salsa2012_CONSTBYTES -crypto_core_salsa2012_INPUTBYTES -crypto_core_salsa2012_KEYBYTES -crypto_core_salsa2012_OUTPUTBYTES -crypto_core_salsa20_CONSTBYTES -crypto_core_salsa20_INPUTBYTES -crypto_core_salsa20_KEYBYTES -crypto_core_salsa20_OUTPUTBYTES -crypto_generichash_BYTES -crypto_generichash_BYTES_MAX -crypto_generichash_BYTES_MIN -crypto_generichash_KEYBYTES -crypto_generichash_KEYBYTES_MAX -crypto_generichash_KEYBYTES_MIN -crypto_generichash_blake2b_BYTES -crypto_generichash_blake2b_BYTES_MAX -crypto_generichash_blake2b_BYTES_MIN -crypto_generichash_blake2b_KEYBYTES -crypto_generichash_blake2b_KEYBYTES_MAX -crypto_generichash_blake2b_KEYBYTES_MIN -crypto_generichash_blake2b_PERSONALBYTES -crypto_generichash_blake2b_SALTBYTES -crypto_hash_BYTES -crypto_hash_sha256_BYTES -crypto_hash_sha512_BYTES -crypto_kdf_BYTES_MAX -crypto_kdf_BYTES_MIN -crypto_kdf_CONTEXTBYTES -crypto_kdf_KEYBYTES -crypto_kdf_blake2b_BYTES_MAX -crypto_kdf_blake2b_BYTES_MIN -crypto_kdf_blake2b_CONTEXTBYTES -crypto_kdf_blake2b_KEYBYTES -crypto_kx_PUBLICKEYBYTES -crypto_kx_SECRETKEYBYTES -crypto_kx_SEEDBYTES -crypto_kx_SESSIONKEYBYTES -crypto_onetimeauth_BYTES -crypto_onetimeauth_KEYBYTES -crypto_onetimeauth_poly1305_BYTES -crypto_onetimeauth_poly1305_KEYBYTES -crypto_pwhash_ALG_ARGON2I13 -crypto_pwhash_ALG_ARGON2ID13 -crypto_pwhash_ALG_DEFAULT -crypto_pwhash_BYTES_MAX -crypto_pwhash_BYTES_MIN -crypto_pwhash_MEMLIMIT_INTERACTIVE -crypto_pwhash_MEMLIMIT_MAX -crypto_pwhash_MEMLIMIT_MIN -crypto_pwhash_MEMLIMIT_MODERATE -crypto_pwhash_MEMLIMIT_SENSITIVE -crypto_pwhash_OPSLIMIT_INTERACTIVE -crypto_pwhash_OPSLIMIT_MAX -crypto_pwhash_OPSLIMIT_MIN -crypto_pwhash_OPSLIMIT_MODERATE -crypto_pwhash_OPSLIMIT_SENSITIVE -crypto_pwhash_PASSWD_MAX -crypto_pwhash_PASSWD_MIN -crypto_pwhash_SALTBYTES -crypto_pwhash_STRBYTES -crypto_pwhash_argon2i_BYTES_MAX -crypto_pwhash_argon2i_BYTES_MIN -crypto_pwhash_argon2i_SALTBYTES -crypto_pwhash_argon2i_STRBYTES -crypto_pwhash_argon2id_BYTES_MAX -crypto_pwhash_argon2id_BYTES_MIN -crypto_pwhash_argon2id_SALTBYTES -crypto_pwhash_argon2id_STRBYTES -crypto_pwhash_scryptsalsa208sha256_BYTES_MAX -crypto_pwhash_scryptsalsa208sha256_BYTES_MIN -crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE -crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX -crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN -crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE -crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE -crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX -crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN -crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE -crypto_pwhash_scryptsalsa208sha256_SALTBYTES -crypto_pwhash_scryptsalsa208sha256_STRBYTES -crypto_scalarmult_BYTES -crypto_scalarmult_SCALARBYTES -crypto_scalarmult_curve25519_BYTES -crypto_scalarmult_curve25519_SCALARBYTES -crypto_scalarmult_ed25519_BYTES -crypto_scalarmult_ed25519_SCALARBYTES -crypto_scalarmult_ristretto255_BYTES -crypto_scalarmult_ristretto255_SCALARBYTES -crypto_secretbox_KEYBYTES -crypto_secretbox_MACBYTES -crypto_secretbox_MESSAGEBYTES_MAX -crypto_secretbox_NONCEBYTES -crypto_secretbox_xchacha20poly1305_KEYBYTES -crypto_secretbox_xchacha20poly1305_MACBYTES -crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX -crypto_secretbox_xchacha20poly1305_NONCEBYTES -crypto_secretbox_xsalsa20poly1305_KEYBYTES -crypto_secretbox_xsalsa20poly1305_MACBYTES -crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX -crypto_secretbox_xsalsa20poly1305_NONCEBYTES -crypto_secretstream_xchacha20poly1305_ABYTES -crypto_secretstream_xchacha20poly1305_HEADERBYTES -crypto_secretstream_xchacha20poly1305_KEYBYTES -crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX -crypto_secretstream_xchacha20poly1305_TAG_FINAL -crypto_secretstream_xchacha20poly1305_TAG_MESSAGE -crypto_secretstream_xchacha20poly1305_TAG_PUSH -crypto_secretstream_xchacha20poly1305_TAG_REKEY -crypto_shorthash_BYTES -crypto_shorthash_KEYBYTES -crypto_shorthash_siphash24_BYTES -crypto_shorthash_siphash24_KEYBYTES -crypto_shorthash_siphashx24_BYTES -crypto_shorthash_siphashx24_KEYBYTES -crypto_sign_BYTES -crypto_sign_MESSAGEBYTES_MAX -crypto_sign_PUBLICKEYBYTES -crypto_sign_SECRETKEYBYTES -crypto_sign_SEEDBYTES -crypto_sign_ed25519_BYTES -crypto_sign_ed25519_MESSAGEBYTES_MAX -crypto_sign_ed25519_PUBLICKEYBYTES -crypto_sign_ed25519_SECRETKEYBYTES -crypto_sign_ed25519_SEEDBYTES -crypto_stream_KEYBYTES -crypto_stream_MESSAGEBYTES_MAX -crypto_stream_NONCEBYTES -crypto_stream_chacha20_IETF_KEYBYTES -crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX -crypto_stream_chacha20_IETF_NONCEBYTES -crypto_stream_chacha20_KEYBYTES -crypto_stream_chacha20_MESSAGEBYTES_MAX -crypto_stream_chacha20_NONCEBYTES -crypto_stream_chacha20_ietf_KEYBYTES -crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX -crypto_stream_chacha20_ietf_NONCEBYTES -crypto_stream_salsa2012_KEYBYTES -crypto_stream_salsa2012_MESSAGEBYTES_MAX -crypto_stream_salsa2012_NONCEBYTES -crypto_stream_salsa208_KEYBYTES -crypto_stream_salsa208_MESSAGEBYTES_MAX -crypto_stream_salsa208_NONCEBYTES -crypto_stream_salsa20_KEYBYTES -crypto_stream_salsa20_MESSAGEBYTES_MAX -crypto_stream_salsa20_NONCEBYTES -crypto_stream_xchacha20_KEYBYTES -crypto_stream_xchacha20_MESSAGEBYTES_MAX -crypto_stream_xchacha20_NONCEBYTES -crypto_stream_xsalsa20_KEYBYTES -crypto_stream_xsalsa20_MESSAGEBYTES_MAX -crypto_stream_xsalsa20_NONCEBYTES -crypto_verify_16_BYTES -crypto_verify_32_BYTES -crypto_verify_64_BYTES -SODIUM_VERSION_STRING -crypto_pwhash_STRPREFIX -crypto_pwhash_scryptsalsa208sha256_STRPREFIX diff --git a/supported_bindings_list.md b/supported_bindings_list.md new file mode 100644 index 0000000..eb7f223 --- /dev/null +++ b/supported_bindings_list.md @@ -0,0 +1,381 @@ +|Function name| Implemented | +|-------------|-------------| +| add | | +| memcmp | | +| memzero | | +| output_formats | | +| pad | | +| unpad | | +| ready | | +| [[ | | +| symbols | | +| to_base64 | | +| to_hex | | +| to_string | | +| crypto_aead_chacha20poly1305_decrypt | | +| crypto_aead_chacha20poly1305_decrypt_detached | | +| crypto_aead_chacha20poly1305_encrypt | | +| crypto_aead_chacha20poly1305_encrypt_detached | | +| crypto_aead_chacha20poly1305_ietf_decrypt | | +| crypto_aead_chacha20poly1305_ietf_decrypt_detached | | +| crypto_aead_chacha20poly1305_ietf_encrypt | | +| crypto_aead_chacha20poly1305_ietf_encrypt_detached | | +| crypto_aead_chacha20poly1305_ietf_keygen | | +| crypto_aead_chacha20poly1305_keygen | | +| crypto_aead_xchacha20poly1305_ietf_decrypt | | +| crypto_aead_xchacha20poly1305_ietf_decrypt_detached | | +| crypto_aead_xchacha20poly1305_ietf_encrypt | | +| crypto_aead_xchacha20poly1305_ietf_encrypt_detached | | +| crypto_aead_xchacha20poly1305_ietf_keygen | | +| crypto_auth | | +| crypto_auth_hmacsha256 | | +| crypto_auth_hmacsha256_keygen | | +| crypto_auth_hmacsha256_verify | | +| crypto_auth_hmacsha512 | | +| crypto_auth_hmacsha512_keygen | | +| crypto_auth_hmacsha512_verify | | +| crypto_auth_keygen | | +| crypto_auth_verify | | +| crypto_box_beforenm | | +| crypto_box_curve25519xchacha20poly1305_keypair | | +| crypto_box_curve25519xchacha20poly1305_seal | | +| crypto_box_curve25519xchacha20poly1305_seal_open | | +| crypto_box_detached | | +| crypto_box_easy | | +| crypto_box_easy_afternm | | +| crypto_box_keypair | | +| crypto_box_open_detached | | +| crypto_box_open_easy | | +| crypto_box_open_easy_afternm | | +| crypto_box_seal | | +| crypto_box_seal_open | | +| crypto_box_seed_keypair | | +| crypto_core_ristretto255_add | | +| crypto_core_ristretto255_from_hash | | +| crypto_core_ristretto255_is_valid_point | | +| crypto_core_ristretto255_random | | +| crypto_core_ristretto255_scalar_add | | +| crypto_core_ristretto255_scalar_complement | | +| crypto_core_ristretto255_scalar_invert | | +| crypto_core_ristretto255_scalar_mul | | +| crypto_core_ristretto255_scalar_negate | | +| crypto_core_ristretto255_scalar_random | | +| crypto_core_ristretto255_scalar_reduce | | +| crypto_core_ristretto255_scalar_sub | | +| crypto_core_ristretto255_sub | | +| crypto_generichash | | DONE +| crypto_generichash_blake2b_salt_personal | | +| crypto_generichash_final | | DONE +| crypto_generichash_init | | DONE +| crypto_generichash_keygen | | +| crypto_generichash_update | | DONE +| crypto_hash | | +| crypto_hash_sha256 | | +| crypto_hash_sha256_final | | +| crypto_hash_sha256_init | | +| crypto_hash_sha256_update | | +| crypto_hash_sha512 | | +| crypto_hash_sha512_final | | +| crypto_hash_sha512_init | | +| crypto_hash_sha512_update | | +| crypto_kdf_derive_from_key | | +| crypto_kdf_keygen | | +| crypto_kx_client_session_keys | | +| crypto_kx_keypair | | +| crypto_kx_seed_keypair | | +| crypto_kx_server_session_keys | | +| crypto_onetimeauth | | +| crypto_onetimeauth_final | | +| crypto_onetimeauth_init | | +| crypto_onetimeauth_keygen | | +| crypto_onetimeauth_update | | +| crypto_onetimeauth_verify | | +| crypto_pwhash | | +| crypto_pwhash_scryptsalsa208sha256 | | +| crypto_pwhash_scryptsalsa208sha256_ll | | +| crypto_pwhash_scryptsalsa208sha256_str | | +| crypto_pwhash_scryptsalsa208sha256_str_verify | | +| crypto_pwhash_str | | +| crypto_pwhash_str_needs_rehash | | +| crypto_pwhash_str_verify | | +| crypto_scalarmult | | +| crypto_scalarmult_base | | +| crypto_scalarmult_ristretto255 | | +| crypto_scalarmult_ristretto255_base | | +| crypto_secretbox_detached | | +| crypto_secretbox_easy | | +| crypto_secretbox_keygen | | +| crypto_secretbox_open_detached | | +| crypto_secretbox_open_easy | | +| crypto_secretstream_xchacha20poly1305_init_pull | :heavy_check_mark: | DONE +| crypto_secretstream_xchacha20poly1305_init_push | :heavy_check_mark: | DONE +| crypto_secretstream_xchacha20poly1305_keygen | :heavy_check_mark: | DONE +| crypto_secretstream_xchacha20poly1305_pull | :heavy_check_mark: | DONE +| crypto_secretstream_xchacha20poly1305_push | :heavy_check_mark: | DONE +| crypto_secretstream_xchacha20poly1305_rekey | :heavy_check_mark: | DONE +| crypto_shorthash |:heavy_check_mark: | DONE +| crypto_shorthash_keygen | :heavy_check_mark: | DONE +| crypto_shorthash_siphashx24 | | +| crypto_sign | | +| crypto_sign_detached | | +| crypto_sign_ed25519_pk_to_curve25519 | | +| crypto_sign_ed25519_sk_to_curve25519 | | +| crypto_sign_ed25519_sk_to_pk | | +| crypto_sign_ed25519_sk_to_seed | | +| crypto_sign_final_create | | +| crypto_sign_final_verify | | +| crypto_sign_init | | +| crypto_sign_keypair | | +| crypto_sign_open | | +| crypto_sign_seed_keypair | | +| crypto_sign_update | | +| crypto_sign_verify_detached | | +| crypto_stream_chacha20 | | +| crypto_stream_chacha20_ietf_xor | | +| crypto_stream_chacha20_ietf_xor_ic | | +| crypto_stream_chacha20_keygen | | +| crypto_stream_chacha20_xor | | +| crypto_stream_chacha20_xor_ic | | +| crypto_stream_keygen | | +| crypto_stream_xchacha20_keygen | | +| crypto_stream_xchacha20_xor | | +| crypto_stream_xchacha20_xor_ic | | +| randombytes_buf | | +| randombytes_buf_deterministic | | +| randombytes_close | | +| randombytes_random | | +| randombytes_stir | | +| randombytes_uniform | | +| sodium_version_string | | +| SODIUM_LIBRARY_VERSION_MAJOR | | +| SODIUM_LIBRARY_VERSION_MINOR | | +| crypto_aead_chacha20poly1305_ABYTES | | +| crypto_aead_chacha20poly1305_IETF_ABYTES | | +| crypto_aead_chacha20poly1305_IETF_KEYBYTES | | +| crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX | | +| crypto_aead_chacha20poly1305_IETF_NPUBBYTES | | +| crypto_aead_chacha20poly1305_IETF_NSECBYTES | | +| crypto_aead_chacha20poly1305_KEYBYTES | | +| crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_aead_chacha20poly1305_NPUBBYTES | | +| crypto_aead_chacha20poly1305_NSECBYTES | | +| crypto_aead_chacha20poly1305_ietf_ABYTES | | +| crypto_aead_chacha20poly1305_ietf_KEYBYTES | | +| crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX | | +| crypto_aead_chacha20poly1305_ietf_NPUBBYTES | | +| crypto_aead_chacha20poly1305_ietf_NSECBYTES | | +| crypto_aead_xchacha20poly1305_IETF_ABYTES | | +| crypto_aead_xchacha20poly1305_IETF_KEYBYTES | | +| crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX | | +| crypto_aead_xchacha20poly1305_IETF_NPUBBYTES | | +| crypto_aead_xchacha20poly1305_IETF_NSECBYTES | | +| crypto_aead_xchacha20poly1305_ietf_ABYTES | | +| crypto_aead_xchacha20poly1305_ietf_KEYBYTES | | +| crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX | | +| crypto_aead_xchacha20poly1305_ietf_NPUBBYTES | | +| crypto_aead_xchacha20poly1305_ietf_NSECBYTES | | +| crypto_auth_BYTES | | +| crypto_auth_KEYBYTES | | +| crypto_auth_hmacsha256_BYTES | | +| crypto_auth_hmacsha256_KEYBYTES | | +| crypto_auth_hmacsha512256_BYTES | | +| crypto_auth_hmacsha512256_KEYBYTES | | +| crypto_auth_hmacsha512_BYTES | | +| crypto_auth_hmacsha512_KEYBYTES | | +| crypto_box_BEFORENMBYTES | | +| crypto_box_MACBYTES | | +| crypto_box_MESSAGEBYTES_MAX | | +| crypto_box_NONCEBYTES | | +| crypto_box_PUBLICKEYBYTES | | +| crypto_box_SEALBYTES | | +| crypto_box_SECRETKEYBYTES | | +| crypto_box_SEEDBYTES | | +| crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES | | +| crypto_box_curve25519xchacha20poly1305_MACBYTES | | +| crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_box_curve25519xchacha20poly1305_NONCEBYTES | | +| crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES | | +| crypto_box_curve25519xchacha20poly1305_SEALBYTES | | +| crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES | | +| crypto_box_curve25519xchacha20poly1305_SEEDBYTES | | +| crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES | | +| crypto_box_curve25519xsalsa20poly1305_MACBYTES | | +| crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX | | +| crypto_box_curve25519xsalsa20poly1305_NONCEBYTES | | +| crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES | | +| crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES | | +| crypto_box_curve25519xsalsa20poly1305_SEEDBYTES | | +| crypto_core_ed25519_BYTES | | +| crypto_core_ed25519_HASHBYTES | | +| crypto_core_ed25519_NONREDUCEDSCALARBYTES | | +| crypto_core_ed25519_SCALARBYTES | | +| crypto_core_ed25519_UNIFORMBYTES | | +| crypto_core_hchacha20_CONSTBYTES | | +| crypto_core_hchacha20_INPUTBYTES | | +| crypto_core_hchacha20_KEYBYTES | | +| crypto_core_hchacha20_OUTPUTBYTES | | +| crypto_core_hsalsa20_CONSTBYTES | | +| crypto_core_hsalsa20_INPUTBYTES | | +| crypto_core_hsalsa20_KEYBYTES | | +| crypto_core_hsalsa20_OUTPUTBYTES | | +| crypto_core_ristretto255_BYTES | | +| crypto_core_ristretto255_HASHBYTES | | +| crypto_core_ristretto255_NONREDUCEDSCALARBYTES | | +| crypto_core_ristretto255_SCALARBYTES | | +| crypto_core_salsa2012_CONSTBYTES | | +| crypto_core_salsa2012_INPUTBYTES | | +| crypto_core_salsa2012_KEYBYTES | | +| crypto_core_salsa2012_OUTPUTBYTES | | +| crypto_core_salsa20_CONSTBYTES | | +| crypto_core_salsa20_INPUTBYTES | | +| crypto_core_salsa20_KEYBYTES | | +| crypto_core_salsa20_OUTPUTBYTES | | +| crypto_generichash_BYTES | | +| crypto_generichash_BYTES_MAX | | +| crypto_generichash_BYTES_MIN | | +| crypto_generichash_KEYBYTES | | +| crypto_generichash_KEYBYTES_MAX | | +| crypto_generichash_KEYBYTES_MIN | | +| crypto_generichash_blake2b_BYTES | | +| crypto_generichash_blake2b_BYTES_MAX | | +| crypto_generichash_blake2b_BYTES_MIN | | +| crypto_generichash_blake2b_KEYBYTES | | +| crypto_generichash_blake2b_KEYBYTES_MAX | | +| crypto_generichash_blake2b_KEYBYTES_MIN | | +| crypto_generichash_blake2b_PERSONALBYTES | | +| crypto_generichash_blake2b_SALTBYTES | | +| crypto_hash_BYTES | | +| crypto_hash_sha256_BYTES | | +| crypto_hash_sha512_BYTES | | +| crypto_kdf_BYTES_MAX | | +| crypto_kdf_BYTES_MIN | | +| crypto_kdf_CONTEXTBYTES | | +| crypto_kdf_KEYBYTES | | +| crypto_kdf_blake2b_BYTES_MAX | | +| crypto_kdf_blake2b_BYTES_MIN | | +| crypto_kdf_blake2b_CONTEXTBYTES | | +| crypto_kdf_blake2b_KEYBYTES | | +| crypto_kx_PUBLICKEYBYTES | | +| crypto_kx_SECRETKEYBYTES | | +| crypto_kx_SEEDBYTES | | +| crypto_kx_SESSIONKEYBYTES | | +| crypto_onetimeauth_BYTES | | +| crypto_onetimeauth_KEYBYTES | | +| crypto_onetimeauth_poly1305_BYTES | | +| crypto_onetimeauth_poly1305_KEYBYTES | | +| crypto_pwhash_ALG_ARGON2I13 | | +| crypto_pwhash_ALG_ARGON2ID13 | | +| crypto_pwhash_ALG_DEFAULT | | +| crypto_pwhash_BYTES_MAX | | +| crypto_pwhash_BYTES_MIN | | +| crypto_pwhash_MEMLIMIT_INTERACTIVE | | +| crypto_pwhash_MEMLIMIT_MAX | | +| crypto_pwhash_MEMLIMIT_MIN | | +| crypto_pwhash_MEMLIMIT_MODERATE | | +| crypto_pwhash_MEMLIMIT_SENSITIVE | | +| crypto_pwhash_OPSLIMIT_INTERACTIVE | | +| crypto_pwhash_OPSLIMIT_MAX | | +| crypto_pwhash_OPSLIMIT_MIN | | +| crypto_pwhash_OPSLIMIT_MODERATE | | +| crypto_pwhash_OPSLIMIT_SENSITIVE | | +| crypto_pwhash_PASSWD_MAX | | +| crypto_pwhash_PASSWD_MIN | | +| crypto_pwhash_SALTBYTES | | +| crypto_pwhash_STRBYTES | | +| crypto_pwhash_argon2i_BYTES_MAX | | +| crypto_pwhash_argon2i_BYTES_MIN | | +| crypto_pwhash_argon2i_SALTBYTES | | +| crypto_pwhash_argon2i_STRBYTES | | +| crypto_pwhash_argon2id_BYTES_MAX | | +| crypto_pwhash_argon2id_BYTES_MIN | | +| crypto_pwhash_argon2id_SALTBYTES | | +| crypto_pwhash_argon2id_STRBYTES | | +| crypto_pwhash_scryptsalsa208sha256_BYTES_MAX | | +| crypto_pwhash_scryptsalsa208sha256_BYTES_MIN | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN | | +| crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN | | +| crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE | | +| crypto_pwhash_scryptsalsa208sha256_SALTBYTES | | +| crypto_pwhash_scryptsalsa208sha256_STRBYTES | | +| crypto_scalarmult_BYTES | | +| crypto_scalarmult_SCALARBYTES | | +| crypto_scalarmult_curve25519_BYTES | | +| crypto_scalarmult_curve25519_SCALARBYTES | | +| crypto_scalarmult_ed25519_BYTES | | +| crypto_scalarmult_ed25519_SCALARBYTES | | +| crypto_scalarmult_ristretto255_BYTES | | +| crypto_scalarmult_ristretto255_SCALARBYTES | | +| crypto_secretbox_KEYBYTES | | +| crypto_secretbox_MACBYTES | | +| crypto_secretbox_MESSAGEBYTES_MAX | | +| crypto_secretbox_NONCEBYTES | | +| crypto_secretbox_xchacha20poly1305_KEYBYTES | | +| crypto_secretbox_xchacha20poly1305_MACBYTES | | +| crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_secretbox_xchacha20poly1305_NONCEBYTES | | +| crypto_secretbox_xsalsa20poly1305_KEYBYTES | | +| crypto_secretbox_xsalsa20poly1305_MACBYTES | | +| crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX | | +| crypto_secretbox_xsalsa20poly1305_NONCEBYTES | | +| crypto_secretstream_xchacha20poly1305_ABYTES | | +| crypto_secretstream_xchacha20poly1305_HEADERBYTES | | +| crypto_secretstream_xchacha20poly1305_KEYBYTES | | +| crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX | | +| crypto_secretstream_xchacha20poly1305_TAG_FINAL | | +| crypto_secretstream_xchacha20poly1305_TAG_MESSAGE | | +| crypto_secretstream_xchacha20poly1305_TAG_PUSH | | +| crypto_secretstream_xchacha20poly1305_TAG_REKEY | | +| crypto_shorthash_BYTES | | +| crypto_shorthash_KEYBYTES | | +| crypto_shorthash_siphash24_BYTES | | +| crypto_shorthash_siphash24_KEYBYTES | | +| crypto_shorthash_siphashx24_BYTES | | +| crypto_shorthash_siphashx24_KEYBYTES | | +| crypto_sign_BYTES | | +| crypto_sign_MESSAGEBYTES_MAX | | +| crypto_sign_PUBLICKEYBYTES | | +| crypto_sign_SECRETKEYBYTES | | +| crypto_sign_SEEDBYTES | | +| crypto_sign_ed25519_BYTES | | +| crypto_sign_ed25519_MESSAGEBYTES_MAX | | +| crypto_sign_ed25519_PUBLICKEYBYTES | | +| crypto_sign_ed25519_SECRETKEYBYTES | | +| crypto_sign_ed25519_SEEDBYTES | | +| crypto_stream_KEYBYTES | | +| crypto_stream_MESSAGEBYTES_MAX | | +| crypto_stream_NONCEBYTES | | +| crypto_stream_chacha20_IETF_KEYBYTES | | +| crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX | | +| crypto_stream_chacha20_IETF_NONCEBYTES | | +| crypto_stream_chacha20_KEYBYTES | | +| crypto_stream_chacha20_MESSAGEBYTES_MAX | | +| crypto_stream_chacha20_NONCEBYTES | | +| crypto_stream_chacha20_ietf_KEYBYTES | | +| crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX | | +| crypto_stream_chacha20_ietf_NONCEBYTES | | +| crypto_stream_salsa2012_KEYBYTES | | +| crypto_stream_salsa2012_MESSAGEBYTES_MAX | | +| crypto_stream_salsa2012_NONCEBYTES | | +| crypto_stream_salsa208_KEYBYTES | | +| crypto_stream_salsa208_MESSAGEBYTES_MAX | | +| crypto_stream_salsa208_NONCEBYTES | | +| crypto_stream_salsa20_KEYBYTES | | +| crypto_stream_salsa20_MESSAGEBYTES_MAX | | +| crypto_stream_salsa20_NONCEBYTES | | +| crypto_stream_xchacha20_KEYBYTES | | +| crypto_stream_xchacha20_MESSAGEBYTES_MAX | | +| crypto_stream_xchacha20_NONCEBYTES | | +| crypto_stream_xsalsa20_KEYBYTES | | +| crypto_stream_xsalsa20_MESSAGEBYTES_MAX | | +| crypto_stream_xsalsa20_NONCEBYTES | | +| crypto_verify_16_BYTES | | +| crypto_verify_32_BYTES | | +| crypto_verify_64_BYTES | | +| SODIUM_VERSION_STRING | | +| crypto_pwhash_STRPREFIX | | +| crypto_pwhash_scryptsalsa208sha256_STRPREFIX | | From 99b9ee5e9dc6be3d7a56df33a0919e3c4111b3e5 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 29 Aug 2020 21:53:17 +0200 Subject: [PATCH 24/65] Added secretbox functions and constants --- buildSrc/src/main/kotlin/Deps.kt | 5 +- .../secretbox/SecretBox.kt | 30 +++++ .../secretstream/SecretStream.kt | 4 + .../kotlin/crypto/secretbox/SecretBoxTest.kt | 83 ++++++++++++ .../crypto/secretstream/SecretStreamTest.kt | 11 +- .../kotlin/crypto/JsSodiumInterface.kt | 10 ++ .../kotlin/crypto/secretbox/SecretBox.kt | 74 ++++++++++ .../crypto/secretstream/SecretStream.kt | 3 + .../kotlin/crypto/secretbox/SecretBox.kt | 82 +++++++++++ .../{SecretStream.kt => SecretStreamJvm.kt} | 7 +- .../kotlin/crypto/secretbox/SecretBox.kt | 127 ++++++++++++++++++ .../crypto/secretstream/SecretStream.kt | 6 +- .../ionspin/kotlin/crypto/util/SodiumUtil.kt | 8 ++ supported_bindings_list.md | 46 +++---- 14 files changed, 464 insertions(+), 32 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt rename multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/{SecretStream.kt => SecretStreamJvm.kt} (90%) create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/SodiumUtil.kt diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index c98ede8..e647100 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -61,8 +61,9 @@ object Deps { val serialization = "org.jetbrains.kotlinx:kotlinx-serialization-runtime-js:${Versions.kotlinSerialization}" object Npm { - val libsodium = Pair("libsodium-wrappers-sumo", "0.7.6") - val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "file:${getProjectPath()}/multiplatform-crypto-delegated/libsodium-wrappers-sumo-0.7.6.tgz") + val libsodium = Pair("libsodium-wrappers-sumo", "0.7.8") + //val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "file:${getProjectPath()}/multiplatform-crypto-delegated/libsodium-wrappers-sumo-0.7.6.tgz") + val libsodiumWrappers = Pair("libsodium-wrappers-sumo", "0.7.8") } } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..23c3d86 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt @@ -0,0 +1,30 @@ +package com.ionspin.kotlin.crypto.secretbox + +import kotlin.js.JsName + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 29-Aug-2020 + */ + +val crypto_secretbox_KEYBYTES = 32 +val crypto_secretbox_MACBYTES = 16 +val crypto_secretbox_NONCEBYTES = 24 + +class SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + +data class SecretBoxEncryptedDataAndTag( + @JsName("data") + val data: UByteArray, val tag: UByteArray) + +expect object SecretBox { + + fun easy(message : UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + fun openEasy(ciphertext: UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + + fun detached(message: UByteArray, nonce: UByteArray, key: UByteArray) : SecretBoxEncryptedDataAndTag + fun openDetached(ciphertext: UByteArray, tag: UByteArray, nonce: UByteArray, key: UByteArray) : UByteArray + + fun keygen() : UByteArray +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt index 24811d4..c58d137 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt @@ -4,6 +4,8 @@ package com.ionspin.kotlin.crypto.secretstream * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 26-Aug-2020 + * + * This file is named with Jvm suffix because of https://youtrack.jetbrains.com/issue/KT-21186 */ expect class SecretStreamState @@ -20,6 +22,8 @@ val crypto_secretstream_xchacha20poly1305_HEADERBYTES = 24 val crypto_secretstream_xchacha20poly1305_KEYBYTES = 32 val crypto_secretstream_xchacha20poly1305_ABYTES = 17 +class SecretStreamCorrupedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + expect object SecretStream { fun xChaCha20Poly1305InitPush(key: UByteArray) : SecretStreamStateAndHeader diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt new file mode 100644 index 0000000..dd3a108 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt @@ -0,0 +1,83 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 29-Aug-2020 + */ +class SecretBoxTest { + + @Test + fun secretBoxTestEasy() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val encrypted = SecretBox.easy(message, nonce, key) + val decrypted = SecretBox.openEasy(encrypted, nonce, key) + assertTrue { decrypted.contentEquals(message) } + assertFailsWith(SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[2] = 0U + SecretBox.openEasy(tamperedTag, nonce, key) + } + } + + + } + + @Test + fun secretBoxTestDetached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + println("Debug") + val encrypted = SecretBox.detached(message, nonce, key) + val decrypted = SecretBox.openDetached(encrypted.data, encrypted.tag, nonce, key) + assertTrue { decrypted.contentEquals(message) } + assertFailsWith(SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[2] = 0U + SecretBox.openDetached(encrypted.data, tamperedTag, nonce, key) + } + } + + + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index 7fc9226..b26dc58 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -5,6 +5,7 @@ import com.ionspin.kotlin.crypto.LibsodiumInitializer import com.ionspin.kotlin.crypto.util.encodeToUByteArray import com.ionspin.kotlin.crypto.util.testBlocking import kotlin.test.Test +import kotlin.test.assertFailsWith import kotlin.test.assertTrue /** @@ -71,7 +72,12 @@ class SecretStreamTest { decrypted.decryptedData.hexColumsPrint() assertTrue { decrypted.decryptedData.contentEquals(message) - + } + assertFailsWith(SecretStreamCorrupedOrTamperedDataException::class) { + encrypted[encrypted.size - 5] = 0U + val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header) + val decrypted = + SecretStream.xChaCha20Poly1305Pull(decryptState.state, encrypted, ubyteArrayOf()) } @@ -80,7 +86,8 @@ class SecretStreamTest { } - +// TODO modify nonce in state so we can have reproducible tests, theres already a similar way of doing this +// in crypto delegated project XChaCha20Poly1305 test expect fun modifyState(state: SecretStreamState, forceNonce: UByteArray) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index aa1711f..8e456a6 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -61,6 +61,16 @@ interface JsSodiumInterface { fun crypto_secretstream_xchacha20poly1305_keygen() : Uint8Array fun crypto_secretstream_xchacha20poly1305_rekey(state: dynamic) + // ---- SecretBox ---- + fun crypto_secretbox_detached(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic + fun crypto_secretbox_easy(message: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_secretbox_keygen() : Uint8Array + fun crypto_secretbox_open_detached(ciphertext : Uint8Array, tag : Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic + fun crypto_secretbox_open_easy(ciphertext : Uint8Array, nonce: Uint8Array, key: Uint8Array) : dynamic + + + // ---- SecretBox End ---- + //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..4ff9188 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt @@ -0,0 +1,74 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual object SecretBox { + actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray { + return getSodium().crypto_secretbox_easy( + message.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } + + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + val decryptionResult = getSodium().crypto_secretbox_open_easy( + ciphertext.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return (decryptionResult as Uint8Array).toUByteArray() + } catch (error: Throwable) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + } + + actual fun detached( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): SecretBoxEncryptedDataAndTag { + val result = getSodium().crypto_secretbox_detached( + message.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return SecretBoxEncryptedDataAndTag( + (result.cipher as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) + } + + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + try { + val decryptionResult = getSodium().crypto_secretbox_open_detached( + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ) + return (decryptionResult as Uint8Array).toUByteArray() + } catch (error: Throwable) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + + } + + actual fun keygen(): UByteArray { + return getSodium().crypto_secretbox_keygen().toUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 82b0a7c..9c09c34 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -40,6 +40,9 @@ actual object SecretStream { val dataAndTag = getSodium().crypto_secretstream_xchacha20poly1305_pull( state, ciphertext.toUInt8Array(), additionalData.toUInt8Array() ) + if (dataAndTag == false) { + throw SecretStreamCorrupedOrTamperedDataException() + } return DecryptedDataAndTag((dataAndTag.message as Uint8Array).toUByteArray(), dataAndTag.tag) } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..8f113e6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt @@ -0,0 +1,82 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object SecretBox { + actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray { + val ciphertext = UByteArray(message.size + crypto_secretbox_MACBYTES) + sodium.crypto_secretbox_easy( + ciphertext.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + return ciphertext + } + + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val decrypted = UByteArray(ciphertext.size - crypto_secretbox_MACBYTES) + val validationResult = sodium.crypto_secretbox_open_easy( + decrypted.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + if (validationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return decrypted + } + + actual fun detached( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): SecretBoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_secretbox_MACBYTES) + sodium.crypto_secretbox_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + return SecretBoxEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_secretbox_open_detached( + message.asByteArray(), + ciphertext.asByteArray(), + tag.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + key.asByteArray() + ) + if (validationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return message + } + + actual fun keygen() : UByteArray { + val generatedKey = UByteArray(crypto_secretbox_KEYBYTES) + sodium.crypto_secretbox_keygen(generatedKey.asByteArray()) + return generatedKey + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt similarity index 90% rename from multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt rename to multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt index ab32a6e..d603555 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt @@ -49,7 +49,7 @@ actual object SecretStream { ): DecryptedDataAndTag { val result = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES) val tagArray = UByteArray(1) { 0U } - sodium.crypto_secretstream_xchacha20poly1305_pull( + val validationResult = sodium.crypto_secretstream_xchacha20poly1305_pull( state, result.asByteArray(), null, @@ -59,11 +59,14 @@ actual object SecretStream { additionalData.asByteArray(), additionalData.size.toLong() ) + if (validationResult != 0) { + throw SecretStreamCorrupedOrTamperedDataException() + } return DecryptedDataAndTag(result, tagArray[0]) } actual fun xChaCha20Poly1305Keygen(): UByteArray { - val generatedKey = UByteArray(crypto_aead_xchacha20poly1305_ietf_KEYBYTES) + val generatedKey = UByteArray(crypto_secretstream_xchacha20poly1305_KEYBYTES) sodium.crypto_secretstream_xchacha20poly1305_keygen(generatedKey.asByteArray()) return generatedKey } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt new file mode 100644 index 0000000..58b9882 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt @@ -0,0 +1,127 @@ +package com.ionspin.kotlin.crypto.secretbox + +import com.ionspin.kotlin.crypto.secretstream.SecretStreamCorrupedOrTamperedDataException +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_secretbox_detached +import libsodium.crypto_secretbox_easy +import libsodium.crypto_secretbox_keygen +import libsodium.crypto_secretbox_open_detached +import libsodium.crypto_secretbox_open_easy + +actual object SecretBox { + actual fun easy(message: UByteArray, nonce: UByteArray, key: UByteArray): UByteArray { + val ciphertext = UByteArray(message.size + crypto_secretbox_MACBYTES) + val ciphertextPinned = ciphertext.pin() + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + crypto_secretbox_easy( + ciphertextPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + return ciphertext + } + + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_secretbox_MACBYTES) + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + val verificationResult = crypto_secretbox_open_easy( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + if (verificationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return message + } + + actual fun detached( + message: UByteArray, + nonce: UByteArray, + key: UByteArray + ): SecretBoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_secretbox_MACBYTES) + val ciphertextPinned = ciphertext.pin() + val authenticationTagPinned = authenticationTag.pin() + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + crypto_secretbox_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + authenticationTagPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + return SecretBoxEncryptedDataAndTag(ciphertext, authenticationTag) + } + + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + val verificationResult = crypto_secretbox_open_detached( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + tagPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + if (verificationResult != 0) { + throw SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() + } + return message + } + + actual fun keygen() :UByteArray { + val generatedKey = UByteArray(crypto_secretbox_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_secretbox_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 529c1be..3df6325 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -101,7 +101,7 @@ actual object SecretStream { } val tag = UByteArray(1) { 0U } val tagPinned = tag.pin() - val validTag = crypto_secretstream_xchacha20poly1305_pull( + val validationResult = crypto_secretstream_xchacha20poly1305_pull( state.ptr, messagePinned.toPtr(), null, @@ -115,8 +115,8 @@ actual object SecretStream { messagePinned.unpin() additionalDataPinned?.unpin() tagPinned.unpin() - if (validTag != 0) { - throw RuntimeException("Invalid tag") + if (validationResult != 0) { + throw SecretStreamCorrupedOrTamperedDataException() } return DecryptedDataAndTag(message, tag[0]) } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/SodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/SodiumUtil.kt new file mode 100644 index 0000000..d30db27 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/SodiumUtil.kt @@ -0,0 +1,8 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 29-Aug-2020 + */ +//fun randomBytesBuf() diff --git a/supported_bindings_list.md b/supported_bindings_list.md index eb7f223..f46df98 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -102,19 +102,19 @@ | crypto_scalarmult_base | | | crypto_scalarmult_ristretto255 | | | crypto_scalarmult_ristretto255_base | | -| crypto_secretbox_detached | | -| crypto_secretbox_easy | | -| crypto_secretbox_keygen | | -| crypto_secretbox_open_detached | | -| crypto_secretbox_open_easy | | -| crypto_secretstream_xchacha20poly1305_init_pull | :heavy_check_mark: | DONE -| crypto_secretstream_xchacha20poly1305_init_push | :heavy_check_mark: | DONE -| crypto_secretstream_xchacha20poly1305_keygen | :heavy_check_mark: | DONE -| crypto_secretstream_xchacha20poly1305_pull | :heavy_check_mark: | DONE -| crypto_secretstream_xchacha20poly1305_push | :heavy_check_mark: | DONE -| crypto_secretstream_xchacha20poly1305_rekey | :heavy_check_mark: | DONE -| crypto_shorthash |:heavy_check_mark: | DONE -| crypto_shorthash_keygen | :heavy_check_mark: | DONE +| crypto_secretbox_detached | :heavy_check_mark: | +| crypto_secretbox_easy | :heavy_check_mark: | +| crypto_secretbox_keygen | :heavy_check_mark: | +| crypto_secretbox_open_detached | :heavy_check_mark: | +| crypto_secretbox_open_easy | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_init_pull | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_init_push | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_keygen | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_pull | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_push | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_rekey | :heavy_check_mark: | +| crypto_shorthash |:heavy_check_mark: | +| crypto_shorthash_keygen | :heavy_check_mark: | | crypto_shorthash_siphashx24 | | | crypto_sign | | | crypto_sign_detached | | @@ -310,10 +310,10 @@ | crypto_scalarmult_ed25519_SCALARBYTES | | | crypto_scalarmult_ristretto255_BYTES | | | crypto_scalarmult_ristretto255_SCALARBYTES | | -| crypto_secretbox_KEYBYTES | | -| crypto_secretbox_MACBYTES | | +| crypto_secretbox_KEYBYTES | :heavy_check_mark: | +| crypto_secretbox_MACBYTES | :heavy_check_mark: | | crypto_secretbox_MESSAGEBYTES_MAX | | -| crypto_secretbox_NONCEBYTES | | +| crypto_secretbox_NONCEBYTES | :heavy_check_mark: | | crypto_secretbox_xchacha20poly1305_KEYBYTES | | | crypto_secretbox_xchacha20poly1305_MACBYTES | | | crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX | | @@ -322,14 +322,14 @@ | crypto_secretbox_xsalsa20poly1305_MACBYTES | | | crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX | | | crypto_secretbox_xsalsa20poly1305_NONCEBYTES | | -| crypto_secretstream_xchacha20poly1305_ABYTES | | -| crypto_secretstream_xchacha20poly1305_HEADERBYTES | | -| crypto_secretstream_xchacha20poly1305_KEYBYTES | | +| crypto_secretstream_xchacha20poly1305_ABYTES | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_HEADERBYTES | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_KEYBYTES | :heavy_check_mark: | | crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX | | -| crypto_secretstream_xchacha20poly1305_TAG_FINAL | | -| crypto_secretstream_xchacha20poly1305_TAG_MESSAGE | | -| crypto_secretstream_xchacha20poly1305_TAG_PUSH | | -| crypto_secretstream_xchacha20poly1305_TAG_REKEY | | +| crypto_secretstream_xchacha20poly1305_TAG_FINAL | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_TAG_MESSAGE | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_TAG_PUSH | :heavy_check_mark: | +| crypto_secretstream_xchacha20poly1305_TAG_REKEY | :heavy_check_mark: | | crypto_shorthash_BYTES | | | crypto_shorthash_KEYBYTES | | | crypto_shorthash_siphash24_BYTES | | From 54489ef6cb22d94ddd3e9e2c99d8fa7012d31619 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 11:21:53 +0200 Subject: [PATCH 25/65] Start work on _aead_ --- ...thenticatedEncryptionWithAssociatedData.kt | 121 ++++++++++ .../secretbox/SecretBox.kt | 4 +- ...thenticatedEncryptionWithAssociatedData.kt | 119 ++++++++++ ...thenticatedEncryptionWithAssociatedData.kt | 119 ++++++++++ ...thenticatedEncryptionWithAssociatedData.kt | 210 ++++++++++++++++++ 5 files changed, 570 insertions(+), 3 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..2108c23 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,121 @@ +package com.ionspin.kotlin.crypto.aead + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ + +//X - Ietf +val crypto_aead_xchacha20poly1305_ietf_KEYBYTES = 32 +val crypto_aead_xchacha20poly1305_ietf_NPUBBYTES = 24 +val crypto_aead_xchacha20poly1305_ietf_ABYTES = 16 + +// Ietf +val crypto_aead_chacha20poly1305_ietf_KEYBYTES = 32 +val crypto_aead_chacha20poly1305_ietf_NPUBBYTES = 12 +val crypto_aead_chacha20poly1305_ietf_ABYTES = 16 + +// original chacha20poly1305 + +val crypto_aead_chacha20poly1305_KEYBYTES = 32 +val crypto_aead_chacha20poly1305_NPUBBYTES = 8 +val crypto_aead_chacha20poly1305_ABYTES = 16 + + +data class AeadEncryptedDataAndTag(val data: UByteArray, val tag: UByteArray) + +expect object AuthenticatedEncryptionWithAssociatedData { + // X - Ietf + fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag + + fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + // Ietf + + fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag + + fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + // Original chacha20poly1305 + + fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + + fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag + + fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt index 23c3d86..94abe7a 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretbox/SecretBox.kt @@ -14,9 +14,7 @@ val crypto_secretbox_NONCEBYTES = 24 class SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") -data class SecretBoxEncryptedDataAndTag( - @JsName("data") - val data: UByteArray, val tag: UByteArray) +data class SecretBoxEncryptedDataAndTag(val data: UByteArray, val tag: UByteArray) expect object SecretBox { diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..332f9a4 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,119 @@ +package com.ionspin.kotlin.crypto.aead + +actual object AuthenticatedEncryptionWithAssociatedData { + + // Ietf + + // Original chacha20poly1305 + actual fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..332f9a4 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,119 @@ +package com.ionspin.kotlin.crypto.aead + +actual object AuthenticatedEncryptionWithAssociatedData { + + // Ietf + + // Original chacha20poly1305 + actual fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt new file mode 100644 index 0000000..eab798d --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -0,0 +1,210 @@ +package com.ionspin.kotlin.crypto.aead + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_aead_chacha20poly1305_encrypt +import libsodium.crypto_aead_chacha20poly1305_ietf_encrypt +import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt + +actual object AuthenticatedEncryptionWithAssociatedData { + + // Ietf + + // Original chacha20poly1305 + actual fun xChaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size + crypto_aead_xchacha20poly1305_ietf_ABYTES) + val ciphertextPinned = ciphertext.pin() + + crypto_aead_xchacha20poly1305_ietf_encrypt( + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return ciphertext + } + + actual fun xChaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun xChaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfEncrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ietf_ABYTES) + val ciphertextPinned = ciphertext.pin() + + crypto_aead_chacha20poly1305_ietf_encrypt( + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return ciphertext + } + + actual fun chaCha20Poly1305IetfDecrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfEncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305IetfDecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305Encrypt( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ABYTES) + val ciphertextPinned = ciphertext.pin() + + crypto_aead_chacha20poly1305_encrypt( + ciphertextPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return ciphertext + } + + actual fun chaCha20Poly1305Decrypt( + ciphertext: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305EncryptDetached( + message: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): AeadEncryptedDataAndTag { + TODO("not implemented yet") + } + + actual fun chaCha20Poly1305DecryptDetached( + ciphertext: UByteArray, + tag: UByteArray, + associatedData: UByteArray, + nonce: UByteArray, + key: UByteArray + ): UByteArray { + TODO("not implemented yet") + } + +} From 3de04749bae20933ac2cbc7718e6398559bf845d Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 11:56:18 +0200 Subject: [PATCH 26/65] Change all occurences of additionalData to associatedData --- .../kotlin/com/ionspin/kotlin/crypto/Api.kt | 12 +++---- .../com/ionspin/kotlin/crypto/Crypto.kt | 16 ++++----- .../DelegatedXChaCha20Poly1305.kt | 8 ++--- .../authenticated/XChaCha20Poly1305Test.kt | 20 +++++------ .../kotlin/crypto/highlevel/EncryptionTest.kt | 6 ++-- .../kotlin/crypto/JsSodiumInterface.kt | 8 ++--- .../XChaCha20Poly1305Delegated.kt | 16 ++++----- .../XChaCha20Poly1305Delegated.kt | 22 ++++++------ .../XChaCha20Poly1305Delegated.kt | 24 ++++++------- .../secretstream/SecretStream.kt | 4 +-- .../crypto/secretstream/SecretStreamTest.kt | 2 +- .../kotlin/crypto/JsSodiumInterface.kt | 8 ++--- .../crypto/secretstream/SecretStream.kt | 8 ++--- .../crypto/secretstream/SecretStreamJvm.kt | 12 +++---- .../crypto/secretstream/SecretStream.kt | 24 ++++++------- .../com/ionspin/kotlin/crypto/Crypto.kt | 16 ++++----- .../authenticated/ChaCha20Poly1305Pure.kt | 8 ++--- .../authenticated/XChaCha20Poly1305Pure.kt | 36 +++++++++---------- .../authenticated/ChaCha20Poly1305Test.kt | 6 ++-- .../authenticated/XChaCha20Poly1305Test.kt | 20 +++++------ .../kotlin/crypto/highlevel/EncryptionTest.kt | 8 ++--- 21 files changed, 142 insertions(+), 142 deletions(-) diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt index 427ffd4..376ea57 100644 --- a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Api.kt @@ -54,16 +54,16 @@ interface HashApi { } interface EncryptionApi { - fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData - fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T + fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData + fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T fun createMultipartEncryptor(key: SymmetricKey) : MultipartAuthenticatedEncryption fun createMultipartDecryptor(key: SymmetricKey, header: MultipartEncryptionHeader) : MultipartAuthenticatedDecryption } interface AuthenticatedEncryption { - fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray - fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray + fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray } @@ -75,12 +75,12 @@ data class MultipartEncryptionHeader(val nonce: UByteArray) class InvalidTagException : RuntimeException("Tag mismatch! Encrypted data is corrupted or tampered with.") interface MultipartAuthenticatedDecryption { - fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray = ubyteArrayOf()) : DecryptedDataPart + fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray = ubyteArrayOf()) : DecryptedDataPart fun cleanup() } interface MultipartAuthenticatedEncryption { - fun encryptPartialData(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : EncryptedDataPart + fun encryptPartialData(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : EncryptedDataPart fun startEncryption() : MultipartEncryptionHeader fun cleanup() diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt index 5d3d87a..4507c00 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt @@ -145,17 +145,17 @@ object Crypto { } object Encryption : EncryptionApi { - override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData { if (key.value.size != 32) { throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}") } val nonce = SRNG.getRandomBytes(24) - return EncryptedData(XChaCha20Poly1305Delegated.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce) + return EncryptedData(XChaCha20Poly1305Delegated.encrypt(key.value, nonce, data.toEncryptableForm(), associatedData), nonce) } - override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { - return byteArrayDeserializer(XChaCha20Poly1305Delegated.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData)) + override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { + return byteArrayDeserializer(XChaCha20Poly1305Delegated.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, associatedData)) } @@ -185,8 +185,8 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe return header } - override fun encryptPartialData(data: UByteArray, additionalData: UByteArray): EncryptedDataPart { - return EncryptedDataPart(primitive.encrypt(data, additionalData)) + override fun encryptPartialData(data: UByteArray, associatedData: UByteArray): EncryptedDataPart { + return EncryptedDataPart(primitive.encrypt(data, associatedData)) } override fun cleanup() { @@ -196,8 +196,8 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Delegated) : MultipartAuthenticatedDecryption { - override fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray): DecryptedDataPart { - return DecryptedDataPart(decryptor.decrypt(data.data, additionalData)) + override fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray): DecryptedDataPart { + return DecryptedDataPart(decryptor.decrypt(data.data, associatedData)) } override fun cleanup() { diff --git a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt index 7166932..5f92fc8 100644 --- a/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt +++ b/multiplatform-crypto-delegated/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/DelegatedXChaCha20Poly1305.kt @@ -9,13 +9,13 @@ package com.ionspin.kotlin.crypto.authenticated expect class XChaCha20Poly1305Delegated internal constructor() { internal constructor(key: UByteArray, testState : UByteArray, testHeader: UByteArray, isDecryptor: Boolean) companion object { - fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray - fun decrypt(key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, additionalData: UByteArray) : UByteArray + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray + fun decrypt(key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, associatedData: UByteArray) : UByteArray } fun initializeForEncryption(key: UByteArray) : UByteArray fun initializeForDecryption(key: UByteArray, header: UByteArray) - fun encrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray - fun decrypt(data: UByteArray, additionalData: UByteArray = ubyteArrayOf()) : UByteArray + fun encrypt(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray + fun decrypt(data: UByteArray, associatedData: UByteArray = ubyteArrayOf()) : UByteArray fun cleanup() diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt index f553169..6ed851c 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt @@ -26,7 +26,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -61,9 +61,9 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) - val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, additionalData) + val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, associatedData) encrypted.hexColumsPrint() - val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData) + val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, associatedData) println("Decrypted") decrypted.hexColumsPrint() println("----------") @@ -74,7 +74,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -93,8 +93,8 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) - val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, additionalData) - val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, additionalData) + val encrypted = XChaCha20Poly1305Delegated.encrypt(key, nonce, message, associatedData) + val decrypted = XChaCha20Poly1305Delegated.decrypt(key, nonce, encrypted, associatedData) encrypted.contentEquals(expected) && decrypted.contentEquals(message) } @@ -109,7 +109,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -144,7 +144,7 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) -// val xChaChaPoly = XChaCha20Poly1305Delegated(key, additionalData) +// val xChaChaPoly = XChaCha20Poly1305Delegated(key, associatedData) // val firstChunk = xChaChaPoly.encrypt(message) // val finalChunk = xChaChaPoly.finishEncryption().first // val result = firstChunk + finalChunk @@ -157,7 +157,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -176,7 +176,7 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) -// val xChaChaPoly = XChaCha20Poly1305Delegated(key, additionalData) +// val xChaChaPoly = XChaCha20Poly1305Delegated(key, associatedData) // val firstChunk = xChaChaPoly.encrypt(message) // val finalChunk = xChaChaPoly.finishEncryption().first // val result = firstChunk + finalChunk diff --git a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt index c85fad2..9573fcc 100644 --- a/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt +++ b/multiplatform-crypto-delegated/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt @@ -22,17 +22,17 @@ class EncryptionTest { val plaintext = ("pUoR4JVXJUeMKNkt6ZGGzEdTo33ajNGXwXpivBKA0XKs8toGRYI9Eul4bELRDkaQDNhd4vZseEFU" + "ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" + "EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray() - val additionalData = "Additional data 1".encodeToUByteArray() + val associatedData = "Additional data 1".encodeToUByteArray() val keyValue = UByteArray(32) { it.toUByte() } val key = SymmetricKey(keyValue) val encryptor = Crypto.Encryption.createMultipartEncryptor(key) val header = encryptor.startEncryption() - val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), additionalData) + val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), associatedData) val ciphertext2 = encryptor.encryptPartialData(plaintext.sliceArray(100 until 200)) val ciphertext3 = encryptor.encryptPartialData(plaintext.sliceArray(200 until 250)) //decrypt val decryptor = Crypto.Encryption.createMultipartDecryptor(key, header) - val plaintext1 = decryptor.decryptPartialData(ciphertext1, additionalData) + val plaintext1 = decryptor.decryptPartialData(ciphertext1, associatedData) val plaintext2 = decryptor.decryptPartialData(ciphertext2) val plaintext3 = decryptor.decryptPartialData(ciphertext3) diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 1934eb9..b917faf 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -40,17 +40,17 @@ interface JsSodiumInterface { fun crypto_hash_sha512_final(state: dynamic): Uint8Array //XChaCha20Poly1305 - fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, additionalData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array - fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, additionalData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array //XChaCha20Poly1305 //encrypt fun crypto_secretstream_xchacha20poly1305_init_push(header: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: Uint8Array, tag: UByte) : Uint8Array + fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, associatedData: Uint8Array, tag: UByte) : Uint8Array //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, associatedData: Uint8Array) : dynamic //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt index 2ab0433..faeea44 100644 --- a/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt +++ b/multiplatform-crypto-delegated/src/jsMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -24,11 +24,11 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, message: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val encrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt( message.toUInt8Array(), - additionalData.toUInt8Array(), + associatedData.toUInt8Array(), Uint8Array(0), nonce.toUInt8Array(), key.toUInt8Array() @@ -40,12 +40,12 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val decrypted = getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt( Uint8Array(0), ciphertext.toUInt8Array(), - additionalData.toUInt8Array(), + associatedData.toUInt8Array(), nonce.toUInt8Array(), key.toUInt8Array() ) @@ -92,25 +92,25 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { isEncryptor = !isDecryptor } - actual fun encrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } if (!isEncryptor) { throw RuntimeException("Initialized as decryptor, attempted to use as encryptor") } - val encrypted = getSodium().crypto_secretstream_xchacha20poly1305_push(state, data.toUInt8Array(), additionalData.toUInt8Array(), 0U) + val encrypted = getSodium().crypto_secretstream_xchacha20poly1305_push(state, data.toUInt8Array(), associatedData.toUInt8Array(), 0U) return encrypted.toUByteArray() } - actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } if (isEncryptor) { throw RuntimeException("Initialized as encryptor, attempted to use as decryptor") } - val decryptedWithTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(state, data.toUInt8Array(), additionalData.toUInt8Array()) + val decryptedWithTag = getSodium().crypto_secretstream_xchacha20poly1305_pull(state, data.toUInt8Array(), associatedData.toUInt8Array()) val decrypted = decryptedWithTag.message as Uint8Array val validTag = decryptedWithTag.tag diff --git a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt index 4edc35b..cb2cdfe 100644 --- a/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt +++ b/multiplatform-crypto-delegated/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -16,7 +16,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, message: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val ciphertext = ByteArray(message.size + 16) SodiumJava().crypto_aead_xchacha20poly1305_ietf_encrypt( @@ -24,8 +24,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { longArrayOf(ciphertext.size.toLong()), message.toByteArray(), message.size.toLong(), - additionalData.toByteArray(), - additionalData.size.toLong(), + associatedData.toByteArray(), + associatedData.size.toLong(), null, nonce.toByteArray(), key.toByteArray() @@ -38,7 +38,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val message = ByteArray(ciphertext.size - 16) SodiumJava().crypto_aead_xchacha20poly1305_ietf_decrypt( @@ -47,8 +47,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { null, ciphertext.toByteArray(), ciphertext.size.toLong(), - additionalData.toByteArray(), - additionalData.size.toLong(), + associatedData.toByteArray(), + associatedData.size.toLong(), nonce.toByteArray(), key.toByteArray() @@ -89,7 +89,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { isEncryptor = false } - actual fun encrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } @@ -100,13 +100,13 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { sodium.crypto_secretstream_xchacha20poly1305_push( state, ciphertext, null, data.asByteArray(), data.size.toLong(), - additionalData.asByteArray(), additionalData.size.toLong(), + associatedData.asByteArray(), associatedData.size.toLong(), 0 ) return ciphertext.asUByteArray() } - actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray { if (!isInitialized) { throw RuntimeException("Not initalized!") } @@ -120,8 +120,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { null, data.asByteArray(), (data.size).toLong(), - additionalData.asByteArray(), - additionalData.size.toLong() + associatedData.asByteArray(), + associatedData.size.toLong() ) if (validTag != 0) { println("Tag validation failed") diff --git a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt index e83dd43..eb7f836 100644 --- a/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt +++ b/multiplatform-crypto-delegated/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Delegated.kt @@ -17,7 +17,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, message: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val ciphertextLength = message.size + crypto_aead_xchacha20poly1305_IETF_ABYTES.toInt() val ciphertext = UByteArray(ciphertextLength) @@ -27,8 +27,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { ulongArrayOf(ciphertextLength.convert()).toCValues(), message.toCValues(), message.size.convert(), - additionalData.toCValues(), - additionalData.size.convert(), + associatedData.toCValues(), + associatedData.size.convert(), null, nonce.toCValues(), key.toCValues() @@ -41,7 +41,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { key: UByteArray, nonce: UByteArray, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): UByteArray { val messageLength = ciphertext.size - crypto_aead_xchacha20poly1305_IETF_ABYTES.toInt() val message = UByteArray(messageLength) @@ -52,8 +52,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { null, ciphertext.toCValues(), ciphertext.size.convert(), - additionalData.toCValues(), - additionalData.size.convert(), + associatedData.toCValues(), + associatedData.size.convert(), nonce.toCValues(), key.toCValues() ) @@ -112,7 +112,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { } - actual fun encrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun encrypt(data: UByteArray, associatedData: UByteArray): UByteArray { val ciphertextWithTag = UByteArray(data.size + crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) val ciphertextWithTagPinned = ciphertextWithTag.pin() crypto_secretstream_xchacha20poly1305_push( @@ -121,8 +121,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { null, data.toCValues(), data.size.convert(), - additionalData.toCValues(), - additionalData.size.convert(), + associatedData.toCValues(), + associatedData.size.convert(), 0U, ) println("Encrypt partial") @@ -132,7 +132,7 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { return ciphertextWithTag } - actual fun decrypt(data: UByteArray, additionalData: UByteArray): UByteArray { + actual fun decrypt(data: UByteArray, associatedData: UByteArray): UByteArray { val plaintext = UByteArray(data.size - crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) val plaintextPinned = plaintext.pin() val validTag = crypto_secretstream_xchacha20poly1305_pull( @@ -142,8 +142,8 @@ actual class XChaCha20Poly1305Delegated internal actual constructor() { null, data.toCValues(), data.size.convert(), - additionalData.toCValues(), - additionalData.size.convert() + associatedData.toCValues(), + associatedData.size.convert() ) plaintextPinned.unpin() println("tag: $validTag") diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt index c58d137..32c7dea 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt @@ -27,9 +27,9 @@ class SecretStreamCorrupedOrTamperedDataException() : RuntimeException("MAC vali expect object SecretStream { fun xChaCha20Poly1305InitPush(key: UByteArray) : SecretStreamStateAndHeader - fun xChaCha20Poly1305Push(state : SecretStreamState, message: UByteArray, additionalData : UByteArray = ubyteArrayOf(), tag: UByte) : UByteArray + fun xChaCha20Poly1305Push(state : SecretStreamState, message: UByteArray, associatedData : UByteArray = ubyteArrayOf(), tag: UByte) : UByteArray fun xChaCha20Poly1305InitPull(key: UByteArray, header: UByteArray) : SecretStreamStateAndHeader - fun xChaCha20Poly1305Pull(state : SecretStreamState, ciphertext: UByteArray, additionalData : UByteArray = ubyteArrayOf()) : DecryptedDataAndTag + fun xChaCha20Poly1305Pull(state : SecretStreamState, ciphertext: UByteArray, associatedData : UByteArray = ubyteArrayOf()) : DecryptedDataAndTag fun xChaCha20Poly1305Keygen() : UByteArray fun xChaCha20Poly1305Rekey(state: SecretStreamState) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index b26dc58..80c3d89 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -22,7 +22,7 @@ class SecretStreamTest { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 8e456a6..c821572 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -45,17 +45,17 @@ interface JsSodiumInterface { fun crypto_hash_sha512_final(state: dynamic): Uint8Array //XChaCha20Poly1305 - fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, additionalData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array - fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, additionalData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array //XChaCha20Poly1305 //encrypt fun crypto_secretstream_xchacha20poly1305_init_push(key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, additionalData: Uint8Array, tag: UByte) : Uint8Array + fun crypto_secretstream_xchacha20poly1305_push(state: dynamic, message: Uint8Array, associatedData: Uint8Array, tag: UByte) : Uint8Array //decrypt fun crypto_secretstream_xchacha20poly1305_init_pull(header: Uint8Array, key: Uint8Array) : dynamic - fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, additionalData: Uint8Array) : dynamic + fun crypto_secretstream_xchacha20poly1305_pull(state: dynamic, ciphertext: Uint8Array, associatedData: Uint8Array) : dynamic //keygen and rekey fun crypto_secretstream_xchacha20poly1305_keygen() : Uint8Array diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 9c09c34..6152e60 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -16,11 +16,11 @@ actual object SecretStream { actual fun xChaCha20Poly1305Push( state: SecretStreamState, message: UByteArray, - additionalData: UByteArray, + associatedData: UByteArray, tag: UByte ): UByteArray { return getSodium().crypto_secretstream_xchacha20poly1305_push( - state, message.toUInt8Array(), additionalData.toUInt8Array(), tag + state, message.toUInt8Array(), associatedData.toUInt8Array(), tag ).toUByteArray() } @@ -35,10 +35,10 @@ actual object SecretStream { actual fun xChaCha20Poly1305Pull( state: SecretStreamState, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): DecryptedDataAndTag { val dataAndTag = getSodium().crypto_secretstream_xchacha20poly1305_pull( - state, ciphertext.toUInt8Array(), additionalData.toUInt8Array() + state, ciphertext.toUInt8Array(), associatedData.toUInt8Array() ) if (dataAndTag == false) { throw SecretStreamCorrupedOrTamperedDataException() diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt index d603555..72d1cf6 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt @@ -16,7 +16,7 @@ actual object SecretStream { actual fun xChaCha20Poly1305Push( state: SecretStreamState, message: UByteArray, - additionalData: UByteArray, + associatedData: UByteArray, tag: UByte ): UByteArray { val ciphertext = UByteArray(message.size + crypto_secretstream_xchacha20poly1305_ABYTES) @@ -26,8 +26,8 @@ actual object SecretStream { null, message.asByteArray(), message.size.toLong(), - additionalData.asByteArray(), - additionalData.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), tag.toByte() ) return ciphertext @@ -45,7 +45,7 @@ actual object SecretStream { actual fun xChaCha20Poly1305Pull( state: SecretStreamState, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): DecryptedDataAndTag { val result = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES) val tagArray = UByteArray(1) { 0U } @@ -56,8 +56,8 @@ actual object SecretStream { tagArray.asByteArray(), ciphertext.asByteArray(), ciphertext.size.toLong(), - additionalData.asByteArray(), - additionalData.size.toLong() + associatedData.asByteArray(), + associatedData.size.toLong() ) if (validationResult != 0) { throw SecretStreamCorrupedOrTamperedDataException() diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 3df6325..b0df283 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -40,14 +40,14 @@ actual object SecretStream { actual fun xChaCha20Poly1305Push( state: SecretStreamState, message: UByteArray, - additionalData: UByteArray, + associatedData: UByteArray, tag: UByte ): UByteArray { val ciphertext = UByteArray(message.size + crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) { 0U } val ciphertextPinned = ciphertext.pin() val messagePinned = message.pin() - val additionalDataPinned = if (additionalData.isNotEmpty()) { - additionalData.pin() + val associatedDataPinned = if (associatedData.isNotEmpty()) { + associatedData.pin() } else { null } @@ -57,14 +57,14 @@ actual object SecretStream { null, messagePinned.toPtr(), message.size.convert(), - additionalDataPinned?.toPtr(), - additionalData.size.convert(), + associatedDataPinned?.toPtr(), + associatedData.size.convert(), tag ) ciphertextPinned.unpin() messagePinned.unpin() - additionalDataPinned?.unpin() + associatedDataPinned?.unpin() return ciphertext } @@ -89,13 +89,13 @@ actual object SecretStream { actual fun xChaCha20Poly1305Pull( state: SecretStreamState, ciphertext: UByteArray, - additionalData: UByteArray + associatedData: UByteArray ): DecryptedDataAndTag { val message = UByteArray(ciphertext.size - crypto_secretstream_xchacha20poly1305_ABYTES.toInt()) val messagePinned = message.pin() val ciphertextPinned = ciphertext.pin() - val additionalDataPinned = if (additionalData.isNotEmpty()) { - additionalData.pin() + val associatedDataPinned = if (associatedData.isNotEmpty()) { + associatedData.pin() } else { null } @@ -108,12 +108,12 @@ actual object SecretStream { tagPinned.toPtr(), ciphertextPinned.toPtr(), ciphertext.size.convert(), - additionalDataPinned?.toPtr(), - additionalData.size.convert() + associatedDataPinned?.toPtr(), + associatedData.size.convert() ) ciphertextPinned.unpin() messagePinned.unpin() - additionalDataPinned?.unpin() + associatedDataPinned?.unpin() tagPinned.unpin() if (validationResult != 0) { throw SecretStreamCorrupedOrTamperedDataException() diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt index 385aaec..d13f8ca 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/Crypto.kt @@ -102,17 +102,17 @@ object Crypto { } object Encryption : EncryptionApi { - override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData { + override fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData { if (key.value.size != 32) { throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}") } val nonce = SRNG.getRandomBytes(24) - return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce) + return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), associatedData), nonce) } - override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { - return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData)) + override fun > decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T { + return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, associatedData)) } @@ -130,8 +130,8 @@ object Crypto { class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey) : MultipartAuthenticatedEncryption { val header = MultipartEncryptionHeader(SRNG.getRandomBytes(24)) val primitive = XChaCha20Poly1305Pure(key.value, header.nonce) - override fun encryptPartialData(data: UByteArray, additionalData: UByteArray): EncryptedDataPart { - return EncryptedDataPart(primitive.streamEncrypt(data, additionalData, 0U)) + override fun encryptPartialData(data: UByteArray, associatedData: UByteArray): EncryptedDataPart { + return EncryptedDataPart(primitive.streamEncrypt(data, associatedData, 0U)) } override fun startEncryption(): MultipartEncryptionHeader { @@ -144,8 +144,8 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe } class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption { - override fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray): DecryptedDataPart { - return DecryptedDataPart(decryptor.streamDecrypt(data.data, additionalData, 0U)) + override fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray): DecryptedDataPart { + return DecryptedDataPart(decryptor.streamDecrypt(data.data, associatedData, 0U)) } override fun cleanup() { diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt index 3c6d6ef..1c35fd9 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Pure.kt @@ -13,7 +13,7 @@ import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray internal class ChaCha20Poly1305Pure { companion object { - fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { + fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray { val state = UIntArray(16) { when (it) { 0 -> ChaCha20Pure.sigma0_32 @@ -37,11 +37,11 @@ internal class ChaCha20Poly1305Pure { } val oneTimeKey = ChaCha20Pure.hash(state).sliceArray(0 until 32) val cipherText = ChaCha20Pure.xorWithKeystream(key, nonce, message, 1U) - val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U } + val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U } val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U } - val macData = additionalData + additionalDataPad + + val macData = associatedData + associatedDataPad + cipherText + cipherTextPad + - additionalData.size.toULong().toLittleEndianUByteArray() + + associatedData.size.toULong().toLittleEndianUByteArray() + cipherText.size.toULong().toLittleEndianUByteArray() val tag = Poly1305.poly1305Authenticate(oneTimeKey, macData) return cipherText + tag diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt index a9340f6..34b8c01 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Pure.kt @@ -15,7 +15,7 @@ import com.ionspin.kotlin.crypto.util.* class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { companion object : AuthenticatedEncryption { - override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray { + override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray { val subKey = XChaCha20Pure.hChacha(key, nonce) val authKey = ChaCha20Pure.xorWithKeystream( @@ -28,17 +28,17 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { // at org.jetbrains.kotlin.ir.backend.js.lower.ConstTransformer.lowerConst(ConstLowering.kt:38) ) val cipherText = XChaCha20Pure.xorWithKeystream(key, nonce, message, 1U) - val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U } + val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U } val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U } - val macData = additionalData + additionalDataPad + + val macData = associatedData + associatedDataPad + cipherText + cipherTextPad + - additionalData.size.toULong().toLittleEndianUByteArray() + + associatedData.size.toULong().toLittleEndianUByteArray() + cipherText.size.toULong().toLittleEndianUByteArray() val tag = Poly1305.poly1305Authenticate(authKey, macData) return cipherText + tag } - override fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray { + override fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, associatedData: UByteArray) : UByteArray { val subKey = XChaCha20Pure.hChacha(key, nonce) val authKey = ChaCha20Pure.xorWithKeystream( @@ -51,11 +51,11 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { val tag = cipherText.sliceArray(cipherText.size - 16 until cipherText.size) //3. Verify tag is valid val cipherTextWithoutTag = cipherText.sliceArray(0 until cipherText.size - 16) - val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U } + val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U } val cipherTextPad = UByteArray(16 - cipherTextWithoutTag.size % 16) { 0U } - val macData = additionalData + additionalDataPad + + val macData = associatedData + associatedDataPad + cipherTextWithoutTag + cipherTextPad + - additionalData.size.toULong().toLittleEndianUByteArray() + + associatedData.size.toULong().toLittleEndianUByteArray() + cipherTextWithoutTag.size.toULong().toLittleEndianUByteArray() val calculatedTag = Poly1305.poly1305Authenticate(authKey, macData) if (!calculatedTag.contentEquals(tag)) { @@ -86,15 +86,15 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { calcNonce[3] = 0U } - fun streamEncrypt(data: UByteArray, additionalData: UByteArray, tag : UByte) : UByteArray { + fun streamEncrypt(data: UByteArray, associatedData: UByteArray, tag : UByte) : UByteArray { //get encryption state val block = UByteArray(64) { 0U } ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 0U).copyInto(block) // This is equivalent to the first 64 bytes of keystream val poly1305 = Poly1305(block) block.overwriteWithZeroes() - if (additionalData.isNotEmpty()) { - val additionalDataPadded = additionalData + UByteArray(16 - additionalData.size % 16) { 0U } - processPolyBytes(poly1305, additionalDataPadded) + if (associatedData.isNotEmpty()) { + val associatedDataPadded = associatedData + UByteArray(16 - associatedData.size % 16) { 0U } + processPolyBytes(poly1305, associatedDataPadded) } block[0] = tag ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block) // This just xors block[0] with keystream @@ -109,21 +109,21 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { // From security standpoint there are no obvious drawbacks, as padding was initially added to decrease implementation complexity. processPolyBytes(poly1305, ciphertext + UByteArray(((16U + data.size.toUInt() - block.size.toUInt()) % 16U).toInt()) { 0U } ) //TODO this is inefficient as it creates a new array and copies data // Last 16byte block containing actual additional data nad ciphertext sizes - val finalMac = additionalData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() + val finalMac = associatedData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() processPolyBytes(poly1305, finalMac) val mac = poly1305.finalizeMac(polyBuffer.sliceArray(0 until polyBufferByteCounter)) calcNonce.xorWithPositionsAndInsertIntoArray(0, 12, mac, 0, calcNonce, 0) return ubyteArrayOf(encryptedTag) + ciphertext + mac } - fun streamDecrypt(data: UByteArray, additionalData: UByteArray, tag: UByte) : UByteArray { + fun streamDecrypt(data: UByteArray, associatedData: UByteArray, tag: UByte) : UByteArray { val block = UByteArray(64) { 0U } ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 0U).copyInto(block) // This is equivalent to the first 64 bytes of keystream val poly1305 = Poly1305(block) block.overwriteWithZeroes() - if (additionalData.isNotEmpty()) { - val additionalDataPadded = additionalData + UByteArray(16 - additionalData.size % 16) { 0U } - processPolyBytes(poly1305, additionalDataPadded) + if (associatedData.isNotEmpty()) { + val associatedDataPadded = associatedData + UByteArray(16 - associatedData.size % 16) { 0U } + processPolyBytes(poly1305, associatedDataPadded) } block[0] = data[0] ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block)// get the keystream xored with zeroes, but also decrypteg tag marker @@ -137,7 +137,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) { val ciphertext = data.sliceArray(1 until data.size - 16) processPolyBytes(poly1305, ciphertext + UByteArray(((16U + ciphertext.size.toUInt() - block.size.toUInt()) % 16U).toInt()) { 0U } ) val plaintext = ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, ciphertext, 2U) - val finalMac = additionalData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() + val finalMac = associatedData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray() processPolyBytes(poly1305, finalMac) val mac = poly1305.finalizeMac(polyBuffer.sliceArray(0 until polyBufferByteCounter)) val expectedMac = data.sliceArray(data.size - 16 until data.size) diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt index 26975f4..ca0a763 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/ChaCha20Poly1305Test.kt @@ -19,7 +19,7 @@ class ChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -44,7 +44,7 @@ class ChaCha20Poly1305Test { 0x61U, 0x16U, 0x1aU, 0xe1U, 0x0bU, 0x59U, 0x4fU, 0x09U, 0xe2U, 0x6aU, 0x7eU, 0x90U, 0x2eU, 0xcbU, 0xd0U, 0x60U, 0x06U, 0x91U ) - val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) + val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData) result.hexColumsPrint() assertTrue { result.contentEquals(expected) @@ -53,4 +53,4 @@ class ChaCha20Poly1305Test { } -} \ No newline at end of file +} diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt index 8445606..c186102 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/authenticated/XChaCha20Poly1305Test.kt @@ -20,7 +20,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -55,8 +55,8 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) - val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) - val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, additionalData) + val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData) + val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, associatedData) encrypted.contentEquals(expected) && decrypted.contentEquals(message) } @@ -65,7 +65,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -84,8 +84,8 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) - val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData) - val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, additionalData) + val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData) + val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, associatedData) encrypted.contentEquals(expected) && decrypted.contentEquals(message) } @@ -99,7 +99,7 @@ class XChaCha20Poly1305Test { val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U ) val key = ubyteArrayOf( @@ -134,7 +134,7 @@ class XChaCha20Poly1305Test { 0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU, 0xcfU, 0x49U ) -// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData) val firstChunk = +// val xChaChaPoly = XChaCha20Poly1305Pure(key, associatedData) val firstChunk = // xChaChaPoly.encryptPartialData(message) val finalChunk = xChaChaPoly.finishEncryption().first val result = // firstChunk + finalChunk result.contentEquals(expected) 1 == 1 @@ -144,7 +144,7 @@ class XChaCha20Poly1305Test { val message = ubyteArrayOf( 0x00U ) - val additionalData = ubyteArrayOf( + val associatedData = ubyteArrayOf( 0x00U ) val key = ubyteArrayOf( @@ -163,7 +163,7 @@ class XChaCha20Poly1305Test { 0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U, 0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU ) -// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData) +// val xChaChaPoly = XChaCha20Poly1305Pure(key, associatedData) // val firstChunk = xChaChaPoly.encryptPartialData(message) // val finalChunk = xChaChaPoly.finishEncryption().first // val result = firstChunk + finalChunk diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt index a163517..d8f05da 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/highlevel/EncryptionTest.kt @@ -20,18 +20,18 @@ class EncryptionTest { "ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" + "EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray() plaintext.hexColumsPrint() - val additionalData = "Additional data 1".encodeToUByteArray() -// val additionalData = ubyteArrayOf() + val associatedData = "Additional data 1".encodeToUByteArray() +// val associatedData = ubyteArrayOf() val keyValue = UByteArray(32) { it.toUByte() } val key = SymmetricKey(keyValue) val encryptor = Crypto.Encryption.createMultipartEncryptor(key) val header = encryptor.startEncryption() - val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), additionalData) + val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), associatedData) val ciphertext2 = encryptor.encryptPartialData(plaintext.sliceArray(100 until 200)) val ciphertext3 = encryptor.encryptPartialData(plaintext.sliceArray(200 until 250)) //decrypt val decryptor = Crypto.Encryption.createMultipartDecryptor(key, header) - val plaintext1 = decryptor.decryptPartialData(ciphertext1, additionalData) + val plaintext1 = decryptor.decryptPartialData(ciphertext1, associatedData) val plaintext2 = decryptor.decryptPartialData(ciphertext2) val plaintext3 = decryptor.decryptPartialData(ciphertext3) From 1a11bdc81b6f3d44035aaec6a1779bbad8f3382d Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 12:07:53 +0200 Subject: [PATCH 27/65] Added native aead chacha poly implementation --- ...thenticatedEncryptionWithAssociatedData.kt | 2 + ...thenticatedEncryptionWithAssociatedData.kt | 315 +++++++++++++++++- 2 files changed, 308 insertions(+), 9 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt index 2108c23..1064f29 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -25,6 +25,8 @@ val crypto_aead_chacha20poly1305_ABYTES = 16 data class AeadEncryptedDataAndTag(val data: UByteArray, val tag: UByteArray) +class AeadCorrupedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + expect object AuthenticatedEncryptionWithAssociatedData { // X - Ietf fun xChaCha20Poly1305IetfEncrypt( diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt index eab798d..a645905 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -3,9 +3,18 @@ package com.ionspin.kotlin.crypto.aead import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.convert import kotlinx.cinterop.pin +import libsodium.crypto_aead_chacha20poly1305_decrypt +import libsodium.crypto_aead_chacha20poly1305_decrypt_detached import libsodium.crypto_aead_chacha20poly1305_encrypt +import libsodium.crypto_aead_chacha20poly1305_encrypt_detached +import libsodium.crypto_aead_chacha20poly1305_ietf_decrypt +import libsodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached import libsodium.crypto_aead_chacha20poly1305_ietf_encrypt +import libsodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached +import libsodium.crypto_aead_xchacha20poly1305_ietf_decrypt +import libsodium.crypto_aead_xchacha20poly1305_ietf_decrypt_detached import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt +import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt_detached actual object AuthenticatedEncryptionWithAssociatedData { @@ -55,7 +64,38 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertextPinned = ciphertext.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_xchacha20poly1305_ietf_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_xchacha20poly1305_ietf_decrypt( + messagePinned.toPtr(), + null, + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message } actual fun xChaCha20Poly1305IetfEncryptDetached( @@ -64,7 +104,39 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size) + val ciphertextPinned = ciphertext.pin() + + val authenticationTag = UByteArray(crypto_aead_xchacha20poly1305_ietf_ABYTES) + val authenticationTagPinned = authenticationTag.pin() + + crypto_aead_xchacha20poly1305_ietf_encrypt_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) } actual fun xChaCha20Poly1305IetfDecryptDetached( @@ -74,7 +146,40 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_xchacha20poly1305_ietf_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_xchacha20poly1305_ietf_decrypt_detached( + messagePinned.toPtr(), + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + tagPinned.toPtr(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + tagPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message } actual fun chaCha20Poly1305IetfEncrypt( @@ -120,7 +225,38 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertextPinned = ciphertext.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ietf_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_ietf_decrypt( + messagePinned.toPtr(), + null, + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message } actual fun chaCha20Poly1305IetfEncryptDetached( @@ -129,7 +265,39 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size) + val ciphertextPinned = ciphertext.pin() + + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ietf_ABYTES) + val authenticationTagPinned = authenticationTag.pin() + + crypto_aead_chacha20poly1305_ietf_encrypt_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) } actual fun chaCha20Poly1305IetfDecryptDetached( @@ -139,7 +307,40 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ietf_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_ietf_decrypt_detached( + messagePinned.toPtr(), + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + tagPinned.toPtr(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + tagPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message } actual fun chaCha20Poly1305Encrypt( @@ -185,7 +386,38 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertextPinned = ciphertext.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_decrypt( + messagePinned.toPtr(), + null, + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message } actual fun chaCha20Poly1305EncryptDetached( @@ -194,7 +426,39 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val messagePinned = message.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val ciphertext = UByteArray(message.size) + val ciphertextPinned = ciphertext.pin() + + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ABYTES) + val authenticationTagPinned = authenticationTag.pin() + + crypto_aead_chacha20poly1305_encrypt_detached( + ciphertextPinned.toPtr(), + authenticationTagPinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + null, // nsec not used in this construct + noncePinned.toPtr(), + keyPinned.toPtr() + + ) + + ciphertextPinned.unpin() + + messagePinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) } actual fun chaCha20Poly1305DecryptDetached( @@ -204,7 +468,40 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + val associatedDataPinned = associatedData.pin() + val noncePinned = nonce.pin() + val keyPinned = key.pin() + + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ABYTES) + val messagePinned = message.pin() + + val validationResult = crypto_aead_chacha20poly1305_decrypt_detached( + messagePinned.toPtr(), + null, + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + tagPinned.toPtr(), + associatedDataPinned.toPtr(), + associatedData.size.convert(), + noncePinned.toPtr(), + keyPinned.toPtr() + ) + + messagePinned.unpin() + + ciphertextPinned.unpin() + tagPinned.unpin() + associatedDataPinned.unpin() + noncePinned.unpin() + keyPinned.unpin() + + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + + return message } } From 3f9f316e041cbe9f81462915ba8531d3b02a8716 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 12:24:43 +0200 Subject: [PATCH 28/65] Fixed (the usual) copypaste error of removing ABYTES in detached implementation, added aead chacha tests --- ...ticatedEncryptionWithAssociatedDataTest.kt | 320 ++++++++++++++++++ .../kotlin/crypto/secretbox/SecretBoxTest.kt | 1 - ...thenticatedEncryptionWithAssociatedData.kt | 6 +- 3 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedDataTest.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedDataTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedDataTest.kt new file mode 100644 index 0000000..c6de2bf --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedDataTest.kt @@ -0,0 +1,320 @@ +package com.ionspin.kotlin.crypto.aead + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ +class AuthenticatedEncryptionWithAssociatedDataTest { + @Test + fun testXChaCha20Poly1305Ieft() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfEncrypt( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecrypt( + encrypted, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecrypt( + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testXChaCha20Poly1305IeftDetached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, + 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfEncryptDetached( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecryptDetached( + encrypted.data, + encrypted.tag, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.xChaCha20Poly1305IetfDecryptDetached( + encrypted.data, + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305Ieft() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfEncrypt( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecrypt( + encrypted, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecrypt( + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305IeftDetached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, + 0x48U, 0x49U, 0x4aU, 0x4bU + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfEncryptDetached( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecryptDetached( + encrypted.data, + encrypted.tag, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305IetfDecryptDetached( + encrypted.data, + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305Encrypt( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305Decrypt( + encrypted, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305Decrypt( + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } + + @Test + fun testChaCha20Poly1305Detached() { + LibsodiumInitializer.initializeWithCallback { + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val associatedData = ubyteArrayOf( + 0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U + ) + val key = ubyteArrayOf( + 0x80U, 0x81U, 0x82U, 0x83U, 0x84U, 0x85U, 0x86U, 0x87U, + 0x88U, 0x89U, 0x8aU, 0x8bU, 0x8cU, 0x8dU, 0x8eU, 0x8fU, + 0x90U, 0x91U, 0x92U, 0x93U, 0x94U, 0x95U, 0x96U, 0x97U, + 0x98U, 0x99U, 0x9aU, 0x9bU, 0x9cU, 0x9dU, 0x9eU, 0x9fU, + ) + + val nonce = ubyteArrayOf( + 0x40U, 0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U + ) + + val encrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305EncryptDetached( + message, + associatedData, + nonce, + key + ) + val decrypted = AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305DecryptDetached( + encrypted.data, + encrypted.tag, + associatedData, + nonce, + key + ) + assertTrue { + message.contentEquals(decrypted) + } + + assertFailsWith(AeadCorrupedOrTamperedDataException::class) { + val tamperedTag = encrypted.tag.copyOf() + tamperedTag[3] = 0U + AuthenticatedEncryptionWithAssociatedData.chaCha20Poly1305DecryptDetached( + encrypted.data, + tamperedTag, + associatedData, + nonce, + key + ) + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt index dd3a108..caf19a5 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBoxTest.kt @@ -67,7 +67,6 @@ class SecretBoxTest { 0x50U, 0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, ) - println("Debug") val encrypted = SecretBox.detached(message, nonce, key) val decrypted = SecretBox.openDetached(encrypted.data, encrypted.tag, nonce, key) assertTrue { decrypted.contentEquals(message) } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt index a645905..71c127c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -152,7 +152,7 @@ actual object AuthenticatedEncryptionWithAssociatedData { val noncePinned = nonce.pin() val keyPinned = key.pin() - val message = UByteArray(ciphertext.size - crypto_aead_xchacha20poly1305_ietf_ABYTES) + val message = UByteArray(ciphertext.size) val messagePinned = message.pin() val validationResult = crypto_aead_xchacha20poly1305_ietf_decrypt_detached( @@ -313,7 +313,7 @@ actual object AuthenticatedEncryptionWithAssociatedData { val noncePinned = nonce.pin() val keyPinned = key.pin() - val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ietf_ABYTES) + val message = UByteArray(ciphertext.size) val messagePinned = message.pin() val validationResult = crypto_aead_chacha20poly1305_ietf_decrypt_detached( @@ -474,7 +474,7 @@ actual object AuthenticatedEncryptionWithAssociatedData { val noncePinned = nonce.pin() val keyPinned = key.pin() - val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ABYTES) + val message = UByteArray(ciphertext.size) val messagePinned = message.pin() val validationResult = crypto_aead_chacha20poly1305_decrypt_detached( From dd0895b5f39317e380ba5eeeaf83da9362511e84 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 13:10:31 +0200 Subject: [PATCH 29/65] Completed cha cha aead variants --- ...thenticatedEncryptionWithAssociatedData.kt | 5 + .../kotlin/crypto/JsSodiumInterface.kt | 26 ++- ...thenticatedEncryptionWithAssociatedData.kt | 152 ++++++++++++- ...thenticatedEncryptionWithAssociatedData.kt | 212 +++++++++++++++++- ...thenticatedEncryptionWithAssociatedData.kt | 27 +++ 5 files changed, 395 insertions(+), 27 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt index 1064f29..6388806 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -120,4 +120,9 @@ expect object AuthenticatedEncryptionWithAssociatedData { key: UByteArray ): UByteArray + + fun xChaCha20Poly1305IetfKeygen() : UByteArray + fun chaCha20Poly1305IetfKeygen() : UByteArray + fun chaCha20Poly1305Keygen() : UByteArray + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index c821572..e214503 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -44,9 +44,9 @@ interface JsSodiumInterface { fun crypto_hash_sha512_final(state: dynamic): Uint8Array - //XChaCha20Poly1305 - fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array - fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + //XChaCha20Poly1305 - also in bindings + //fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, secretNonce: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array + //fun crypto_aead_xchacha20poly1305_ietf_decrypt(secretNonce: Uint8Array, ciphertext: Uint8Array, associatedData: Uint8Array, nonce: Uint8Array, key: Uint8Array) : Uint8Array //XChaCha20Poly1305 //encrypt @@ -71,6 +71,26 @@ interface JsSodiumInterface { // ---- SecretBox End ---- + + // ---- AEAD ---- + fun crypto_aead_chacha20poly1305_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array + fun crypto_aead_chacha20poly1305_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic + fun crypto_aead_chacha20poly1305_ietf_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_ietf_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array + fun crypto_aead_chacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_chacha20poly1305_ietf_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic + fun crypto_aead_chacha20poly1305_ietf_keygen() : Uint8Array + fun crypto_aead_chacha20poly1305_keygen() : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_decrypt(nsec : Uint8Array?, ciphertext: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_decrypt_detached(nsec: Uint8Array?, ciphertext: Uint8Array, mac: Uint8Array, associatedData: Uint8Array, npub: Uint8Array, key: Uint8Array): Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_encrypt(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_aead_xchacha20poly1305_ietf_encrypt_detached(message: Uint8Array, associatedData: Uint8Array, nsec: Uint8Array?, npub: Uint8Array, key: Uint8Array) : dynamic + fun crypto_aead_xchacha20poly1305_ietf_keygen(): Uint8Array + + // ---- AEAD end ---- + //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt index 332f9a4..846ccb7 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -1,5 +1,10 @@ package com.ionspin.kotlin.crypto.aead +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + actual object AuthenticatedEncryptionWithAssociatedData { // Ietf @@ -11,7 +16,13 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ).toUByteArray() } actual fun xChaCha20Poly1305IetfDecrypt( @@ -20,7 +31,17 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + try { + return getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt( + null, + ciphertext.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } } actual fun xChaCha20Poly1305IetfEncryptDetached( @@ -29,7 +50,17 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val result = getSodium().crypto_aead_xchacha20poly1305_ietf_encrypt_detached( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ) + return AeadEncryptedDataAndTag( + (result.ciphertext as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) } actual fun xChaCha20Poly1305IetfDecryptDetached( @@ -39,7 +70,18 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + try { + return getSodium().crypto_aead_xchacha20poly1305_ietf_decrypt_detached( + null, + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } } actual fun chaCha20Poly1305IetfEncrypt( @@ -48,7 +90,13 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_aead_chacha20poly1305_ietf_encrypt( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ).toUByteArray() } actual fun chaCha20Poly1305IetfDecrypt( @@ -57,7 +105,17 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + try { + return getSodium().crypto_aead_chacha20poly1305_ietf_decrypt( + null, + ciphertext.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } } actual fun chaCha20Poly1305IetfEncryptDetached( @@ -66,7 +124,17 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val result = getSodium().crypto_aead_chacha20poly1305_ietf_encrypt_detached( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ) + return AeadEncryptedDataAndTag( + (result.ciphertext as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) } actual fun chaCha20Poly1305IetfDecryptDetached( @@ -76,7 +144,18 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + try { + return getSodium().crypto_aead_chacha20poly1305_ietf_decrypt_detached( + null, + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } } actual fun chaCha20Poly1305Encrypt( @@ -85,7 +164,13 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_aead_chacha20poly1305_encrypt( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ).toUByteArray() } actual fun chaCha20Poly1305Decrypt( @@ -94,7 +179,17 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + try { + return getSodium().crypto_aead_chacha20poly1305_decrypt( + null, + ciphertext.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } } actual fun chaCha20Poly1305EncryptDetached( @@ -103,7 +198,17 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val result = getSodium().crypto_aead_chacha20poly1305_encrypt_detached( + message.toUInt8Array(), + associatedData.toUInt8Array(), + null, + nonce.toUInt8Array(), + key.toUInt8Array(), + ) + return AeadEncryptedDataAndTag( + (result.ciphertext as Uint8Array).toUByteArray(), + (result.mac as Uint8Array).toUByteArray() + ) } actual fun chaCha20Poly1305DecryptDetached( @@ -113,7 +218,30 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + try { + return getSodium().crypto_aead_chacha20poly1305_decrypt_detached( + null, + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + associatedData.toUInt8Array(), + nonce.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } catch (error: Throwable) { + throw AeadCorrupedOrTamperedDataException() + } + } + + actual fun xChaCha20Poly1305IetfKeygen(): UByteArray { + return getSodium().crypto_aead_xchacha20poly1305_ietf_keygen().toUByteArray() + } + + actual fun chaCha20Poly1305IetfKeygen(): UByteArray { + return getSodium().crypto_aead_chacha20poly1305_ietf_keygen().toUByteArray() + } + + actual fun chaCha20Poly1305Keygen(): UByteArray { + return getSodium().crypto_aead_chacha20poly1305_keygen().toUByteArray() } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt index 332f9a4..8fa92fd 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -1,5 +1,7 @@ package com.ionspin.kotlin.crypto.aead +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + actual object AuthenticatedEncryptionWithAssociatedData { // Ietf @@ -11,7 +13,19 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size + crypto_aead_xchacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_xchacha20poly1305_ietf_encrypt( + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return ciphertext } actual fun xChaCha20Poly1305IetfDecrypt( @@ -20,7 +34,22 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val message = UByteArray(ciphertext.size - crypto_aead_xchacha20poly1305_ietf_ABYTES) + val validationResult = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt( + message.asByteArray(), + null, + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message } actual fun xChaCha20Poly1305IetfEncryptDetached( @@ -29,7 +58,21 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_aead_xchacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_xchacha20poly1305_ietf_encrypt_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) } actual fun xChaCha20Poly1305IetfDecryptDetached( @@ -39,7 +82,22 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt_detached( + message.asByteArray(), + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + tag.asByteArray(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message } actual fun chaCha20Poly1305IetfEncrypt( @@ -48,7 +106,19 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_chacha20poly1305_ietf_encrypt( + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return ciphertext } actual fun chaCha20Poly1305IetfDecrypt( @@ -57,7 +127,22 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ietf_ABYTES) + val validationResult = sodium.crypto_aead_chacha20poly1305_ietf_decrypt( + message.asByteArray(), + null, + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message } actual fun chaCha20Poly1305IetfEncryptDetached( @@ -66,7 +151,21 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ietf_ABYTES) + sodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) } actual fun chaCha20Poly1305IetfDecryptDetached( @@ -76,7 +175,22 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached( + message.asByteArray(), + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + tag.asByteArray(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message } actual fun chaCha20Poly1305Encrypt( @@ -85,7 +199,19 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size + crypto_aead_chacha20poly1305_ABYTES) + sodium.crypto_aead_chacha20poly1305_encrypt( + ciphertext.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return ciphertext } actual fun chaCha20Poly1305Decrypt( @@ -94,7 +220,22 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val message = UByteArray(ciphertext.size - crypto_aead_chacha20poly1305_ABYTES) + val validationResult = sodium.crypto_aead_chacha20poly1305_decrypt( + message.asByteArray(), + null, + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message } actual fun chaCha20Poly1305EncryptDetached( @@ -103,7 +244,21 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): AeadEncryptedDataAndTag { - TODO("not implemented yet") + val ciphertext = UByteArray(message.size) + val authenticationTag = UByteArray(crypto_aead_chacha20poly1305_ABYTES) + sodium.crypto_aead_chacha20poly1305_encrypt_detached( + ciphertext.asByteArray(), + authenticationTag.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + associatedData.asByteArray(), + associatedData.size.toLong(), + null, + nonce.asByteArray(), + key.asByteArray(), + ) + return AeadEncryptedDataAndTag(ciphertext, authenticationTag) } actual fun chaCha20Poly1305DecryptDetached( @@ -113,7 +268,40 @@ actual object AuthenticatedEncryptionWithAssociatedData { nonce: UByteArray, key: UByteArray ): UByteArray { - TODO("not implemented yet") + val message = UByteArray(ciphertext.size) + val validationResult = sodium.crypto_aead_chacha20poly1305_decrypt_detached( + message.asByteArray(), + null, + ciphertext.asByteArray(), + ciphertext.size.toLong(), + tag.asByteArray(), + associatedData.asByteArray(), + associatedData.size.toLong(), + nonce.asByteArray(), + key.asByteArray(), + ) + if (validationResult != 0) { + throw AeadCorrupedOrTamperedDataException() + } + return message + } + + actual fun xChaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_xchacha20poly1305_ietf_KEYBYTES) + sodium.crypto_aead_xchacha20poly1305_ietf_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun chaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_ietf_KEYBYTES) + sodium.crypto_aead_chacha20poly1305_ietf_keygen(generatedKey.asByteArray()) + return generatedKey + } + + actual fun chaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_KEYBYTES) + sodium.crypto_aead_chacha20poly1305_keygen(generatedKey.asByteArray()) + return generatedKey } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt index 71c127c..6d0531d 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/aead/AuthenticatedEncryptionWithAssociatedData.kt @@ -11,10 +11,13 @@ import libsodium.crypto_aead_chacha20poly1305_ietf_decrypt import libsodium.crypto_aead_chacha20poly1305_ietf_decrypt_detached import libsodium.crypto_aead_chacha20poly1305_ietf_encrypt import libsodium.crypto_aead_chacha20poly1305_ietf_encrypt_detached +import libsodium.crypto_aead_chacha20poly1305_ietf_keygen +import libsodium.crypto_aead_chacha20poly1305_keygen import libsodium.crypto_aead_xchacha20poly1305_ietf_decrypt import libsodium.crypto_aead_xchacha20poly1305_ietf_decrypt_detached import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt import libsodium.crypto_aead_xchacha20poly1305_ietf_encrypt_detached +import libsodium.crypto_aead_xchacha20poly1305_ietf_keygen actual object AuthenticatedEncryptionWithAssociatedData { @@ -504,4 +507,28 @@ actual object AuthenticatedEncryptionWithAssociatedData { return message } + actual fun xChaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_xchacha20poly1305_ietf_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_aead_xchacha20poly1305_ietf_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun chaCha20Poly1305IetfKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_ietf_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_aead_chacha20poly1305_ietf_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun chaCha20Poly1305Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_aead_chacha20poly1305_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_aead_chacha20poly1305_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + } From 6768832332ad73bb27011cd73d8458d1a205cc44 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 13:13:03 +0200 Subject: [PATCH 30/65] Update cheklist --- supported_bindings_list.md | 48 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/supported_bindings_list.md b/supported_bindings_list.md index f46df98..6117093 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -12,21 +12,21 @@ | to_base64 | | | to_hex | | | to_string | | -| crypto_aead_chacha20poly1305_decrypt | | -| crypto_aead_chacha20poly1305_decrypt_detached | | -| crypto_aead_chacha20poly1305_encrypt | | -| crypto_aead_chacha20poly1305_encrypt_detached | | -| crypto_aead_chacha20poly1305_ietf_decrypt | | -| crypto_aead_chacha20poly1305_ietf_decrypt_detached | | -| crypto_aead_chacha20poly1305_ietf_encrypt | | -| crypto_aead_chacha20poly1305_ietf_encrypt_detached | | -| crypto_aead_chacha20poly1305_ietf_keygen | | -| crypto_aead_chacha20poly1305_keygen | | -| crypto_aead_xchacha20poly1305_ietf_decrypt | | -| crypto_aead_xchacha20poly1305_ietf_decrypt_detached | | -| crypto_aead_xchacha20poly1305_ietf_encrypt | | -| crypto_aead_xchacha20poly1305_ietf_encrypt_detached | | -| crypto_aead_xchacha20poly1305_ietf_keygen | | +| crypto_aead_chacha20poly1305_decrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_decrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_encrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_encrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_decrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_decrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_encrypt | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_encrypt_detached | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_keygen | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_keygen | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_decrypt | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_decrypt_detached | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_encrypt | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_encrypt_detached | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_keygen | :heavy_check_mark: | | crypto_auth | | | crypto_auth_hmacsha256 | | | crypto_auth_hmacsha256_keygen | | @@ -150,29 +150,29 @@ | SODIUM_LIBRARY_VERSION_MAJOR | | | SODIUM_LIBRARY_VERSION_MINOR | | | crypto_aead_chacha20poly1305_ABYTES | | -| crypto_aead_chacha20poly1305_IETF_ABYTES | | -| crypto_aead_chacha20poly1305_IETF_KEYBYTES | | +| crypto_aead_chacha20poly1305_IETF_ABYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_IETF_KEYBYTES | :heavy_check_mark: | | crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX | | -| crypto_aead_chacha20poly1305_IETF_NPUBBYTES | | +| crypto_aead_chacha20poly1305_IETF_NPUBBYTES | :heavy_check_mark: | | crypto_aead_chacha20poly1305_IETF_NSECBYTES | | | crypto_aead_chacha20poly1305_KEYBYTES | | | crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX | | | crypto_aead_chacha20poly1305_NPUBBYTES | | | crypto_aead_chacha20poly1305_NSECBYTES | | -| crypto_aead_chacha20poly1305_ietf_ABYTES | | -| crypto_aead_chacha20poly1305_ietf_KEYBYTES | | +| crypto_aead_chacha20poly1305_ietf_ABYTES | :heavy_check_mark: | +| crypto_aead_chacha20poly1305_ietf_KEYBYTES | :heavy_check_mark: | | crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX | | -| crypto_aead_chacha20poly1305_ietf_NPUBBYTES | | +| crypto_aead_chacha20poly1305_ietf_NPUBBYTES | :heavy_check_mark: | | crypto_aead_chacha20poly1305_ietf_NSECBYTES | | | crypto_aead_xchacha20poly1305_IETF_ABYTES | | | crypto_aead_xchacha20poly1305_IETF_KEYBYTES | | | crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX | | | crypto_aead_xchacha20poly1305_IETF_NPUBBYTES | | | crypto_aead_xchacha20poly1305_IETF_NSECBYTES | | -| crypto_aead_xchacha20poly1305_ietf_ABYTES | | -| crypto_aead_xchacha20poly1305_ietf_KEYBYTES | | +| crypto_aead_xchacha20poly1305_ietf_ABYTES | :heavy_check_mark: | +| crypto_aead_xchacha20poly1305_ietf_KEYBYTES | :heavy_check_mark: | | crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX | | -| crypto_aead_xchacha20poly1305_ietf_NPUBBYTES | | +| crypto_aead_xchacha20poly1305_ietf_NPUBBYTES | :heavy_check_mark: | | crypto_aead_xchacha20poly1305_ietf_NSECBYTES | | | crypto_auth_BYTES | | | crypto_auth_KEYBYTES | | From 4cf1d482255b0e27580f60d73aeff41a8ee1fcb1 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 13:15:41 +0200 Subject: [PATCH 31/65] Add generic hash to checklist --- supported_bindings_list.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 6117093..b53e853 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -63,12 +63,12 @@ | crypto_core_ristretto255_scalar_reduce | | | crypto_core_ristretto255_scalar_sub | | | crypto_core_ristretto255_sub | | -| crypto_generichash | | DONE +| crypto_generichash | :heavy_check_mark: | | crypto_generichash_blake2b_salt_personal | | -| crypto_generichash_final | | DONE -| crypto_generichash_init | | DONE +| crypto_generichash_final | :heavy_check_mark: | +| crypto_generichash_init | :heavy_check_mark: | | crypto_generichash_keygen | | -| crypto_generichash_update | | DONE +| crypto_generichash_update | :heavy_check_mark: | | crypto_hash | | | crypto_hash_sha256 | | | crypto_hash_sha256_final | | From 0c8de7b5c56a11c98eb08bcc0599e5892ed204ed Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 17:56:12 +0200 Subject: [PATCH 32/65] Adding crypto_auth --- .../com.ionspin.kotlin.crypto/auth/Auth.kt | 32 ++++ .../com/ionspin/kotlin/crypto/auth/Auth.kt | 48 +++++ .../com/ionspin/kotlin/crypto/auth/Auth.kt | 48 +++++ .../com/ionspin/kotlin/crypto/auth/Auth.kt | 166 ++++++++++++++++++ 4 files changed, 294 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt new file mode 100644 index 0000000..51fd66e --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt @@ -0,0 +1,32 @@ +package com.ionspin.kotlin.crypto.auth + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ + +val crypto_auth_BYTES = 32 +val crypto_auth_KEYBYTES = 32 + +val crypto_auth_hmacsha256_KEYBYTES = 32 +val crypto_auth_hmacsha256_BYTES =32 + +val crypto_auth_hmacsha512_KEYBYTES = 32 +val crypto_auth_hmacsha512_BYTES = 64 + +expect object Auth { + + fun authKeygen() : UByteArray + fun auth(message: UByteArray, key: UByteArray) : UByteArray + fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean + + fun authHmacSha256Keygen() : UByteArray + fun authHmacSha256(message: UByteArray, key: UByteArray) : UByteArray + fun authHmacSha256Verify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean + + fun authHmacSha512Keygen() : UByteArray + fun authHmacSha512(message: UByteArray, key: UByteArray) : UByteArray + fun authHmacSha512Verify(mac: UByteArray, message: UByteArray, key: UByteArray) : Boolean + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt new file mode 100644 index 0000000..7ad35a1 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -0,0 +1,48 @@ +package com.ionspin.kotlin.crypto.auth + +actual object Auth { + actual fun authKeygen(): UByteArray { + TODO("not implemented yet") + } + + actual fun auth(message: UByteArray, key: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { + TODO("not implemented yet") + } + + actual fun authHmacSha256Keygen(): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha256Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + TODO("not implemented yet") + } + + actual fun authHmacSha512Keygen(): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha512Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + TODO("not implemented yet") + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt new file mode 100644 index 0000000..7ad35a1 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -0,0 +1,48 @@ +package com.ionspin.kotlin.crypto.auth + +actual object Auth { + actual fun authKeygen(): UByteArray { + TODO("not implemented yet") + } + + actual fun auth(message: UByteArray, key: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { + TODO("not implemented yet") + } + + actual fun authHmacSha256Keygen(): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha256Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + TODO("not implemented yet") + } + + actual fun authHmacSha512Keygen(): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun authHmacSha512Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + TODO("not implemented yet") + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt new file mode 100644 index 0000000..5cf01dd --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -0,0 +1,166 @@ +package com.ionspin.kotlin.crypto.auth + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_auth +import libsodium.crypto_auth_hmacsha256 +import libsodium.crypto_auth_hmacsha256_keygen +import libsodium.crypto_auth_hmacsha256_verify +import libsodium.crypto_auth_hmacsha512 +import libsodium.crypto_auth_hmacsha512_keygen +import libsodium.crypto_auth_hmacsha512_verify +import libsodium.crypto_auth_keygen +import libsodium.crypto_auth_verify + +actual object Auth { + actual fun authKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_auth_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun auth(message: UByteArray, key: UByteArray): UByteArray { + val messagePinned = message.pin() + val keyPinned = key.pin() + + val mac = UByteArray(crypto_auth_BYTES) + val macPinned = mac.pin() + + crypto_auth( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr() + ) + + macPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + + return mac + } + + actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { + val macPinned = mac.pin() + val messagePinned = message.pin() + val keyPinned = key.pin() + + val verify = crypto_auth_verify( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr(), + ) + + keyPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + return verify == 0 + } + + actual fun authHmacSha256Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_hmacsha256_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_auth_hmacsha256_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { + val messagePinned = message.pin() + val keyPinned = key.pin() + + val mac = UByteArray(crypto_auth_hmacsha256_BYTES) + val macPinned = mac.pin() + + crypto_auth_hmacsha256( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr() + ) + + macPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + + return mac + } + + actual fun authHmacSha256Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + val macPinned = mac.pin() + val messagePinned = message.pin() + val keyPinned = key.pin() + + val verify = crypto_auth_hmacsha256_verify( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr(), + ) + + keyPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + return verify == 0 + } + + actual fun authHmacSha512Keygen(): UByteArray { + val generatedKey = UByteArray(crypto_auth_hmacsha512_KEYBYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_auth_hmacsha512_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + + actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { + val messagePinned = message.pin() + val keyPinned = key.pin() + + val mac = UByteArray(crypto_auth_hmacsha512_BYTES) + val macPinned = mac.pin() + + crypto_auth_hmacsha512( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr() + ) + + macPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + + return mac + } + + actual fun authHmacSha512Verify( + mac: UByteArray, + message: UByteArray, + key: UByteArray + ): Boolean { + val macPinned = mac.pin() + val messagePinned = message.pin() + val keyPinned = key.pin() + + val verify = crypto_auth_hmacsha512_verify( + macPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + keyPinned.toPtr(), + ) + + keyPinned.unpin() + messagePinned.unpin() + keyPinned.unpin() + return verify == 0 + } + +} From d2fda34807667a16b4a23f8fad23be54b6c15833 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 18:33:14 +0200 Subject: [PATCH 33/65] Add auth native and tests --- .../com.ionspin.kotlin.crypto/auth/Auth.kt | 3 + .../ionspin/kotlin/crypto/auth/AuthTest.kt | 95 +++++++++++++++++++ .../com/ionspin/kotlin/crypto/auth/Auth.kt | 7 +- 3 files changed, 101 insertions(+), 4 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt index 51fd66e..f11cbc4 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt @@ -9,6 +9,9 @@ package com.ionspin.kotlin.crypto.auth val crypto_auth_BYTES = 32 val crypto_auth_KEYBYTES = 32 +val crypto_auth_hmacsha512256_BYTES = 32 +val crypto_auth_hmacsha512256_KEYBYTES = 32 + val crypto_auth_hmacsha256_KEYBYTES = 32 val crypto_auth_hmacsha256_BYTES =32 diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt new file mode 100644 index 0000000..a3cd065 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt @@ -0,0 +1,95 @@ +package com.ionspin.kotlin.crypto.auth + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 30-Aug-2020 + */ +class AuthTest { + @Test + fun testAuth() { + LibsodiumInitializer.initializeWithCallback { + val message = ("I wonder if it would be possible" + + " to get some lyrics in these tests").encodeToUByteArray() + + val key = "We'll see1We'll see1We'll see123".encodeToUByteArray() + println("Key size ${key.size}") + + val expected = "702beb4494a1d80795512668df016807ec052dc848a4c958eb1544ec1c8d6314".hexStringToUByteArray() + + val hashed = Auth.auth(message, key) + println(hashed.toHexString()) + assertTrue { + hashed.contentEquals(expected) + } + assertTrue { Auth.authVerify(hashed, message, key) } + + assertFalse { + val tampered = hashed.copyOf() + tampered[5] = 0U + Auth.authVerify(tampered, message, key) + } + } + + } + + @Test + fun testAuthHmacSha256() { + LibsodiumInitializer.initializeWithCallback { + val message = ("I wonder if it would be possible" + + " to get some lyrics in these tests").encodeToUByteArray() + + val key = "We'll see1We'll see1We'll see123".encodeToUByteArray() + + val expected = "b1b3cf73089e04106a135629ba586b6c94b81b87162302f3f32b4fb797f82e8a".hexStringToUByteArray() + + val hashed = Auth.authHmacSha256(message, key) + println(hashed.toHexString()) + assertTrue { + hashed.contentEquals(expected) + } + assertTrue { Auth.authHmacSha256Verify(hashed, message, key) } + + assertFalse { + val tampered = hashed.copyOf() + tampered[5] = 0U + Auth.authHmacSha256Verify(tampered, message, key) + } + } + } + + @Test + fun testAuthHmacSha512() { + LibsodiumInitializer.initializeWithCallback { + val message = ("I wonder if it would be possible" + + " to get some lyrics in these tests").encodeToUByteArray() + + val key = "We'll see1We'll see1We'll see123".encodeToUByteArray() + + val expected = ("702beb4494a1d80795512668df016807ec052dc848a4c958eb1544ec1c8d63145fd11513c2d" + + "aecb03780e2b8b121e87f0a171033489de92665d9a218f4ed9589").hexStringToUByteArray() + + val hashed = Auth.authHmacSha512(message, key) + println(hashed.toHexString()) + assertTrue { + hashed.contentEquals(expected) + } + println(hashed.toHexString()) + assertTrue { Auth.authHmacSha512Verify(hashed, message, key) } + + assertFalse { + val tampered = hashed.copyOf() + tampered[5] = 0U + Auth.authHmacSha512Verify(tampered, message, key) + } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt index 5cf01dd..1964240 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -47,7 +47,6 @@ actual object Auth { val macPinned = mac.pin() val messagePinned = message.pin() val keyPinned = key.pin() - val verify = crypto_auth_verify( macPinned.toPtr(), messagePinned.toPtr(), @@ -57,7 +56,7 @@ actual object Auth { keyPinned.unpin() messagePinned.unpin() - keyPinned.unpin() + macPinned.unpin() return verify == 0 } @@ -108,7 +107,7 @@ actual object Auth { keyPinned.unpin() messagePinned.unpin() - keyPinned.unpin() + macPinned.unpin() return verify == 0 } @@ -159,7 +158,7 @@ actual object Auth { keyPinned.unpin() messagePinned.unpin() - keyPinned.unpin() + macPinned.unpin() return verify == 0 } From 16cb5c2dee07ef89e3a6e9b8d79b4733151ec893 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 30 Aug 2020 19:02:40 +0200 Subject: [PATCH 34/65] Completed crypto auth and added tests --- .../com.ionspin.kotlin.crypto/auth/Auth.kt | 3 +- .../ionspin/kotlin/crypto/auth/AuthTest.kt | 15 ++++- .../kotlin/crypto/JsSodiumInterface.kt | 14 +++++ .../com/ionspin/kotlin/crypto/auth/Auth.kt | 45 +++++++++++--- .../com/ionspin/kotlin/crypto/auth/Auth.kt | 62 ++++++++++++++++--- supported_bindings_list.md | 34 +++++----- 6 files changed, 136 insertions(+), 37 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt index f11cbc4..2b0d120 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/auth/Auth.kt @@ -9,11 +9,12 @@ package com.ionspin.kotlin.crypto.auth val crypto_auth_BYTES = 32 val crypto_auth_KEYBYTES = 32 +// do the 512 hmac and the deliver just 32 bytes of result val crypto_auth_hmacsha512256_BYTES = 32 val crypto_auth_hmacsha512256_KEYBYTES = 32 val crypto_auth_hmacsha256_KEYBYTES = 32 -val crypto_auth_hmacsha256_BYTES =32 +val crypto_auth_hmacsha256_BYTES = 32 val crypto_auth_hmacsha512_KEYBYTES = 32 val crypto_auth_hmacsha512_BYTES = 64 diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt index a3cd065..9650457 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/auth/AuthTest.kt @@ -21,7 +21,6 @@ class AuthTest { " to get some lyrics in these tests").encodeToUByteArray() val key = "We'll see1We'll see1We'll see123".encodeToUByteArray() - println("Key size ${key.size}") val expected = "702beb4494a1d80795512668df016807ec052dc848a4c958eb1544ec1c8d6314".hexStringToUByteArray() @@ -92,4 +91,18 @@ class AuthTest { } } } + + @Test + fun simpleKeygenTest() { + LibsodiumInitializer.initializeWithCallback { + val authKey = Auth.authKeygen() + assertTrue { authKey.size == crypto_auth_KEYBYTES } + val auth256Key = Auth.authHmacSha256Keygen() + assertTrue { auth256Key.size == crypto_auth_hmacsha256_KEYBYTES } + val auth512Key = Auth.authHmacSha512Keygen() + assertTrue { auth512Key.size == crypto_auth_hmacsha512_KEYBYTES } + } + + + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index e214503..ed83523 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -91,6 +91,20 @@ interface JsSodiumInterface { // ---- AEAD end ---- + // ---- Auth ---- + + fun crypto_auth(message: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_auth_keygen() : Uint8Array + fun crypto_auth_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean + fun crypto_auth_hmacsha256(message: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_auth_hmacsha256_keygen() : Uint8Array + fun crypto_auth_hmacsha256_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean + fun crypto_auth_hmacsha512(message: Uint8Array, key: Uint8Array) : Uint8Array + fun crypto_auth_hmacsha512_keygen() : Uint8Array + fun crypto_auth_hmacsha512_verify(tag: Uint8Array, message: Uint8Array, key: Uint8Array) : Boolean + + // ---- Auth end ---- + //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt index 7ad35a1..50cf35a 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -1,24 +1,40 @@ package com.ionspin.kotlin.crypto.auth +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + actual object Auth { actual fun authKeygen(): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_auth_keygen().toUByteArray() } actual fun auth(message: UByteArray, key: UByteArray): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_auth( + message.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() + } actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { - TODO("not implemented yet") + return getSodium().crypto_auth_verify( + mac.toUInt8Array(), + message.toUInt8Array(), + key.toUInt8Array() + ) } actual fun authHmacSha256Keygen(): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_auth_hmacsha256_keygen().toUByteArray() } actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_auth_hmacsha256( + message.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() } actual fun authHmacSha256Verify( @@ -26,15 +42,22 @@ actual object Auth { message: UByteArray, key: UByteArray ): Boolean { - TODO("not implemented yet") + return getSodium().crypto_auth_hmacsha256_verify( + mac.toUInt8Array(), + message.toUInt8Array(), + key.toUInt8Array() + ) } actual fun authHmacSha512Keygen(): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_auth_hmacsha512_keygen().toUByteArray() } actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { - TODO("not implemented yet") + return getSodium().crypto_auth_hmacsha512( + message.toUInt8Array(), + key.toUInt8Array() + ).toUByteArray() } actual fun authHmacSha512Verify( @@ -42,7 +65,11 @@ actual object Auth { message: UByteArray, key: UByteArray ): Boolean { - TODO("not implemented yet") + return getSodium().crypto_auth_hmacsha512_verify( + mac.toUInt8Array(), + message.toUInt8Array(), + key.toUInt8Array() + ) } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt index 7ad35a1..afaec45 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/auth/Auth.kt @@ -1,24 +1,49 @@ package com.ionspin.kotlin.crypto.auth +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + actual object Auth { actual fun authKeygen(): UByteArray { - TODO("not implemented yet") + val generatedKey = UByteArray(crypto_auth_KEYBYTES) + sodium.crypto_auth_keygen(generatedKey.asByteArray()) + return generatedKey } actual fun auth(message: UByteArray, key: UByteArray): UByteArray { - TODO("not implemented yet") + val mac = UByteArray(crypto_auth_BYTES) + sodium.crypto_auth( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) + return mac } actual fun authVerify(mac: UByteArray, message: UByteArray, key: UByteArray): Boolean { - TODO("not implemented yet") + return sodium.crypto_auth_verify( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) == 0 } actual fun authHmacSha256Keygen(): UByteArray { - TODO("not implemented yet") + val generatedKey = UByteArray(crypto_auth_hmacsha256_KEYBYTES) + sodium.crypto_auth_hmacsha256_keygen(generatedKey.asByteArray()) + return generatedKey } actual fun authHmacSha256(message: UByteArray, key: UByteArray): UByteArray { - TODO("not implemented yet") + val mac = UByteArray(crypto_auth_hmacsha256_BYTES) + sodium.crypto_auth_hmacsha256( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) + return mac } actual fun authHmacSha256Verify( @@ -26,15 +51,29 @@ actual object Auth { message: UByteArray, key: UByteArray ): Boolean { - TODO("not implemented yet") + return sodium.crypto_auth_hmacsha256_verify( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) == 0 } actual fun authHmacSha512Keygen(): UByteArray { - TODO("not implemented yet") + val generatedKey = UByteArray(crypto_auth_hmacsha512_KEYBYTES) + sodium.crypto_auth_hmacsha512_keygen(generatedKey.asByteArray()) + return generatedKey } actual fun authHmacSha512(message: UByteArray, key: UByteArray): UByteArray { - TODO("not implemented yet") + val mac = UByteArray(crypto_auth_hmacsha512_BYTES) + sodium.crypto_auth_hmacsha512( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) + return mac } actual fun authHmacSha512Verify( @@ -42,7 +81,12 @@ actual object Auth { message: UByteArray, key: UByteArray ): Boolean { - TODO("not implemented yet") + return sodium.crypto_auth_hmacsha512_verify( + mac.asByteArray(), + message.asByteArray(), + message.size.toLong(), + key.asByteArray() + ) == 0 } } diff --git a/supported_bindings_list.md b/supported_bindings_list.md index b53e853..90ae5f0 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -27,15 +27,15 @@ | crypto_aead_xchacha20poly1305_ietf_encrypt | :heavy_check_mark: | | crypto_aead_xchacha20poly1305_ietf_encrypt_detached | :heavy_check_mark: | | crypto_aead_xchacha20poly1305_ietf_keygen | :heavy_check_mark: | -| crypto_auth | | -| crypto_auth_hmacsha256 | | -| crypto_auth_hmacsha256_keygen | | -| crypto_auth_hmacsha256_verify | | -| crypto_auth_hmacsha512 | | -| crypto_auth_hmacsha512_keygen | | -| crypto_auth_hmacsha512_verify | | -| crypto_auth_keygen | | -| crypto_auth_verify | | +| crypto_auth | :heavy_check_mark: | +| crypto_auth_hmacsha256 | :heavy_check_mark: | +| crypto_auth_hmacsha256_keygen | :heavy_check_mark: | +| crypto_auth_hmacsha256_verify | :heavy_check_mark: | +| crypto_auth_hmacsha512 | :heavy_check_mark: | +| crypto_auth_hmacsha512_keygen | :heavy_check_mark: | +| crypto_auth_hmacsha512_verify | :heavy_check_mark: | +| crypto_auth_keygen | :heavy_check_mark: | +| crypto_auth_verify | :heavy_check_mark: | | crypto_box_beforenm | | | crypto_box_curve25519xchacha20poly1305_keypair | | | crypto_box_curve25519xchacha20poly1305_seal | | @@ -174,14 +174,14 @@ | crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX | | | crypto_aead_xchacha20poly1305_ietf_NPUBBYTES | :heavy_check_mark: | | crypto_aead_xchacha20poly1305_ietf_NSECBYTES | | -| crypto_auth_BYTES | | -| crypto_auth_KEYBYTES | | -| crypto_auth_hmacsha256_BYTES | | -| crypto_auth_hmacsha256_KEYBYTES | | -| crypto_auth_hmacsha512256_BYTES | | -| crypto_auth_hmacsha512256_KEYBYTES | | -| crypto_auth_hmacsha512_BYTES | | -| crypto_auth_hmacsha512_KEYBYTES | | +| crypto_auth_BYTES | :heavy_check_mark: | +| crypto_auth_KEYBYTES | :heavy_check_mark: | +| crypto_auth_hmacsha256_BYTES | :heavy_check_mark: | +| crypto_auth_hmacsha256_KEYBYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512256_BYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512256_KEYBYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512_BYTES | :heavy_check_mark: | +| crypto_auth_hmacsha512_KEYBYTES | :heavy_check_mark: | | crypto_box_BEFORENMBYTES | | | crypto_box_MACBYTES | | | crypto_box_MESSAGEBYTES_MAX | | From 1878144b8f48ec08f642c0fcff7b4bf4747c8a3a Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Mon, 31 Aug 2020 19:39:19 +0200 Subject: [PATCH 35/65] Added generichash keygen --- .../com.ionspin.kotlin.crypto/generichash/GenericHash.kt | 4 ++++ .../com/ionspin/kotlin/crypto/JsSodiumInterface.kt | 2 ++ .../com/ionspin/kotlin/crypto/generichash/GenericHash.kt | 4 ++++ .../com/ionspin/kotlin/crypto/generichash/GenericHash.kt | 6 ++++++ .../com/ionspin/kotlin/crypto/generichash/GenericHash.kt | 9 +++++++++ supported_bindings_list.md | 4 ++-- 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt index b66c2d1..cddacce 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt @@ -6,6 +6,8 @@ package com.ionspin.kotlin.crypto.generichash * on 21-Aug-2020 */ +val crypto_generichash_BYTES = 32 + data class GenericHashState(val hashLength: Int, val internalState: GenericHashStateInternal) expect class GenericHashStateInternal @@ -18,6 +20,8 @@ expect object GenericHash { fun genericHashUpdate(state: GenericHashState, messagePart : UByteArray) fun genericHashFinal(state : GenericHashState) : UByteArray + fun genericHashKeygen() : UByteArray + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index ed83523..2bc4158 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -26,6 +26,8 @@ interface JsSodiumInterface { fun crypto_generichash_final(state: dynamic, hashLength: Int) : Uint8Array + fun crypto_generichash_keygen() : Uint8Array + //Short hash fun crypto_shorthash(data : Uint8Array, key: Uint8Array) : Uint8Array diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt index 8055387..bcd6d3c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -44,4 +44,8 @@ actual object GenericHash { actual fun genericHashFinal(state: GenericHashState): UByteArray { return getSodium().crypto_generichash_final(state.internalState, state.hashLength).toUByteArray() } + + actual fun genericHashKeygen(): UByteArray { + return getSodium().crypto_generichash_keygen().toUByteArray() + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt index f94586c..f674d82 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -49,5 +49,11 @@ actual object GenericHash { return hashResult.asUByteArray() } + actual fun genericHashKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_generichash_BYTES) + sodium.crypto_generichash_keygen(generatedKey.asByteArray()) + return generatedKey + } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt index e8c9742..2f765d4 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -10,6 +10,7 @@ import kotlinx.cinterop.reinterpret import libsodium.crypto_generichash import libsodium.crypto_generichash_final import libsodium.crypto_generichash_init +import libsodium.crypto_generichash_keygen import libsodium.crypto_generichash_update import platform.posix.malloc @@ -88,5 +89,13 @@ actual object GenericHash { return hashResult } + actual fun genericHashKeygen(): UByteArray { + val generatedKey = UByteArray(crypto_generichash_BYTES) + val generatedKeyPinned = generatedKey.pin() + crypto_generichash_keygen(generatedKeyPinned.toPtr()) + generatedKeyPinned.unpin() + return generatedKey + } + } diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 90ae5f0..6c765f4 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -67,8 +67,8 @@ | crypto_generichash_blake2b_salt_personal | | | crypto_generichash_final | :heavy_check_mark: | | crypto_generichash_init | :heavy_check_mark: | -| crypto_generichash_keygen | | -| crypto_generichash_update | :heavy_check_mark: | +| crypto_generichash_keygen | :heavy_check_mark: | +| crypto_generichash_update | :heavy_check_mark: | | crypto_hash | | | crypto_hash_sha256 | | | crypto_hash_sha256_final | | From 15be7071145b5cf15d38f6c476d0503d9c9df7a3 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Mon, 31 Aug 2020 20:44:37 +0200 Subject: [PATCH 36/65] Added sha2 hashes in common and native and test --- .../generichash/GenericHash.kt | 19 +++- .../com.ionspin.kotlin.crypto/hash/Hash.kt | 31 ++++++ .../ionspin/kotlin/crypto/hash/HashTest.kt | 77 +++++++++++++++ .../kotlin/crypto/JsSodiumInterface.kt | 22 ++++- .../kotlin/crypto/generichash/GenericHash.kt | 31 ++++++ .../com/ionspin/kotlin/crypto/hash/Hash.kt | 39 ++++++++ .../com/ionspin/kotlin/crypto/hash/Hash.kt | 98 +++++++++++++++++++ 7 files changed, 313 insertions(+), 4 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt index cddacce..c778647 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/generichash/GenericHash.kt @@ -7,10 +7,18 @@ package com.ionspin.kotlin.crypto.generichash */ val crypto_generichash_BYTES = 32 +val crypto_generichash_blake2b_BYTES_MIN = 16 +val crypto_generichash_blake2b_BYTES_MAX = 64 +val crypto_generichash_blake2b_BYTES = 32 +val crypto_generichash_blake2b_KEYBYTES_MIN = 16 +val crypto_generichash_blake2b_KEYBYTES_MAX = 64 +val crypto_generichash_blake2b_KEYBYTES = 32 +val crypto_generichash_blake2b_SALTBYTES = 16 + +expect class GenericHashStateInternal data class GenericHashState(val hashLength: Int, val internalState: GenericHashStateInternal) -expect class GenericHashStateInternal expect object GenericHash { @@ -21,6 +29,15 @@ expect object GenericHash { fun genericHashFinal(state : GenericHashState) : UByteArray fun genericHashKeygen() : UByteArray +// ---- Not present in LazySodium nor libsodium.js +// fun blake2b(message : UByteArray, requestedHashLength: Int, key : UByteArray? = null) : UByteArray +// +// fun blake2bInit(requestedHashLength: Int, key : UByteArray? = null) : Blake2bState +// fun blake2bUpdate(state: GenericHashState, messagePart : UByteArray) +// fun blake2bFinal(state : GenericHashState) : UByteArray +// +// fun blake2bKeygen() : UByteArray + } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt new file mode 100644 index 0000000..77a787c --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt @@ -0,0 +1,31 @@ +package com.ionspin.kotlin.crypto.hash + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ + +val crypto_hash_BYTES = 64 +val crypto_hash_sha256_BYTES = 32 +val crypto_hash_sha512_BYTES = 64 + +expect class Sha256State +expect class Sha512State + +expect object Hash { + + fun hash(data: UByteArray) : UByteArray + + fun sha256(data: UByteArray) : UByteArray + fun sha256Init() : Sha256State + fun sha256Update(state: Sha256State, data : UByteArray) + fun sha256Final(state : Sha256State) : UByteArray + + fun sha512(data: UByteArray) : UByteArray + fun sha512Init() : Sha512State + fun sha512Update(state: Sha512State, data : UByteArray) + fun sha512Final(state : Sha512State) : UByteArray + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt new file mode 100644 index 0000000..b88df15 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt @@ -0,0 +1,77 @@ +package com.ionspin.kotlin.crypto.hash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.hexStringToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ +class HashTest { + @Test + fun hashTest() { + LibsodiumInitializer.initializeWithCallback { + val input = ("Input for various hash functions").encodeToUByteArray() + val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" + + "838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray() + + val result = Hash.hash(input) + assertTrue { + result.contentEquals(expected) + } + } + + } + + + @Test + fun hashTestSha256() { + LibsodiumInitializer.initializeWithCallback { + val input = ("Input for various hash functions").encodeToUByteArray() + val expected = ("2bb078ec5993b5428355ba49bf030b1ac7" + + "1519e635aebc2f28124fac2aef9264").hexStringToUByteArray() + + val result = Hash.sha256(input) + assertTrue { + result.contentEquals(expected) + } + + val sha256State = Hash.sha256Init() + Hash.sha256Update(sha256State, input) + val multipartResult = Hash.sha256Final(sha256State) + assertTrue { + multipartResult.contentEquals(expected) + } + } + + } + + @Test + fun hashTestSha512() { + LibsodiumInitializer.initializeWithCallback { + val input = ("Input for various hash functions").encodeToUByteArray() + val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" + + "838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray() + + val result = Hash.sha512(input) + assertTrue { + result.contentEquals(expected) + } + + val sha512State = Hash.sha512Init() + Hash.sha512Update(sha512State, input) + val multipartResult = Hash.sha512Final(sha512State) + assertTrue { + multipartResult.contentEquals(expected) + } + } + + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 2bc4158..37880e3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -18,7 +18,7 @@ interface JsSodiumInterface { fun crypto_hash_sha512(message: Uint8Array): Uint8Array - //Updateable + // ---- Generic hash ---- // Updateable fun crypto_generichash_init(key : Uint8Array, hashLength: Int) : dynamic @@ -28,11 +28,27 @@ interface JsSodiumInterface { fun crypto_generichash_keygen() : Uint8Array - //Short hash + // ---- Generic hash end ---- // Updateable + + // ---- Blake2b ---- + + fun crypto_generichash_blake2b(hashLength: Int, inputMessage: Uint8Array, key: Uint8Array): Uint8Array + + fun crypto_generichash_blake2b_init(key : Uint8Array, hashLength: Int) : dynamic + + fun crypto_generichash_blake2b_update(state: dynamic, inputMessage: Uint8Array) + + fun crypto_generichash_blake2b_final(state: dynamic, hashLength: Int) : Uint8Array + + fun crypto_generichash_blake2b_keygen() : Uint8Array + + // ---- Blake2b end ---- + + // ---- Short hash ---- fun crypto_shorthash(data : Uint8Array, key: Uint8Array) : Uint8Array fun crypto_shorthash_keygen() : Uint8Array - + // ---- Short hash end ---- fun crypto_hash_sha256_init() : dynamic diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt index bcd6d3c..3ea5001 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/generichash/GenericHash.kt @@ -48,4 +48,35 @@ actual object GenericHash { actual fun genericHashKeygen(): UByteArray { return getSodium().crypto_generichash_keygen().toUByteArray() } +// -- Not present in LazySodium nor libsodium.js +// actual fun blake2b(message: UByteArray, requestedHashLength: Int, key: UByteArray?) : UByteArray { +// return getSodium().crypto_generichash_blake2b( +// requestedHashLength, +// message.toUInt8Array(), +// key?.toUInt8Array() ?: Uint8Array(0) +// ).toUByteArray() +// } +// +// actual fun blake2bInit( +// requestedHashLength: Int, +// key: UByteArray? +// ): Blake2bState { +// val state = getSodium().crypto_generichash_blake2b_init(key?.toUInt8Array() ?: Uint8Array(0), requestedHashLength) +// return Blake2bState(requestedHashLength, state) +// } +// +// actual fun blake2bUpdate( +// state: GenericHashState, +// messagePart: UByteArray +// ) { +// getSodium().crypto_generichash_blake2b_update(state.internalState, messagePart.toUInt8Array()) +// } +// +// actual fun blake2bFinal(state: GenericHashState): UByteArray { +// return getSodium().crypto_generichash_blake2b_final(state.internalState, state.hashLength).toUByteArray() +// } +// +// actual fun blake2bKeygen(): UByteArray { +// return getSodium().crypto_generichash_blake2b_keygen().toUByteArray() +// } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt new file mode 100644 index 0000000..9746dd6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -0,0 +1,39 @@ +package com.ionspin.kotlin.crypto.hash + +actual object Hash { + actual fun hash(data: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun sha256(data: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun sha256Init(): Sha256State { + TODO("not implemented yet") + } + + actual fun sha256Update(state: Sha256State, data: UByteArray) { + } + + actual fun sha256Final(state: Sha256State): UByteArray { + TODO("not implemented yet") + } + + actual fun sha512(data: UByteArray): UByteArray { + TODO("not implemented yet") + } + + actual fun sha512Init(): Sha512State { + TODO("not implemented yet") + } + + actual fun sha512Update(state: Sha512State, data: UByteArray) { + } + + actual fun sha512Final(state: Sha512State): UByteArray { + TODO("not implemented yet") + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt new file mode 100644 index 0000000..5b76344 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -0,0 +1,98 @@ +package com.ionspin.kotlin.crypto.hash + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.pointed +import kotlinx.cinterop.ptr +import kotlinx.cinterop.reinterpret +import libsodium.crypto_hash +import libsodium.crypto_hash_sha256 +import libsodium.crypto_hash_sha256_final +import libsodium.crypto_hash_sha256_init +import libsodium.crypto_hash_sha256_state +import libsodium.crypto_hash_sha256_update +import libsodium.crypto_hash_sha512 +import libsodium.crypto_hash_sha512_final +import libsodium.crypto_hash_sha512_init +import libsodium.crypto_hash_sha512_state +import libsodium.crypto_hash_sha512_update +import platform.posix.malloc + +actual typealias Sha256State = crypto_hash_sha256_state +actual typealias Sha512State = crypto_hash_sha512_state + +actual object Hash { + actual fun hash(data: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_hash_BYTES) + val hashResultPinned = hashResult.pin() + val dataPinned = data.pin() + crypto_hash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) + hashResultPinned.unpin() + dataPinned.unpin() + + return hashResult + } + + actual fun sha256(data: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_hash_sha256_BYTES) + val hashResultPinned = hashResult.pin() + val dataPinned = data.pin() + crypto_hash_sha256(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) + hashResultPinned.unpin() + dataPinned.unpin() + + return hashResult + } + + actual fun sha256Init(): Sha256State { + val stateAllocated = malloc(Sha256State.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + crypto_hash_sha256_init(statePointed.ptr) + return statePointed + } + + actual fun sha256Update(state: Sha256State, data: UByteArray) { + val dataPinned = data.pin() + crypto_hash_sha256_update(state.ptr, dataPinned.toPtr(), data.size.convert()) + } + + actual fun sha256Final(state: Sha256State): UByteArray { + val hashResult = UByteArray(crypto_hash_sha256_BYTES) + val hashResultPinned = hashResult.pin() + crypto_hash_sha256_final(state.ptr, hashResultPinned.toPtr()) + return hashResult + } + + actual fun sha512(data: UByteArray): UByteArray { + val hashResult = UByteArray(crypto_hash_sha512_BYTES) + val hashResultPinned = hashResult.pin() + val dataPinned = data.pin() + crypto_hash_sha512(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) + hashResultPinned.unpin() + dataPinned.unpin() + + return hashResult + } + + actual fun sha512Init(): Sha512State { + val stateAllocated = malloc(Sha512State.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + crypto_hash_sha512_init(statePointed.ptr) + return statePointed + } + + actual fun sha512Update(state: Sha512State, data: UByteArray) { + val dataPinned = data.pin() + crypto_hash_sha512_update(state.ptr, dataPinned.toPtr(), data.size.convert()) + } + + actual fun sha512Final(state: Sha512State): UByteArray { + val hashResult = UByteArray(crypto_hash_sha512_BYTES) + val hashResultPinned = hashResult.pin() + crypto_hash_sha512_final(state.ptr, hashResultPinned.toPtr()) + return hashResult + } + + +} From 1894a5d995f05b9eed50bc994161d4556b927403 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Mon, 31 Aug 2020 20:56:36 +0200 Subject: [PATCH 37/65] Added jvm and js implementation for sha256/512 --- .../com.ionspin.kotlin.crypto/hash/Hash.kt | 3 +- .../ionspin/kotlin/crypto/hash/HashTest.kt | 29 +++++----- .../com/ionspin/kotlin/crypto/hash/Hash.kt | 47 ++++++++++++++++ .../com/ionspin/kotlin/crypto/hash/Hash.kt | 39 ------------- .../com/ionspin/kotlin/crypto/hash/HashJvm.kt | 56 +++++++++++++++++++ .../com/ionspin/kotlin/crypto/hash/Hash.kt | 21 +++---- 6 files changed, 131 insertions(+), 64 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt delete mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/HashJvm.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt index 77a787c..f0fb7eb 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/hash/Hash.kt @@ -15,7 +15,8 @@ expect class Sha512State expect object Hash { - fun hash(data: UByteArray) : UByteArray + //Not present in LazySodium + //fun hash(data: UByteArray) : UByteArray fun sha256(data: UByteArray) : UByteArray fun sha256Init() : Sha256State diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt index b88df15..70800e3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/hash/HashTest.kt @@ -13,20 +13,21 @@ import kotlin.test.assertTrue * on 31-Aug-2020 */ class HashTest { - @Test - fun hashTest() { - LibsodiumInitializer.initializeWithCallback { - val input = ("Input for various hash functions").encodeToUByteArray() - val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" + - "838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray() - - val result = Hash.hash(input) - assertTrue { - result.contentEquals(expected) - } - } - - } + //Not present in Lazy sodium +// @Test +// fun hashTest() { +// LibsodiumInitializer.initializeWithCallback { +// val input = ("Input for various hash functions").encodeToUByteArray() +// val expected = ("34fcbcdcfe9e6aa3e6d5a64649afcfafb449c4b8435a65e5e7b7c2b6af3b04da350acee" + +// "838246d7c2637021def0c844fcb79ac42d6a50279f1078e535997b6e6").hexStringToUByteArray() +// +// val result = Hash.hash(input) +// assertTrue { +// result.contentEquals(expected) +// } +// } +// +// } @Test diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt new file mode 100644 index 0000000..13fe9bd --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -0,0 +1,47 @@ +package com.ionspin.kotlin.crypto.hash + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual typealias Sha256State = Any +actual typealias Sha512State = Any + +actual object Hash { + + //Not present in LazySodium + //fun hash(data: UByteArray) : UByteArray + actual fun sha256(data: UByteArray): UByteArray { + return getSodium().crypto_hash_sha256(data.toUInt8Array()).toUByteArray() + } + + actual fun sha256Init(): Sha256State { + return getSodium().crypto_hash_sha256_init() + } + + actual fun sha256Update(state: Sha256State, data: UByteArray) { + getSodium().crypto_hash_sha256_update(state, data.toUInt8Array()) + } + + actual fun sha256Final(state: Sha256State): UByteArray { + return getSodium().crypto_hash_sha256_final(state).toUByteArray() + } + + actual fun sha512(data: UByteArray): UByteArray { + return getSodium().crypto_hash_sha512(data.toUInt8Array()).toUByteArray() + } + + actual fun sha512Init(): Sha512State { + return getSodium().crypto_hash_sha512_init() + } + + actual fun sha512Update(state: Sha512State, data: UByteArray) { + getSodium().crypto_hash_sha512_update(state, data.toUInt8Array()) + } + + actual fun sha512Final(state: Sha512State): UByteArray { + return getSodium().crypto_hash_sha512_final(state).toUByteArray() + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt deleted file mode 100644 index 9746dd6..0000000 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.ionspin.kotlin.crypto.hash - -actual object Hash { - actual fun hash(data: UByteArray): UByteArray { - TODO("not implemented yet") - } - - actual fun sha256(data: UByteArray): UByteArray { - TODO("not implemented yet") - } - - actual fun sha256Init(): Sha256State { - TODO("not implemented yet") - } - - actual fun sha256Update(state: Sha256State, data: UByteArray) { - } - - actual fun sha256Final(state: Sha256State): UByteArray { - TODO("not implemented yet") - } - - actual fun sha512(data: UByteArray): UByteArray { - TODO("not implemented yet") - } - - actual fun sha512Init(): Sha512State { - TODO("not implemented yet") - } - - actual fun sha512Update(state: Sha512State, data: UByteArray) { - } - - actual fun sha512Final(state: Sha512State): UByteArray { - TODO("not implemented yet") - } - - -} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/HashJvm.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/HashJvm.kt new file mode 100644 index 0000000..cdaf573 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/hash/HashJvm.kt @@ -0,0 +1,56 @@ +package com.ionspin.kotlin.crypto.hash + +import com.goterl.lazycode.lazysodium.interfaces.Hash +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual typealias Sha256State = Hash.State256 +actual typealias Sha512State = Hash.State512 + +actual object Hash { + + actual fun sha256(data: UByteArray): UByteArray { + val resultHash = UByteArray(crypto_hash_sha256_BYTES) + sodium.crypto_hash_sha256(resultHash.asByteArray(), data.asByteArray(), data.size.toLong()) + return resultHash + } + + actual fun sha256Init(): Sha256State { + val state = Hash.State256() + sodium.crypto_hash_sha256_init(state) + return state + } + + actual fun sha256Update(state: Sha256State, data: UByteArray) { + sodium.crypto_hash_sha256_update(state, data.asByteArray(), data.size.toLong()) + } + + actual fun sha256Final(state: Sha256State): UByteArray { + val resultHash = UByteArray(crypto_hash_sha256_BYTES) + sodium.crypto_hash_sha256_final(state, resultHash.asByteArray()) + return resultHash + } + + actual fun sha512(data: UByteArray): UByteArray { + val resultHash = UByteArray(crypto_hash_sha512_BYTES) + sodium.crypto_hash_sha512(resultHash.asByteArray(), data.asByteArray(), data.size.toLong()) + return resultHash + } + + actual fun sha512Init(): Sha512State { + val state = Hash.State512() + sodium.crypto_hash_sha512_init(state) + return state + } + + actual fun sha512Update(state: Sha512State, data: UByteArray) { + sodium.crypto_hash_sha512_update(state, data.asByteArray(), data.size.toLong()) + } + + actual fun sha512Final(state: Sha512State): UByteArray { + val resultHash = UByteArray(crypto_hash_sha512_BYTES) + sodium.crypto_hash_sha512_final(state, resultHash.asByteArray()) + return resultHash + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt index 5b76344..25d9458 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/hash/Hash.kt @@ -23,16 +23,17 @@ actual typealias Sha256State = crypto_hash_sha256_state actual typealias Sha512State = crypto_hash_sha512_state actual object Hash { - actual fun hash(data: UByteArray): UByteArray { - val hashResult = UByteArray(crypto_hash_BYTES) - val hashResultPinned = hashResult.pin() - val dataPinned = data.pin() - crypto_hash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) - hashResultPinned.unpin() - dataPinned.unpin() - - return hashResult - } + //Not present in Lazy Sodium +// actual fun hash(data: UByteArray): UByteArray { +// val hashResult = UByteArray(crypto_hash_BYTES) +// val hashResultPinned = hashResult.pin() +// val dataPinned = data.pin() +// crypto_hash(hashResultPinned.toPtr(), dataPinned.toPtr(), data.size.convert()) +// hashResultPinned.unpin() +// dataPinned.unpin() +// +// return hashResult +// } actual fun sha256(data: UByteArray): UByteArray { val hashResult = UByteArray(crypto_hash_sha256_BYTES) From 57f9bd9d2038ec45dd0cc1125ae80e282bfe3598 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Mon, 31 Aug 2020 22:56:37 +0200 Subject: [PATCH 38/65] Adding crypto_box functions --- .../com.ionspin.kotlin.crypto/box/Box.kt | 90 +++++++++++++++++++ .../secretstream/SecretStream.kt | 2 +- .../util/LibsodiumUtil.kt | 10 +++ supported_bindings_list.md | 28 +++--- 4 files changed, 114 insertions(+), 16 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt new file mode 100644 index 0000000..5a6db9b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt @@ -0,0 +1,90 @@ +package com.ionspin.kotlin.crypto.box + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ + +val crypto_box_PUBLICKEYBYTES = 32 +val crypto_box_SECRETKEYBYTES = 32 +val crypto_box_MACBYTES = 16 +val crypto_box_SEEDBYTES = 32 +val crypto_box_NONCEBYTES = 24 +val crypto_box_SEALBYTES = 48 +val crypto_box_BEFORENMBYTES = 32 + +data class BoxKeyPair(val publicKey : UByteArray, val secretKey: UByteArray) +data class BoxEncryptedDataAndTag(val ciphertext: UByteArray, val tag: UByteArray) + +class BoxCorruptedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") + +expect object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + fun keypair() : BoxKeyPair + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + fun seedKeypair(seed: UByteArray) : BoxKeyPair + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + fun easy(message : UByteArray, nonce : UByteArray, recipientsPublicKey: UByteArray, sendersSecretKey: UByteArray) : UByteArray + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + fun openEasy(ciphertext : UByteArray, nonce: UByteArray, sendersPublicKey: UByteArray, recipientsSecretKey: UByteArray) : UByteArray + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + fun beforeNM(publicKey: UByteArray, secretKey: UByteArray) : UByteArray + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + fun easyAfterNM(message : UByteArray, nonce: UByteArray, precomputedKey: UByteArray) : UByteArray + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + fun openEasyAfterNM(ciphertext: UByteArray, nonce: UByteArray, precomputedKey: UByteArray) : UByteArray + + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + fun detached(message: UByteArray, nonce: UByteArray, recipientsPublicKey: UByteArray, sendersSecretKey: UByteArray) : BoxEncryptedDataAndTag + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + fun openDetached(ciphertext: UByteArray, tag: UByteArray, nonce: UByteArray, sendersPublicKey: UByteArray, recipientsSecretKey: UByteArray) : UByteArray + + + fun seal(message: UByteArray, recipientsPublicKey: UByteArray) : UByteArray + + fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray) : UByteArray + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt index 32c7dea..2aaeb2c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/secretstream/SecretStream.kt @@ -22,7 +22,7 @@ val crypto_secretstream_xchacha20poly1305_HEADERBYTES = 24 val crypto_secretstream_xchacha20poly1305_KEYBYTES = 32 val crypto_secretstream_xchacha20poly1305_ABYTES = 17 -class SecretStreamCorrupedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") +class SecretStreamCorruptedOrTamperedDataException() : RuntimeException("MAC validation failed. Data is corrupted or tampered with.") expect object SecretStream { diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..5f88538 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt @@ -0,0 +1,10 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ +//expect object LibsodiumUtil { +// +//} diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 6c765f4..47b0102 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -6,8 +6,6 @@ | output_formats | | | pad | | | unpad | | -| ready | | -| [[ | | | symbols | | | to_base64 | | | to_hex | | @@ -37,9 +35,9 @@ | crypto_auth_keygen | :heavy_check_mark: | | crypto_auth_verify | :heavy_check_mark: | | crypto_box_beforenm | | -| crypto_box_curve25519xchacha20poly1305_keypair | | -| crypto_box_curve25519xchacha20poly1305_seal | | -| crypto_box_curve25519xchacha20poly1305_seal_open | | +| crypto_box_curve25519xchacha20poly1305_keypair | not present in LazySodium | +| crypto_box_curve25519xchacha20poly1305_seal | not present in LazySodium | +| crypto_box_curve25519xchacha20poly1305_seal_open |not present in LazySodium | | crypto_box_detached | | | crypto_box_easy | | | crypto_box_easy_afternm | | @@ -70,14 +68,14 @@ | crypto_generichash_keygen | :heavy_check_mark: | | crypto_generichash_update | :heavy_check_mark: | | crypto_hash | | -| crypto_hash_sha256 | | -| crypto_hash_sha256_final | | -| crypto_hash_sha256_init | | -| crypto_hash_sha256_update | | -| crypto_hash_sha512 | | -| crypto_hash_sha512_final | | -| crypto_hash_sha512_init | | -| crypto_hash_sha512_update | | +| crypto_hash_sha256 | :heavy_check_mark | +| crypto_hash_sha256_final | :heavy_check_mark | +| crypto_hash_sha256_init | :heavy_check_mark | +| crypto_hash_sha256_update | :heavy_check_mark | +| crypto_hash_sha512 | :heavy_check_mark | +| crypto_hash_sha512_final | :heavy_check_mark | +| crypto_hash_sha512_init | :heavy_check_mark | +| crypto_hash_sha512_update | :heavy_check_mark | | crypto_kdf_derive_from_key | | | crypto_kdf_keygen | | | crypto_kx_client_session_keys | | @@ -245,8 +243,8 @@ | crypto_generichash_blake2b_PERSONALBYTES | | | crypto_generichash_blake2b_SALTBYTES | | | crypto_hash_BYTES | | -| crypto_hash_sha256_BYTES | | -| crypto_hash_sha512_BYTES | | +| crypto_hash_sha256_BYTES | :heavy_check_mark: | +| crypto_hash_sha512_BYTES | :heavy_check_mark: | | crypto_kdf_BYTES_MAX | | | crypto_kdf_BYTES_MIN | | | crypto_kdf_CONTEXTBYTES | | From 4762bd96d6bc1bf6539170d6396aceeb0e6e8337 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 1 Sep 2020 20:27:51 +0200 Subject: [PATCH 39/65] Implemented native --- .../com/ionspin/kotlin/crypto/box/Box.kt | 335 ++++++++++++++++++ 1 file changed, 335 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt new file mode 100644 index 0000000..d293594 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -0,0 +1,335 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_box_beforenm +import libsodium.crypto_box_detached +import libsodium.crypto_box_easy +import libsodium.crypto_box_easy_afternm +import libsodium.crypto_box_keypair +import libsodium.crypto_box_open_detached +import libsodium.crypto_box_seal +import libsodium.crypto_box_seal_open +import libsodium.crypto_box_seed_keypair + +actual object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + actual fun keypair(): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + crypto_box_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr()) + publicKeyPinned.unpin() + secretKeyPinned.unpin() + return BoxKeyPair(publicKey, secretKey) + } + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + val seed: UByteArray = UByteArray(crypto_box_SEEDBYTES) + val seedPinned = seed.pin() + crypto_box_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr()) + publicKeyPinned.unpin() + secretKeyPinned.unpin() + seedPinned.unpin() + return BoxKeyPair(publicKey, secretKey) + } + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + actual fun easy( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size - crypto_box_MACBYTES) + val ciphertextPinned = ciphertext.pin() + + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val recipientsPublicKeyPinned = recipientsPublicKey.pin() + val sendersSecretKeyPinned = sendersSecretKey.pin() + + crypto_box_easy( + ciphertextPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + recipientsPublicKeyPinned.toPtr(), + sendersSecretKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + recipientsPublicKeyPinned.unpin() + sendersSecretKeyPinned.unpin() + + return message + } + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size + crypto_box_MACBYTES) + val messagePinned = message.pin() + + val ciphertextPinned = ciphertext.pin() + val noncePinned = nonce.pin() + val sendersPublicKeyPinned = sendersPublicKey.pin() + val recipientsSecretKeyPinned = recipientsSecretKey.pin() + + crypto_box_easy( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + sendersPublicKeyPinned.toPtr(), + recipientsSecretKeyPinned.toPtr() + ) + + messagePinned.unpin() + ciphertextPinned.unpin() + noncePinned.unpin() + sendersPublicKeyPinned.unpin() + recipientsSecretKeyPinned.unpin() + + return message + } + + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray { + val sessionKey = UByteArray(crypto_box_BEFORENMBYTES) + + val sessionKeyPinned = sessionKey.pin() + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + + crypto_box_beforenm(sessionKeyPinned.toPtr(), publicKeyPinned.toPtr(), secretKeyPinned.toPtr()) + + sessionKeyPinned.unpin() + publicKeyPinned.unpin() + secretKeyPinned.unpin() + + return sessionKey + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun easyAfterNM( + message: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) + + val ciphertextPinned = ciphertext.pin() + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val precomputedKeyPinned = precomputedKey.pin() + + crypto_box_easy_afternm( + ciphertextPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + precomputedKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + precomputedKeyPinned.unpin() + + return ciphertext + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun openEasyAfterNM( + ciphertext: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) + + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val noncePinned = nonce.pin() + val precomputedKeyPinned = precomputedKey.pin() + + crypto_box_easy_afternm( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + noncePinned.toPtr(), + precomputedKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + precomputedKeyPinned.unpin() + + return ciphertext + } + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + actual fun detached( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): BoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val tag = UByteArray(crypto_box_MACBYTES) + + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val recipientsPublicKeyPinned = recipientsPublicKey.pin() + val sendersSecretKeyPinned = sendersSecretKey.pin() + + crypto_box_detached( + ciphertextPinned.toPtr(), + messagePinned.toPtr(), + tagPinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + recipientsPublicKeyPinned.toPtr(), + sendersSecretKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + tagPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + recipientsPublicKeyPinned.unpin() + sendersSecretKeyPinned.unpin() + + return BoxEncryptedDataAndTag(ciphertext, tag) + } + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + + val ciphertextPinned = ciphertext.pin() + val tagPinned = tag.pin() + + val messagePinned = message.pin() + val noncePinned = nonce.pin() + val recipientsSecretKeyPinned = recipientsSecretKey.pin() + val sendersPublicKeyPinned = sendersPublicKey.pin() + + + crypto_box_open_detached( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + tagPinned.toPtr(), + message.size.convert(), + noncePinned.toPtr(), + recipientsSecretKeyPinned.toPtr(), + sendersPublicKeyPinned.toPtr() + ) + + ciphertextPinned.unpin() + tagPinned.unpin() + messagePinned.unpin() + noncePinned.unpin() + recipientsSecretKeyPinned.unpin() + sendersPublicKeyPinned.unpin() + + return message + } + + actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray { + val ciphertextWithPublicKey = UByteArray(message.size + crypto_box_SEALBYTES) + + val ciphertextWithPublicKeyPinned = ciphertextWithPublicKey.pin() + val messagePinned = message.pin() + val recipientsPublicKeyPinned = recipientsPublicKey.pin() + + crypto_box_seal( + ciphertextWithPublicKeyPinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + recipientsPublicKeyPinned.toPtr() + ) + + ciphertextWithPublicKeyPinned.unpin() + messagePinned.unpin() + recipientsPublicKeyPinned.unpin() + + return message + + } + + actual fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES) + val messagePinned = message.pin() + val ciphertextPinned = ciphertext.pin() + val recipientsSecretKeyPinned = recipientsSecretKey.pin() + + crypto_box_seal_open(messagePinned.toPtr(), ciphertextPinned.toPtr(), recipientsSecretKeyPinned.toPtr()) + + messagePinned.unpin() + ciphertextPinned.unpin() + recipientsSecretKeyPinned.unpin() + + return message + } + + +} From 9cb27017155ca8c34f924eccb4a6af2ddd6e2477 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 1 Sep 2020 23:29:56 +0200 Subject: [PATCH 40/65] Added tests, fixed bugs --- .../com/ionspin/kotlin/crypto/box/BoxTest.kt | 96 +++++++++++++++++++ .../crypto/secretstream/SecretStreamTest.kt | 2 +- .../com/ionspin/kotlin/crypto/box/Box.kt | 61 ++++++++---- .../kotlin/crypto/secretbox/SecretBox.kt | 1 - .../crypto/secretstream/SecretStream.kt | 2 +- 5 files changed, 143 insertions(+), 19 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt new file mode 100644 index 0000000..e2cc2b7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt @@ -0,0 +1,96 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.random.Random +import kotlin.random.nextUBytes +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 01-Sep-2020 + */ +class BoxTest { + @Test + fun keypairTest() { + LibsodiumInitializer.initializeWithCallback { + val keypair = Box.keypair() + assertTrue { + keypair.publicKey.size == crypto_box_PUBLICKEYBYTES + } + assertTrue { + keypair.secretKey.size == crypto_box_SECRETKEYBYTES + } + } + } + + @Test + fun testBoxEasy() { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) + val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + assertTrue { + decrypted.contentEquals(message) + } + + assertFailsWith() { + val tampered = encrypted.copyOf() + tampered[1] = 0U + Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + } + } + + @Test + fun testBoxEasyDetached() { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val encrypted = Box.detached(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) + val decrypted = Box.openDetached(encrypted.ciphertext, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + assertTrue { + decrypted.contentEquals(message) + } + + assertFailsWith() { + val tampered = encrypted.ciphertext.copyOf() + tampered[1] = 0U + Box.openDetached(tampered, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + } + } + + @Test + fun testBeforeNonceAndMessage() { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val senderComputedSessionKey = Box.beforeNM(recipientKeypair.publicKey, senderKeypair.secretKey) + val recipientComputedSessionKey = Box.beforeNM(senderKeypair.publicKey, recipientKeypair.secretKey) + + assertTrue { + senderComputedSessionKey.contentEquals(recipientComputedSessionKey) + } + val encrypted = Box.easyAfterNM(message, messageNonce, senderComputedSessionKey) + val decrypted = Box.openEasyAfterNM(encrypted, messageNonce, recipientComputedSessionKey) + assertTrue { + decrypted.contentEquals(message) + } + + assertFailsWith() { + val tampered = encrypted.copyOf() + tampered[1] = 0U + Box.openEasyAfterNM(tampered, messageNonce, recipientComputedSessionKey) + } + } + + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt index 80c3d89..574891f 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamTest.kt @@ -73,7 +73,7 @@ class SecretStreamTest { assertTrue { decrypted.decryptedData.contentEquals(message) } - assertFailsWith(SecretStreamCorrupedOrTamperedDataException::class) { + assertFailsWith(SecretStreamCorruptedOrTamperedDataException::class) { encrypted[encrypted.size - 5] = 0U val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header) val decrypted = diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt index d293594..535c284 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.box +import com.ionspin.kotlin.crypto.util.toHexString import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.convert import kotlinx.cinterop.pin @@ -9,6 +10,8 @@ import libsodium.crypto_box_easy import libsodium.crypto_box_easy_afternm import libsodium.crypto_box_keypair import libsodium.crypto_box_open_detached +import libsodium.crypto_box_open_easy +import libsodium.crypto_box_open_easy_afternm import libsodium.crypto_box_seal import libsodium.crypto_box_seal_open import libsodium.crypto_box_seed_keypair @@ -38,7 +41,6 @@ actual object Box { val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) val publicKeyPinned = publicKey.pin() val secretKeyPinned = secretKey.pin() - val seed: UByteArray = UByteArray(crypto_box_SEEDBYTES) val seedPinned = seed.pin() crypto_box_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr()) publicKeyPinned.unpin() @@ -60,7 +62,7 @@ actual object Box { recipientsPublicKey: UByteArray, sendersSecretKey: UByteArray ): UByteArray { - val ciphertext = UByteArray(message.size - crypto_box_MACBYTES) + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) val ciphertextPinned = ciphertext.pin() val messagePinned = message.pin() @@ -83,7 +85,7 @@ actual object Box { recipientsPublicKeyPinned.unpin() sendersSecretKeyPinned.unpin() - return message + return ciphertext } /** @@ -99,7 +101,7 @@ actual object Box { sendersPublicKey: UByteArray, recipientsSecretKey: UByteArray ): UByteArray { - val message = UByteArray(ciphertext.size + crypto_box_MACBYTES) + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) val messagePinned = message.pin() val ciphertextPinned = ciphertext.pin() @@ -107,7 +109,7 @@ actual object Box { val sendersPublicKeyPinned = sendersPublicKey.pin() val recipientsSecretKeyPinned = recipientsSecretKey.pin() - crypto_box_easy( + val validationResult = crypto_box_open_easy( messagePinned.toPtr(), ciphertextPinned.toPtr(), ciphertext.size.convert(), @@ -122,6 +124,10 @@ actual object Box { sendersPublicKeyPinned.unpin() recipientsSecretKeyPinned.unpin() + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + return message } @@ -173,6 +179,8 @@ actual object Box { noncePinned.unpin() precomputedKeyPinned.unpin() + + return ciphertext } @@ -191,7 +199,7 @@ actual object Box { val noncePinned = nonce.pin() val precomputedKeyPinned = precomputedKey.pin() - crypto_box_easy_afternm( + val validationResult = crypto_box_open_easy_afternm( messagePinned.toPtr(), ciphertextPinned.toPtr(), ciphertext.size.convert(), @@ -204,7 +212,11 @@ actual object Box { noncePinned.unpin() precomputedKeyPinned.unpin() - return ciphertext + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message } /** @@ -232,8 +244,8 @@ actual object Box { crypto_box_detached( ciphertextPinned.toPtr(), - messagePinned.toPtr(), tagPinned.toPtr(), + messagePinned.toPtr(), message.size.convert(), noncePinned.toPtr(), recipientsPublicKeyPinned.toPtr(), @@ -246,7 +258,6 @@ actual object Box { noncePinned.unpin() recipientsPublicKeyPinned.unpin() sendersSecretKeyPinned.unpin() - return BoxEncryptedDataAndTag(ciphertext, tag) } @@ -265,23 +276,22 @@ actual object Box { ): UByteArray { val message = UByteArray(ciphertext.size) + val messagePinned = message.pin() val ciphertextPinned = ciphertext.pin() val tagPinned = tag.pin() - - val messagePinned = message.pin() val noncePinned = nonce.pin() val recipientsSecretKeyPinned = recipientsSecretKey.pin() val sendersPublicKeyPinned = sendersPublicKey.pin() - crypto_box_open_detached( + val validationResult = crypto_box_open_detached( messagePinned.toPtr(), ciphertextPinned.toPtr(), tagPinned.toPtr(), - message.size.convert(), + ciphertext.size.convert(), noncePinned.toPtr(), - recipientsSecretKeyPinned.toPtr(), - sendersPublicKeyPinned.toPtr() + sendersPublicKeyPinned.toPtr(), + recipientsSecretKeyPinned.toPtr() ) ciphertextPinned.unpin() @@ -291,6 +301,10 @@ actual object Box { recipientsSecretKeyPinned.unpin() sendersPublicKeyPinned.unpin() + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + return message } @@ -318,16 +332,31 @@ actual object Box { actual fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray): UByteArray { val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES) + val senderPublicKey = UByteArray(crypto_box_SEALBYTES) { + message[ciphertext.size - crypto_box_SEALBYTES + it - 1] + } + val senderPublicKeyPinned = senderPublicKey.pin() val messagePinned = message.pin() val ciphertextPinned = ciphertext.pin() val recipientsSecretKeyPinned = recipientsSecretKey.pin() - crypto_box_seal_open(messagePinned.toPtr(), ciphertextPinned.toPtr(), recipientsSecretKeyPinned.toPtr()) + val validationResult = crypto_box_seal_open( + messagePinned.toPtr(), + ciphertextPinned.toPtr(), + ciphertext.size.convert(), + senderPublicKeyPinned.toPtr(), + recipientsSecretKeyPinned.toPtr() + ) messagePinned.unpin() ciphertextPinned.unpin() + senderPublicKeyPinned.unpin() recipientsSecretKeyPinned.unpin() + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + return message } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt index 58b9882..b0da444 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretbox/SecretBox.kt @@ -1,6 +1,5 @@ package com.ionspin.kotlin.crypto.secretbox -import com.ionspin.kotlin.crypto.secretstream.SecretStreamCorrupedOrTamperedDataException import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.convert import kotlinx.cinterop.pin diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index b0df283..ce04cf0 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -116,7 +116,7 @@ actual object SecretStream { associatedDataPinned?.unpin() tagPinned.unpin() if (validationResult != 0) { - throw SecretStreamCorrupedOrTamperedDataException() + throw SecretStreamCorruptedOrTamperedDataException() } return DecryptedDataAndTag(message, tag[0]) } From 7a8640638cf8b123278ea7f8db3f54aee8aa9a08 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Thu, 10 Sep 2020 18:30:06 +0200 Subject: [PATCH 41/65] Added jvm implementation, fixed seal invalid return --- .../com.ionspin.kotlin.crypto/box/Box.kt | 2 +- .../com/ionspin/kotlin/crypto/box/BoxTest.kt | 108 +++++---- .../com/ionspin/kotlin/crypto/box/Box.kt | 229 ++++++++++++++++++ .../crypto/secretstream/SecretStreamJvm.kt | 2 +- .../com/ionspin/kotlin/crypto/box/Box.kt | 5 +- 5 files changed, 295 insertions(+), 51 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt index 5a6db9b..7fd4c2c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt @@ -87,4 +87,4 @@ expect object Box { fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray) : UByteArray -} +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt index e2cc2b7..f59122b 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt @@ -1,9 +1,7 @@ package com.ionspin.kotlin.crypto.box -import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint import com.ionspin.kotlin.crypto.LibsodiumInitializer import com.ionspin.kotlin.crypto.util.encodeToUByteArray -import com.ionspin.kotlin.crypto.util.toHexString import kotlin.random.Random import kotlin.random.nextUBytes import kotlin.test.Test @@ -31,64 +29,82 @@ class BoxTest { @Test fun testBoxEasy() { - val message = "Message message message".encodeToUByteArray() - val senderKeypair = Box.keypair() - val recipientKeypair = Box.keypair() - val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) - val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) - val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) - assertTrue { - decrypted.contentEquals(message) - } + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) + val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + assertTrue { + decrypted.contentEquals(message) + } - assertFailsWith() { - val tampered = encrypted.copyOf() - tampered[1] = 0U - Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + assertFailsWith() { + val tampered = encrypted.copyOf() + tampered[1] = 0U + Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + } } } @Test fun testBoxEasyDetached() { - val message = "Message message message".encodeToUByteArray() - val senderKeypair = Box.keypair() - val recipientKeypair = Box.keypair() - val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) - val encrypted = Box.detached(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) - val decrypted = Box.openDetached(encrypted.ciphertext, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) - assertTrue { - decrypted.contentEquals(message) - } + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val encrypted = Box.detached(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey) + val decrypted = Box.openDetached( + encrypted.ciphertext, + encrypted.tag, + messageNonce, + senderKeypair.publicKey, + recipientKeypair.secretKey + ) + assertTrue { + decrypted.contentEquals(message) + } - assertFailsWith() { - val tampered = encrypted.ciphertext.copyOf() - tampered[1] = 0U - Box.openDetached(tampered, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey) + assertFailsWith() { + val tampered = encrypted.ciphertext.copyOf() + tampered[1] = 0U + Box.openDetached( + tampered, + encrypted.tag, + messageNonce, + senderKeypair.publicKey, + recipientKeypair.secretKey + ) + } } } @Test fun testBeforeNonceAndMessage() { - val message = "Message message message".encodeToUByteArray() - val senderKeypair = Box.keypair() - val recipientKeypair = Box.keypair() - val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) - val senderComputedSessionKey = Box.beforeNM(recipientKeypair.publicKey, senderKeypair.secretKey) - val recipientComputedSessionKey = Box.beforeNM(senderKeypair.publicKey, recipientKeypair.secretKey) + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val senderKeypair = Box.keypair() + val recipientKeypair = Box.keypair() + val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES) + val senderComputedSessionKey = Box.beforeNM(recipientKeypair.publicKey, senderKeypair.secretKey) + val recipientComputedSessionKey = Box.beforeNM(senderKeypair.publicKey, recipientKeypair.secretKey) - assertTrue { - senderComputedSessionKey.contentEquals(recipientComputedSessionKey) - } - val encrypted = Box.easyAfterNM(message, messageNonce, senderComputedSessionKey) - val decrypted = Box.openEasyAfterNM(encrypted, messageNonce, recipientComputedSessionKey) - assertTrue { - decrypted.contentEquals(message) - } + assertTrue { + senderComputedSessionKey.contentEquals(recipientComputedSessionKey) + } + val encrypted = Box.easyAfterNM(message, messageNonce, senderComputedSessionKey) + val decrypted = Box.openEasyAfterNM(encrypted, messageNonce, recipientComputedSessionKey) + assertTrue { + decrypted.contentEquals(message) + } - assertFailsWith() { - val tampered = encrypted.copyOf() - tampered[1] = 0U - Box.openEasyAfterNM(tampered, messageNonce, recipientComputedSessionKey) + assertFailsWith() { + val tampered = encrypted.copyOf() + tampered[1] = 0U + Box.openEasyAfterNM(tampered, messageNonce, recipientComputedSessionKey) + } } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt new file mode 100644 index 0000000..9104d6b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -0,0 +1,229 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + actual fun keypair(): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + sodium.crypto_box_keypair(publicKey.asByteArray(), secretKey.asByteArray()) + return BoxKeyPair(publicKey, secretKey) + } + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): BoxKeyPair { + val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_box_SECRETKEYBYTES) + sodium.crypto_box_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray()) + return BoxKeyPair(publicKey, secretKey) + } + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + actual fun easy( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) + sodium.crypto_box_easy( + ciphertext.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + recipientsPublicKey.asByteArray(), + sendersSecretKey.asByteArray() + ) + return ciphertext + } + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) + val validationResult = sodium.crypto_box_open_easy( + message.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + sendersPublicKey.asByteArray(), + recipientsSecretKey.asByteArray() + ) + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray { + val sessionKey = UByteArray(crypto_box_BEFORENMBYTES) + sodium.crypto_box_beforenm(sessionKey.asByteArray(), publicKey.asByteArray(), secretKey.asByteArray()) + return sessionKey + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun easyAfterNM( + message: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val ciphertext = UByteArray(message.size + crypto_box_MACBYTES) + + sodium.crypto_box_easy_afternm( + ciphertext.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + precomputedKey.asByteArray() + ) + + return ciphertext + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun openEasyAfterNM( + ciphertext: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_MACBYTES) + val validationResult = sodium.crypto_box_open_easy_afternm( + message.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + precomputedKey.asByteArray() + ) + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + actual fun detached( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): BoxEncryptedDataAndTag { + val ciphertext = UByteArray(message.size) + val tag = UByteArray(crypto_box_MACBYTES) + + sodium.crypto_box_detached( + ciphertext.asByteArray(), + tag.asByteArray(), + message.asByteArray(), + message.size.toLong(), + nonce.asByteArray(), + recipientsPublicKey.asByteArray(), + sendersSecretKey.asByteArray() + ) + + return BoxEncryptedDataAndTag(ciphertext, tag) + } + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + val message = UByteArray(ciphertext.size) + + val validationResult = sodium.crypto_box_open_detached( + message.asByteArray(), + ciphertext.asByteArray(), + tag.asByteArray(), + ciphertext.size.toLong(), + nonce.asByteArray(), + sendersPublicKey.asByteArray(), + recipientsSecretKey.asByteArray() + ) + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray { + val ciphertextWithPublicKey = UByteArray(message.size + crypto_box_SEALBYTES) + sodium.crypto_box_seal( + ciphertextWithPublicKey.asByteArray(), + message.asByteArray(), + message.size.toLong(), + recipientsPublicKey.asByteArray() + ) + return ciphertextWithPublicKey + } + + actual fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray): UByteArray { + val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES) + val senderPublicKey = UByteArray(crypto_box_SEALBYTES) { + message[ciphertext.size - crypto_box_SEALBYTES + it - 1] + } + val validationResult = sodium.crypto_box_seal_open( + message.asByteArray(), + ciphertext.asByteArray(), + ciphertext.size.toLong(), + senderPublicKey.asByteArray(), + recipientsSecretKey.asByteArray() + ) + + if (validationResult != 0) { + throw BoxCorruptedOrTamperedDataException() + } + + return message + } + + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt index 72d1cf6..ca6470c 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStreamJvm.kt @@ -60,7 +60,7 @@ actual object SecretStream { associatedData.size.toLong() ) if (validationResult != 0) { - throw SecretStreamCorrupedOrTamperedDataException() + throw SecretStreamCorruptedOrTamperedDataException() } return DecryptedDataAndTag(result, tagArray[0]) } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt index 535c284..b803efa 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -1,6 +1,5 @@ package com.ionspin.kotlin.crypto.box -import com.ionspin.kotlin.crypto.util.toHexString import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.convert import kotlinx.cinterop.pin @@ -326,7 +325,7 @@ actual object Box { messagePinned.unpin() recipientsPublicKeyPinned.unpin() - return message + return ciphertextWithPublicKey } @@ -361,4 +360,4 @@ actual object Box { } -} +} \ No newline at end of file From 25fcd0cae29fdec00367a72099c785d13ae780eb Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Thu, 10 Sep 2020 20:50:14 +0200 Subject: [PATCH 42/65] Added seal box test, fxed seal box jvm implementation --- .../com.ionspin.kotlin.crypto/box/Box.kt | 2 +- .../com/ionspin/kotlin/crypto/box/BoxTest.kt | 20 +++++++++++++++++++ .../com/ionspin/kotlin/crypto/box/Box.kt | 7 ++----- .../com/ionspin/kotlin/crypto/box/Box.kt | 12 +++++------ 4 files changed, 28 insertions(+), 13 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt index 7fd4c2c..fdbc907 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/box/Box.kt @@ -85,6 +85,6 @@ expect object Box { fun seal(message: UByteArray, recipientsPublicKey: UByteArray) : UByteArray - fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray) : UByteArray + fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray) : UByteArray } \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt index f59122b..e1ebb59 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/box/BoxTest.kt @@ -108,5 +108,25 @@ class BoxTest { } } + @Test + fun testSeal() { + LibsodiumInitializer.initializeWithCallback { + val message = "Message message message".encodeToUByteArray() + val recipientKeypair = Box.keypair() + val sealed = Box.seal(message, recipientKeypair.publicKey) + val unsealed = Box.sealOpen(sealed, recipientKeypair.publicKey, recipientKeypair.secretKey) + + assertTrue { + unsealed.contentEquals(message) + } + + assertFailsWith() { + val tampered = sealed.copyOf() + tampered[1] = 0U + Box.sealOpen(tampered, recipientKeypair.publicKey, recipientKeypair.secretKey) + } + } + } + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt index 9104d6b..27b8be7 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -205,16 +205,13 @@ actual object Box { return ciphertextWithPublicKey } - actual fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray): UByteArray { + actual fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray): UByteArray { val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES) - val senderPublicKey = UByteArray(crypto_box_SEALBYTES) { - message[ciphertext.size - crypto_box_SEALBYTES + it - 1] - } val validationResult = sodium.crypto_box_seal_open( message.asByteArray(), ciphertext.asByteArray(), ciphertext.size.toLong(), - senderPublicKey.asByteArray(), + recipientsPublicKey.asByteArray(), recipientsSecretKey.asByteArray() ) diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt index b803efa..48f64c9 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -329,12 +329,10 @@ actual object Box { } - actual fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray): UByteArray { + actual fun sealOpen(ciphertext: UByteArray, recipientsPublicKey: UByteArray, recipientsSecretKey: UByteArray): UByteArray { val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES) - val senderPublicKey = UByteArray(crypto_box_SEALBYTES) { - message[ciphertext.size - crypto_box_SEALBYTES + it - 1] - } - val senderPublicKeyPinned = senderPublicKey.pin() + + val recipientsPublicKeyPinned = recipientsPublicKey.pin() val messagePinned = message.pin() val ciphertextPinned = ciphertext.pin() val recipientsSecretKeyPinned = recipientsSecretKey.pin() @@ -343,13 +341,13 @@ actual object Box { messagePinned.toPtr(), ciphertextPinned.toPtr(), ciphertext.size.convert(), - senderPublicKeyPinned.toPtr(), + recipientsPublicKeyPinned.toPtr(), recipientsSecretKeyPinned.toPtr() ) messagePinned.unpin() ciphertextPinned.unpin() - senderPublicKeyPinned.unpin() + recipientsPublicKeyPinned.unpin() recipientsSecretKeyPinned.unpin() if (validationResult != 0) { From 03a17f5b6a07c31e4d7100bfe0d60120dfdf65ed Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 11 Sep 2020 19:27:54 +0200 Subject: [PATCH 43/65] Added js box implementation --- .../kotlin/crypto/JsSodiumInterface.kt | 34 +++ .../com/ionspin/kotlin/crypto/box/Box.kt | 200 ++++++++++++++++++ .../crypto/secretstream/SecretStream.kt | 2 +- 3 files changed, 235 insertions(+), 1 deletion(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index 37880e3..ff9423d 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -1,6 +1,7 @@ package ext.libsodium.com.ionspin.kotlin.crypto +import com.ionspin.kotlin.crypto.box.BoxKeyPair import org.khronos.webgl.Uint8Array /** @@ -123,6 +124,39 @@ interface JsSodiumInterface { // ---- Auth end ---- + // ---- Box ---- + + fun crypto_box_keypair() : dynamic + fun crypto_box_seed_keypair(seed : Uint8Array) : dynamic + fun crypto_box_easy(message: Uint8Array, + nonce: Uint8Array, + recipientsPublicKey: Uint8Array, + sendersSecretKey: Uint8Array) : Uint8Array + fun crypto_box_open_easy(ciphertext: Uint8Array, + nonce: Uint8Array, + sendersPublicKey: Uint8Array, + recipientsSecretKey: Uint8Array) : Uint8Array + fun crypto_box_detached(message: Uint8Array, + nonce: Uint8Array, + recipientsPublicKey: Uint8Array, + sendersSecretKey: Uint8Array) : dynamic + fun crypto_box_open_detached(ciphertext: Uint8Array, + tag: Uint8Array, + nonce: Uint8Array, + sendersPublicKey: Uint8Array, + recipientsSecretKey: Uint8Array) : Uint8Array + fun crypto_box_beforenm(publicKey: Uint8Array, secretKey: Uint8Array) : Uint8Array + fun crypto_box_easy_afternm(message: Uint8Array, + nonce: Uint8Array, + precomputedKey: Uint8Array) : Uint8Array + fun crypto_box_open_easy_afternm(ciphertext: Uint8Array, + nonce: Uint8Array, + precomputedKey: Uint8Array) : Uint8Array + fun crypto_box_seal(message: Uint8Array, recipientsPublicKey: Uint8Array) : Uint8Array + fun crypto_box_seal_open(ciphertext: Uint8Array, recipientsPublicKey: Uint8Array, recipientsSecretKey: Uint8Array) : Uint8Array + + // ---- Box end ---- + //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt new file mode 100644 index 0000000..376f4a6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/box/Box.kt @@ -0,0 +1,200 @@ +package com.ionspin.kotlin.crypto.box + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual object Box { + /** + * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into + * sk (crypto_box_SECRETKEYBYTES bytes). + */ + actual fun keypair(): BoxKeyPair { + val keypair = getSodium().crypto_box_keypair() + return BoxKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): BoxKeyPair { + val keypair = getSodium().crypto_box_seed_keypair(seed.toUInt8Array()) + return BoxKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n. + * n should be crypto_box_NONCEBYTES bytes. + * c should be at least crypto_box_MACBYTES + mlen bytes long. + * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c, + * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen. + */ + actual fun easy( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): UByteArray { + return getSodium().crypto_box_easy( + message.toUInt8Array(), + nonce.toUInt8Array(), + recipientsPublicKey.toUInt8Array(), + sendersSecretKey.toUInt8Array(), + ).toUByteArray() + + } + + /** + * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy(). + * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message. + * The nonce n has to match the nonce used to encrypt and authenticate the message. + * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openEasy( + ciphertext: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_open_easy( + ciphertext.toUInt8Array(), + nonce.toUInt8Array(), + sendersPublicKey.toUInt8Array(), + recipientsSecretKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + + } + + /** + * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk, + * and puts it into k (crypto_box_BEFORENMBYTES bytes). + */ + actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray { + return getSodium().crypto_box_beforenm( + publicKey.toUInt8Array(), + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun easyAfterNM( + message: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + return getSodium().crypto_box_easy_afternm( + message.toUInt8Array(), + nonce.toUInt8Array(), + precomputedKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair. + */ + actual fun openEasyAfterNM( + ciphertext: UByteArray, + nonce: UByteArray, + precomputedKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_open_easy_afternm( + ciphertext.toUInt8Array(), + nonce.toUInt8Array(), + precomputedKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + } + + /** + * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose + * public key is pk, and puts the encrypted message into c. + * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag. + * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac. + */ + actual fun detached( + message: UByteArray, + nonce: UByteArray, + recipientsPublicKey: UByteArray, + sendersSecretKey: UByteArray + ): BoxEncryptedDataAndTag { + val detached = getSodium().crypto_box_detached( + message.toUInt8Array(), + nonce.toUInt8Array(), + recipientsPublicKey.toUInt8Array(), + sendersSecretKey.toUInt8Array(), + ) + return BoxEncryptedDataAndTag( + (detached.ciphertext as Uint8Array).toUByteArray(), + (detached.mac as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk. + * clen doesn't include the tag, so this length is the same as the plaintext. + * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k. + * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails. + */ + actual fun openDetached( + ciphertext: UByteArray, + tag: UByteArray, + nonce: UByteArray, + sendersPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_open_detached( + ciphertext.toUInt8Array(), + tag.toUInt8Array(), + nonce.toUInt8Array(), + sendersPublicKey.toUInt8Array(), + recipientsSecretKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + } + + actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray { + return getSodium().crypto_box_seal( + message.toUInt8Array(), + recipientsPublicKey.toUInt8Array() + ).toUByteArray() + } + + actual fun sealOpen( + ciphertext: UByteArray, + recipientsPublicKey: UByteArray, + recipientsSecretKey: UByteArray + ): UByteArray { + try { + return getSodium().crypto_box_seal_open( + ciphertext.toUInt8Array(), + recipientsPublicKey.toUInt8Array(), + recipientsSecretKey.toUInt8Array(), + ).toUByteArray() + } catch (error: Throwable) { + throw BoxCorruptedOrTamperedDataException() + } + } + + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt index 6152e60..27856e8 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/secretstream/SecretStream.kt @@ -41,7 +41,7 @@ actual object SecretStream { state, ciphertext.toUInt8Array(), associatedData.toUInt8Array() ) if (dataAndTag == false) { - throw SecretStreamCorrupedOrTamperedDataException() + throw SecretStreamCorruptedOrTamperedDataException() } return DecryptedDataAndTag((dataAndTag.message as Uint8Array).toUByteArray(), dataAndTag.tag) From 21aea687b2f38fcc4e6af013b66da6c31921abe4 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 13 Sep 2020 16:12:53 +0200 Subject: [PATCH 44/65] Updated bindings list to include crypto_box --- supported_bindings_list.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 47b0102..e2fb823 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -34,20 +34,20 @@ | crypto_auth_hmacsha512_verify | :heavy_check_mark: | | crypto_auth_keygen | :heavy_check_mark: | | crypto_auth_verify | :heavy_check_mark: | -| crypto_box_beforenm | | +| crypto_box_beforenm | :heavy_check_mark: | | crypto_box_curve25519xchacha20poly1305_keypair | not present in LazySodium | | crypto_box_curve25519xchacha20poly1305_seal | not present in LazySodium | | crypto_box_curve25519xchacha20poly1305_seal_open |not present in LazySodium | -| crypto_box_detached | | -| crypto_box_easy | | -| crypto_box_easy_afternm | | -| crypto_box_keypair | | -| crypto_box_open_detached | | -| crypto_box_open_easy | | -| crypto_box_open_easy_afternm | | -| crypto_box_seal | | -| crypto_box_seal_open | | -| crypto_box_seed_keypair | | +| crypto_box_detached | :heavy_check_mark: | +| crypto_box_easy | :heavy_check_mark: | +| crypto_box_easy_afternm | :heavy_check_mark: | +| crypto_box_keypair | :heavy_check_mark: | +| crypto_box_open_detached | :heavy_check_mark: | +| crypto_box_open_easy | :heavy_check_mark: | +| crypto_box_open_easy_afternm | :heavy_check_mark: | +| crypto_box_seal | :heavy_check_mark: | +| crypto_box_seal_open | :heavy_check_mark: | +| crypto_box_seed_keypair | :heavy_check_mark: | | crypto_core_ristretto255_add | | | crypto_core_ristretto255_from_hash | | | crypto_core_ristretto255_is_valid_point | | From 1936e748ae2d8053890f113b5038269809325dc5 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 13 Sep 2020 17:11:59 +0200 Subject: [PATCH 45/65] Adding common crypto_sign, called signature because object named Sign could be confusing --- .../signature/Signature.kt | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt new file mode 100644 index 0000000..4a9c70b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt @@ -0,0 +1,73 @@ +package com.ionspin.kotlin.crypto.signature + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 13/Sep/2020 + */ +expect class SignatureState + +data class SignKeyPair(val publicKey: UByteArray, val secretKey: UByteArray) + +const val crypto_sign_BYTES = 64 +const val crypto_sign_SEEDBYTES = 32 +const val crypto_sign_PUBLICKEYBYTES = 32 +const val crypto_sign_SECRETKEY2BYTES = 64 + +class InvalidSignatureException() : RuntimeException("Signature validation failed") + +expect object Signature { + fun init(): SignatureState + fun update(state: SignatureState, data: UByteArray) + fun finalCreate(state: SignatureState, secretKey: UByteArray): UByteArray + fun finalVerify(state: SignatureState, signature: UByteArray, publicKey: UByteArray) + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + fun keypair(): SignKeyPair + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + fun seedKeypair(seed: UByteArray): SignKeyPair + + /** + * The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is crypto_sign_BYTES + mlen bytes long. + */ + fun sign(message : UByteArray, secretKey : UByteArray) : UByteArray + + /** + * The crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + fun open(signedMessage: UByteArray, publicKey: UByteArray) : UByteArray + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to crypto_sign_BYTES bytes long. + */ + fun detached(message: UByteArray, secretKey: UByteArray): UByteArray + + /** + * The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + fun verifyDetached(signature: UByteArray, message: UByteArray, publicKey: UByteArray): Boolean + fun ed25519PkToCurve25519() + fun ed25519SkToCurve25519() + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + fun ed25519SkToSeed(secretKey : UByteArray) : UByteArray + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + fun ed25519SkToPk(secretKey: UByteArray) : UByteArray +} \ No newline at end of file From b0ce2e10fcec2f3f41d692a45d08289ce20d6a4d Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Mon, 14 Sep 2020 18:51:25 +0200 Subject: [PATCH 46/65] Adding _sign_ native implementation and started writing tests --- .../signature/Signature.kt | 22 +- .../kotlin/crypto/signature/SignatureTest.kt | 32 +++ .../kotlin/crypto/signature/Signature.kt | 268 ++++++++++++++++++ 3 files changed, 315 insertions(+), 7 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt index 4a9c70b..4f7a22a 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/signature/Signature.kt @@ -5,12 +5,13 @@ package com.ionspin.kotlin.crypto.signature */ expect class SignatureState -data class SignKeyPair(val publicKey: UByteArray, val secretKey: UByteArray) +data class SignatureKeyPair(val publicKey: UByteArray, val secretKey: UByteArray) const val crypto_sign_BYTES = 64 const val crypto_sign_SEEDBYTES = 32 const val crypto_sign_PUBLICKEYBYTES = 32 -const val crypto_sign_SECRETKEY2BYTES = 64 +const val crypto_sign_SECRETKEYBYTES = 64 +const val crypto_scalarmult_curve25519_BYTES = 32 class InvalidSignatureException() : RuntimeException("Signature validation failed") @@ -24,14 +25,14 @@ expect object Signature { * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). */ - fun keypair(): SignKeyPair + fun keypair(): SignatureKeyPair /** * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). */ - fun seedKeypair(seed: UByteArray): SignKeyPair + fun seedKeypair(seed: UByteArray): SignatureKeyPair /** * The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. @@ -56,9 +57,16 @@ expect object Signature { * The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length * is mlen bytes, using the signer's public key pk. */ - fun verifyDetached(signature: UByteArray, message: UByteArray, publicKey: UByteArray): Boolean - fun ed25519PkToCurve25519() - fun ed25519SkToCurve25519() + fun verifyDetached(signature: UByteArray, message: UByteArray, publicKey: UByteArray) + /** + * The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray + + /** + * The crypto_sign_ed25519_sk_to_curve25519() function converts an Ed25519 secret key ed25519_sk to an X25519 secret key and stores it into x25519_sk. + */ + fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray /** * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt new file mode 100644 index 0000000..508dbf2 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt @@ -0,0 +1,32 @@ +package com.ionspin.kotlin.crypto.signature + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Sep/2020 + */ +class SignatureTest { + + @Test + fun testSignAndVerify() { + LibsodiumInitializer.initializeWithCallback { + val keys = Signature.keypair() + val message = "Some text that will be signed".encodeToUByteArray() + val signedMessage = Signature.sign(message, keys.secretKey) + val verifiedMessage = Signature.open(signedMessage, keys.publicKey) + assertTrue { + verifiedMessage.contentEquals(message) + } + assertFailsWith(InvalidSignatureException::class) { + val tamperedMessage = signedMessage.copyOf() + tamperedMessage[crypto_sign_BYTES + 1] = 0U + Signature.open(tamperedMessage, keys.publicKey) + } + } + + } +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt new file mode 100644 index 0000000..69a1dcc --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt @@ -0,0 +1,268 @@ +package com.ionspin.kotlin.crypto.signature + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.* +import libsodium.* +import platform.posix.malloc + +actual typealias SignatureState = crypto_sign_ed25519ph_state + +actual object Signature { + actual fun init(): SignatureState { + val stateAllocated = malloc(SignatureState.size.convert()) + val statePointed = stateAllocated!!.reinterpret().pointed + crypto_sign_init(statePointed.ptr) + return statePointed + } + + actual fun update(state: SignatureState, data: UByteArray) { + val dataPinned = data.pin() + crypto_sign_update(state.ptr, dataPinned.toPtr(), data.size.convert()) + dataPinned.unpin() + } + + actual fun finalCreate( + state: SignatureState, + secretKey: UByteArray + ): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + val secretKeyPinned = secretKey.pin() + val signaturePinned = signature.pin() + crypto_sign_final_create( + state.ptr, + signaturePinned.toPtr(), + null, + secretKeyPinned.toPtr() + ) + secretKeyPinned.unpin() + signaturePinned.unpin() + return signature + } + + actual fun finalVerify( + state: SignatureState, + signature: UByteArray, + publicKey: UByteArray + ) { + val signaturePinned = signature.pin() + val publicKeyPinned = publicKey.pin() + val verificationResult = crypto_sign_final_verify( + state.ptr, + signaturePinned.toPtr(), + publicKeyPinned.toPtr() + ) + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + actual fun keypair(): SignatureKeyPair { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign_keypair( + publicKeyPinned.toPtr(), + secretKeyPinned.toPtr(), + ) + publicKeyPinned.unpin() + secretKeyPinned.unpin() + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): SignatureKeyPair { + val seedPinned = seed.pin() + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + val publicKeyPinned = publicKey.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign_seed_keypair( + publicKeyPinned.toPtr(), + secretKeyPinned.toPtr(), + seedPinned.toPtr() + ) + seedPinned.unpin() + publicKeyPinned.unpin() + secretKeyPinned.unpin() + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is crypto_sign_BYTES + mlen bytes long. + */ + actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray { + val signedMessage = UByteArray(message.size + crypto_sign_BYTES) + val signedMessagePinned = signedMessage.pin() + val messagePinned = message.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign( + signedMessagePinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + secretKeyPinned.toPtr() + ) + signedMessagePinned.unpin() + messagePinned.unpin() + secretKeyPinned.unpin() + + return signedMessage + } + + /** + * The crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray { + val message = UByteArray(signedMessage.size - crypto_sign_BYTES) + val messagePinned = message.pin() + val signedMessagePinned = signedMessage.pin() + val publicKeyPinned = publicKey.pin() + + val verificationResult = crypto_sign_open( + messagePinned.toPtr(), + null, + signedMessagePinned.toPtr(), + signedMessage.size.convert(), + publicKeyPinned.toPtr() + ) + if (verificationResult == -1) { + throw InvalidSignatureException() + } + return message + } + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to crypto_sign_BYTES bytes long. + */ + actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + val signaturePinned = signature.pin() + val messagePinned = message.pin() + val secretKeyPinned = secretKey.pin() + crypto_sign_detached( + signaturePinned.toPtr(), + null, + messagePinned.toPtr(), + message.size.convert(), + secretKeyPinned.toPtr() + ) + signaturePinned.unpin() + messagePinned.unpin() + secretKeyPinned.unpin() + + return signature + } + + /** + * The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + actual fun verifyDetached( + signature: UByteArray, + message: UByteArray, + publicKey: UByteArray + ) { + val signaturePinned = signature.pin() + val messagePinned = message.pin() + val publicKeyPinned = publicKey.pin() + val verificationResult = crypto_sign_verify_detached( + signaturePinned.toPtr(), + messagePinned.toPtr(), + message.size.convert(), + publicKeyPinned.toPtr() + ) + signaturePinned.unpin() + messagePinned.unpin() + publicKeyPinned.unpin() + + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray { + val x25519PublicKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + val x25519PublicKeyPinned = x25519PublicKey.pin() + val ed25519PublicKeyPinned = ed25519PublicKey.pin() + crypto_sign_ed25519_sk_to_curve25519( + x25519PublicKeyPinned.toPtr(), + ed25519PublicKeyPinned.toPtr() + ) + x25519PublicKeyPinned.unpin() + ed25519PublicKeyPinned.unpin() + return x25519PublicKey + } + + actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray { + val x25519SecretKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + val x25519SecretKeyPinned = x25519SecretKey.pin() + val ed25519SecretKeyPinned = ed25519SecretKey.pin() + crypto_sign_ed25519_sk_to_curve25519( + x25519SecretKeyPinned.toPtr(), + ed25519SecretKeyPinned.toPtr() + ) + x25519SecretKeyPinned.unpin() + ed25519SecretKeyPinned.unpin() + return x25519SecretKey + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray { + val seed = UByteArray(crypto_sign_SEEDBYTES) + + val secretKeyPinned = secretKey.pin() + val seedPinned = seed.pin() + + crypto_sign_ed25519_sk_to_seed( + seedPinned.toPtr(), + secretKeyPinned.toPtr() + ) + + secretKeyPinned.unpin() + seedPinned.unpin() + + return seed + + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + + val secretKeyPinned = secretKey.pin() + val publicKeyPinned = publicKey.pin() + + crypto_sign_ed25519_sk_to_pk( + publicKeyPinned.toPtr(), + secretKeyPinned.toPtr() + ) + + secretKeyPinned.unpin() + publicKeyPinned.unpin() + + return publicKey + } + +} \ No newline at end of file From 37a5cdb2d004996c75fa5680e57737db833e7a40 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 15 Sep 2020 13:02:43 +0200 Subject: [PATCH 47/65] Added jvm _sign_ implementation --- .../kotlin/crypto/signature/SignatureTest.kt | 37 ++++ .../kotlin/crypto/signature/SignatureJvm.kt | 209 ++++++++++++++++++ .../kotlin/crypto/signature/Signature.kt | 7 + 3 files changed, 253 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/signature/SignatureJvm.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt index 508dbf2..17f22e6 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/signature/SignatureTest.kt @@ -29,4 +29,41 @@ class SignatureTest { } } + + @Test + fun testDetachedSignAndVerify() { + LibsodiumInitializer.initializeWithCallback { + val keys = Signature.keypair() + val message = "Some text that will be signed".encodeToUByteArray() + val signature = Signature.detached(message, keys.secretKey) + val verifiedMessage = Signature.verifyDetached(signature, message, keys.publicKey) + assertFailsWith(InvalidSignatureException::class) { + val tamperedSignature = signature.copyOf() + tamperedSignature[crypto_sign_BYTES - 1] = 0U + Signature.verifyDetached(tamperedSignature, message, keys.publicKey) + } + } + } + + @Test + fun testMultipart() { + LibsodiumInitializer.initializeWithCallback { + val keys = Signature.keypair() + val message1 = "Some text that ".encodeToUByteArray() + val message2 = "will be signed".encodeToUByteArray() + val state = Signature.init() + Signature.update(state, message1) + Signature.update(state, message2) + val signature = Signature.finalCreate(state, keys.secretKey) + val verificationState = Signature.init() + Signature.update(verificationState, message1) + Signature.update(verificationState, message2) + Signature.finalVerify(verificationState, signature, keys.publicKey) + assertFailsWith(InvalidSignatureException::class) { + val tamperedSignature = signature.copyOf() + tamperedSignature[crypto_sign_BYTES - 1] = 0U + Signature.finalVerify(verificationState, tamperedSignature, keys.publicKey) + } + } + } } \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/signature/SignatureJvm.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/signature/SignatureJvm.kt new file mode 100644 index 0000000..56f022b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/signature/SignatureJvm.kt @@ -0,0 +1,209 @@ +package com.ionspin.kotlin.crypto.signature + +import com.goterl.lazycode.lazysodium.interfaces.Sign +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual typealias SignatureState = Sign.StateCryptoSign + +actual object Signature { + actual fun init(): SignatureState { + return SignatureState() + } + + actual fun update(state: SignatureState, data: UByteArray) { + sodium.crypto_sign_update(state, data.asByteArray(), data.size.toLong()) + } + + actual fun finalCreate( + state: SignatureState, + secretKey: UByteArray + ): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + sodium.crypto_sign_final_create( + state, + signature.asByteArray(), + null, + secretKey.asByteArray() + ) + return signature + } + + actual fun finalVerify( + state: SignatureState, + signature: UByteArray, + publicKey: UByteArray + ) { + val verificationResult = sodium.crypto_sign_final_verify( + state, + signature.asByteArray(), + publicKey.asByteArray() + ) + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + actual fun keypair(): SignatureKeyPair { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + sodium.crypto_sign_keypair( + publicKey.asByteArray(), + secretKey.asByteArray(), + ) + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): SignatureKeyPair { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + val secretKey = UByteArray(crypto_sign_SECRETKEYBYTES) + + + sodium.crypto_sign_seed_keypair( + publicKey.asByteArray(), + secretKey.asByteArray(), + seed.asByteArray() + ) + return SignatureKeyPair(publicKey, secretKey) + } + + /** + * The sodium.crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is sodium.crypto_sign_BYTES + mlen bytes long. + */ + actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray { + val signedMessage = UByteArray(message.size + crypto_sign_BYTES) + + sodium.crypto_sign( + signedMessage.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + secretKey.asByteArray() + ) + + return signedMessage + } + + /** + * The sodium.crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray { + val message = UByteArray(signedMessage.size - crypto_sign_BYTES) + + val verificationResult = sodium.crypto_sign_open( + message.asByteArray(), + null, + signedMessage.asByteArray(), + signedMessage.size.toLong(), + publicKey.asByteArray() + ) + if (verificationResult == -1) { + throw InvalidSignatureException() + } + return message + } + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The sodium.crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to sodium.crypto_sign_BYTES bytes long. + */ + actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray { + val signature = UByteArray(crypto_sign_BYTES) + + sodium.crypto_sign_detached( + signature.asByteArray(), + null, + message.asByteArray(), + message.size.toLong(), + secretKey.asByteArray() + ) + + return signature + } + + /** + * The sodium.crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + actual fun verifyDetached( + signature: UByteArray, + message: UByteArray, + publicKey: UByteArray + ) { + + val verificationResult = sodium.crypto_sign_verify_detached( + signature.asByteArray(), + message.asByteArray(), + message.size.toLong(), + publicKey.asByteArray() + ) + + if (verificationResult == -1) { + throw InvalidSignatureException() + } + } + + /** + * The sodium.crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray) : UByteArray { + val x25519PublicKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + sodium.crypto_sign_ed25519_sk_to_curve25519( + x25519PublicKey.asByteArray(), + ed25519PublicKey.asByteArray() + ) + return x25519PublicKey + } + + actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray) : UByteArray { + val x25519SecretKey = UByteArray(crypto_scalarmult_curve25519_BYTES) + sodium.crypto_sign_ed25519_sk_to_curve25519( + x25519SecretKey.asByteArray(), + ed25519SecretKey.asByteArray() + ) + return x25519SecretKey + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray { + val seed = UByteArray(crypto_sign_SEEDBYTES) + + sodium.crypto_sign_ed25519_sk_to_seed( + seed.asByteArray(), + secretKey.asByteArray() + ) + + return seed + + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to sodium.crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray { + val publicKey = UByteArray(crypto_sign_PUBLICKEYBYTES) + + sodium.crypto_sign_ed25519_sk_to_pk( + publicKey.asByteArray(), + secretKey.asByteArray() + ) + + return publicKey + } + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt index 69a1dcc..722ec37 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt @@ -51,6 +51,10 @@ actual object Signature { signaturePinned.toPtr(), publicKeyPinned.toPtr() ) + + signaturePinned.unpin() + publicKeyPinned.unpin() + if (verificationResult == -1) { throw InvalidSignatureException() } @@ -136,6 +140,9 @@ actual object Signature { signedMessage.size.convert(), publicKeyPinned.toPtr() ) + messagePinned.unpin() + signedMessagePinned.unpin() + publicKeyPinned.unpin() if (verificationResult == -1) { throw InvalidSignatureException() } From a24fa342960d95fc624aab301bba964de133bfcf Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 15 Sep 2020 14:00:03 +0200 Subject: [PATCH 48/65] Added _sign_ js implementation --- .../kotlin/crypto/JsSodiumInterface.kt | 19 +++ .../kotlin/crypto/signature/Signature.kt | 161 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index ff9423d..d7caf7d 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -157,6 +157,25 @@ interface JsSodiumInterface { // ---- Box end ---- + // ---- Sign start ---- + fun crypto_sign(message: Uint8Array, secretKey: Uint8Array) : Uint8Array + fun crypto_sign_detached(message: Uint8Array, secretKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_pk_to_curve25519(ed25519PublicKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_sk_to_curve25519(ed25519SecretKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_sk_to_pk(ed25519SecretKey: Uint8Array) : Uint8Array + fun crypto_sign_ed25519_sk_to_seed(ed25519SecretKey: Uint8Array) : Uint8Array + fun crypto_sign_final_create(state: dynamic, secretKey: Uint8Array) : Uint8Array + fun crypto_sign_final_verify(state: dynamic, signature: Uint8Array, publicKey: Uint8Array) : Boolean + fun crypto_sign_init() : dynamic + fun crypto_sign_keypair() : dynamic + fun crypto_sign_open(signedMessage: Uint8Array, publicKey: Uint8Array) : Uint8Array + fun crypto_sign_seed_keypair(seed: Uint8Array) : dynamic + fun crypto_sign_update(state: dynamic, message: Uint8Array) + fun crypto_sign_verify_detached(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array) : Boolean + + + // ---- Sign end + //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt new file mode 100644 index 0000000..6b6fb3b --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/signature/Signature.kt @@ -0,0 +1,161 @@ +package com.ionspin.kotlin.crypto.signature + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array +import org.khronos.webgl.Uint8Array + +actual typealias SignatureState = Any + +actual object Signature { + actual fun init(): SignatureState { + return getSodium().crypto_sign_init() + } + + actual fun update(state: SignatureState, data: UByteArray) { + getSodium().crypto_sign_update(state, data.toUInt8Array()) + } + + actual fun finalCreate( + state: SignatureState, + secretKey: UByteArray + ): UByteArray { + return getSodium().crypto_sign_final_create( + state, + secretKey.toUInt8Array() + ).toUByteArray() + } + + actual fun finalVerify( + state: SignatureState, + signature: UByteArray, + publicKey: UByteArray + ) { + val verificationResult = getSodium().crypto_sign_final_verify( + state, + signature.toUInt8Array(), + publicKey.toUInt8Array() + ) + if (verificationResult == false) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + */ + actual fun keypair(): SignatureKeyPair { + val keypair = getSodium().crypto_sign_keypair() + return SignatureKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_sign_keypair() function randomly generates a secret key and a corresponding public key. + * The public key is put into pk (crypto_sign_PUBLICKEYBYTES bytes) and the secret key into sk (crypto_sign_SECRETKEYBYTES bytes). + * Using crypto_sign_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_sign_SEEDBYTES bytes). + */ + actual fun seedKeypair(seed: UByteArray): SignatureKeyPair { + val keypair = getSodium().crypto_sign_seed_keypair(seed.toUInt8Array()) + return SignatureKeyPair( + (keypair.publicKey as Uint8Array).toUByteArray(), + (keypair.privateKey as Uint8Array).toUByteArray() + ) + } + + /** + * The crypto_sign() function prepends a signature to a message m whose length is mlen bytes, using the secret key sk. + * The signed message, which includes the signature + a plain copy of the message, is put into sm, and is crypto_sign_BYTES + mlen bytes long. + */ + actual fun sign(message: UByteArray, secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign( + message.toUInt8Array(), + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_sign_open() function checks that the signed message sm whose length is smlen bytes has a valid signature for the public key pk. + * If the signature is doesn't appear to be valid, the function throws an exception + */ + actual fun open(signedMessage: UByteArray, publicKey: UByteArray): UByteArray { + try { + return getSodium().crypto_sign_open( + signedMessage.toUInt8Array(), + publicKey.toUInt8Array() + ).toUByteArray() + } catch (error : Throwable) { + throw InvalidSignatureException() + } + } + + /** + * In detached mode, the signature is stored without attaching a copy of the original message to it. + * The crypto_sign_detached() function signs the message m whose length is mlen bytes, using the secret key sk, + * and puts the signature into sig, which can be up to crypto_sign_BYTES bytes long. + */ + actual fun detached(message: UByteArray, secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_detached( + message.toUInt8Array(), + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_sign_verify_detached() function verifies that sig is a valid signature for the message m whose length + * is mlen bytes, using the signer's public key pk. + */ + actual fun verifyDetached(signature: UByteArray, message: UByteArray, publicKey: UByteArray) { + val verificationResult = getSodium().crypto_sign_verify_detached( + signature.toUInt8Array(), + message.toUInt8Array(), + publicKey.toUInt8Array() + ) + + if (verificationResult == false) { + throw InvalidSignatureException() + } + } + + /** + * The crypto_sign_ed25519_pk_to_curve25519() function converts an Ed25519 public key ed25519_pk to an X25519 public key and stores it into x25519_pk. + */ + actual fun ed25519PkToCurve25519(ed25519PublicKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_pk_to_curve25519( + ed25519PublicKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_sign_ed25519_sk_to_curve25519() function converts an Ed25519 secret key ed25519_sk to an X25519 secret key and stores it into x25519_sk. + */ + actual fun ed25519SkToCurve25519(ed25519SecretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_sk_to_curve25519( + ed25519SecretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToSeed(secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_sk_to_seed( + secretKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The secret key actually includes the seed (either a random seed or the one given to crypto_sign_seed_keypair()) as well as the public key. + * While the public key can always be derived from the seed, the precomputation saves a significant amount of CPU cycles when signing. + */ + actual fun ed25519SkToPk(secretKey: UByteArray): UByteArray { + return getSodium().crypto_sign_ed25519_sk_to_pk( + secretKey.toUInt8Array() + ).toUByteArray() + } + +} \ No newline at end of file From 25c46341804d06f4169adba91af10e639a909ced Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 15 Sep 2020 14:01:00 +0200 Subject: [PATCH 49/65] Update implemented list --- supported_bindings_list.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/supported_bindings_list.md b/supported_bindings_list.md index e2fb823..cf9a0f3 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -114,20 +114,20 @@ | crypto_shorthash |:heavy_check_mark: | | crypto_shorthash_keygen | :heavy_check_mark: | | crypto_shorthash_siphashx24 | | -| crypto_sign | | -| crypto_sign_detached | | -| crypto_sign_ed25519_pk_to_curve25519 | | -| crypto_sign_ed25519_sk_to_curve25519 | | -| crypto_sign_ed25519_sk_to_pk | | -| crypto_sign_ed25519_sk_to_seed | | -| crypto_sign_final_create | | -| crypto_sign_final_verify | | -| crypto_sign_init | | -| crypto_sign_keypair | | -| crypto_sign_open | | -| crypto_sign_seed_keypair | | -| crypto_sign_update | | -| crypto_sign_verify_detached | | +| crypto_sign | :heavy_check_mark: | +| crypto_sign_detached | :heavy_check_mark: | +| crypto_sign_ed25519_pk_to_curve25519 | :heavy_check_mark: | +| crypto_sign_ed25519_sk_to_curve25519 | :heavy_check_mark: | +| crypto_sign_ed25519_sk_to_pk | :heavy_check_mark: | +| crypto_sign_ed25519_sk_to_seed | :heavy_check_mark: | +| crypto_sign_final_create | :heavy_check_mark: | +| crypto_sign_final_verify | :heavy_check_mark: | +| crypto_sign_init | :heavy_check_mark: | +| crypto_sign_keypair | :heavy_check_mark: | +| crypto_sign_open | :heavy_check_mark: | +| crypto_sign_seed_keypair | :heavy_check_mark: | +| crypto_sign_update | :heavy_check_mark: | +| crypto_sign_verify_detached | :heavy_check_mark: | | crypto_stream_chacha20 | | | crypto_stream_chacha20_ietf_xor | | | crypto_stream_chacha20_ietf_xor_ic | | From 7b2c08c2638a22c7273f3ae44c7a7d0845c1d520 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 15 Sep 2020 14:02:20 +0200 Subject: [PATCH 50/65] Typo fixed --- supported_bindings_list.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/supported_bindings_list.md b/supported_bindings_list.md index cf9a0f3..92f3c0c 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -68,14 +68,14 @@ | crypto_generichash_keygen | :heavy_check_mark: | | crypto_generichash_update | :heavy_check_mark: | | crypto_hash | | -| crypto_hash_sha256 | :heavy_check_mark | -| crypto_hash_sha256_final | :heavy_check_mark | -| crypto_hash_sha256_init | :heavy_check_mark | -| crypto_hash_sha256_update | :heavy_check_mark | -| crypto_hash_sha512 | :heavy_check_mark | -| crypto_hash_sha512_final | :heavy_check_mark | -| crypto_hash_sha512_init | :heavy_check_mark | -| crypto_hash_sha512_update | :heavy_check_mark | +| crypto_hash_sha256 | :heavy_check_mark: | +| crypto_hash_sha256_final | :heavy_check_mark: | +| crypto_hash_sha256_init | :heavy_check_mark: | +| crypto_hash_sha256_update | :heavy_check_mark: | +| crypto_hash_sha512 | :heavy_check_mark: | +| crypto_hash_sha512_final | :heavy_check_mark: | +| crypto_hash_sha512_init | :heavy_check_mark: | +| crypto_hash_sha512_update | :heavy_check_mark: | | crypto_kdf_derive_from_key | | | crypto_kdf_keygen | | | crypto_kx_client_session_keys | | From 5c387545ab3a34e42858edf9df8a7cd846c37f3d Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 15 Sep 2020 14:04:52 +0200 Subject: [PATCH 51/65] Add constants to the implemented list --- supported_bindings_list.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 92f3c0c..7125753 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -302,7 +302,7 @@ | crypto_pwhash_scryptsalsa208sha256_STRBYTES | | | crypto_scalarmult_BYTES | | | crypto_scalarmult_SCALARBYTES | | -| crypto_scalarmult_curve25519_BYTES | | +| crypto_scalarmult_curve25519_BYTES | :heavy_check_mark: | | crypto_scalarmult_curve25519_SCALARBYTES | | | crypto_scalarmult_ed25519_BYTES | | | crypto_scalarmult_ed25519_SCALARBYTES | | @@ -334,11 +334,11 @@ | crypto_shorthash_siphash24_KEYBYTES | | | crypto_shorthash_siphashx24_BYTES | | | crypto_shorthash_siphashx24_KEYBYTES | | -| crypto_sign_BYTES | | +| crypto_sign_BYTES | :heavy_check_mark: | | crypto_sign_MESSAGEBYTES_MAX | | -| crypto_sign_PUBLICKEYBYTES | | -| crypto_sign_SECRETKEYBYTES | | -| crypto_sign_SEEDBYTES | | +| crypto_sign_PUBLICKEYBYTES | :heavy_check_mark: | +| crypto_sign_SECRETKEYBYTES | :heavy_check_mark: | +| crypto_sign_SEEDBYTES | :heavy_check_mark: | | crypto_sign_ed25519_BYTES | | | crypto_sign_ed25519_MESSAGEBYTES_MAX | | | crypto_sign_ed25519_PUBLICKEYBYTES | | From 8b26764938822a328424f758198ffde855660f99 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Wed, 16 Sep 2020 14:09:14 +0200 Subject: [PATCH 52/65] Added _kdf_ all implementations and a simple and probably pointless test, also noted which functions are not available as they are not part of LazySodium --- .../com.ionspin.kotlin.crypto/kdf/Kdf.kt | 33 ++++++++++ .../com/ionspin/kotlin/crypto/kdf/KdfTest.kt | 34 ++++++++++ .../kotlin/crypto/JsSodiumInterface.kt | 10 ++- .../com/ionspin/kotlin/crypto/kdf/Kdf.kt | 43 ++++++++++++ .../com/ionspin/kotlin/crypto/kdf/Kdf.kt | 49 ++++++++++++++ .../com/ionspin/kotlin/crypto/kdf/Kdf.kt | 66 +++++++++++++++++++ supported_bindings_list.md | 56 ++++++++-------- 7 files changed, 262 insertions(+), 29 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/kdf/Kdf.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/kdf/KdfTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/kdf/Kdf.kt new file mode 100644 index 0000000..4c64812 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/kdf/Kdf.kt @@ -0,0 +1,33 @@ +package com.ionspin.kotlin.crypto.kdf + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 16/Sep/2020 + */ +const val crypto_kdf_PRIMITIVE = "blake2b" +const val crypto_kdf_BYTES_MIN = 16 +const val crypto_kdf_BYTES_MAX = 64 +const val crypto_kdf_CONTEXTBYTES = 8 +const val crypto_kdf_KEYBYTES = 32 + +expect object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + fun deriveFromKey(subkeyId: Int, subkeyLength: Int, context: String, masterKey: UByteArray) : UByteArray + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + fun keygen() : UByteArray +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/kdf/KdfTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/kdf/KdfTest.kt new file mode 100644 index 0000000..06c4f99 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/kdf/KdfTest.kt @@ -0,0 +1,34 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import kotlin.test.Test +import kotlin.test.assertFails +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 16/Sep/2020 + */ +class KdfTest { + @Test + fun testKdf() { + LibsodiumInitializer.initializeWithCallback { + val masterKey = Kdf.keygen() + val subkey1 = Kdf.deriveFromKey(1, crypto_kdf_BYTES_MAX, "test1234", masterKey) + val subkey2 = Kdf.deriveFromKey(2, crypto_kdf_BYTES_MAX, "test1234", masterKey) + + assertTrue { + subkey1.size == crypto_kdf_BYTES_MAX && + subkey2.size == crypto_kdf_BYTES_MAX + } + + val repeatSubkey1 = Kdf.deriveFromKey(1, crypto_kdf_BYTES_MAX, "test1234", masterKey) + assertTrue { + subkey1.contentEquals(repeatSubkey1) + } + assertFalse { + subkey1.contentEquals(subkey2) + } + } + } +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index d7caf7d..d97fe22 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -174,7 +174,15 @@ interface JsSodiumInterface { fun crypto_sign_verify_detached(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array) : Boolean - // ---- Sign end + // ---- Sign end ---- + + + // ---- KDF ---- + + fun crypto_kdf_derive_from_key(subkey_len: UInt, subkeyId : UInt, ctx: String, key: Uint8Array) : Uint8Array + fun crypto_kdf_keygen() : Uint8Array + + // ---- KDF end ----- //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt new file mode 100644 index 0000000..1866909 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt @@ -0,0 +1,43 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + actual fun deriveFromKey( + subkeyId: Int, + subkeyLength: Int, + context: String, + masterKey: UByteArray + ): UByteArray { + return getSodium().crypto_kdf_derive_from_key( + subkeyLength.toUInt(), + subkeyId.toUInt(), + context, + masterKey.toUInt8Array() + ).toUByteArray() + } + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + actual fun keygen(): UByteArray { + return getSodium().crypto_kdf_keygen().toUByteArray() + } + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt new file mode 100644 index 0000000..7df70a6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt @@ -0,0 +1,49 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +actual object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + actual fun deriveFromKey( + subkeyId: Int, + subkeyLength: Int, + context: String, + masterKey: UByteArray + ): UByteArray { + val subkey = UByteArray(subkeyLength) + val contextEncoded = context.encodeToByteArray() + + sodium.crypto_kdf_derive_from_key( + subkey.asByteArray(), + subkeyLength, + subkeyId.toLong(), + contextEncoded, + masterKey.asByteArray() + ) + + return subkey + } + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + actual fun keygen(): UByteArray { + val masterKey = UByteArray(crypto_kdf_KEYBYTES) + sodium.crypto_kdf_keygen(masterKey.asByteArray()) + return masterKey + } + +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt new file mode 100644 index 0000000..972ce15 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/kdf/Kdf.kt @@ -0,0 +1,66 @@ +package com.ionspin.kotlin.crypto.kdf + +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_kdf_derive_from_key +import libsodium.crypto_kdf_keygen + +actual object Kdf { + /** + * The crypto_kdf_derive_from_key() function derives a subkey_id-th subkey subkey of length subkey_len bytes using + * the master key key and the context ctx. + * subkey_id can be any value up to (2^64)-1. + * subkey_len has to be between crypto_kdf_BYTES_MIN (inclusive) and crypto_kdf_BYTES_MAX (inclusive). + * Similar to a type, the context ctx is a 8 characters string describing what the key is going to be used for. + * Its purpose is to mitigate accidental bugs by separating domains. The same function used with the same key but + * in two distinct contexts is likely to generate two different outputs. + * Contexts don't have to be secret and can have a low entropy. + * Examples of contexts include UserName, __auth__, pictures and userdata. + * They must be crypto_kdf_CONTEXTBYTES bytes long. + * If more convenient, it is also fine to use a single global context for a whole application. This will still + * prevent the same keys from being mistakenly used by another application. + */ + actual fun deriveFromKey( + subkeyId: Int, + subkeyLength: Int, + context: String, + masterKey: UByteArray + ): UByteArray { + val subkey = UByteArray(subkeyLength) + val contextEncoded = context.encodeToByteArray() + + val contextEncodedAndPinned = contextEncoded.pin() + val masterKeyPinned = masterKey.pin() + val subkeyPinned = subkey.pin() + crypto_kdf_derive_from_key( + subkeyPinned.toPtr(), + subkeyLength.convert(), + subkeyId.convert(), + contextEncodedAndPinned.addressOf(0), + masterKeyPinned.toPtr() + ) + + contextEncodedAndPinned.unpin() + masterKeyPinned.unpin() + subkeyPinned.unpin() + + return subkey + + + } + + /** + * The crypto_kdf_keygen() function creates a master key. + */ + actual fun keygen(): UByteArray { + val masterKey = UByteArray(crypto_kdf_KEYBYTES) + val masterKeyPinned = masterKey.pin() + crypto_kdf_keygen(masterKeyPinned.toPtr()) + masterKeyPinned.unpin() + return masterKey + } + +} \ No newline at end of file diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 7125753..5f15aa3 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -48,19 +48,19 @@ | crypto_box_seal | :heavy_check_mark: | | crypto_box_seal_open | :heavy_check_mark: | | crypto_box_seed_keypair | :heavy_check_mark: | -| crypto_core_ristretto255_add | | -| crypto_core_ristretto255_from_hash | | -| crypto_core_ristretto255_is_valid_point | | -| crypto_core_ristretto255_random | | -| crypto_core_ristretto255_scalar_add | | -| crypto_core_ristretto255_scalar_complement | | -| crypto_core_ristretto255_scalar_invert | | -| crypto_core_ristretto255_scalar_mul | | -| crypto_core_ristretto255_scalar_negate | | -| crypto_core_ristretto255_scalar_random | | -| crypto_core_ristretto255_scalar_reduce | | -| crypto_core_ristretto255_scalar_sub | | -| crypto_core_ristretto255_sub | | +| crypto_core_ristretto255_add | not present in LazySodium | +| crypto_core_ristretto255_from_hash | not present in LazySodium | +| crypto_core_ristretto255_is_valid_point | not present in LazySodium | +| crypto_core_ristretto255_random | not present in LazySodium | +| crypto_core_ristretto255_scalar_add | not present in LazySodium | +| crypto_core_ristretto255_scalar_complement | not present in LazySodium | +| crypto_core_ristretto255_scalar_invert | not present in LazySodium | +| crypto_core_ristretto255_scalar_mul | not present in LazySodium | +| crypto_core_ristretto255_scalar_negate | not present in LazySodium | +| crypto_core_ristretto255_scalar_random | not present in LazySodium | +| crypto_core_ristretto255_scalar_reduce | not present in LazySodium | +| crypto_core_ristretto255_scalar_sub | not present in LazySodium | +| crypto_core_ristretto255_sub | not present in LazySodium | | crypto_generichash | :heavy_check_mark: | | crypto_generichash_blake2b_salt_personal | | | crypto_generichash_final | :heavy_check_mark: | @@ -76,23 +76,23 @@ | crypto_hash_sha512_final | :heavy_check_mark: | | crypto_hash_sha512_init | :heavy_check_mark: | | crypto_hash_sha512_update | :heavy_check_mark: | -| crypto_kdf_derive_from_key | | -| crypto_kdf_keygen | | +| crypto_kdf_derive_from_key | :heavy_check_mark: | +| crypto_kdf_keygen | :heavy_check_mark: | | crypto_kx_client_session_keys | | | crypto_kx_keypair | | | crypto_kx_seed_keypair | | | crypto_kx_server_session_keys | | -| crypto_onetimeauth | | -| crypto_onetimeauth_final | | -| crypto_onetimeauth_init | | -| crypto_onetimeauth_keygen | | -| crypto_onetimeauth_update | | -| crypto_onetimeauth_verify | | +| crypto_onetimeauth | not present in LazySodium | +| crypto_onetimeauth_final | not present in LazySodium | +| crypto_onetimeauth_init | not present in LazySodium | +| crypto_onetimeauth_keygen | not present in LazySodium | +| crypto_onetimeauth_update | not present in LazySodium | +| crypto_onetimeauth_verify | not present in LazySodium | | crypto_pwhash | | -| crypto_pwhash_scryptsalsa208sha256 | | -| crypto_pwhash_scryptsalsa208sha256_ll | | -| crypto_pwhash_scryptsalsa208sha256_str | | -| crypto_pwhash_scryptsalsa208sha256_str_verify | | +| crypto_pwhash_scryptsalsa208sha256 | not present in LazySodium for Android | +| crypto_pwhash_scryptsalsa208sha256_ll | not present in LazySodium for Android | +| crypto_pwhash_scryptsalsa208sha256_str | not present in LazySodium for Android | +| crypto_pwhash_scryptsalsa208sha256_str_verify | not present in LazySodium for Android | | crypto_pwhash_str | | | crypto_pwhash_str_needs_rehash | | | crypto_pwhash_str_verify | | @@ -135,9 +135,9 @@ | crypto_stream_chacha20_xor | | | crypto_stream_chacha20_xor_ic | | | crypto_stream_keygen | | -| crypto_stream_xchacha20_keygen | | -| crypto_stream_xchacha20_xor | | -| crypto_stream_xchacha20_xor_ic | | +| crypto_stream_xchacha20_keygen | not present in LazySodium Android | +| crypto_stream_xchacha20_xor | not present in LazySodium Android| +| crypto_stream_xchacha20_xor_ic | not present in LazySodium Android | | randombytes_buf | | | randombytes_buf_deterministic | | | randombytes_close | | From 65bf54765f71e51e679aa9951cfb5829a252f224 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Thu, 17 Sep 2020 18:20:24 +0200 Subject: [PATCH 53/65] Adding _pwhash_ --- .../pwhash/PasswordHash.kt | 68 +++++++++++++ .../kotlin/crypto/pwhash/PasswordHash.kt | 97 +++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt new file mode 100644 index 0000000..8fe6e9d --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt @@ -0,0 +1,68 @@ +package com.ionspin.kotlin.crypto.pwhash + +/** + * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 17/Sep/2020 + */ + + +const val crypto_pwhash_BYTES_MIN = 16U +const val crypto_pwhash_MEMLIMIT_INTERACTIVE = 67108864U +const val crypto_pwhash_MEMLIMIT_MIN = 8192U +const val crypto_pwhash_MEMLIMIT_MODERATE = 268435456U +const val crypto_pwhash_MEMLIMIT_SENSITIVE = 1073741824U +const val crypto_pwhash_OPSLIMIT_INTERACTIVE = 2U +const val crypto_pwhash_OPSLIMIT_MAX = 4294967295U +const val crypto_pwhash_OPSLIMIT_MIN = 1U +const val crypto_pwhash_OPSLIMIT_MODERATE = 3U +const val crypto_pwhash_OPSLIMIT_SENSITIVE = 4U +const val crypto_pwhash_PASSWD_MAX = 4294967295U +const val crypto_pwhash_PASSWD_MIN = 0U +const val crypto_pwhash_SALTBYTES = 16U +const val crypto_pwhash_STRBYTES = 128U +const val crypto_pwhash_STRPREFIX = "\$argon2id$" + +val crypto_pwhash_argon2id_ALG_ARGON2ID13 = 2 +val crypto_pwhash_argon2i_ALG_ARGON2I13 = 1 +val crypto_pwhash_ALG_DEFAULT = crypto_pwhash_argon2id_ALG_ARGON2ID13 + +class PasswordHashFailed() : RuntimeException("Password hashing failed") + +expect object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * PASSWD_MIN and crypto_pwhash_PASSWD_MAX. outlen should be at least crypto_pwhash_BYTES_MIN = 16 (128 bits) and + * at most crypto_pwhash_BYTES_MAX. + * + * See https://libsodium.gitbook.io/doc/password_hashing/default_phf for more details + */ + fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ): UByteArray + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + fun str(password: String, opslimit: ULong, memlimit: Int): String + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + fun strNeedsRehash(password: String, opslimit: ULong, memlimit: Int): Boolean + fun strVerify(passwordHash: String, password: UByteArray): Boolean +} \ No newline at end of file diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt new file mode 100644 index 0000000..1e5bf37 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -0,0 +1,97 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.util.toPtr +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.crypto_pwhash +import libsodium.crypto_pwhash_str +import libsodium.crypto_pwhash_str_needs_rehash + +actual object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * PASSWD_MIN and crypto_pwhash_PASSWD_MAX. outlen should be at least crypto_pwhash_BYTES_MIN = 16 (128 bits) and + * at most crypto_pwhash_BYTES_MAX. + * + * See https://libsodium.gitbook.io/doc/password_hashing/default_phf for more details + */ + actual fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ) : UByteArray { + val hashedPassword = UByteArray(outputLength) + + val hashedPasswordPinned = hashedPassword.pin() + val saltPinned = salt.pin() + + crypto_pwhash( + hashedPasswordPinned.toPtr(), + outputLength.convert(), + password, + password.length.convert(), + saltPinned.toPtr(), + opsLimit, + memLimit.convert(), + algorithm + ) + saltPinned.unpin() + hashedPasswordPinned.unpin() + + return hashedPassword + } + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + actual fun str(password: String, opslimit: ULong, memlimit: Int): String { + val output = ByteArray(crypto_pwhash_STRBYTES.toInt()) + val outputPinned = output.pin() + crypto_pwhash_str( + outputPinned.addressOf(0), + password, + password.length.convert(), + opslimit, + memlimit.convert() + ) + outputPinned.unpin() + + return output.decodeToString() + } + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + actual fun strNeedsRehash( + password: String, + opslimit: ULong, + memlimit: Int + ): Boolean { + val password = password.encodeToByteArray() + crypto_pwhash_str_needs_rehash( + , + opslimit, + memlimit.convert() + ) + } + + actual fun strVerify(passwordHash: String, password: UByteArray): Boolean { + TODO("Not yet implemented") + } + +} \ No newline at end of file From 2b4d8aa4b16b53ec59a22564cfde777cc979578c Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Mon, 21 Sep 2020 19:07:06 +0200 Subject: [PATCH 54/65] Adding pwhash native and tests --- .../pwhash/PasswordHash.kt | 41 +++++++------ .../kotlin/crypto/pwhash/PasswordHashTest.kt | 57 +++++++++++++++++++ .../kotlin/crypto/pwhash/PasswordHash.kt | 41 +++++++++---- test | 0 4 files changed, 110 insertions(+), 29 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt create mode 100644 test diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt index 8fe6e9d..75f5ab8 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/pwhash/PasswordHash.kt @@ -7,25 +7,25 @@ package com.ionspin.kotlin.crypto.pwhash const val crypto_pwhash_BYTES_MIN = 16U const val crypto_pwhash_MEMLIMIT_INTERACTIVE = 67108864U -const val crypto_pwhash_MEMLIMIT_MIN = 8192U -const val crypto_pwhash_MEMLIMIT_MODERATE = 268435456U -const val crypto_pwhash_MEMLIMIT_SENSITIVE = 1073741824U -const val crypto_pwhash_OPSLIMIT_INTERACTIVE = 2U -const val crypto_pwhash_OPSLIMIT_MAX = 4294967295U -const val crypto_pwhash_OPSLIMIT_MIN = 1U -const val crypto_pwhash_OPSLIMIT_MODERATE = 3U -const val crypto_pwhash_OPSLIMIT_SENSITIVE = 4U -const val crypto_pwhash_PASSWD_MAX = 4294967295U -const val crypto_pwhash_PASSWD_MIN = 0U -const val crypto_pwhash_SALTBYTES = 16U -const val crypto_pwhash_STRBYTES = 128U +const val crypto_pwhash_MEMLIMIT_MIN = 8192 +const val crypto_pwhash_MEMLIMIT_MODERATE = 268435456 +const val crypto_pwhash_MEMLIMIT_SENSITIVE = 1073741824 +const val crypto_pwhash_OPSLIMIT_INTERACTIVE = 2 +const val crypto_pwhash_OPSLIMIT_MAX = 4294967295UL +const val crypto_pwhash_OPSLIMIT_MIN = 1UL +const val crypto_pwhash_OPSLIMIT_MODERATE = 3UL +const val crypto_pwhash_OPSLIMIT_SENSITIVE = 4UL +const val crypto_pwhash_PASSWD_MAX = 4294967295 +const val crypto_pwhash_PASSWD_MIN = 0 +const val crypto_pwhash_SALTBYTES = 16 +const val crypto_pwhash_STRBYTES = 128 const val crypto_pwhash_STRPREFIX = "\$argon2id$" val crypto_pwhash_argon2id_ALG_ARGON2ID13 = 2 val crypto_pwhash_argon2i_ALG_ARGON2I13 = 1 val crypto_pwhash_ALG_DEFAULT = crypto_pwhash_argon2id_ALG_ARGON2ID13 -class PasswordHashFailed() : RuntimeException("Password hashing failed") +class PasswordHashingFailed() : RuntimeException("Password hashing failed") expect object PasswordHash { /** @@ -55,7 +55,7 @@ expect object PasswordHash { * and other data stores. No extra information has to be stored in order to verify the password. * The function returns 0 on success and -1 if it didn't complete successfully. */ - fun str(password: String, opslimit: ULong, memlimit: Int): String + fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray /** * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. @@ -63,6 +63,13 @@ expect object PasswordHash { * The function returns 0 if the parameters already match the given ones. * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. */ - fun strNeedsRehash(password: String, opslimit: ULong, memlimit: Int): Boolean - fun strVerify(passwordHash: String, password: UByteArray): Boolean -} \ No newline at end of file + fun strNeedsRehash(passwordHash: UByteArray, opslimit: ULong, memlimit: Int): Int + + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * It returns 0 if the verification succeeds, and -1 on error. + */ + fun strVerify(passwordHash: UByteArray, password: String): Boolean + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt new file mode 100644 index 0000000..7f463c8 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt @@ -0,0 +1,57 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.util.toHexString +import kotlin.random.Random +import kotlin.random.nextUBytes +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 21-Sep-2020 + */ +class PasswordHashTest { + @Test + fun testPasswordHash() { + val randomBytes = Random(0).nextUBytes(crypto_pwhash_SALTBYTES) + val password = "correct horse battery staple" + val hashedPassword = PasswordHash.pwhash( + 64, + password, + randomBytes, + crypto_pwhash_OPSLIMIT_MIN, + crypto_pwhash_MEMLIMIT_MIN, + crypto_pwhash_ALG_DEFAULT + ) + println("Hashed password: ${hashedPassword.toHexString()}") + } + + @Test + fun testPasswordHashForStorage() { + val password = "correct horse battery staple" + val hashedPassword = PasswordHash.str( + password, + crypto_pwhash_OPSLIMIT_MIN, + crypto_pwhash_MEMLIMIT_MIN + ) + println("Hashed password for storage: ${hashedPassword.toHexString()}") + + assertTrue { + PasswordHash.strVerify( + hashedPassword, + password + ) + } + + assertTrue { + PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_MIN) == 0 + } + + assertTrue { + PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_SENSITIVE) == 1 + } + + //TODO strNeedsRehash -1 case? + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt index 1e5bf37..20a4381 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -4,9 +4,11 @@ import com.ionspin.kotlin.crypto.util.toPtr import kotlinx.cinterop.addressOf import kotlinx.cinterop.convert import kotlinx.cinterop.pin +import kotlinx.cinterop.toCValues import libsodium.crypto_pwhash import libsodium.crypto_pwhash_str import libsodium.crypto_pwhash_str_needs_rehash +import libsodium.crypto_pwhash_str_verify actual object PasswordHash { /** @@ -30,7 +32,7 @@ actual object PasswordHash { val hashedPasswordPinned = hashedPassword.pin() val saltPinned = salt.pin() - crypto_pwhash( + val hashingResult = crypto_pwhash( hashedPasswordPinned.toPtr(), outputLength.convert(), password, @@ -42,6 +44,9 @@ actual object PasswordHash { ) saltPinned.unpin() hashedPasswordPinned.unpin() + if (hashingResult != 0) { + throw PasswordHashingFailed() + } return hashedPassword } @@ -56,8 +61,8 @@ actual object PasswordHash { * and other data stores. No extra information has to be stored in order to verify the password. * The function returns 0 on success and -1 if it didn't complete successfully. */ - actual fun str(password: String, opslimit: ULong, memlimit: Int): String { - val output = ByteArray(crypto_pwhash_STRBYTES.toInt()) + actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { + val output = ByteArray(crypto_pwhash_STRBYTES) val outputPinned = output.pin() crypto_pwhash_str( outputPinned.addressOf(0), @@ -68,7 +73,7 @@ actual object PasswordHash { ) outputPinned.unpin() - return output.decodeToString() + return output.asUByteArray() } /** @@ -78,20 +83,32 @@ actual object PasswordHash { * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. */ actual fun strNeedsRehash( - password: String, + passwordHash: UByteArray, opslimit: ULong, memlimit: Int - ): Boolean { - val password = password.encodeToByteArray() - crypto_pwhash_str_needs_rehash( - , + ): Int { + val result = crypto_pwhash_str_needs_rehash( + passwordHash.asByteArray().toCValues(), opslimit, memlimit.convert() ) + return result + + } - actual fun strVerify(passwordHash: String, password: UByteArray): Boolean { - TODO("Not yet implemented") + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * It returns 0 if the verification succeeds, and -1 on error. + */ + actual fun strVerify(passwordHash: UByteArray, password: String): Boolean { + val result = crypto_pwhash_str_verify( + passwordHash.asByteArray().toCValues(), + password, + password.length.convert() + ) + return result == 0 } -} \ No newline at end of file +} diff --git a/test b/test new file mode 100644 index 0000000..e69de29 From fe4134a65f77a366e2376087909ecc071f02409b Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Mon, 21 Sep 2020 22:13:36 +0200 Subject: [PATCH 55/65] Added java implementation of _pwhash_ --- .../kotlin/crypto/pwhash/PasswordHashTest.kt | 70 ++++++++------ .../kotlin/crypto/pwhash/PasswordHash.kt | 94 +++++++++++++++++++ 2 files changed, 134 insertions(+), 30 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt index 7f463c8..942ac78 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHashTest.kt @@ -1,5 +1,6 @@ package com.ionspin.kotlin.crypto.pwhash +import com.ionspin.kotlin.crypto.LibsodiumInitializer import com.ionspin.kotlin.crypto.util.toHexString import kotlin.random.Random import kotlin.random.nextUBytes @@ -14,44 +15,53 @@ import kotlin.test.assertTrue class PasswordHashTest { @Test fun testPasswordHash() { - val randomBytes = Random(0).nextUBytes(crypto_pwhash_SALTBYTES) - val password = "correct horse battery staple" - val hashedPassword = PasswordHash.pwhash( - 64, - password, - randomBytes, - crypto_pwhash_OPSLIMIT_MIN, - crypto_pwhash_MEMLIMIT_MIN, - crypto_pwhash_ALG_DEFAULT - ) - println("Hashed password: ${hashedPassword.toHexString()}") + LibsodiumInitializer.initializeWithCallback { + val randomBytes = Random(0).nextUBytes(crypto_pwhash_SALTBYTES) + val password = "correct horse battery staple" + val hashedPassword = PasswordHash.pwhash( + 64, + password, + randomBytes, + crypto_pwhash_OPSLIMIT_MIN, + crypto_pwhash_MEMLIMIT_MIN, + crypto_pwhash_ALG_DEFAULT + ) + println("Hashed password: ${hashedPassword.toHexString()}") + assertTrue { + hashedPassword.toHexString().equals("e762ee529e90e3bbc242c23e8e2f963ab9a17ed9e79f89a00c71261a979207b2213cc" + + "0330c53f410a9c8933c46e8642dc542efc0660c69e255b601c7244ef6b0") + } + } } @Test fun testPasswordHashForStorage() { - val password = "correct horse battery staple" - val hashedPassword = PasswordHash.str( - password, - crypto_pwhash_OPSLIMIT_MIN, - crypto_pwhash_MEMLIMIT_MIN - ) - println("Hashed password for storage: ${hashedPassword.toHexString()}") - assertTrue { - PasswordHash.strVerify( - hashedPassword, - password + LibsodiumInitializer.initializeWithCallback { + val password = "correct horse battery staple" + val hashedPassword = PasswordHash.str( + password, + crypto_pwhash_OPSLIMIT_MIN, + crypto_pwhash_MEMLIMIT_MIN ) - } + println("Hashed password for storage: ${hashedPassword.toHexString()}") - assertTrue { - PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_MIN) == 0 - } + assertTrue { + PasswordHash.strVerify( + hashedPassword, + password + ) + } - assertTrue { - PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_SENSITIVE) == 1 - } + assertTrue { + PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_MIN) == 0 + } - //TODO strNeedsRehash -1 case? + assertTrue { + PasswordHash.strNeedsRehash(hashedPassword, crypto_pwhash_OPSLIMIT_MIN, crypto_pwhash_MEMLIMIT_SENSITIVE) == 1 + } + + //TODO strNeedsRehash -1 case? + } } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt new file mode 100644 index 0000000..93999ca --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -0,0 +1,94 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium +import com.sun.jna.NativeLong + +actual object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * PASSWD_MIN and crypto_pwhash_PASSWD_MAX. outlen should be at least crypto_pwhash_BYTES_MIN = 16 (128 bits) and + * at most crypto_pwhash_BYTES_MAX. + * + * See https://libsodium.gitbook.io/doc/password_hashing/default_phf for more details + */ + actual fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ): UByteArray { + val hashedPassword = UByteArray(outputLength) + + sodium.crypto_pwhash( + hashedPassword.asByteArray(), + outputLength.toLong(), + password.encodeToByteArray(), + password.length.toLong(), + salt.asByteArray(), + opsLimit.toLong(), + NativeLong(memLimit.toLong()), + algorithm + ) + + return hashedPassword + } + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { + val output = ByteArray(crypto_pwhash_STRBYTES) + sodium.crypto_pwhash_str( + output, + password.encodeToByteArray(), + password.length.toLong(), + opslimit.toLong(), + NativeLong(memlimit.toLong()) + ) + return output.asUByteArray() + } + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + actual fun strNeedsRehash( + passwordHash: UByteArray, + opslimit: ULong, + memlimit: Int + ): Int { + return sodium.crypto_pwhash_str_needs_rehash( + passwordHash.asByteArray(), + opslimit.toLong(), + NativeLong(memlimit.toLong()) + ) + } + + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * It returns 0 if the verification succeeds, and -1 on error. + */ + actual fun strVerify(passwordHash: UByteArray, password: String): Boolean { + val result = sodium.crypto_pwhash_str_verify( + passwordHash.asByteArray(), + password.encodeToByteArray(), + password.length.toLong() + ) + + return result == 0 + } + +} From a44935a10e554415b841f7b7325492756a8148f8 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 22 Sep 2020 20:54:02 +0200 Subject: [PATCH 56/65] Added js _pwhash_ --- .../kotlin/crypto/JsSodiumInterface.kt | 11 +++ .../kotlin/crypto/pwhash/PasswordHash.kt | 89 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index d97fe22..a6b9b7a 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -184,6 +184,17 @@ interface JsSodiumInterface { // ---- KDF end ----- + // ---- Password hashing ---- + + fun crypto_pwhash(keyLength : UInt, password : Uint8Array, salt: Uint8Array, opsLimit: UInt, memLimit: UInt, algorithm: UInt) : Uint8Array + fun crypto_pwhash_str(password: Uint8Array, opsLimit: UInt, memLimit: UInt) : String + fun crypto_pwhash_str_needs_rehash(hashedPassword: String, opsLimit: UInt, memLimit: UInt) : Boolean + fun crypto_pwhash_str_verify(hashedPassword: String, password: Uint8Array) : Boolean + + + // ---- Password hashing end ---- + + //util fun memzero(array: Uint8Array) diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt new file mode 100644 index 0000000..9cc13b7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/pwhash/PasswordHash.kt @@ -0,0 +1,89 @@ +package com.ionspin.kotlin.crypto.pwhash + +import com.ionspin.kotlin.crypto.getSodium +import com.ionspin.kotlin.crypto.util.encodeToUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual object PasswordHash { + /** + * The crypto_pwhash() function derives an outlen bytes long key from a password passwd whose length is passwdlen + * and a salt salt whose fixed length is crypto_pwhash_SALTBYTES bytes. passwdlen should be at least crypto_pwhash_ + * PASSWD_MIN and crypto_pwhash_PASSWD_MAX. outlen should be at least crypto_pwhash_BYTES_MIN = 16 (128 bits) and + * at most crypto_pwhash_BYTES_MAX. + * + * See https://libsodium.gitbook.io/doc/password_hashing/default_phf for more details + */ + actual fun pwhash( + outputLength: Int, + password: String, + salt: UByteArray, + opsLimit: ULong, + memLimit: Int, + algorithm: Int + ): UByteArray { + return getSodium().crypto_pwhash( + outputLength.toUInt(), + password.encodeToUByteArray().toUInt8Array(), + salt.toUInt8Array(), + opsLimit.toUInt(), + memLimit.toUInt(), + algorithm.toUInt() + ).toUByteArray() + } + + /** + * The crypto_pwhash_str() function puts an ASCII encoded string into out, which includes: + * the result of a memory-hard, CPU-intensive hash function applied to the password passwd of length passwdlen + * the automatically generated salt used for the previous computation + * the other parameters required to verify the password, including the algorithm identifier, its version, opslimit and memlimit. + * out must be large enough to hold crypto_pwhash_STRBYTES bytes, but the actual output string may be shorter. + * The output string is zero-terminated, includes only ASCII characters and can be safely stored into SQL databases + * and other data stores. No extra information has to be stored in order to verify the password. + * The function returns 0 on success and -1 if it didn't complete successfully. + */ + actual fun str(password: String, opslimit: ULong, memlimit: Int): UByteArray { + return getSodium().crypto_pwhash_str( + password.encodeToUByteArray().toUInt8Array(), + opslimit.toUInt(), + memlimit.toUInt() + ).encodeToUByteArray() + } + + /** + * Check if a password verification string str matches the parameters opslimit and memlimit, and the current default algorithm. + * The function returns 1 if the string appears to be correct, but doesn't match the given parameters. In that situation, applications may want to compute a new hash using the current parameters the next time the user logs in. + * The function returns 0 if the parameters already match the given ones. + * It returns -1 on error. If it happens, applications may want to compute a correct hash the next time the user logs in. + */ + actual fun strNeedsRehash( + passwordHash: UByteArray, + opslimit: ULong, + memlimit: Int + ): Int { + return if ( + getSodium().crypto_pwhash_str_needs_rehash( + passwordHash.asByteArray().decodeToString(), + opslimit.toUInt(), + memlimit.toUInt() + ) + ) { + 1 + } else { + 0 + } + } + + /** + * his function verifies that str is a valid password verification string (as generated by crypto_pwhash_str()) for passwd whose length is passwdlen. + * str has to be zero-terminated. + * It returns 0 if the verification succeeds, and -1 on error. + */ + actual fun strVerify(passwordHash: UByteArray, password: String): Boolean { + return getSodium().crypto_pwhash_str_verify( + passwordHash.asByteArray().decodeToString(), + password.encodeToUByteArray().toUInt8Array() + ) + } + +} From eb65967dd263044d98ac6badb8a6b11c19d61692 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Tue, 22 Sep 2020 20:55:50 +0200 Subject: [PATCH 57/65] Update binding list --- supported_bindings_list.md | 42 +++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 5f15aa3..1038a64 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -88,14 +88,14 @@ | crypto_onetimeauth_keygen | not present in LazySodium | | crypto_onetimeauth_update | not present in LazySodium | | crypto_onetimeauth_verify | not present in LazySodium | -| crypto_pwhash | | +| crypto_pwhash | :heavy_check_mark: | | crypto_pwhash_scryptsalsa208sha256 | not present in LazySodium for Android | | crypto_pwhash_scryptsalsa208sha256_ll | not present in LazySodium for Android | | crypto_pwhash_scryptsalsa208sha256_str | not present in LazySodium for Android | | crypto_pwhash_scryptsalsa208sha256_str_verify | not present in LazySodium for Android | -| crypto_pwhash_str | | -| crypto_pwhash_str_needs_rehash | | -| crypto_pwhash_str_verify | | +| crypto_pwhash_str | :heavy_check_mark: | +| crypto_pwhash_str_needs_rehash | :heavy_check_mark: | +| crypto_pwhash_str_verify | :heavy_check_mark: | | crypto_scalarmult | | | crypto_scalarmult_base | | | crypto_scalarmult_ristretto255 | | @@ -261,25 +261,25 @@ | crypto_onetimeauth_KEYBYTES | | | crypto_onetimeauth_poly1305_BYTES | | | crypto_onetimeauth_poly1305_KEYBYTES | | -| crypto_pwhash_ALG_ARGON2I13 | | -| crypto_pwhash_ALG_ARGON2ID13 | | -| crypto_pwhash_ALG_DEFAULT | | +| crypto_pwhash_ALG_ARGON2I13 | :heavy_check_mark: | +| crypto_pwhash_ALG_ARGON2ID13 | :heavy_check_mark: | +| crypto_pwhash_ALG_DEFAULT | :heavy_check_mark: | | crypto_pwhash_BYTES_MAX | | -| crypto_pwhash_BYTES_MIN | | -| crypto_pwhash_MEMLIMIT_INTERACTIVE | | +| crypto_pwhash_BYTES_MIN | :heavy_check_mark: | +| crypto_pwhash_MEMLIMIT_INTERACTIVE | :heavy_check_mark: | | crypto_pwhash_MEMLIMIT_MAX | | -| crypto_pwhash_MEMLIMIT_MIN | | -| crypto_pwhash_MEMLIMIT_MODERATE | | -| crypto_pwhash_MEMLIMIT_SENSITIVE | | -| crypto_pwhash_OPSLIMIT_INTERACTIVE | | -| crypto_pwhash_OPSLIMIT_MAX | | -| crypto_pwhash_OPSLIMIT_MIN | | -| crypto_pwhash_OPSLIMIT_MODERATE | | -| crypto_pwhash_OPSLIMIT_SENSITIVE | | -| crypto_pwhash_PASSWD_MAX | | -| crypto_pwhash_PASSWD_MIN | | -| crypto_pwhash_SALTBYTES | | -| crypto_pwhash_STRBYTES | | +| crypto_pwhash_MEMLIMIT_MIN | :heavy_check_mark: | +| crypto_pwhash_MEMLIMIT_MODERATE | :heavy_check_mark: | +| crypto_pwhash_MEMLIMIT_SENSITIVE | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_INTERACTIVE | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_MAX | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_MIN | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_MODERATE | :heavy_check_mark: | +| crypto_pwhash_OPSLIMIT_SENSITIVE | :heavy_check_mark: | +| crypto_pwhash_PASSWD_MAX | :heavy_check_mark: | +| crypto_pwhash_PASSWD_MIN | :heavy_check_mark: | +| crypto_pwhash_SALTBYTES | :heavy_check_mark: | +| crypto_pwhash_STRBYTES | :heavy_check_mark: | | crypto_pwhash_argon2i_BYTES_MAX | | | crypto_pwhash_argon2i_BYTES_MIN | | | crypto_pwhash_argon2i_SALTBYTES | | From 7d3fe70d4d564f2ca4f691df9877bb2c67b0cabb Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 25 Sep 2020 19:02:45 +0200 Subject: [PATCH 58/65] Started working on sodium_ utility functions --- .../util/LibsodiumUtil.kt | 19 +++- .../kotlin/crypto/util/LibsodiumUtilTest.kt | 27 +++++ .../kotlin/crypto/util/LibsodiumUtil.kt | 102 ++++++++++++++++++ 3 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt index 5f88538..51564e3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt @@ -5,6 +5,19 @@ package com.ionspin.kotlin.crypto.util * ugljesa.jovanovic@ionspin.com * on 31-Aug-2020 */ -//expect object LibsodiumUtil { -// -//} +expect object LibsodiumUtil { + + fun memcmp(first: UByteArray, second: UByteArray) : Boolean + fun memzero(target: UByteArray) + + fun pad(unpaddedData : UByteArray, blocksize: Int) : UByteArray + fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray + + fun toBase64(data: UByteArray) : String + fun toHex(data: UByteArray) : String + fun toString(data : UByteArray) : String + + fun fromBase64(data: String) : UByteArray + fun fromHex(data: String) : UByteArray + fun fromString(data: String) : UByteArray +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt new file mode 100644 index 0000000..b84bd76 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt @@ -0,0 +1,27 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 25-Sep-2020 + */ + +class LibsodiumUtilTest { + @Test + fun testPadding() { + val input = ubyteArrayOf(1U, 2U) + val blocksize = 16 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..4c49823 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -0,0 +1,102 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.StableRef +import kotlinx.cinterop.addressOf +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import kotlinx.cinterop.reinterpret +import libsodium.sodium_memcmp +import libsodium.sodium_memzero +import libsodium.sodium_pad +import libsodium.sodium_unpad +import platform.posix.size_t + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 31-Aug-2020 + */ +actual object LibsodiumUtil { + + + actual fun memcmp(first: UByteArray, second: UByteArray): Boolean { + val firstPinned = first.pin() + val secondPinned = second.pin() + val result = sodium_memcmp(firstPinned.toPtr(), secondPinned.toPtr(), first.size.convert()) + firstPinned.unpin() + secondPinned.unpin() + return result == 0 + } + + actual fun memzero(target: UByteArray) { + val targetPinned = target.pin() + sodium_memzero(targetPinned.toPtr(), target.size.convert()) + } + + actual fun pad(unpaddedData : UByteArray, blocksize: Int) : UByteArray { + val resultingSize = if (unpaddedData.size % blocksize != 0 ) { + ((unpaddedData.size / blocksize) + 1 ) * blocksize + } else { + unpaddedData.size + 1 + } + val paddedData = UByteArray(resultingSize) + unpaddedData.copyInto(paddedData, 0, 0) + val paddedDataPinned = paddedData.pin() + + sodium_pad( + null, + paddedDataPinned.toPtr(), + unpaddedData.size.convert(), + blocksize.convert(), + resultingSize.convert() + ) + paddedDataPinned.unpin() + return paddedData + } + + actual fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray { + val paddedDataCopy = paddedData.copyOf() + val paddedDataCopyPinned = paddedDataCopy.pin() + var newSize = ULongArray(1) { 99UL } + val newSizePinned = newSize.pin() + sodium_unpad( + newSizePinned.addressOf(0), + paddedDataCopyPinned.toPtr(), + paddedData.size.convert(), + blocksize.convert() + ) + val unpaddedSize = newSize[0] + if (unpaddedSize > Int.MAX_VALUE.toULong()) { + throw RuntimeException("Unsupported array size (larger than Integer max value) $unpaddedSize") + } + val unpadded = paddedDataCopy.sliceArray(0 until unpaddedSize.toInt()) + paddedDataCopyPinned.unpin() + newSizePinned.unpin() + return unpadded + } + + actual fun toBase64(data: UByteArray): String { + TODO("not implemented yet") + } + + actual fun toHex(data: UByteArray): String { + TODO("not implemented yet") + } + + actual fun toString(data: UByteArray): String { + TODO("not implemented yet") + } + + actual fun fromBase64(data: String): UByteArray { + TODO("not implemented yet") + } + + actual fun fromHex(data: String): UByteArray { + TODO("not implemented yet") + } + + actual fun fromString(data: String): UByteArray { + TODO("not implemented yet") + } + +} From 7e2b52a193a32d9e128db956bcafa76c7266c1e3 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Fri, 25 Sep 2020 19:05:22 +0200 Subject: [PATCH 59/65] Add more tests, fix array when input is aligned --- .../kotlin/crypto/util/LibsodiumUtilTest.kt | 28 +++++++++++++++++++ .../kotlin/crypto/util/LibsodiumUtil.kt | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt index b84bd76..cdb5a7e 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt @@ -24,4 +24,32 @@ class LibsodiumUtilTest { input.contentEquals(unpadded) } } + + @Test + fun testPaddingAligned() { + val input = ubyteArrayOf(1U, 2U) + val blocksize = 2 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } + + @Test + fun testPaddingMultiblock() { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U) + val blocksize = 4 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt index 4c49823..6836f90 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -37,7 +37,7 @@ actual object LibsodiumUtil { val resultingSize = if (unpaddedData.size % blocksize != 0 ) { ((unpaddedData.size / blocksize) + 1 ) * blocksize } else { - unpaddedData.size + 1 + unpaddedData.size } val paddedData = UByteArray(resultingSize) unpaddedData.copyInto(paddedData, 0, 0) From f113f7805d6a1dec8fc21704e07d5786d7aecbc1 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 26 Sep 2020 22:02:51 +0200 Subject: [PATCH 60/65] Added to hex and to base64 and from conversions --- .../util/LibsodiumUtil.kt | 9 +- .../kotlin/crypto/util/LibsodiumUtilTest.kt | 48 ++++++++++ .../kotlin/crypto/util/LibsodiumUtil.kt | 91 ++++++++++++++++--- 3 files changed, 134 insertions(+), 14 deletions(-) diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt index 51564e3..c8df280 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt @@ -5,6 +5,11 @@ package com.ionspin.kotlin.crypto.util * ugljesa.jovanovic@ionspin.com * on 31-Aug-2020 */ + +enum class Base64Variants(val value: Int) { + ORIGINAL(1), ORIGINAL_NO_PADDING(3), URLSAFE(5), URLSAFE_NO_PADDING(7) +} + expect object LibsodiumUtil { fun memcmp(first: UByteArray, second: UByteArray) : Boolean @@ -13,11 +18,11 @@ expect object LibsodiumUtil { fun pad(unpaddedData : UByteArray, blocksize: Int) : UByteArray fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray - fun toBase64(data: UByteArray) : String + fun toBase64(data: UByteArray, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : String fun toHex(data: UByteArray) : String fun toString(data : UByteArray) : String - fun fromBase64(data: String) : UByteArray + fun fromBase64(data: String, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : UByteArray fun fromHex(data: String) : UByteArray fun fromString(data: String) : UByteArray } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt index cdb5a7e..ec2e100 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt @@ -1,6 +1,7 @@ package com.ionspin.kotlin.crypto.util import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import kotlin.math.exp import kotlin.test.Test import kotlin.test.assertTrue @@ -52,4 +53,51 @@ class LibsodiumUtilTest { input.contentEquals(unpadded) } } + + @Test + fun testToBase64() { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + val expected = "AQIDBAUgQID_" + val output = LibsodiumUtil.toBase64(input) + println("Output: |$output|") + println("Expected|$expected| ") + assertTrue { + output == expected + } + val reconstructed = LibsodiumUtil.fromBase64(output) + println("Reconstructed: ${reconstructed.toHexString()}") + assertTrue { + reconstructed.contentEquals(input) + } + } + + @Test + fun testToBase64Unaligned() { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) + val expected = "AQIDBAUgQID_gA" + val output = LibsodiumUtil.toBase64(input) + println("Output: |$output|") + println("Expected|$expected| ") + assertTrue { + output == expected + } + val reconstructed = LibsodiumUtil.fromBase64(output) + println("Reconstructed: ${reconstructed.toHexString()}") + assertTrue { + reconstructed.contentEquals(input) + } + } + + @Test + fun toHex() { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) + val hex = LibsodiumUtil.toHex(input) + assertTrue { + hex == input.toHexString() + } + val reconstructed = LibsodiumUtil.fromHex(hex) + assertTrue { + reconstructed.contentEquals(input) + } + } } diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt index 6836f90..5948f00 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -1,24 +1,27 @@ package com.ionspin.kotlin.crypto.util -import kotlinx.cinterop.StableRef import kotlinx.cinterop.addressOf import kotlinx.cinterop.convert import kotlinx.cinterop.pin -import kotlinx.cinterop.reinterpret +import libsodium.sodium_base642bin +import libsodium.sodium_base64_encoded_len +import libsodium.sodium_bin2base64 +import libsodium.sodium_bin2hex +import libsodium.sodium_hex2bin import libsodium.sodium_memcmp import libsodium.sodium_memzero import libsodium.sodium_pad import libsodium.sodium_unpad -import platform.posix.size_t /** * Created by Ugljesa Jovanovic * ugljesa.jovanovic@ionspin.com * on 31-Aug-2020 */ -actual object LibsodiumUtil { +actual object LibsodiumUtil { + actual fun memcmp(first: UByteArray, second: UByteArray): Boolean { val firstPinned = first.pin() val secondPinned = second.pin() @@ -37,7 +40,7 @@ actual object LibsodiumUtil { val resultingSize = if (unpaddedData.size % blocksize != 0 ) { ((unpaddedData.size / blocksize) + 1 ) * blocksize } else { - unpaddedData.size + unpaddedData.size + 1 } val paddedData = UByteArray(resultingSize) unpaddedData.copyInto(paddedData, 0, 0) @@ -57,7 +60,7 @@ actual object LibsodiumUtil { actual fun unpad(paddedData: UByteArray, blocksize: Int) : UByteArray { val paddedDataCopy = paddedData.copyOf() val paddedDataCopyPinned = paddedDataCopy.pin() - var newSize = ULongArray(1) { 99UL } + var newSize = ULongArray(1) { 0UL } val newSizePinned = newSize.pin() sodium_unpad( newSizePinned.addressOf(0), @@ -75,24 +78,88 @@ actual object LibsodiumUtil { return unpadded } - actual fun toBase64(data: UByteArray): String { - TODO("not implemented yet") + actual fun toBase64(data: UByteArray, variant : Base64Variants): String { + val maxlen = sodium_base64_encoded_len(data.size.convert(), variant.value) + val dataPinned = data.pin() + val result = ByteArray(maxlen.toInt()) { 0 } + val resultPinned = result.pin() + sodium_bin2base64( + resultPinned.addressOf(0), + maxlen, + dataPinned.toPtr(), + data.size.convert(), + variant.value + ) + dataPinned.unpin() + resultPinned.unpin() + //Drop '\0' + return result.map { it.toChar() }.dropLast(1).joinToString("") } actual fun toHex(data: UByteArray): String { - TODO("not implemented yet") + val hexLen = (data.size * 2) + 1 // +1 for terminator char + val result = ByteArray(hexLen) + val resultPinned = result.pin() + val dataPinned = data.pin() + sodium_bin2hex( + resultPinned.addressOf(0), + hexLen.convert(), + dataPinned.toPtr(), + data.size.convert() + ) + resultPinned.unpin() + dataPinned.unpin() + //Drop \0 termination + return result.map { it.toChar() }.dropLast(1).joinToString("") } actual fun toString(data: UByteArray): String { TODO("not implemented yet") } - actual fun fromBase64(data: String): UByteArray { - TODO("not implemented yet") + actual fun fromBase64(data: String, variant : Base64Variants): UByteArray { + val maxLength = (data.length * 3) / 4 + val intermediaryResult = UByteArray(maxLength) { 0U } + + val intermediaryResultPinned = intermediaryResult.pin() + var binLen = ULongArray(1) { 0UL } + var binLenPinned = binLen.pin() + sodium_base642bin( + intermediaryResultPinned.toPtr(), + maxLength.convert(), + data, + data.length.convert(), + null, + binLenPinned.addressOf(0), + null, + variant.value + + ) + binLenPinned.unpin() + intermediaryResultPinned.unpin() + + return if (binLen[0].toInt() != maxLength) { + intermediaryResult.sliceArray(0 until binLen[0].toInt()) + } else { + intermediaryResult + } } actual fun fromHex(data: String): UByteArray { - TODO("not implemented yet") + val expectedSize = (data.length + 1) / 2 + val result = UByteArray(expectedSize) + val resultPinned = result.pin() + sodium_hex2bin( + resultPinned.toPtr(), + expectedSize.convert(), + data, + data.length.convert(), + null, + null, + null + ) + resultPinned.unpin() + return result } actual fun fromString(data: String): UByteArray { From 4af1477c908791fd4b44bf69d3ab37a4051f4a43 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 26 Sep 2020 23:58:45 +0200 Subject: [PATCH 61/65] Added js _util functions --- .../util/LibsodiumUtil.kt | 3 +- .../kotlin/crypto/util/LibsodiumUtilTest.kt | 154 +++++++++++------- .../kotlin/crypto/JsSodiumInterface.kt | 15 +- .../kotlin/crypto/util/LibsodiumUtil.kt | 50 ++++++ .../kotlin/crypto/util/LibsodiumUtil.kt | 8 - 5 files changed, 161 insertions(+), 69 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt index c8df280..d8360f0 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumUtil.kt @@ -20,9 +20,8 @@ expect object LibsodiumUtil { fun toBase64(data: UByteArray, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : String fun toHex(data: UByteArray) : String - fun toString(data : UByteArray) : String fun fromBase64(data: String, variant : Base64Variants = Base64Variants.URLSAFE_NO_PADDING) : UByteArray fun fromHex(data: String) : UByteArray - fun fromString(data: String) : UByteArray + } diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt index ec2e100..7dc61c7 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt @@ -1,8 +1,10 @@ package com.ionspin.kotlin.crypto.util import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint +import com.ionspin.kotlin.crypto.LibsodiumInitializer import kotlin.math.exp import kotlin.test.Test +import kotlin.test.assertFalse import kotlin.test.assertTrue /** @@ -13,91 +15,129 @@ import kotlin.test.assertTrue class LibsodiumUtilTest { @Test - fun testPadding() { - val input = ubyteArrayOf(1U, 2U) - val blocksize = 16 - val padded = LibsodiumUtil.pad(input, blocksize) - println(padded.hexColumsPrint()) - val unpadded = LibsodiumUtil.unpad(padded, blocksize) - println(unpadded.hexColumsPrint()) + fun testMemzero() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + LibsodiumUtil.memzero(input) + assertTrue { + input.contentEquals(UByteArray(9) { 0U }) + } + } + } - assertTrue { - input.contentEquals(unpadded) + @Test + fun testMemcmp() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + val input2 = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + val input3 = ubyteArrayOf(2U, 2U, 2U, 2U, 2U, 2U, 21U, 2U, 2U) + assertTrue { + LibsodiumUtil.memcmp(input, input2) + } + assertFalse { + LibsodiumUtil.memcmp(input, input3) + } + } + } + + @Test + fun testPadding() { + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U) + val blocksize = 16 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } } } @Test fun testPaddingAligned() { - val input = ubyteArrayOf(1U, 2U) - val blocksize = 2 - val padded = LibsodiumUtil.pad(input, blocksize) - println(padded.hexColumsPrint()) - val unpadded = LibsodiumUtil.unpad(padded, blocksize) - println(unpadded.hexColumsPrint()) + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U) + val blocksize = 2 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) - assertTrue { - input.contentEquals(unpadded) + assertTrue { + input.contentEquals(unpadded) + } } } @Test fun testPaddingMultiblock() { - val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U) - val blocksize = 4 - val padded = LibsodiumUtil.pad(input, blocksize) - println(padded.hexColumsPrint()) - val unpadded = LibsodiumUtil.unpad(padded, blocksize) - println(unpadded.hexColumsPrint()) + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U) + val blocksize = 4 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) - assertTrue { - input.contentEquals(unpadded) + assertTrue { + input.contentEquals(unpadded) + } } } @Test fun testToBase64() { - val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) - val expected = "AQIDBAUgQID_" - val output = LibsodiumUtil.toBase64(input) - println("Output: |$output|") - println("Expected|$expected| ") - assertTrue { - output == expected - } - val reconstructed = LibsodiumUtil.fromBase64(output) - println("Reconstructed: ${reconstructed.toHexString()}") - assertTrue { - reconstructed.contentEquals(input) + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U) + val expected = "AQIDBAUgQID_" + val output = LibsodiumUtil.toBase64(input) + println("Output: |$output|") + println("Expected|$expected| ") + assertTrue { + output == expected + } + val reconstructed = LibsodiumUtil.fromBase64(output) + println("Reconstructed: ${reconstructed.toHexString()}") + assertTrue { + reconstructed.contentEquals(input) + } } } @Test fun testToBase64Unaligned() { - val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) - val expected = "AQIDBAUgQID_gA" - val output = LibsodiumUtil.toBase64(input) - println("Output: |$output|") - println("Expected|$expected| ") - assertTrue { - output == expected - } - val reconstructed = LibsodiumUtil.fromBase64(output) - println("Reconstructed: ${reconstructed.toHexString()}") - assertTrue { - reconstructed.contentEquals(input) + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) + val expected = "AQIDBAUgQID_gA" + val output = LibsodiumUtil.toBase64(input) + println("Output: |$output|") + println("Expected|$expected| ") + assertTrue { + output == expected + } + val reconstructed = LibsodiumUtil.fromBase64(output) + println("Reconstructed: ${reconstructed.toHexString()}") + assertTrue { + reconstructed.contentEquals(input) + } } } @Test fun toHex() { - val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) - val hex = LibsodiumUtil.toHex(input) - assertTrue { - hex == input.toHexString() - } - val reconstructed = LibsodiumUtil.fromHex(hex) - assertTrue { - reconstructed.contentEquals(input) + LibsodiumInitializer.initializeWithCallback { + val input = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 32U, 64U, 128U, 255U, 128U) + val hex = LibsodiumUtil.toHex(input) + assertTrue { + hex == input.toHexString() + } + val reconstructed = LibsodiumUtil.fromHex(hex) + assertTrue { + reconstructed.contentEquals(input) + } } } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index a6b9b7a..ebe0be0 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -194,9 +194,20 @@ interface JsSodiumInterface { // ---- Password hashing end ---- + // ---- Utils ---- - //util - fun memzero(array: Uint8Array) + fun memcmp(first: Uint8Array, second: Uint8Array) : Boolean + fun memzero(data: Uint8Array) + fun pad(data : Uint8Array, blocksize: Int) : Uint8Array + fun unpad(data: Uint8Array, blocksize: Int) : Uint8Array + fun to_base64(data: Uint8Array, variant: Int) : String + fun to_hex(data: Uint8Array) : String + fun to_string(data: Uint8Array) : String + fun from_base64(data: String, variant: Int): Uint8Array + fun from_hex(data : String): Uint8Array + fun from_string(data : String): Uint8Array + + // ---- Utils end ---- diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..5ee7278 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -0,0 +1,50 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +actual object LibsodiumUtil { + actual fun memcmp(first: UByteArray, second: UByteArray): Boolean { + return getSodium().memcmp(first.toUInt8Array(), second.toUInt8Array()) + } + + actual fun memzero(target: UByteArray) { + // libsodium.js does this as well, and theres no clear way at the moment of casting ubytearray to uint8array + //although I feel like there should be a way to work around it + target.forEachIndexed { + index, _ -> target[index] = 0U + } + } + + actual fun pad(unpaddedData: UByteArray, blocksize: Int): UByteArray { + return getSodium().pad(unpaddedData.toUInt8Array(), blocksize).toUByteArray() + } + + actual fun unpad(paddedData: UByteArray, blocksize: Int): UByteArray { + return getSodium().unpad(paddedData.toUInt8Array(), blocksize).toUByteArray() + } + + actual fun toBase64( + data: UByteArray, + variant: Base64Variants + ): String { + return getSodium().to_base64(data.toUInt8Array(), variant.value) + } + + actual fun toHex(data: UByteArray): String { + return getSodium().to_hex(data.toUInt8Array()) + } + + actual fun fromBase64( + data: String, + variant: Base64Variants + ): UByteArray { + return getSodium().from_base64(data, variant.value).toUByteArray() + } + + actual fun fromHex(data: String): UByteArray { + return getSodium().from_hex(data).toUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt index 5948f00..fe16466 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -113,10 +113,6 @@ actual object LibsodiumUtil { return result.map { it.toChar() }.dropLast(1).joinToString("") } - actual fun toString(data: UByteArray): String { - TODO("not implemented yet") - } - actual fun fromBase64(data: String, variant : Base64Variants): UByteArray { val maxLength = (data.length * 3) / 4 val intermediaryResult = UByteArray(maxLength) { 0U } @@ -162,8 +158,4 @@ actual object LibsodiumUtil { return result } - actual fun fromString(data: String): UByteArray { - TODO("not implemented yet") - } - } From 2d63215c707c3aff84ead831f920a2c63f909204 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 27 Sep 2020 19:20:22 +0200 Subject: [PATCH 62/65] Completed jvm implementation, there are some issues in lazysodium-java that I've worked around --- .../kotlin/crypto/util/LibsodiumUtilTest.kt | 16 ++ .../kotlin/crypto/util/LibsodiumUtil.kt | 6 +- .../kotlin/crypto/util/LibsodiumUtil.kt | 166 ++++++++++++++++++ .../kotlin/crypto/util/LibsodiumUtil.kt | 2 +- 4 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt index 7dc61c7..52b97f9 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtilTest.kt @@ -56,6 +56,22 @@ class LibsodiumUtilTest { } } + @Test + fun testPaddingChars() { + LibsodiumInitializer.initializeWithCallback { + val input = charArrayOf('a', 'b', 'c', 'd').map { it.toByte().toUByte() }.toUByteArray() + val blocksize = 4 + val padded = LibsodiumUtil.pad(input, blocksize) + println(padded.hexColumsPrint()) + val unpadded = LibsodiumUtil.unpad(padded, blocksize) + println(unpadded.hexColumsPrint()) + + assertTrue { + input.contentEquals(unpadded) + } + } + } + @Test fun testPaddingAligned() { LibsodiumInitializer.initializeWithCallback { diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt index 5ee7278..e9c83fd 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -11,9 +11,9 @@ actual object LibsodiumUtil { actual fun memzero(target: UByteArray) { // libsodium.js does this as well, and theres no clear way at the moment of casting ubytearray to uint8array - //although I feel like there should be a way to work around it - target.forEachIndexed { - index, _ -> target[index] = 0U + // although I feel like there should be a way to work around it + (target.indices).forEach { + index -> target[index] = 0U } } diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt new file mode 100644 index 0000000..54aad8e --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -0,0 +1,166 @@ +package com.ionspin.kotlin.crypto.util + +import com.goterl.lazycode.lazysodium.LazySodiumJava +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium +import com.sun.jna.ptr.IntByReference +import java.lang.RuntimeException +import java.util.* + +actual object LibsodiumUtil { + actual fun memcmp(first: UByteArray, second: UByteArray): Boolean { + if (first.size != second.size) { + throw RuntimeException("Sodium memcmp() only supports comparing same length arrays") + } + return sodium.sodium_memcmp(first.asByteArray(), second.asByteArray(), first.size) == 0 + } + + actual fun memzero(target: UByteArray) { + sodium.sodium_memzero(target.asByteArray(), target.size) + } + + actual fun pad(unpaddedData: UByteArray, blocksize: Int): UByteArray { + + // Pad is invalid in lazysodium-java because it uses char arrays, which are 2 bytes in java + // while libsodium expects 1 byte char array + // See https://github.com/terl/lazysodium-java/issues/85 + + //This is temporary solution until lazysodium is fixed + if (blocksize == 0) { + throw RuntimeException("Invalid block size: $blocksize") + } + val padAmount = blocksize - (unpaddedData.size % blocksize) + val result = if (padAmount == blocksize) { + unpaddedData + UByteArray(blocksize) { + when (it) { + 0 -> 0x80U + else -> 0x00U + } + } + } else { + unpaddedData + UByteArray(padAmount) { + when (it) { + 0 -> 0x80U + else -> 0x00U + } + } + } + + return result + +// val newPadSizeReference = IntByReference(0) +// val newSize = ((unpaddedData.size / blocksize) + 1) * blocksize +// val charArray = CharArray(newSize) { +// if (it < unpaddedData.size) { +// unpaddedData[it].toByte().toChar() +// } else { +// '\u0000' +// } +// } +// sodium.sodium_pad( +// newPadSizeReference.pointer, +// charArray, +// unpaddedData.size + 1, +// blocksize, +// newSize +// ) +// +// return charArray.slice(0 until newPadSizeReference.value).map { it.toByte().toUByte()}.toUByteArray() + + } + + actual fun unpad(paddedData: UByteArray, blocksize: Int): UByteArray { + + // Pad is invalid in lazysodium-java because it uses char arrays, which are 2 bytes in java + // while libsodium expects 1 byte char array + // See https://github.com/terl/lazysodium-java/issues/85 + + //This is temporary solution until lazysodium is fixed + + val unpaddedData = paddedData.dropLastWhile { it == 0U.toUByte() } + if (unpaddedData.last() != 0x80U.toUByte()) { + throw RuntimeException("Invalid padding!") + } + return unpaddedData.dropLast(1).toUByteArray() + + +// val paddedDataCopy = paddedData.copyOf().asByteArray().map { it.toChar() }.toCharArray() +// var unpaddedSize = IntByReference(0) +// +// sodium.sodium_unpad( +// unpaddedSize.pointer, +// paddedDataCopy, +// paddedData.size, +// blocksize +// ) +// +// val unpadded = paddedDataCopy.sliceArray(0 until unpaddedSize.value).map { it.toByte().toUByte() }.toUByteArray() +// +// return unpadded + } + + actual fun toBase64( + data: UByteArray, + variant: Base64Variants + ): String { + val maxlen = sodium.sodium_base64_encoded_len(data.size, variant.value) + val result = ByteArray(maxlen) { 0 } + sodium.sodium_bin2base64( + result, + maxlen, + data.asByteArray(), + data.size, + variant.value + ) + //Drop terminating char \0 + return String(result.sliceArray(0 until result.size - 1)) + } + + actual fun toHex(data: UByteArray): String { + val hexLen = (data.size * 2) + 1 // +1 for terminator char + val result = ByteArray(hexLen) + sodium.sodium_bin2hex( + result, + hexLen, + data.asByteArray(), + data.size + ) + //Drop terminating char \0 + return String(result.sliceArray(0 until result.size - 1)) + } + + actual fun fromBase64( + data: String, + variant: Base64Variants + ): UByteArray { + // from base64 is currently broken in lazysodium-java + // see https://github.com/terl/lazysodium-java/issues/83 +// val maxLength = (data.length * 3) / 4 +// val intermediaryResult = UByteArray(maxLength) { 0U } +// +// sodium.sodium_base642bin( +// intermediaryResult.asByteArray(), +// maxLength, +// data.encodeToByteArray(), +// data.length, +// null, +// binLenPinned.addressOf(0), +// null, +// variant.value +// +// ) + val decoder = when(variant) { + Base64Variants.ORIGINAL -> Base64.getDecoder() + Base64Variants.ORIGINAL_NO_PADDING -> Base64.getDecoder() + Base64Variants.URLSAFE -> Base64.getUrlDecoder() + Base64Variants.URLSAFE_NO_PADDING -> Base64.getUrlDecoder() + } + return decoder.decode(data).asUByteArray() + } + + actual fun fromHex(data: String): UByteArray { + // from hex is currently broken in lazysodium-java + // see https://github.com/terl/lazysodium-java/issues/83 + return data.hexStringToUByteArray() + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt index fe16466..81577aa 100644 --- a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -40,7 +40,7 @@ actual object LibsodiumUtil { val resultingSize = if (unpaddedData.size % blocksize != 0 ) { ((unpaddedData.size / blocksize) + 1 ) * blocksize } else { - unpaddedData.size + 1 + unpaddedData.size + blocksize } val paddedData = UByteArray(resultingSize) unpaddedData.copyInto(paddedData, 0, 0) From cb17d75deb0857dd2e22078fd8c37401c2b9753f Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 27 Sep 2020 19:54:48 +0200 Subject: [PATCH 63/65] Adding jvm implementation, but it's broken in lazysodium-java, so will need more work --- .../util/LibsodiumRandom.kt | 36 +++++++++++ .../kotlin/crypto/util/LibsodiumRandom.kt | 54 ++++++++++++++++ .../kotlin/crypto/util/LibsodiumRandom.kt | 63 +++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt new file mode 100644 index 0000000..b653d90 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt @@ -0,0 +1,36 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +expect object LibsodiumRandom { + + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + fun buf(size: Int) : UByteArray + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + fun bufDeterministic(size: Int, seed: UByteArray) : UByteArray + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + fun random() : UInt + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0 + */ + fun uniform(upperBound : UInt) : UInt +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt new file mode 100644 index 0000000..df628b7 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -0,0 +1,54 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +actual object LibsodiumRandom { + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + actual fun buf(size: Int): UByteArray { + val result = ByteArray(size) + sodium.randombytes_buf(result, size) + return result.asUByteArray() + } + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { + val result = ByteArray(size) + sodium.randombytes_buf(result, size, seed.asByteArray()) + return result.asUByteArray() + } + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + actual fun random(): UInt { + //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 + TODO() + } + + + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0 + */ + actual fun uniform(upperBound: UInt): UInt { + //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 + TODO("not implemented yet") + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt new file mode 100644 index 0000000..8ea76d6 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/nativeMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -0,0 +1,63 @@ +package com.ionspin.kotlin.crypto.util + +import kotlinx.cinterop.convert +import kotlinx.cinterop.pin +import libsodium.randombytes_buf +import libsodium.randombytes_buf_deterministic +import libsodium.randombytes_close +import libsodium.randombytes_random +import libsodium.randombytes_stir +import libsodium.randombytes_uniform + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +actual object LibsodiumRandom { + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + actual fun buf(size: Int): UByteArray { + val result = UByteArray(size) + val resultPinned = result.pin() + randombytes_buf(resultPinned.toPtr(), size.convert()) + resultPinned.unpin() + return result + } + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { + val result = UByteArray(size) + val resultPinned = result.pin() + val seedPinned = seed.pin() + randombytes_buf_deterministic(resultPinned.toPtr(), size.convert(), seedPinned.toPtr()) + resultPinned.unpin() + seedPinned.unpin() + return result + } + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + actual fun random(): UInt { + return randombytes_random() + } + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0 + */ + actual fun uniform(upperBound: UInt): UInt { + return randombytes_uniform(upperBound) + } + +} From 0431f27e3e412a89d6e49aa681b410a177fef8cd Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 3 Oct 2020 18:16:26 +0200 Subject: [PATCH 64/65] Completed random support functions --- README.md | 275 +---------------- buildSrc/src/main/kotlin/Deps.kt | 7 +- multiplatform-crypto-api/README.md | 285 ++++++++++++++++++ .../build.gradle.kts | 3 + .../util/LibsodiumRandom.kt | 2 + .../kotlin/crypto/util/LibsodiumRandomTest.kt | 56 ++++ .../kotlin/crypto/JsSodiumInterface.kt | 9 + .../kotlin/crypto/util/LibsodiumRandom.kt | 48 +++ .../kotlin/crypto/util/LibsodiumRandom.kt | 8 +- supported_bindings_list.md | 27 +- 10 files changed, 430 insertions(+), 290 deletions(-) create mode 100644 multiplatform-crypto-api/README.md create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandomTest.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt diff --git a/README.md b/README.md index d0a8635..52f79ac 100644 --- a/README.md +++ b/README.md @@ -3,279 +3,10 @@ # Kotlin Multiplatform Crypto Library -#Note: -### Next stable release will be published after public release of Kotlin 1.4, until then API will change significantly - -Kotlin Multiplatform Crypto is a library for various cryptographic applications. - -The library comes in two flavors `multiplatform-crypto` and `multiplatform-crypto-delegated`. This project also provides -direct libsodium bindings under `multiplatform-crypto-libsodium-bindings`. - -* `multiplatform-crypto` contains pure kotlin implementations, is not reviewed, should be considered unsafe and only -for prototyping or experimentation purposes. - -* `multiplatform-crypto-delegated` relies on platform specific implementations, mostly libsodium, but care should still be taken that the kotlin code is not reviewed or proven safe. - -APIs of both variants are identical. - -* `multiplatform-crypto-libsodium-bindings` is a generated bindings library using `kotlin-multiplatform-libsodium-generator` - * Under HEAVY development at the moment - - - -### Table of contents -1. [Supported platforms](#supported-platforms-by-variant) -2. [API](#api) -3. TODO - -## Supported platforms by variant -|Platform|Pure variant| Delegated variant| -|--------|------------|------------------| -|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. - -## Why? - -This is an experimental implementation, mostly for expanding personal understanding of cryptography. -It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure. - -## API for Pure and Delegated flavourd - -### Hashing functions -* Blake2b -* SHA512 -* SHA256 - -### Key Derivation - -* Argon2 - -### Authenticated symmetric encryption (AEAD) - -* XChaCha20-Poly1305 - - -### Delegated flavor dependancy table -The following table describes which library is used for particular cryptographic primitive - -| Primitive | JVM | JS | Native | -| ----------|-----|----|--------| -| Blake2b | LazySodium | libsodium.js | libsodium | -| SHA256 | LazySodium | libsodium.js | libsodium | -| SHA512 | LazySodium | libsodium.js | libsodium | -| XChaCha20-Poly1305 | LazySodium | libsodium.js | libsodium | - - - -## Integration - -NOTE: Latest version of the library is built with Kotlin 1.4-M2 and therefore only SNAPSHOT variant is available. Next -stable version will be released when Kotlin 1.4. is released - -#### Gradle -Kotlin -```kotlin -implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0") - -or - -implementation("com.ionspin.kotlin:multiplatform-crypto-delegated:0.1.0") -``` - -#### Snapshot builds -```kotlin -repositories { - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots") - } -} -implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0-SNAPSHOT") - -``` - -## Usage - -### Helper functions - -All API take `UByteArray` as message/key/nonce/etc parameter. For convenience when working with strings we provide -`String.enocdeToUbyteArray()` extensions function, and `UByteArray.toHexString` extension function. - -More convenience functions will be added. - -### Hashes - -Hashes are provided in two versions, "stateless", usually the companion object of the hash, -which takes the data to be hashed in one go, and "updatable" which can be fed data in chunks. - - -#### Blake2b - -You can use Blake 2b in two modes - -##### Stateless version -You need to deliver the complete data that is to be hashed in one go - -```kotlin -val input = "abc" -val result = Crypto.Blake2b.stateless(input.encodeToUByteArray()) -``` - -Result is returned as a `UByteArray` - -##### Updatable instance version -You can create an instance and feed the data by using `update(input : UByteArray)` call. Once all data is supplied, -you should call `digest()`. - -If you want to use Blake2b with a key, you should supply it when creating the `Blake2b` instance. - -```kotlin -val test = "abc" -val key = "key" -val blake2b = Crypto.Blake2b.updateable(key.encodeToUByteArray()) -blake2b.update(test.encodeToUByteArray()) -val result = blake2b.digest().toHexString() -``` - -After digest is called, the instance is reset and can be reused (Keep in mind key stays the same for the particular instance). -#### SHA2 (SHA256 and SHA512) - -##### Stateless version - -You need to deliver the complete data that is to be hashed in one go. You can either provide the `UByteArray` as input -or `String`. Result is always returned as `UByteArray` (At least in verision 0.0.1) - -```kotlin -val input = "abc" -val result = Crypto.Sha256.stateless(input.encodeToUByteArray()) -``` - -```kotlin -val input ="abc" -val result = Crypto.Sha512.stateless(input.encodeToUByteArray()) -``` - -Result is returned as a `UByteArray` - -##### Updateable version - -Or you can use the updatable instance version - -```kotlin -val sha256 = Crypto.Sha256.updateable() -sha256.update("abc".encodeToUByteArray()) -val result = sha256.digest() -``` - -```kotlin -val sha512 = Crypto.Sha512.updateable() -sha512.update("abc".encodeToUByteArray()) -val result = sha512.digest() -``` - -### Key derivation - -#### Argon2 - -NOTE: This implementation is tested against KAT generated by reference Argon2 implementation, which does not follow -specification completely. See this issue https://github.com/P-H-C/phc-winner-argon2/issues/183 - -```kotlin -val argon2Instance = Argon2( - password = "Password", - salt = "RandomSalt", - parallelism = 8, - tagLength = 64U, - requestedMemorySize = 256U, //4GB - numberOfIterations = 4U, - key = "", - associatedData = "", - argonType = ArgonType.Argon2id - ) -val tag = argon2Instance.derive() -val tagString = tag.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") -val expectedTagString = "c255e3e94305817d5e09a7c771e574e3a81cc78fef5da4a9644b6df0" + - "0ba1c9b424e3dd0ce7e600b1269b14c84430708186a8a60403e1bfbda935991592b9ff37" -println("Tag: ${tagString}") -assertEquals(tagString, expectedTagString) -``` - -### Symmetric encryption (OUTDATED, won't be exposed in next release, no counterpart in delegated flavor - 0.1.1) - -#### AES - -Aes is available with CBC and CTR mode through `AesCbc` and `AesCtr` classes/objects. -Similarly to hashes you can either use stateless or updateable version. - -Initialization vector, or counter states are chosen by the SDK automaticaly, and returned alongside encrypted data - -##### Stateless AesCbc and AesCtr - -AesCtr - -```kotlin -val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" -val key = AesKey.Aes128Key(keyString) -val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" - -val encryptedDataAndInitializationVector = AesCtr.encrypt(key, plainText.hexStringToUByteArray()) -val decrypted = AesCtr.decrypt( - key, - encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initialCounter -) -plainText == decrypted.toHexString() -``` - -AesCbc - -```kotlin - -val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" -val key = AesKey.Aes128Key(keyString) - -val plainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" - -val encryptedDataAndInitializationVector = AesCbc.encrypt(key, plainText.hexStringToUByteArray()) -val decrypted = AesCbc.decrypt( - key, - encryptedDataAndInitializationVector.encryptedData, - encryptedDataAndInitializationVector.initilizationVector -) -plainText == decrypted.toHexString() - -``` - -## Libsodium bindings - -* Under development +This repository contains two crypto related projects: +1. Libsodium bindings for Kotiln Multiplatform +2. Pure/Delegated kotlin multiplatform crypto library written from scratch in pure form. diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index e647100..2d0fb60 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -25,7 +25,7 @@ object Versions { val kotlinBigNumVersion = "0.1.6-1.4.0-rc-SNAPSHOT" - val lazySodium = "4.2.6" + val lazySodium = "4.3.1-SNAPSHOT" val jna = "5.5.0" val kotlinPoet = "1.6.0" @@ -81,7 +81,10 @@ object Deps { val kotlinPoet = "com.squareup:kotlinpoet:${Versions.kotlinPoet}" object Delegated { - val lazysodium = "com.goterl.lazycode:lazysodium-java:${Versions.lazySodium}" + // Temporary until reported lazysodium issues are fixed. My snapshot build with + // And cause I registered com.ionspin.kotlin as maven central package root now I have to use + // that even though this is pure java library. :) + val lazysodium = "com.ionspin.kotlin:lazysodium-java:${Versions.lazySodium}" val jna = "net.java.dev.jna:jna:${Versions.jna}" } } diff --git a/multiplatform-crypto-api/README.md b/multiplatform-crypto-api/README.md new file mode 100644 index 0000000..8d19365 --- /dev/null +++ b/multiplatform-crypto-api/README.md @@ -0,0 +1,285 @@ +# Kotlin Multiplatform Crypto Library + + +Kotlin Multiplatform Crypto is a library for various cryptographic applications. + +The library comes in two flavors `multiplatform-crypto` and `multiplatform-crypto-delegated`. + +* `multiplatform-crypto` contains pure kotlin implementations, is not reviewed, should be considered unsafe and only +for prototyping or experimentation purposes. + +* `multiplatform-crypto-delegated` relies on platform specific implementations, mostly libsodium, but care should still be taken that the kotlin code is not reviewed or proven safe. + +APIs of both variants are identical. + + +### Table of contents +1. [Supported platforms](#supported-platforms-by-variant) +2. [API](#api) +3. TODO + +## Supported platforms by variant +|Platform|Pure variant| Delegated variant| +|--------|------------|------------------| +|Linux X86 64| :heavy_check_mark: | :heavy_check_mark: | +|Linux Arm 64| :heavy_check_mark: | :heavy_check_mark: | +|Linux Arm 32| :heavy_check_mark: | :x: | +|macOS X86 64| :heavy_check_mark: | :heavy_check_mark: | +|iOS x86 64 | :heavy_check_mark: | :heavy_check_mark: | +|iOS Arm 64 | :heavy_check_mark: | :heavy_check_mark: | +|iOS Arm 32 | :heavy_check_mark: | :heavy_check_mark: | +|watchOS X86 32 | :heavy_check_mark: | :heavy_check_mark: | +|watchOS Arm 64(_32) | :heavy_check_mark: | :heavy_check_mark: | +|watchos Arm 32 | :heavy_check_mark: | :heavy_check_mark: | +|tvOS X86 64 | :heavy_check_mark: | :heavy_check_mark: | +|tvOS Arm 64 | :heavy_check_mark: | :heavy_check_mark: | +|minGW X86 64| :heavy_check_mark: | :heavy_check_mark: | +|minGW X86 32| :x: | :x: | + +## Sample project +The library includes sample project that shows usage on different platforms +- NOTE: Currently only linux, macOs and windows are included. + +## Notes & Roadmap + +**The API will move fast and break often until v1.0** + +Next steps: +- Expand API (ECC, Signing ...) + +## Should I use this in production? +**NO.** +The library is under HEAVY development. Until development is done it will not be reviewed and therefore it shouldn't be used. +Contributions are still welcome! + +## Why? + +This is an experimental implementation, mostly for expanding personal understanding of cryptography. +It's not peer reviewed, not guaranteed to be bug free, and not guaranteed to be secure. + +## API for Pure and Delegated flavours + +### Hashing functions +* Blake2b +* SHA512 +* SHA256 + +### Key Derivation + +* Argon2 + +### Authenticated symmetric encryption (AEAD) + +* XChaCha20-Poly1305 + + +### Delegated flavor dependancy table +The following table describes which library is used for particular cryptographic primitive + +| Primitive | JVM | JS | Native | +| ----------|-----|----|--------| +| Blake2b | LazySodium | libsodium.js | libsodium | +| SHA256 | LazySodium | libsodium.js | libsodium | +| SHA512 | LazySodium | libsodium.js | libsodium | +| XChaCha20-Poly1305 | LazySodium | libsodium.js | libsodium | + + + +## Integration + +NOTE: Latest version of the library is built with Kotlin 1.4-M2 and therefore only SNAPSHOT variant is available. Next +stable version will be released when Kotlin 1.4. is released + +#### Gradle +Kotlin +```kotlin +implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0") + +or + +implementation("com.ionspin.kotlin:multiplatform-crypto-delegated:0.1.0") +``` + +#### Snapshot builds +```kotlin +repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + } +} +implementation("com.ionspin.kotlin:multiplatform-crypto:0.1.0-SNAPSHOT") + +``` + +## Usage + +### Helper functions + +All API take `UByteArray` as message/key/nonce/etc parameter. For convenience when working with strings we provide +`String.enocdeToUbyteArray()` extensions function, and `UByteArray.toHexString` extension function. + +More convenience functions will be added. + +### Hashes + +Hashes are provided in two versions, "stateless", usually the companion object of the hash, +which takes the data to be hashed in one go, and "updatable" which can be fed data in chunks. + + +#### Blake2b + +You can use Blake 2b in two modes + +##### Stateless version +You need to deliver the complete data that is to be hashed in one go + +```kotlin +val input = "abc" +val result = Crypto.Blake2b.stateless(input.encodeToUByteArray()) +``` + +Result is returned as a `UByteArray` + +##### Updatable instance version +You can create an instance and feed the data by using `update(input : UByteArray)` call. Once all data is supplied, +you should call `digest()`. + +If you want to use Blake2b with a key, you should supply it when creating the `Blake2b` instance. + +```kotlin +val test = "abc" +val key = "key" +val blake2b = Crypto.Blake2b.updateable(key.encodeToUByteArray()) +blake2b.update(test.encodeToUByteArray()) +val result = blake2b.digest().toHexString() +``` + +After digest is called, the instance is reset and can be reused (Keep in mind key stays the same for the particular instance). +#### SHA2 (SHA256 and SHA512) + +##### Stateless version + +You need to deliver the complete data that is to be hashed in one go. You can either provide the `UByteArray` as input +or `String`. Result is always returned as `UByteArray` (At least in verision 0.0.1) + +```kotlin +val input = "abc" +val result = Crypto.Sha256.stateless(input.encodeToUByteArray()) +``` + +```kotlin +val input ="abc" +val result = Crypto.Sha512.stateless(input.encodeToUByteArray()) +``` + +Result is returned as a `UByteArray` + +##### Updateable version + +Or you can use the updatable instance version + +```kotlin +val sha256 = Crypto.Sha256.updateable() +sha256.update("abc".encodeToUByteArray()) +val result = sha256.digest() +``` + +```kotlin +val sha512 = Crypto.Sha512.updateable() +sha512.update("abc".encodeToUByteArray()) +val result = sha512.digest() +``` + +### Key derivation + +#### Argon2 + +NOTE: This implementation is tested against KAT generated by reference Argon2 implementation, which does not follow +specification completely. See this issue https://github.com/P-H-C/phc-winner-argon2/issues/183 + +```kotlin +val argon2Instance = Argon2( + password = "Password", + salt = "RandomSalt", + parallelism = 8, + tagLength = 64U, + requestedMemorySize = 256U, //4GB + numberOfIterations = 4U, + key = "", + associatedData = "", + argonType = ArgonType.Argon2id + ) +val tag = argon2Instance.derive() +val tagString = tag.map { it.toString(16).padStart(2, '0') }.joinToString(separator = "") +val expectedTagString = "c255e3e94305817d5e09a7c771e574e3a81cc78fef5da4a9644b6df0" + + "0ba1c9b424e3dd0ce7e600b1269b14c84430708186a8a60403e1bfbda935991592b9ff37" +println("Tag: ${tagString}") +assertEquals(tagString, expectedTagString) +``` + +### Symmetric encryption (OUTDATED, won't be exposed in next release, no counterpart in delegated flavor - 0.1.1) + +#### AES + +Aes is available with CBC and CTR mode through `AesCbc` and `AesCtr` classes/objects. +Similarly to hashes you can either use stateless or updateable version. + +Initialization vector, or counter states are chosen by the SDK automaticaly, and returned alongside encrypted data + +##### Stateless AesCbc and AesCtr + +AesCtr + +```kotlin +val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" +val key = AesKey.Aes128Key(keyString) +val plainText = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710" + +val encryptedDataAndInitializationVector = AesCtr.encrypt(key, plainText.hexStringToUByteArray()) +val decrypted = AesCtr.decrypt( + key, + encryptedDataAndInitializationVector.encryptedData, + encryptedDataAndInitializationVector.initialCounter +) +plainText == decrypted.toHexString() +``` + +AesCbc + +```kotlin + +val keyString = "4278b840fb44aaa757c1bf04acbe1a3e" +val key = AesKey.Aes128Key(keyString) + +val plainText = "3c888bbbb1a8eb9f3e9b87acaad986c466e2f7071c83083b8a557971918850e5" + +val encryptedDataAndInitializationVector = AesCbc.encrypt(key, plainText.hexStringToUByteArray()) +val decrypted = AesCbc.decrypt( + key, + encryptedDataAndInitializationVector.encryptedData, + encryptedDataAndInitializationVector.initilizationVector +) +plainText == decrypted.toHexString() + +``` + +## Libsodium bindings + +* Under development + + + + + + + + + + + + + + + + + diff --git a/multiplatform-crypto-libsodium-bindings/build.gradle.kts b/multiplatform-crypto-libsodium-bindings/build.gradle.kts index 91ed8ac..57c3ca5 100644 --- a/multiplatform-crypto-libsodium-bindings/build.gradle.kts +++ b/multiplatform-crypto-libsodium-bindings/build.gradle.kts @@ -47,6 +47,9 @@ repositories { mavenCentral() jcenter() maven("https://dl.bintray.com/terl/lazysodium-maven") + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + } } group = ReleaseInfo.group diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt index b653d90..83aa113 100644 --- a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com.ionspin.kotlin.crypto/util/LibsodiumRandom.kt @@ -5,6 +5,8 @@ package com.ionspin.kotlin.crypto.util * ugljesa.jovanovic@ionspin.com * on 27-Sep-2020 */ +val randombytes_SEEDBYTES = 32 + expect object LibsodiumRandom { /** diff --git a/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandomTest.kt b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandomTest.kt new file mode 100644 index 0000000..a515a32 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonTest/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandomTest.kt @@ -0,0 +1,56 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.LibsodiumInitializer +import kotlin.test.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 03-Oct-2020 + */ +class LibsodiumRandomTest { + + @Test + fun testRandom() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^32 + LibsodiumInitializer.initializeWithCallback { + val random = LibsodiumRandom.random() + assertTrue { random != 0U } + } + + } + + @Test + fun testRandomUniform() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^31 + LibsodiumInitializer.initializeWithCallback { + val random = LibsodiumRandom.uniform(UInt.MAX_VALUE / 2U) + assertTrue { random != 0U && random < (UInt.MAX_VALUE / 2U)} + } + } + + @Test + fun testRandomBuffer() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^52 + LibsodiumInitializer.initializeWithCallback { + val result = LibsodiumRandom.buf(20) + val lowProbability = UByteArray(20) { 0U } + assertFalse { result.contentEquals(lowProbability) } + } + } + + @Test + fun testRandomBufferDeterministic() { + //This is just a sanity test, it should fail on occasion though, with probability of 1/2^52 + LibsodiumInitializer.initializeWithCallback { + val seed = UByteArray(randombytes_SEEDBYTES) { 1U } + val result = LibsodiumRandom.bufDeterministic(20, seed) + val lowProbability = UByteArray(20) { 0U } + assertFalse { result.contentEquals(lowProbability) } + val secondResult = LibsodiumRandom.bufDeterministic(20, seed) + assertTrue { result.contentEquals(secondResult) } + } + } +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt index ebe0be0..f216f00 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/JsSodiumInterface.kt @@ -207,9 +207,18 @@ interface JsSodiumInterface { fun from_hex(data : String): Uint8Array fun from_string(data : String): Uint8Array + // ---- > ---- Random ---- < ----- + + fun randombytes_buf(length: UInt) : Uint8Array + fun randombytes_buf_deterministic(length: UInt, seed : Uint8Array) : Uint8Array + fun randombytes_random() : UInt + fun randombytes_uniform(upper_bound: UInt) : UInt + // ---- Utils end ---- + + } diff --git a/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt new file mode 100644 index 0000000..1854710 --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/jsMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -0,0 +1,48 @@ +package com.ionspin.kotlin.crypto.util + +import com.ionspin.kotlin.crypto.getSodium +import ext.libsodium.com.ionspin.kotlin.crypto.toUByteArray +import ext.libsodium.com.ionspin.kotlin.crypto.toUInt8Array + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 27-Sep-2020 + */ +actual object LibsodiumRandom { + /** + * The randombytes_buf() function fills size bytes starting at buf with an unpredictable sequence of bytes. + */ + actual fun buf(size: Int): UByteArray { + return getSodium().randombytes_buf(size).toUByteArray() + } + + /** + * The randombytes_buf_deterministic function stores size bytes into buf indistinguishable from random bytes without knowing seed. + * For a given seed, this function will always output the same sequence. size can be up to 2^31 (~8GB) because we use kotlin arrays + * and they are limited by Int primitive type + * seed is randombytes_SEEDBYTES bytes long. + * This function is mainly useful for writing tests, and was introduced in libsodium 1.0.12. Under the hood, it uses the ChaCha20 stream cipher. + * + */ + actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { + return getSodium().randombytes_buf_deterministic(size.toUInt(), seed.toUInt8Array()).toUByteArray() + } + + /** + * The randombytes_random() function returns an unpredictable value between 0 and 0xffffffff (included). + */ + actual fun random(): UInt { + return getSodium().randombytes_random() + } + + /** + * The randombytes_uniform() function returns an unpredictable value between 0 and upper_bound (excluded). Unlike r + * andombytes_random() % upper_bound, it guarantees a uniform distribution of the possible output values even when + * upper_bound is not a power of 2. Note that an upper_bound < 2 leaves only a single element to be chosen, namely 0 + */ + actual fun uniform(upperBound: UInt): UInt { + return getSodium().randombytes_uniform(upperBound) + } + +} diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt index df628b7..fbbcae3 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumRandom.kt @@ -27,7 +27,7 @@ actual object LibsodiumRandom { */ actual fun bufDeterministic(size: Int, seed: UByteArray): UByteArray { val result = ByteArray(size) - sodium.randombytes_buf(result, size, seed.asByteArray()) + sodium.randombytes_buf_deterministic(result, size, seed.asByteArray()) return result.asUByteArray() } @@ -36,7 +36,8 @@ actual object LibsodiumRandom { */ actual fun random(): UInt { //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 - TODO() + //Using temporary forked and fixed build until pull request is accepted in original repo + return sodium.randombytes_random().toUInt() } @@ -48,7 +49,8 @@ actual object LibsodiumRandom { */ actual fun uniform(upperBound: UInt): UInt { //Broken in lazysodium-java https://github.com/terl/lazysodium-java/issues/86 - TODO("not implemented yet") + //Using temporary fixed build until pull request is accepted + return sodium.randombytes_uniform(upperBound.toInt()).toUInt() } } diff --git a/supported_bindings_list.md b/supported_bindings_list.md index 1038a64..a797b30 100644 --- a/supported_bindings_list.md +++ b/supported_bindings_list.md @@ -1,15 +1,16 @@ |Function name| Implemented | |-------------|-------------| | add | | -| memcmp | | -| memzero | | +| memcmp | :heavy_check_mark: | +| memzero | :heavy_check_mark: | | output_formats | | -| pad | | -| unpad | | +| pad | :heavy_check_mark: | +| unpad | :heavy_check_mark: | | symbols | | -| to_base64 | | -| to_hex | | -| to_string | | +| to_base64 | :heavy_check_mark: | +| to_hex | :heavy_check_mark: | +| from_base64 | :heavy_check_mark: | +| from_hex | :heavy_check_mark: | | crypto_aead_chacha20poly1305_decrypt | :heavy_check_mark: | | crypto_aead_chacha20poly1305_decrypt_detached | :heavy_check_mark: | | crypto_aead_chacha20poly1305_encrypt | :heavy_check_mark: | @@ -138,12 +139,12 @@ | crypto_stream_xchacha20_keygen | not present in LazySodium Android | | crypto_stream_xchacha20_xor | not present in LazySodium Android| | crypto_stream_xchacha20_xor_ic | not present in LazySodium Android | -| randombytes_buf | | -| randombytes_buf_deterministic | | -| randombytes_close | | -| randombytes_random | | -| randombytes_stir | | -| randombytes_uniform | | +| randombytes_buf | :heavy_check_mark: | +| randombytes_buf_deterministic | :heavy_check_mark: | +| randombytes_close | not present in LazySodium | +| randombytes_random | :heavy_check_mark: | +| randombytes_stir | not present in LazySodium | +| randombytes_uniform | :heavy_check_mark: | | sodium_version_string | | | SODIUM_LIBRARY_VERSION_MAJOR | | | SODIUM_LIBRARY_VERSION_MINOR | | From 4490f21c89d52e59782bbadbf74ea2ee59f24d1f Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sat, 3 Oct 2020 18:49:08 +0200 Subject: [PATCH 65/65] Split docs for bindings and standalone implementations --- README.md | 140 +++++++++++++++++- multiplatform-crypto-api/README.md | 3 + .../kotlin/crypto/util/LibsodiumUtil.kt | 2 - 3 files changed, 140 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 52f79ac..ebf10c3 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,146 @@ [![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 -This repository contains two crypto related projects: +This repository contains two cryptography related projects: 1. Libsodium bindings for Kotiln Multiplatform -2. Pure/Delegated kotlin multiplatform crypto library written from scratch in pure form. +2. Pure/Delegated kotlin multiplatform crypto library written from scratch in pure form. [Link to project readme](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/multiplatform-crypto-api/README.md) + +This readme represents the libsodium bindings project + +# 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. + +## Installation + +The libsodium binding library is not published yet as it is still missing several features, you can track the +[progress here](https://github.com/ionspin/kotlin-multiplatform-crypto/blob/master/supported_bindings_list.md) + + +## Usage + +Before using the wrapper you need to initialize the underlying libsodium library. You can use either a callback or coroutines approach + +``` + LibsodiumInitializer.initializeWithCallback { + // Libsodium initialized + } +``` + +``` + suspend fun initalizeProject() { + ... + LibsodiumInitializer.intialize() + ... + } +``` + +After intiailization you can call libsodium functions directly + +The API is very close to libsodium but still adapted to kotlin standards, as an example here is the usage of authenticated +encryption api: + +**libsodium:** + +``` + #define MESSAGE ((const unsigned char *) "test") + #define MESSAGE_LEN 4 + #define CIPHERTEXT_LEN (crypto_secretbox_MACBYTES + MESSAGE_LEN) + + unsigned char key[crypto_secretbox_KEYBYTES]; + unsigned char nonce[crypto_secretbox_NONCEBYTES]; + unsigned char ciphertext[CIPHERTEXT_LEN]; + + crypto_secretbox_keygen(key); + randombytes_buf(nonce, sizeof nonce); + crypto_secretbox_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce, key); + + unsigned char decrypted[MESSAGE_LEN]; + if (crypto_secretbox_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce, key) != 0) { + /* message forged! */ + } +``` + +**kotlin:** +``` + val message = ("Ladies and Gentlemen of the class of '99: If I could offer you " + + "only one tip for the future, sunscreen would be it.").encodeToUByteArray() + + val key = LibsodiumRandom.buf(32) + + val nonce = LibsodiumRandom.buf(24) + + val encrypted = SecretBox.easy(message, nonce, key) + val decrypted = SecretBox.openEasy(encrypted, nonce, key) +``` +If message cannot be verified, `openEasy` function will throw a `SecretBoxCorruptedOrTamperedDataExceptionOrInvalidKey` + +In some cases libsodium C api returns two values, usually encrypted data and a autogenerated nonce. In situations like +those, kotlin API returns a data class wrapping both objects. An example of this behavior is initializing the secret stream, where initialization funciton returns both the header and state: + +**libsodium:** +``` + crypto_secretstream_xchacha20poly1305_state state; + unsigned char key[crypto_secretstream_xchacha20poly1305_KEYBYTES]; + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES]; + + /* Set up a new stream: initialize the state and create the header */ + crypto_secretstream_xchacha20poly1305_init_push(&state, header, key); +``` + +**kotlin:** +This is what the response data class definition looks like: +``` + data class SecretStreamStateAndHeader(val state: SecretStreamState, val header : UByteArray) +``` +And here is the usage sample +``` + val key = LibsodiumRandom.buf(crypto_secretstream_xchacha20poly1305_KEYBYTES) + val stateAndHeader = SecretStream.xChaCha20Poly1305InitPush(key) + val state = stateAndHeader.state + val header = stateAndHeader.header +``` + +The functions are mapped from libsodium to kotiln objects, so `crypto_secretstream_xchacha20poly1305_init_push` becomes +`SecretStream.xChaCha20Poly1305InitPush` + +At the moment you should refer to original libsodium documentation for instructions on how to use the library + +## Supported native platforms + +Currently supported native platforms: + +|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: | + + +### TODO: +- Copy/adapt code documentation, currently only some functions have documentation that is a copy-paste from libsodium website +- Complete the bindings list +- Samples +- Android testing + + + + + + diff --git a/multiplatform-crypto-api/README.md b/multiplatform-crypto-api/README.md index 8d19365..d65ec6a 100644 --- a/multiplatform-crypto-api/README.md +++ b/multiplatform-crypto-api/README.md @@ -1,3 +1,6 @@ +[![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 diff --git a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt index 54aad8e..a88bf78 100644 --- a/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt +++ b/multiplatform-crypto-libsodium-bindings/src/jvmMain/kotlin/com/ionspin/kotlin/crypto/util/LibsodiumUtil.kt @@ -1,8 +1,6 @@ package com.ionspin.kotlin.crypto.util -import com.goterl.lazycode.lazysodium.LazySodiumJava import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium -import com.sun.jna.ptr.IntByReference import java.lang.RuntimeException import java.util.*