From 8b3b94df3aa319c0baf04b62bef3a1bbee7bcb84 Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 26 Jul 2020 20:21:37 +0200 Subject: [PATCH] Switch to latest BigInteger, use new byte conversion api --- buildSrc/src/main/kotlin/Deps.kt | 2 +- .../crypto/util/ByteArrayConversions.kt | 10 ++++++ .../kotlin/crypto/keyderivation/Sodium.kt | 7 ++++ .../com/ionspin/kotlin/crypto/mac/Poly1305.kt | 35 +++++++++++++------ .../kotlin/crypto/symmetric/AesCtrPure.kt | 5 +-- 5 files changed, 45 insertions(+), 14 deletions(-) create mode 100644 multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/ByteArrayConversions.kt create mode 100644 multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Sodium.kt diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index d9c6f62..106513c 100644 --- a/buildSrc/src/main/kotlin/Deps.kt +++ b/buildSrc/src/main/kotlin/Deps.kt @@ -23,7 +23,7 @@ object Versions { val dokkaPlugin = "0.11.0-dev-44" val taskTreePlugin = "1.5" - val kotlinBigNumVersion = "0.1.6-1.4-M3-1-SNAPSHOT" + val kotlinBigNumVersion = "0.1.6-1.4-M3-2-SNAPSHOT" val lazySodium = "4.2.6" val jna = "5.5.0" diff --git a/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/ByteArrayConversions.kt b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/ByteArrayConversions.kt new file mode 100644 index 0000000..61065cb --- /dev/null +++ b/multiplatform-crypto-api/src/commonMain/kotlin/com/ionspin/kotlin/crypto/util/ByteArrayConversions.kt @@ -0,0 +1,10 @@ +package com.ionspin.kotlin.crypto.util + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 26-Jul-2020 + */ +fun UByteArray.fromLittleEndianUByteArrayToBigEndianUByteArray() : UByteArray { + return this.reversedArray() +} diff --git a/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Sodium.kt b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Sodium.kt new file mode 100644 index 0000000..2207add --- /dev/null +++ b/multiplatform-crypto-libsodium-bindings/src/commonMain/kotlin/com/ionspin/kotlin/crypto/keyderivation/Sodium.kt @@ -0,0 +1,7 @@ +package com.ionspin.kotlin.crypto.keyderivation + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 26-Jul-2020 + */ diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305.kt index e32caef..406ebeb 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305.kt @@ -2,6 +2,8 @@ package com.ionspin.kotlin.crypto.mac import com.ionspin.kotlin.bignum.Endianness import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign +import com.ionspin.kotlin.crypto.util.fromLittleEndianUByteArrayToBigEndianUByteArray import com.ionspin.kotlin.crypto.util.hexColumsPrint /** @@ -28,7 +30,8 @@ class Poly1305(key: UByteArray) { val P = BigInteger.fromUByteArray( ubyteArrayOf( 0x03U, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xfbU - ) + ), + Sign.POSITIVE ) val powersOfTwo = Array(129) { BigInteger.ONE shl it @@ -45,22 +48,22 @@ class Poly1305(key: UByteArray) { val s= UByteArray(16) { key[it + 16]} var accumulator = BigInteger.ZERO - val rAsBigInt = BigInteger.fromUByteArray(r, Endianness.LITTLE) //TODO update BigInt to make this eraseable - val sAsBigInt = BigInteger.fromUByteArray(s, Endianness.LITTLE) + val rAsBigInt = BigInteger.fromUByteArray(r.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) //TODO convert from little endian ubyte array to what BigInteger expects + val sAsBigInt = BigInteger.fromUByteArray(s.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) val blocks = message.size / 16 val remainder = message.size % 16 for (i in 0 until blocks) { val slice = message.sliceArray(i * 16 until i * 16 + 16) slice.hexColumsPrint() - val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[128] + val blockAsInt = BigInteger.fromUByteArray(slice.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) + powersOfTwo[128] accumulator += blockAsInt accumulator *= rAsBigInt accumulator %= P } if (remainder != 0) { val slice = message.sliceArray(blocks * 16 until blocks * 16 + remainder) - val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[remainder * 8] + val blockAsInt = BigInteger.fromUByteArray(slice.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) + powersOfTwo[remainder * 8] accumulator += blockAsInt accumulator *= rAsBigInt accumulator %= P @@ -68,22 +71,29 @@ class Poly1305(key: UByteArray) { accumulator += sAsBigInt accumulator = accumulator and resultMask - val result = accumulator.toUByteArray(Endianness.BIG) + val result = accumulator.toUByteArray() result.reverse() return result } } - var rAsBigInt = BigInteger.fromUByteArray(clampR(key.sliceArray(0 until 16)), Endianness.LITTLE) - var sAsBigInt = BigInteger.fromUByteArray(key.sliceArray(16 until 32), Endianness.LITTLE) + var rAsBigInt = BigInteger.fromUByteArray( + clampR(key.sliceArray(0 until 16)).fromLittleEndianUByteArrayToBigEndianUByteArray(), + Sign.POSITIVE + ) + var sAsBigInt = BigInteger.fromUByteArray( + key.sliceArray(16 until 32).fromLittleEndianUByteArrayToBigEndianUByteArray(), + Sign.POSITIVE) var accumulator = BigInteger.ZERO fun updateMac(data : UByteArray) { if (data.size != 16) { throw RuntimeException("Invalide block size, required 16, got ${data.size}") } - val blockAsInt = BigInteger.fromUByteArray(data, Endianness.LITTLE) + powersOfTwo[128] + val blockAsInt = BigInteger.fromUByteArray( + data.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE + ) + powersOfTwo[128] accumulator += blockAsInt accumulator *= rAsBigInt accumulator %= P @@ -91,14 +101,17 @@ class Poly1305(key: UByteArray) { fun finalizeMac(data: UByteArray = ubyteArrayOf()) : UByteArray{ if (data.size != 0) { - val blockAsInt = BigInteger.fromUByteArray(data, Endianness.LITTLE) + powersOfTwo[data.size * 8] + val blockAsInt = BigInteger.fromUByteArray( + data.fromLittleEndianUByteArrayToBigEndianUByteArray(), + Sign.POSITIVE + ) + powersOfTwo[data.size * 8] accumulator += blockAsInt accumulator *= rAsBigInt accumulator %= P } accumulator += sAsBigInt accumulator = accumulator and resultMask - val result = accumulator.toUByteArray(Endianness.BIG) + val result = accumulator.toUByteArray() result.reverse() return result } 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 6e62e07..e477d39 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 @@ -18,6 +18,7 @@ package com.ionspin.kotlin.crypto.symmetric import com.ionspin.kotlin.bignum.Endianness import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign import com.ionspin.kotlin.bignum.modular.ModularBigInteger import com.ionspin.kotlin.crypto.SRNG import com.ionspin.kotlin.crypto.symmetric.AesCtrPure.Companion.encrypt @@ -82,7 +83,7 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m } else { initialCounter } - var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart.toTypedArray(), Endianness.BIG)) + var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart, Sign.POSITIVE)) val output = MutableList(0) { ubyteArrayOf() } @@ -161,7 +162,7 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m } private fun consumeBlock(data: UByteArray, blockCount: ModularBigInteger): UByteArray { - val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).expandCounterTo16Bytes() + val blockCountAsByteArray = blockCount.toUByteArray().expandCounterTo16Bytes() return when (mode) { Mode.ENCRYPT -> { AesPure.encrypt(aesKey, blockCountAsByteArray) xor data