Test secret stream generated code

This commit is contained in:
Ugljesa Jovanovic 2020-08-15 17:50:46 +02:00 committed by Ugljesa Jovanovic
parent df87dae376
commit 0c098e57db
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
13 changed files with 137 additions and 39 deletions

View File

@ -95,7 +95,8 @@ class FunctionDefinition(
class ParameterDefinition( class ParameterDefinition(
val parameterName: String, val parameterName: String,
val parameterType: GeneralTypeDefinition, val parameterType: GeneralTypeDefinition,
val modifiesReturn: Boolean = false, val modifiesReturnObjectSize: Boolean = false,
val specificReturnModification : String? = null,
val isActuallyAnOutputParam: Boolean = false, val isActuallyAnOutputParam: Boolean = false,
val isStateType: Boolean = false, val isStateType: Boolean = false,
val dropParameterFromDefinition: Boolean = false, val dropParameterFromDefinition: Boolean = false,

View File

@ -33,6 +33,6 @@ fun ClassDefinition.defineGenericHashFunctions() {
specificJvmInitializer = "sodium.crypto_generichash_statebytes()" specificJvmInitializer = "sodium.crypto_generichash_statebytes()"
) )
+ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES) +ParameterDefinition("key", TypeDefinition.ARRAY_OF_UBYTES)
+ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturn = true) +ParameterDefinition("outlen", TypeDefinition.INT, modifiesReturnObjectSize = true)
} }
} }

View File

@ -1,7 +1,5 @@
package com.ionspin.kotlin.crypto.generator.libsodium.definitions 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 * Created by Ugljesa Jovanovic (jovanovic.ugljesa@gmail.com) on 14/Aug/2020
*/ */
@ -132,7 +130,8 @@ fun ClassDefinition.defineSecretStreamFunctions() {
+ParameterDefinition( +ParameterDefinition(
"m", "m",
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE,
modifiesReturn = true modifiesReturnObjectSize = true,
specificReturnModification = "m.size + 17"
) )
+ParameterDefinition( +ParameterDefinition(
"ad", "ad",
@ -173,7 +172,8 @@ fun ClassDefinition.defineSecretStreamFunctions() {
+ParameterDefinition( +ParameterDefinition(
"c", "c",
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE, TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE,
modifiesReturn = true modifiesReturnObjectSize = true,
specificReturnModification = "c.size - 17"
) )
+ParameterDefinition( +ParameterDefinition(
"ad", "ad",
@ -183,4 +183,5 @@ fun ClassDefinition.defineSecretStreamFunctions() {
} }
} }

View File

@ -63,7 +63,7 @@ object JsLibsodiumGenerator {
val methodBuilder = FunSpec.builder(methodDefinition.name) val methodBuilder = FunSpec.builder(methodDefinition.name)
var returnModifierFound = false var returnModifierFound = false
var returnModifierName = "" var returnModifierValue = ""
var actualReturnType: TypeName = DYNAMIC var actualReturnType: TypeName = DYNAMIC
var actualReturnTypeFound: Boolean = false var actualReturnTypeFound: Boolean = false
for (paramDefinition in methodDefinition.parameterList) { for (paramDefinition in methodDefinition.parameterList) {
@ -74,18 +74,22 @@ object JsLibsodiumGenerator {
methodBuilder.addParameter(parameterSpec.build()) methodBuilder.addParameter(parameterSpec.build())
} }
} }
if (paramDefinition.modifiesReturn) { if (paramDefinition.modifiesReturnObjectSize) {
if (returnModifierFound == true) { if (returnModifierFound == true) {
throw RuntimeException("Return modifier already found") throw RuntimeException("Return modifier already found")
} }
returnModifierFound = true returnModifierFound = true
when (paramDefinition.parameterType) { if (paramDefinition.specificReturnModification == null) {
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { when (paramDefinition.parameterType) {
returnModifierName = "${paramDefinition.parameterName}.size" TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
} returnModifierValue = "${paramDefinition.parameterName}.size"
TypeDefinition.INT -> { }
returnModifierName = paramDefinition.parameterName TypeDefinition.INT -> {
returnModifierValue = paramDefinition.parameterName
}
} }
} else {
returnModifierValue = paramDefinition.specificReturnModification!!
} }
} }
if (paramDefinition.isActuallyAnOutputParam) { if (paramDefinition.isActuallyAnOutputParam) {

View File

@ -55,7 +55,7 @@ object JvmLibsodiumGenerator {
val methodBuilder = FunSpec.builder(methodDefinition.name) val methodBuilder = FunSpec.builder(methodDefinition.name)
methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList
var returnModifierFound = false var returnModifierFound = false
var returnModifierName = "" var returnModifierValue = ""
lateinit var actualReturnParameterDefinition: ParameterDefinition lateinit var actualReturnParameterDefinition: ParameterDefinition
var actualReturnTypeFound: Boolean = false var actualReturnTypeFound: Boolean = false
for (paramDefinition in methodDefinition.parameterList) { for (paramDefinition in methodDefinition.parameterList) {
@ -69,18 +69,23 @@ object JvmLibsodiumGenerator {
methodBuilder.addParameter(parameterSpec.build()) methodBuilder.addParameter(parameterSpec.build())
} }
} }
if (paramDefinition.modifiesReturn) { if (paramDefinition.modifiesReturnObjectSize) {
if (returnModifierFound == true) { if (returnModifierFound == true) {
throw RuntimeException("Return modifier already found") throw RuntimeException("Return modifier already found")
} }
returnModifierFound = true returnModifierFound = true
when (paramDefinition.parameterType) {
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { if (paramDefinition.specificReturnModification == null) {
returnModifierName = "${paramDefinition.parameterName}.size" when (paramDefinition.parameterType) {
} TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
TypeDefinition.INT -> { returnModifierValue = "${paramDefinition.parameterName}.size"
returnModifierName = paramDefinition.parameterName }
TypeDefinition.INT -> {
returnModifierValue = paramDefinition.parameterName
}
} }
} else {
returnModifierValue = paramDefinition.specificReturnModification!!
} }
} }
if (paramDefinition.isActuallyAnOutputParam) { if (paramDefinition.isActuallyAnOutputParam) {
@ -92,7 +97,7 @@ object JvmLibsodiumGenerator {
if (returnModifierFound) { if (returnModifierFound) {
createOutputParam( createOutputParam(
actualReturnParameterDefinition, actualReturnParameterDefinition,
returnModifierName, returnModifierValue,
methodBuilder methodBuilder
) )
} else { } else {

View File

@ -70,7 +70,7 @@ object NativeLibsodiumGenerator {
val methodBuilder = FunSpec.builder(methodDefinition.name) val methodBuilder = FunSpec.builder(methodDefinition.name)
methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList methodBuilder.modifiers += MultiplatformModifier.ACTUAL.modifierList
var returnModifierFound = false var returnModifierFound = false
var returnModifierName = "" var returnModifierValue = ""
lateinit var actualReturnParameterDefinition: ParameterDefinition lateinit var actualReturnParameterDefinition: ParameterDefinition
var actualReturnTypeFound: Boolean = false var actualReturnTypeFound: Boolean = false
for (paramDefinition in methodDefinition.parameterList) { for (paramDefinition in methodDefinition.parameterList) {
@ -84,18 +84,22 @@ object NativeLibsodiumGenerator {
methodBuilder.addParameter(parameterSpec.build()) methodBuilder.addParameter(parameterSpec.build())
} }
} }
if (paramDefinition.modifiesReturn) { if (paramDefinition.modifiesReturnObjectSize) {
if (returnModifierFound == true) { if (returnModifierFound == true) {
throw RuntimeException("Return modifier already found") throw RuntimeException("Return modifier already found")
} }
returnModifierFound = true returnModifierFound = true
when (paramDefinition.parameterType) { if (paramDefinition.specificReturnModification == null) {
TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> { when (paramDefinition.parameterType) {
returnModifierName = "${paramDefinition.parameterName}.size" TypeDefinition.ARRAY_OF_UBYTES_LONG_SIZE -> {
} returnModifierValue = "${paramDefinition.parameterName}.size"
TypeDefinition.INT -> { }
returnModifierName = paramDefinition.parameterName TypeDefinition.INT -> {
returnModifierValue = paramDefinition.parameterName
}
} }
} else {
returnModifierValue = paramDefinition.specificReturnModification!!
} }
} }
@ -106,7 +110,7 @@ object NativeLibsodiumGenerator {
} }
if (actualReturnTypeFound) { if (actualReturnTypeFound) {
if (returnModifierFound) { if (returnModifierFound) {
createOutputParam(actualReturnParameterDefinition, returnModifierName, methodBuilder) createOutputParam(actualReturnParameterDefinition, returnModifierValue, methodBuilder)
} else { } else {
if (methodDefinition.outputLengthWhenArray == -1) { if (methodDefinition.outputLengthWhenArray == -1) {
throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}") throw RuntimeException("Function definition lacks a way to define output array length, function ${methodDefinition.name}")

View File

@ -249,7 +249,6 @@ kotlin {
implementation(kotlin(Deps.Common.stdLib)) implementation(kotlin(Deps.Common.stdLib))
implementation(kotlin(Deps.Common.test)) implementation(kotlin(Deps.Common.test))
implementation(Deps.Common.kotlinBigNum) implementation(Deps.Common.kotlinBigNum)
api(project(Deps.Common.apiProject))
} }
} }
val commonTest by getting { val commonTest by getting {

View File

@ -1,7 +1,7 @@
package com.ionspin.kotlin.crypto package com.ionspin.kotlin.crypto
import com.ionspin.kotlin.bignum.integer.BigInteger 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.testBlocking
import com.ionspin.kotlin.crypto.util.toHexString import com.ionspin.kotlin.crypto.util.toHexString
import debug.test.Crypto import debug.test.Crypto

View File

@ -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)
}
}
}

View File

@ -34,3 +34,17 @@ fun testBlocking(block : suspend () -> Unit) {
} }
block.startCoroutine(continuation) 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)
}
}
}

View File

@ -103,7 +103,7 @@ actual class Crypto internal actual constructor() {
ad: UByteArray, ad: UByteArray,
tag: UByte tag: UByte
): UByteArray { ): UByteArray {
val c = UByteArray(m.size) val c = UByteArray(m.size + 17)
println("Debug crypto_secretstream_xchacha20poly1305_push") println("Debug crypto_secretstream_xchacha20poly1305_push")
sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(), sodium.crypto_secretstream_xchacha20poly1305_push(state, c.asByteArray(), null, m.asByteArray(),
m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte()) m.size.toLong(), ad.asByteArray(), ad.size.toLong(), tag.toByte())
@ -118,7 +118,7 @@ actual class Crypto internal actual constructor() {
c: UByteArray, c: UByteArray,
ad: UByteArray ad: UByteArray
): UByteArray { ): UByteArray {
val m = UByteArray(c.size) val m = UByteArray(c.size - 17)
println("Debug crypto_secretstream_xchacha20poly1305_pull") 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, null,
c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong()) c.asByteArray(), c.size.toLong(), ad.asByteArray(), ad.size.toLong())

View File

@ -142,7 +142,7 @@ actual class Crypto internal actual constructor() {
ad: UByteArray, ad: UByteArray,
tag: UByte tag: UByte
): UByteArray { ): UByteArray {
val c = UByteArray(m.size) val c = UByteArray(m.size + 17)
println("Debug crypto_secretstream_xchacha20poly1305_push") println("Debug crypto_secretstream_xchacha20poly1305_push")
val pinnedC = c.pin() val pinnedC = c.pin()
val pinnedM = m.pin() val pinnedM = m.pin()
@ -163,7 +163,7 @@ actual class Crypto internal actual constructor() {
c: UByteArray, c: UByteArray,
ad: UByteArray ad: UByteArray
): UByteArray { ): UByteArray {
val m = UByteArray(c.size) val m = UByteArray(c.size - 17)
println("Debug crypto_secretstream_xchacha20poly1305_pull") println("Debug crypto_secretstream_xchacha20poly1305_pull")
val pinnedM = m.pin() val pinnedM = m.pin()
val pinnedC = c.pin() val pinnedC = c.pin()