Switch to latest BigInteger, use new byte conversion api

This commit is contained in:
Ugljesa Jovanovic 2020-07-26 20:21:37 +02:00 committed by Ugljesa Jovanovic
parent 0af9ed4337
commit 8b3b94df3a
No known key found for this signature in database
GPG Key ID: 178E6DFCECCB0E0F
5 changed files with 45 additions and 14 deletions

View File

@ -23,7 +23,7 @@ object Versions {
val dokkaPlugin = "0.11.0-dev-44" val dokkaPlugin = "0.11.0-dev-44"
val taskTreePlugin = "1.5" 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 lazySodium = "4.2.6"
val jna = "5.5.0" val jna = "5.5.0"

View File

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

View File

@ -0,0 +1,7 @@
package com.ionspin.kotlin.crypto.keyderivation
/**
* Created by Ugljesa Jovanovic
* ugljesa.jovanovic@ionspin.com
* on 26-Jul-2020
*/

View File

@ -2,6 +2,8 @@ package com.ionspin.kotlin.crypto.mac
import com.ionspin.kotlin.bignum.Endianness import com.ionspin.kotlin.bignum.Endianness
import com.ionspin.kotlin.bignum.integer.BigInteger 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 import com.ionspin.kotlin.crypto.util.hexColumsPrint
/** /**
@ -28,7 +30,8 @@ class Poly1305(key: UByteArray) {
val P = BigInteger.fromUByteArray( val P = BigInteger.fromUByteArray(
ubyteArrayOf( ubyteArrayOf(
0x03U, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xfbU 0x03U, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xffU, 0xfbU
) ),
Sign.POSITIVE
) )
val powersOfTwo = Array(129) { val powersOfTwo = Array(129) {
BigInteger.ONE shl it BigInteger.ONE shl it
@ -45,22 +48,22 @@ class Poly1305(key: UByteArray) {
val s= UByteArray(16) { key[it + 16]} val s= UByteArray(16) { key[it + 16]}
var accumulator = BigInteger.ZERO var accumulator = BigInteger.ZERO
val rAsBigInt = BigInteger.fromUByteArray(r, Endianness.LITTLE) //TODO update BigInt to make this eraseable val rAsBigInt = BigInteger.fromUByteArray(r.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) //TODO convert from little endian ubyte array to what BigInteger expects
val sAsBigInt = BigInteger.fromUByteArray(s, Endianness.LITTLE) val sAsBigInt = BigInteger.fromUByteArray(s.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE)
val blocks = message.size / 16 val blocks = message.size / 16
val remainder = message.size % 16 val remainder = message.size % 16
for (i in 0 until blocks) { for (i in 0 until blocks) {
val slice = message.sliceArray(i * 16 until i * 16 + 16) val slice = message.sliceArray(i * 16 until i * 16 + 16)
slice.hexColumsPrint() slice.hexColumsPrint()
val blockAsInt = BigInteger.fromUByteArray(slice, Endianness.LITTLE) + powersOfTwo[128] val blockAsInt = BigInteger.fromUByteArray(slice.fromLittleEndianUByteArrayToBigEndianUByteArray(), Sign.POSITIVE) + powersOfTwo[128]
accumulator += blockAsInt accumulator += blockAsInt
accumulator *= rAsBigInt accumulator *= rAsBigInt
accumulator %= P accumulator %= P
} }
if (remainder != 0) { if (remainder != 0) {
val slice = message.sliceArray(blocks * 16 until blocks * 16 + remainder) 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 += blockAsInt
accumulator *= rAsBigInt accumulator *= rAsBigInt
accumulator %= P accumulator %= P
@ -68,22 +71,29 @@ class Poly1305(key: UByteArray) {
accumulator += sAsBigInt accumulator += sAsBigInt
accumulator = accumulator and resultMask accumulator = accumulator and resultMask
val result = accumulator.toUByteArray(Endianness.BIG) val result = accumulator.toUByteArray()
result.reverse() result.reverse()
return result return result
} }
} }
var rAsBigInt = BigInteger.fromUByteArray(clampR(key.sliceArray(0 until 16)), Endianness.LITTLE) var rAsBigInt = BigInteger.fromUByteArray(
var sAsBigInt = BigInteger.fromUByteArray(key.sliceArray(16 until 32), Endianness.LITTLE) 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 var accumulator = BigInteger.ZERO
fun updateMac(data : UByteArray) { fun updateMac(data : UByteArray) {
if (data.size != 16) { if (data.size != 16) {
throw RuntimeException("Invalide block size, required 16, got ${data.size}") 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 += blockAsInt
accumulator *= rAsBigInt accumulator *= rAsBigInt
accumulator %= P accumulator %= P
@ -91,14 +101,17 @@ class Poly1305(key: UByteArray) {
fun finalizeMac(data: UByteArray = ubyteArrayOf()) : UByteArray{ fun finalizeMac(data: UByteArray = ubyteArrayOf()) : UByteArray{
if (data.size != 0) { 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 += blockAsInt
accumulator *= rAsBigInt accumulator *= rAsBigInt
accumulator %= P accumulator %= P
} }
accumulator += sAsBigInt accumulator += sAsBigInt
accumulator = accumulator and resultMask accumulator = accumulator and resultMask
val result = accumulator.toUByteArray(Endianness.BIG) val result = accumulator.toUByteArray()
result.reverse() result.reverse()
return result return result
} }

View File

@ -18,6 +18,7 @@ package com.ionspin.kotlin.crypto.symmetric
import com.ionspin.kotlin.bignum.Endianness import com.ionspin.kotlin.bignum.Endianness
import com.ionspin.kotlin.bignum.integer.BigInteger 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.bignum.modular.ModularBigInteger
import com.ionspin.kotlin.crypto.SRNG import com.ionspin.kotlin.crypto.SRNG
import com.ionspin.kotlin.crypto.symmetric.AesCtrPure.Companion.encrypt import com.ionspin.kotlin.crypto.symmetric.AesCtrPure.Companion.encrypt
@ -82,7 +83,7 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m
} else { } else {
initialCounter initialCounter
} }
var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart.toTypedArray(), Endianness.BIG)) var blockCounter = modularCreator.fromBigInteger(BigInteger.fromUByteArray(counterStart, Sign.POSITIVE))
val output = MutableList<UByteArray>(0) { ubyteArrayOf() } val output = MutableList<UByteArray>(0) { ubyteArrayOf() }
@ -161,7 +162,7 @@ internal class AesCtrPure internal constructor(val aesKey: InternalAesKey, val m
} }
private fun consumeBlock(data: UByteArray, blockCount: ModularBigInteger): UByteArray { private fun consumeBlock(data: UByteArray, blockCount: ModularBigInteger): UByteArray {
val blockCountAsByteArray = blockCount.toUByteArray(Endianness.BIG).expandCounterTo16Bytes() val blockCountAsByteArray = blockCount.toUByteArray().expandCounterTo16Bytes()
return when (mode) { return when (mode) {
Mode.ENCRYPT -> { Mode.ENCRYPT -> {
AesPure.encrypt(aesKey, blockCountAsByteArray) xor data AesPure.encrypt(aesKey, blockCountAsByteArray) xor data