diff --git a/buildSrc/src/main/kotlin/Deps.kt b/buildSrc/src/main/kotlin/Deps.kt index 1c80a48..7a906c0 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-M2-SNAPSHOT" + val kotlinBigNumVersion = "0.1.6-1.4-M2-2-SNAPSHOT" val lazySodium = "4.2.6" val jna = "5.5.0" diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305Pure.kt deleted file mode 100644 index f92a2cc..0000000 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/Poly1305Pure.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.ionspin.kotlin.crypto.mac - -/** - * Created by Ugljesa Jovanovic - * ugljesa.jovanovic@ionspin.com - * on 17-Jun-2020 - */ diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/XChaCha20Poly1305Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/XChaCha20Poly1305Pure.kt new file mode 100644 index 0000000..e1bafc0 --- /dev/null +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/mac/XChaCha20Poly1305Pure.kt @@ -0,0 +1,84 @@ +package com.ionspin.kotlin.crypto.mac + +import com.ionspin.kotlin.bignum.Endianness +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.crypto.util.hexColumsPrint + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +class XChaCha20Poly1305Pure { + companion object { + fun clampR(r: UByteArray) { + r[3] = r[3] and 0b00001111U + r[7] = r[7] and 0b00001111U + r[11] = r[11] and 0b00001111U + r[15] = r[15] and 0b00001111U + + r[4] = r[4] and 0b11111100U + r[8] = r[8] and 0b11111100U + r[12] = r[12] and 0b11111100U + + } + + val P = BigInteger.fromUByteArray( + ubyteArrayOf( + 0x03U, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xfbU + ).toTypedArray() //TODO remove to typed array after bignum update + ) + val powersOfTwo = Array(129) { + BigInteger.ONE shl it + } + val resultMask = (BigInteger.ONE shl 129) - 1 + //Doesn't have to be every power, just divisible by 8 + val twoToThe128 = BigInteger.ONE.shl(128) + + fun poly1305Authenticate(key: UByteArray, message: UByteArray) : UByteArray { + val r = UByteArray(16) { key[it] } + val s= UByteArray(16) { key[it + 16]} + clampR(r) + println("P: ${P.toString(16)}") + var accumulator = BigInteger.ZERO + val rAsBigInt = BigInteger.fromUByteArray(r, Endianness.LITTLE) + val sAsBigInt = BigInteger.fromUByteArray(s, Endianness.LITTLE) + 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] + println("blockAsInt: ${blockAsInt.toString(16)}") + accumulator += blockAsInt + println("Accumlator: ${accumulator.toString(16)}") + accumulator *= rAsBigInt + println("Accumlator: ${accumulator.toString(16)}") + accumulator %= P + println("Accumlator: ${accumulator.toString(16)}") + } + + val slice = message.sliceArray(blocks * 16 until blocks * 16 + remainder) + val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[remainder * 8] + println("blockAsInt: ${blockAsInt.toString(16)}") + accumulator += blockAsInt + println("Accumlator: ${accumulator.toString(16)}") + accumulator *= rAsBigInt + println("Accumlator: ${accumulator.toString(16)}") + accumulator %= P + println("Accumlator: ${accumulator.toString(16)}") + + + println("Result mask: ${resultMask.toString(2)}") + accumulator += sAsBigInt + accumulator = accumulator and resultMask + println("Accumlator: ${accumulator.toString(16)}") + val result = accumulator.toUByteArray(Endianness.BIG) + result.reverse() + return result + + + } + } +} \ No newline at end of file diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Pure.kt index 8cbfdfd..81b61fd 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/ChaCha20Pure.kt @@ -7,7 +7,7 @@ import com.ionspin.kotlin.crypto.util.* * ugljesa.jovanovic@ionspin.com * on 16-Jun-2020 */ -class ChaCha20Pure { +internal class ChaCha20Pure { companion object { fun quarterRound(input: UIntArray, aPosition: Int, bPosition: Int, cPosition: Int, dPosition: Int) { input[aPosition] += input[bPosition] diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Pure.kt index 3260e03..56d177f 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Pure.kt @@ -7,7 +7,7 @@ import com.ionspin.kotlin.crypto.util.* * ugljesa.jovanovic@ionspin.com * on 14-Jun-2020 */ -class Salsa20Pure { +internal class Salsa20Pure { companion object { fun quarterRound(input: UIntArray, y0position: Int, y1position: Int, y2position: Int, y3position: Int) { input[y1position] = input[y1position] xor ((input[y0position] + input[y3position]) rotateLeft 7) diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Pure.kt index b04a623..a3589c7 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XChaCha20Pure.kt @@ -9,7 +9,7 @@ import com.ionspin.kotlin.crypto.util.xorWithPositionsAndInsertIntoArray * ugljesa.jovanovic@ionspin.com * on 14-Jun-2020 */ -class XChaCha20Pure { +internal class XChaCha20Pure { companion object { fun hChacha(key: UByteArray, nonce: UByteArray) : UIntArray { val state = UIntArray(16) { diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Pure.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Pure.kt index e80b536..9849f86 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Pure.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/XSalsa20Pure.kt @@ -9,7 +9,7 @@ import com.ionspin.kotlin.crypto.util.xorWithPositionsAndInsertIntoArray * ugljesa.jovanovic@ionspin.com * on 16-Jun-2020 */ -class XSalsa20Pure { +internal class XSalsa20Pure { companion object { fun hSalsa(key: UByteArray, nonce: UByteArray): UIntArray { val state = UIntArray(16) { diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/mac/XChaCha20Poly1305Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/mac/XChaCha20Poly1305Test.kt new file mode 100644 index 0000000..a09635d --- /dev/null +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/mac/XChaCha20Poly1305Test.kt @@ -0,0 +1,51 @@ +package com.ionspin.kotlin.crypto.mac + +import com.ionspin.kotlin.crypto.util.hexColumsPrint +import kotlin.test.Test +import kotlin.test.assertTrue + +/** + * Created by Ugljesa Jovanovic + * ugljesa.jovanovic@ionspin.com + * on 17-Jun-2020 + */ +class XChaCha20Poly1305Test { + @Test + fun debugTest() { + XChaCha20Poly1305Pure.poly1305Authenticate( + UByteArray(32) { if (it < 16) { 0U } else {1U} }, + UByteArray(37) { it.toUByte() }, + ) + } + + /** + * From RFC7539 + */ + @Test + fun testPoly1305() { + val key = ubyteArrayOf( + 0x85U, 0xd6U, 0xbeU, 0x78U, 0x57U, 0x55U, 0x6dU, 0x33U, 0x7fU, 0x44U, 0x52U, 0xfeU, 0x42U, 0xd5U, 0x06U, + 0xa8U, 0x01U, 0x03U, 0x80U, 0x8aU, 0xfbU, 0x0dU, 0xb2U, 0xfdU, 0x4aU, 0xbfU, 0xf6U, 0xafU, 0x41U, 0x49U, + 0xf5U, 0x1bU + ) + val message = ubyteArrayOf( + 0x43U, 0x72U, 0x79U, 0x70U, 0x74U, 0x6fU, 0x67U, 0x72U, 0x61U, 0x70U, 0x68U, 0x69U, 0x63U, 0x20U, 0x46U, 0x6fU, + 0x72U, 0x75U, 0x6dU, 0x20U, 0x52U, 0x65U, 0x73U, 0x65U, 0x61U, 0x72U, 0x63U, 0x68U, 0x20U, 0x47U, 0x72U, 0x6fU, + 0x75U, 0x70U + ) + val expected = ubyteArrayOf( + 0xA8U, 0x06U, 0x1DU, 0xC1U, + 0x30U, 0x51U, 0x36U, 0xC6U, + 0xC2U, 0x2BU, 0x8BU, 0xAFU, + 0x0CU, 0x01U, 0x27U, 0xA9U, + ) + + val result = XChaCha20Poly1305Pure.poly1305Authenticate( + key, + message, + ) + assertTrue { + expected.contentEquals(result) + } + } +} \ No newline at end of file