From 946fc6a4ce7a5431dec49a9dfc99680d339c187f Mon Sep 17 00:00:00 2001 From: Ugljesa Jovanovic Date: Sun, 14 Jun 2020 19:13:36 +0200 Subject: [PATCH] Salsa 20 progress --- .../kotlin/crypto/symmetric/Salsa20.kt | 110 +++++- .../kotlin/crypto/symmetric/Salsa20Test.kt | 327 ++++++++++++++++-- 2 files changed, 387 insertions(+), 50 deletions(-) diff --git a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20.kt b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20.kt index 770dd3a..82c488b 100644 --- a/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20.kt +++ b/multiplatform-crypto/src/commonMain/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20.kt @@ -1,6 +1,6 @@ package com.ionspin.kotlin.crypto.symmetric -import com.ionspin.kotlin.crypto.util.* +import com.ionspin.kotlin.crypto.util.rotateLeft /** * Created by Ugljesa Jovanovic @@ -9,23 +9,103 @@ import com.ionspin.kotlin.crypto.util.* */ class Salsa20 { companion object { - fun coreHash(input: UByteArray) : UByteArray { - val y0 = input.fromBigEndianArrayToUintWithPosition(0) - val y1 = input.fromBigEndianArrayToUintWithPosition(4) - val y2 = input.fromBigEndianArrayToUintWithPosition(8) - val y3 = input.fromBigEndianArrayToUintWithPosition(12); + fun quarterRound(input: UIntArray, y0position: Int, y1position: Int, y2position: Int, y3position: Int) { + input[y1position] = input[y1position] xor ((input[y0position] + input[y3position]) rotateLeft 7) + input[y2position] = input[y2position] xor ((input[y1position] + input[y0position]) rotateLeft 9) + input[y3position] = input[y3position] xor ((input[y2position] + input[y1position]) rotateLeft 13) + input[y0position] = input[y0position] xor ((input[y3position] + input[y2position]) rotateLeft 18) + } - val z1 = y1 xor ((y0 + y3) rotateLeft 7) - val z2 = y2 xor ((z1 + y0) rotateLeft 9) - val z3 = y3 xor ((z2 + z1) rotateLeft 13) - val z0 = y0 xor ((z3 + z2) rotateLeft 18) - val result = UByteArray(16) - result.insertUIntAtPositionAsBigEndian(0, z0) - result.insertUIntAtPositionAsBigEndian(4, z1) - result.insertUIntAtPositionAsBigEndian(8, z2) - result.insertUIntAtPositionAsBigEndian(12, z3) + fun rowRound(input: UIntArray) { + quarterRound(input, 0, 1, 2, 3) + quarterRound(input, 5, 6, 7, 4) + quarterRound(input, 10, 11, 8, 9) + quarterRound(input, 15, 12, 13, 14) + } + + fun columnRound(input: UIntArray) { + quarterRound(input, 0, 4, 8, 12) + quarterRound(input, 5, 9, 13, 1) + quarterRound(input, 10, 14, 2, 6) + quarterRound(input, 15, 3, 7, 11) + } + + fun doubleRound(input: UIntArray) { + columnRound(input) + rowRound(input) + } + + fun littleEndian( + input: UByteArray, + byte0Position: Int, + byte1Position: Int, + byte2Position: Int, + byte3Position: Int + ): UInt { + var uint = 0U + uint = input[byte0Position].toUInt() + uint = uint or (input[byte1Position].toUInt() shl 8) + uint = uint or (input[byte2Position].toUInt() shl 16) + uint = uint or (input[byte3Position].toUInt() shl 24) + + return uint + } + + fun littleEndianInverted( + input: UIntArray, + startingPosition: Int, + output: UByteArray, + outputPosition: Int + ) { + output[outputPosition] = (input[startingPosition] and 0xFFU).toUByte() + output[outputPosition + 1] = ((input[startingPosition] shr 8) and 0xFFU).toUByte() + output[outputPosition + 2] = ((input[startingPosition] shr 16) and 0xFFU).toUByte() + output[outputPosition + 3] = ((input[startingPosition] shr 24) and 0xFFU).toUByte() + } + + fun littleEndianInverted( + input: UInt, + output: UByteArray, + outputPosition: Int + ) { + output[outputPosition] = (input and 0xFFU).toUByte() + output[outputPosition + 1] = ((input shr 8) and 0xFFU).toUByte() + output[outputPosition + 2] = ((input shr 16) and 0xFFU).toUByte() + output[outputPosition + 3] = ((input shr 24) and 0xFFU).toUByte() + } + + fun hash(input: UByteArray): UByteArray { + val state = UIntArray(16) { + littleEndian(input, (it * 4) + 0, (it * 4) + 1, (it * 4) + 2, (it * 4) + 3) + } + val initialState = state.copyOf() + for (i in 0 until 10) { + doubleRound(state) + } + val result = UByteArray(64) + for (i in 0 until 16) { + littleEndianInverted(initialState[i] + state[i], result, i * 4) + } return result } + + val sigma0_32 = ubyteArrayOf(101U, 120U, 112U, 97U) + val sigma1_32 = ubyteArrayOf(110U, 100U, 32U, 51U) + val sigma2_32 = ubyteArrayOf(50U, 45U, 98U, 121U) + val sigma3_32 = ubyteArrayOf(116U, 101U, 32U, 107U) + + val sigma0_16 = ubyteArrayOf(101U, 120U, 112U, 97U) + val sigma1_16 = ubyteArrayOf(110U, 100U, 32U, 49U) + val sigma2_16 = ubyteArrayOf(54U, 45U, 98U, 121U) + val sigma3_16 = ubyteArrayOf(116U, 101U, 32U, 107U) + + fun expansion16(k: UByteArray, n: UByteArray) : UByteArray { + return hash(sigma0_16 + k + sigma1_16 + n + sigma2_16 + k + sigma3_16) + } + + fun expansion32(k:UByteArray, n: UByteArray) : UByteArray { + return hash(sigma0_32 + k.slice(0 until 16) + sigma1_32 + n + sigma2_32 + k.slice(16 until 32) + sigma3_32) + } } } \ No newline at end of file diff --git a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Test.kt b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Test.kt index 5e758d5..f16b489 100644 --- a/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Test.kt +++ b/multiplatform-crypto/src/commonTest/kotlin/com/ionspin/kotlin/crypto/symmetric/Salsa20Test.kt @@ -1,8 +1,6 @@ package com.ionspin.kotlin.crypto.symmetric -import com.ionspin.kotlin.crypto.util.hexStringToUByteArray import com.ionspin.kotlin.crypto.util.rotateLeft -import com.ionspin.kotlin.crypto.util.toHexString import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -18,65 +16,324 @@ class Salsa20Test { fun testRotateLeft() { val a = 0xc0a8787eU val b = a rotateLeft 5 - val expected = 0x150f0fd8U + val expected = 0x150f0fd8U assertEquals(b, expected) } @Test - fun testCoreHash() { + fun testQuarterRound() { assertTrue { - val input = "00000000000000000000000000000000".hexStringToUByteArray() - val expected = "00000000000000000000000000000000".hexStringToUByteArray() - val result = Salsa20.coreHash(input) - println("Result ${result.toHexString()}") + val input = uintArrayOf(0U, 0U, 0U, 0U) + val expected = uintArrayOf(0U, 0U, 0U, 0U) + Salsa20.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") - expected.contentEquals(result) + expected.contentEquals(input) } assertTrue { - val input = "00000001000000000000000000000000".hexStringToUByteArray() - val expected = "08008145000000800001020020500000".hexStringToUByteArray() - val result = Salsa20.coreHash(input) - println("Result ${result.toHexString()}") + val input = uintArrayOf(1U, 0U, 0U, 0U) + val expected = uintArrayOf(0x08008145U, 0x00000080U, 0x00010200U, 0x20500000U) + Salsa20.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") - expected.contentEquals(result) + expected.contentEquals(input) } assertTrue { - val input = "00000000000000010000000000000000".hexStringToUByteArray() - val expected = "88000100000000010000020000402000".hexStringToUByteArray() - val result = Salsa20.coreHash(input) - println("Result ${result.toHexString()}") + val input = uintArrayOf(0U, 1U, 0U, 0U) + val expected = uintArrayOf(0x88000100U, 0x00000001U, 0x00000200U, 0x00402000U) + Salsa20.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") - expected.contentEquals(result) + expected.contentEquals(input) } assertTrue { - val input = "00000000000000000000000100000000".hexStringToUByteArray() - val expected = "80040000000000000000000100002000".hexStringToUByteArray() - val result = Salsa20.coreHash(input) - println("Result ${result.toHexString()}") - - expected.contentEquals(result) + val input = uintArrayOf(0U, 0U, 1U, 0U) + val expected = uintArrayOf(0x80040000U, 0x00000000U, 0x00000001U, 0x00002000U) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + Salsa20.quarterRound(input, 0, 1, 2, 3) + expected.contentEquals(input) } assertTrue { - val input = "00000000000000000000000000000001".hexStringToUByteArray() - val expected = "00048044000000800001000020100001".hexStringToUByteArray() - val result = Salsa20.coreHash(input) - println("Result ${result.toHexString()}") + val input = uintArrayOf(0U, 0U, 0U, 1U) + val expected = uintArrayOf(0x00048044U, 0x00000080U, 0x00010000U, 0x20100001U) + Salsa20.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") - expected.contentEquals(result) + expected.contentEquals(input) } assertTrue { - val input = "d3917c5b55f1c40752a58a7a8f887a3b".hexStringToUByteArray() - val expected = "3e2f308cd90a8f366ab2a9232883524c".hexStringToUByteArray() - val result = Salsa20.coreHash(input) - println("Result ${result.toHexString()}") + val input = uintArrayOf(0xd3917c5bU, 0x55f1c407U, 0x52a58a7aU, 0x8f887a3bU) + val expected = uintArrayOf(0x3e2f308cU, 0xd90a8f36U, 0x6ab2a923U, 0x2883524cU) + Salsa20.quarterRound(input, 0, 1, 2, 3) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } - expected.contentEquals(result) + @Test + fun testRowRound() { + assertTrue { + val input = uintArrayOf( + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U + ) + val expected = uintArrayOf( + 0x08008145U, 0x00000080U, 0x00010200U, 0x20500000U, + 0x20100001U, 0x00048044U, 0x00000080U, 0x00010000U, + 0x00000001U, 0x00002000U, 0x80040000U, 0x00000000U, + 0x00000001U, 0x00000200U, 0x00402000U, 0x88000100U + ) + + Salsa20.rowRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + assertTrue { + + val input = uintArrayOf( + 0x08521bd6U, 0x1fe88837U, 0xbb2aa576U, 0x3aa26365U, + 0xc54c6a5bU, 0x2fc74c2fU, 0x6dd39cc3U, 0xda0a64f6U, + 0x90a2f23dU, 0x067f95a6U, 0x06b35f61U, 0x41e4732eU, + 0xe859c100U, 0xea4d84b7U, 0x0f619bffU, 0xbc6e965aU + ) + val expected = uintArrayOf( + 0xa890d39dU, 0x65d71596U, 0xe9487daaU, 0xc8ca6a86U, + 0x949d2192U, 0x764b7754U, 0xe408d9b9U, 0x7a41b4d1U, + 0x3402e183U, 0x3c3af432U, 0x50669f96U, 0xd89ef0a8U, + 0x0040ede5U, 0xb545fbceU, 0xd257ed4fU, 0x1818882dU + ) + Salsa20.rowRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } + + @Test + fun testColumnRound() { + assertTrue { + val input = uintArrayOf( + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U + ) + val expected = uintArrayOf( + 0x10090288U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000101U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00020401U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x40a04001U, 0x00000000U, 0x00000000U, 0x00000000U + ) + + Salsa20.columnRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + assertTrue { + + val input = uintArrayOf( + 0x08521bd6U, 0x1fe88837U, 0xbb2aa576U, 0x3aa26365U, + 0xc54c6a5bU, 0x2fc74c2fU, 0x6dd39cc3U, 0xda0a64f6U, + 0x90a2f23dU, 0x067f95a6U, 0x06b35f61U, 0x41e4732eU, + 0xe859c100U, 0xea4d84b7U, 0x0f619bffU, 0xbc6e965aU + ) + val expected = uintArrayOf( + 0x8c9d190aU, 0xce8e4c90U, 0x1ef8e9d3U, 0x1326a71aU, + 0x90a20123U, 0xead3c4f3U, 0x63a091a0U, 0xf0708d69U, + 0x789b010cU, 0xd195a681U, 0xeb7d5504U, 0xa774135cU, + 0x481c2027U, 0x53a8e4b5U, 0x4c1f89c5U, 0x3f78c9c8U + ) + Salsa20.columnRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } + + @Test + fun testDoubleRound() { + assertTrue { + val input = uintArrayOf( + 0x00000001U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U, + 0x00000000U, 0x00000000U, 0x00000000U, 0x00000000U + ) + val expected = uintArrayOf( + 0x8186a22dU, 0x0040a284U, 0x82479210U, 0x06929051U, + 0x08000090U, 0x02402200U, 0x00004000U, 0x00800000U, + 0x00010200U, 0x20400000U, 0x08008104U, 0x00000000U, + 0x20500000U, 0xa0000040U, 0x0008180aU, 0x612a8020U + ) + + Salsa20.doubleRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + assertTrue { + + val input = uintArrayOf( + 0xde501066U, 0x6f9eb8f7U, 0xe4fbbd9bU, 0x454e3f57U, + 0xb75540d3U, 0x43e93a4cU, 0x3a6f2aa0U, 0x726d6b36U, + 0x9243f484U, 0x9145d1e8U, 0x4fa9d247U, 0xdc8dee11U, + 0x054bf545U, 0x254dd653U, 0xd9421b6dU, 0x67b276c1U + ) + val expected = uintArrayOf( + 0xccaaf672U, 0x23d960f7U, 0x9153e63aU, 0xcd9a60d0U, + 0x50440492U, 0xf07cad19U, 0xae344aa0U, 0xdf4cfdfcU, + 0xca531c29U, 0x8e7943dbU, 0xac1680cdU, 0xd503ca00U, + 0xa74b2ad6U, 0xbc331c5cU, 0x1dda24c7U, 0xee928277U + ) + Salsa20.doubleRound(input) + println("Result ${input.joinToString { it.toString(16).padStart(2, '0') }}") + expected.contentEquals(input) + } + } + + @Test + fun littleEndianTest() { + assertTrue { + val input = ubyteArrayOf(86U, 75U, 30U, 9U) + val expected = 0x091e4b56U + val result = Salsa20.littleEndian(input, 0, 1, 2, 3) + result == expected + } + + assertTrue { + val input = ubyteArrayOf(255U, 255U, 255U, 250U) + val expected = 0xFAFFFFFFU + val result = Salsa20.littleEndian(input, 0, 1, 2, 3) + result == expected + } + } + + @Test + fun littleEndianInvertedArrayTest() { + assertTrue { + val expected = ubyteArrayOf(86U, 75U, 30U, 9U) + val input = uintArrayOf(0x091e4b56U) + val result = UByteArray(4) + Salsa20.littleEndianInverted(input, 0, result, 0) + result.contentEquals(expected) + } + + assertTrue { + val expected = ubyteArrayOf(255U, 255U, 255U, 250U) + val input = uintArrayOf(0xFAFFFFFFU) + val result = UByteArray(4) + Salsa20.littleEndianInverted(input, 0, result, 0) + result.contentEquals(expected) + } + } + + @Test + fun littleEndianInvertedTest() { + assertTrue { + val expected = ubyteArrayOf(86U, 75U, 30U, 9U) + val input = 0x091e4b56U + val result = UByteArray(4) + Salsa20.littleEndianInverted(input, result, 0) + result.contentEquals(expected) + } + + assertTrue { + val expected = ubyteArrayOf(255U, 255U, 255U, 250U) + val input = 0xFAFFFFFFU + val result = UByteArray(4) + Salsa20.littleEndianInverted(input, result, 0) + result.contentEquals(expected) + } + } + + @Test + fun salsa20HashTest() { + assertTrue { + val input = ubyteArrayOf( + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U + ) + val expected = ubyteArrayOf( + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, + 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U + ) + val result = Salsa20.hash(input) + input.contentEquals(expected) + } + + assertTrue { + val input = ubyteArrayOf( + 211U, 159U, 13U, 115U, 76U, 55U, 82U, 183U, 3U, 117U, 222U, 37U, 191U, 187U, 234U, 136U, + 49U, 237U, 179U, 48U, 1U, 106U, 178U, 219U, 175U, 199U, 166U, 48U, 86U, 16U, 179U, 207U, + 31U, 240U, 32U, 63U, 15U, 83U, 93U, 161U, 116U, 147U, 48U, 113U, 238U, 55U, 204U, 36U, + 79U, 201U, 235U, 79U, 3U, 81U, 156U, 47U, 203U, 26U, 244U, 243U, 88U, 118U, 104U, 54U + ) + val expected = ubyteArrayOf( + 109U, 42U, 178U, 168U, 156U, 240U, 248U, 238U, 168U, 196U, 190U, 203U, 26U, 110U, 170U, 154U, + 29U, 29U, 150U, 26U, 150U, 30U, 235U, 249U, 190U, 163U, 251U, 48U, 69U, 144U, 51U, 57U, + 118U, 40U, 152U, 157U, 180U, 57U, 27U, 94U, 107U, 42U, 236U, 35U, 27U, 111U, 114U, 114U, + 219U, 236U, 232U, 135U, 111U, 155U, 110U, 18U, 24U, 232U, 95U, 158U, 179U, 19U, 48U, 202U + ) + val result = Salsa20.hash(input) + result.contentEquals(expected) + } + + assertTrue { + val input = ubyteArrayOf( + 6U, 124U, 83U, 146U, 38U, 191U, 9U, 50U, 4U, 161U, 47U, 222U, 122U, 182U, 223U, 185U, + 75U, 27U, 0U, 216U, 16U, 122U, 7U, 89U, 162U, 104U, 101U, 147U, 213U, 21U, 54U, 95U, + 225U, 253U, 139U, 176U, 105U, 132U, 23U, 116U, 76U, 41U, 176U, 207U, 221U, 34U, 157U, 108U, + 94U, 94U, 99U, 52U, 90U, 117U, 91U, 220U, 146U, 190U, 239U, 143U, 196U, 176U, 130U, 186U + ) + val expected = ubyteArrayOf( + 8U, 18U, 38U, 199U, 119U, 76U, 215U, 67U, 173U, 127U, 144U, 162U, 103U, 212U, 176U, 217U, + 192U, 19U, 233U, 33U, 159U, 197U, 154U, 160U, 128U, 243U, 219U, 65U, 171U, 136U, 135U, 225U, + 123U, 11U, 68U, 86U, 237U, 82U, 20U, 155U, 133U, 189U, 9U, 83U, 167U, 116U, 194U, 78U, + 122U, 127U, 195U, 185U, 185U, 204U, 188U, 90U, 245U, 9U, 183U, 248U, 226U, 85U, 245U, 104U + ) + val result = (0 until 1_000_000).fold(input) { acc, _ -> + Salsa20.hash(acc) + } + result.contentEquals(expected) + } + + } + + @Test + fun testExpansion() { + val k0 = ubyteArrayOf(1U, 2U, 3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U, 13U, 14U, 15U, 16U) + val k1 = ubyteArrayOf(201U, 202U, 203U, 204U, 205U, 206U, 207U, 208U, 209U, 210U, 211U, 212U, 213U, 214U, 215U, 216U) + val n = ubyteArrayOf(101U, 102U, 103U, 104U, 105U, 106U, 107U, 108U, 109U, 110U, 111U, 112U, 113U, 114U, 115U, 116U) + + assertTrue { + val expected = ubyteArrayOf( + 69U, 37U, 68U, 39U, 41U, 15U,107U,193U,255U,139U,122U, 6U,170U,233U,217U, 98U, + 89U,144U,182U,106U, 21U, 51U,200U, 65U,239U, 49U,222U, 34U,215U,114U, 40U,126U, + 104U,197U, 7U,225U,197U,153U, 31U, 2U,102U, 78U, 76U,176U, 84U,245U,246U,184U, + 177U,160U,133U,130U, 6U, 72U,149U,119U,192U,195U,132U,236U,234U,103U,246U, 74U + ) + val result = Salsa20.expansion32(k0+k1, n) + result.contentEquals(expected) + } + + assertTrue { + val expected = ubyteArrayOf( + 39U,173U, 46U,248U, 30U,200U, 82U, 17U, 48U, 67U,254U,239U, 37U, 18U, 13U,247U, + 241U,200U, 61U,144U, 10U, 55U, 50U,185U, 6U, 47U,246U,253U,143U, 86U,187U,225U, + 134U, 85U,110U,246U,161U,163U, 43U,235U,231U, 94U,171U, 51U,145U,214U,112U, 29U, + 14U,232U, 5U, 16U,151U,140U,183U,141U,171U, 9U,122U,181U,104U,182U,177U,193U + ) + val result = Salsa20.expansion16(k0, n) + result.contentEquals(expected) } } } \ No newline at end of file