Change all occurences of additionalData to associatedData
This commit is contained in:
1 parent
54489ef6cb
commit
3de04749ba
21 files changed
+142
-142
No files matched your search
@@ -102,17 +102,17 @@ object Crypto {
|
||||
}
|
||||
|
||||
object Encryption : EncryptionApi {
|
||||
override fun encrypt(key: SymmetricKey, data : Encryptable<*>, additionalData : UByteArray) : EncryptedData {
|
||||
override fun encrypt(key: SymmetricKey, data : Encryptable<*>, associatedData : UByteArray) : EncryptedData {
|
||||
if (key.value.size != 32) {
|
||||
throw RuntimeException("Invalid key size! Required 32, supplied ${key.value.size}")
|
||||
}
|
||||
val nonce = SRNG.getRandomBytes(24)
|
||||
return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), additionalData), nonce)
|
||||
return EncryptedData(XChaCha20Poly1305Pure.encrypt(key.value, nonce, data.toEncryptableForm(), associatedData), nonce)
|
||||
|
||||
}
|
||||
|
||||
override fun <T: Encryptable<T>> decrypt(key: SymmetricKey, encryptedData : EncryptedData, additionalData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T {
|
||||
return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, additionalData))
|
||||
override fun <T: Encryptable<T>> decrypt(key: SymmetricKey, encryptedData : EncryptedData, associatedData: UByteArray, byteArrayDeserializer : (UByteArray) -> T) : T {
|
||||
return byteArrayDeserializer(XChaCha20Poly1305Pure.decrypt(key.value, encryptedData.nonce, encryptedData.ciphertext, associatedData))
|
||||
|
||||
}
|
||||
|
||||
@@ -130,8 +130,8 @@ object Crypto {
|
||||
class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKey) : MultipartAuthenticatedEncryption {
|
||||
val header = MultipartEncryptionHeader(SRNG.getRandomBytes(24))
|
||||
val primitive = XChaCha20Poly1305Pure(key.value, header.nonce)
|
||||
override fun encryptPartialData(data: UByteArray, additionalData: UByteArray): EncryptedDataPart {
|
||||
return EncryptedDataPart(primitive.streamEncrypt(data, additionalData, 0U))
|
||||
override fun encryptPartialData(data: UByteArray, associatedData: UByteArray): EncryptedDataPart {
|
||||
return EncryptedDataPart(primitive.streamEncrypt(data, associatedData, 0U))
|
||||
}
|
||||
|
||||
override fun startEncryption(): MultipartEncryptionHeader {
|
||||
@@ -144,8 +144,8 @@ class MultipartAuthenticatedEncryptor internal constructor(val key : SymmetricKe
|
||||
}
|
||||
|
||||
class MultipartAuthenticatedDecryptor internal constructor(val decryptor: XChaCha20Poly1305Pure) : MultipartAuthenticatedDecryption {
|
||||
override fun decryptPartialData(data: EncryptedDataPart, additionalData: UByteArray): DecryptedDataPart {
|
||||
return DecryptedDataPart(decryptor.streamDecrypt(data.data, additionalData, 0U))
|
||||
override fun decryptPartialData(data: EncryptedDataPart, associatedData: UByteArray): DecryptedDataPart {
|
||||
return DecryptedDataPart(decryptor.streamDecrypt(data.data, associatedData, 0U))
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
|
||||
+4
-4
@@ -13,7 +13,7 @@ import com.ionspin.kotlin.crypto.util.toLittleEndianUByteArray
|
||||
internal class ChaCha20Poly1305Pure {
|
||||
companion object {
|
||||
|
||||
fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray {
|
||||
fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray {
|
||||
val state = UIntArray(16) {
|
||||
when (it) {
|
||||
0 -> ChaCha20Pure.sigma0_32
|
||||
@@ -37,11 +37,11 @@ internal class ChaCha20Poly1305Pure {
|
||||
}
|
||||
val oneTimeKey = ChaCha20Pure.hash(state).sliceArray(0 until 32)
|
||||
val cipherText = ChaCha20Pure.xorWithKeystream(key, nonce, message, 1U)
|
||||
val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U }
|
||||
val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U }
|
||||
val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U }
|
||||
val macData = additionalData + additionalDataPad +
|
||||
val macData = associatedData + associatedDataPad +
|
||||
cipherText + cipherTextPad +
|
||||
additionalData.size.toULong().toLittleEndianUByteArray() +
|
||||
associatedData.size.toULong().toLittleEndianUByteArray() +
|
||||
cipherText.size.toULong().toLittleEndianUByteArray()
|
||||
val tag = Poly1305.poly1305Authenticate(oneTimeKey, macData)
|
||||
return cipherText + tag
|
||||
|
||||
+18
-18
@@ -15,7 +15,7 @@ import com.ionspin.kotlin.crypto.util.*
|
||||
class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
|
||||
companion object : AuthenticatedEncryption {
|
||||
|
||||
override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, additionalData: UByteArray) : UByteArray {
|
||||
override fun encrypt(key: UByteArray, nonce: UByteArray, message: UByteArray, associatedData: UByteArray) : UByteArray {
|
||||
val subKey = XChaCha20Pure.hChacha(key, nonce)
|
||||
val authKey =
|
||||
ChaCha20Pure.xorWithKeystream(
|
||||
@@ -28,17 +28,17 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
|
||||
// at org.jetbrains.kotlin.ir.backend.js.lower.ConstTransformer.lowerConst(ConstLowering.kt:38)
|
||||
)
|
||||
val cipherText = XChaCha20Pure.xorWithKeystream(key, nonce, message, 1U)
|
||||
val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U }
|
||||
val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U }
|
||||
val cipherTextPad = UByteArray(16 - cipherText.size % 16) { 0U }
|
||||
val macData = additionalData + additionalDataPad +
|
||||
val macData = associatedData + associatedDataPad +
|
||||
cipherText + cipherTextPad +
|
||||
additionalData.size.toULong().toLittleEndianUByteArray() +
|
||||
associatedData.size.toULong().toLittleEndianUByteArray() +
|
||||
cipherText.size.toULong().toLittleEndianUByteArray()
|
||||
val tag = Poly1305.poly1305Authenticate(authKey, macData)
|
||||
return cipherText + tag
|
||||
}
|
||||
|
||||
override fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, additionalData: UByteArray) : UByteArray {
|
||||
override fun decrypt(key: UByteArray, nonce: UByteArray, cipherText: UByteArray, associatedData: UByteArray) : UByteArray {
|
||||
val subKey = XChaCha20Pure.hChacha(key, nonce)
|
||||
val authKey =
|
||||
ChaCha20Pure.xorWithKeystream(
|
||||
@@ -51,11 +51,11 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
|
||||
val tag = cipherText.sliceArray(cipherText.size - 16 until cipherText.size)
|
||||
//3. Verify tag is valid
|
||||
val cipherTextWithoutTag = cipherText.sliceArray(0 until cipherText.size - 16)
|
||||
val additionalDataPad = UByteArray(16 - additionalData.size % 16) { 0U }
|
||||
val associatedDataPad = UByteArray(16 - associatedData.size % 16) { 0U }
|
||||
val cipherTextPad = UByteArray(16 - cipherTextWithoutTag.size % 16) { 0U }
|
||||
val macData = additionalData + additionalDataPad +
|
||||
val macData = associatedData + associatedDataPad +
|
||||
cipherTextWithoutTag + cipherTextPad +
|
||||
additionalData.size.toULong().toLittleEndianUByteArray() +
|
||||
associatedData.size.toULong().toLittleEndianUByteArray() +
|
||||
cipherTextWithoutTag.size.toULong().toLittleEndianUByteArray()
|
||||
val calculatedTag = Poly1305.poly1305Authenticate(authKey, macData)
|
||||
if (!calculatedTag.contentEquals(tag)) {
|
||||
@@ -86,15 +86,15 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
|
||||
calcNonce[3] = 0U
|
||||
}
|
||||
|
||||
fun streamEncrypt(data: UByteArray, additionalData: UByteArray, tag : UByte) : UByteArray {
|
||||
fun streamEncrypt(data: UByteArray, associatedData: UByteArray, tag : UByte) : UByteArray {
|
||||
//get encryption state
|
||||
val block = UByteArray(64) { 0U }
|
||||
ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 0U).copyInto(block) // This is equivalent to the first 64 bytes of keystream
|
||||
val poly1305 = Poly1305(block)
|
||||
block.overwriteWithZeroes()
|
||||
if (additionalData.isNotEmpty()) {
|
||||
val additionalDataPadded = additionalData + UByteArray(16 - additionalData.size % 16) { 0U }
|
||||
processPolyBytes(poly1305, additionalDataPadded)
|
||||
if (associatedData.isNotEmpty()) {
|
||||
val associatedDataPadded = associatedData + UByteArray(16 - associatedData.size % 16) { 0U }
|
||||
processPolyBytes(poly1305, associatedDataPadded)
|
||||
}
|
||||
block[0] = tag
|
||||
ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block) // This just xors block[0] with keystream
|
||||
@@ -109,21 +109,21 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
|
||||
// From security standpoint there are no obvious drawbacks, as padding was initially added to decrease implementation complexity.
|
||||
processPolyBytes(poly1305, ciphertext + UByteArray(((16U + data.size.toUInt() - block.size.toUInt()) % 16U).toInt()) { 0U } ) //TODO this is inefficient as it creates a new array and copies data
|
||||
// Last 16byte block containing actual additional data nad ciphertext sizes
|
||||
val finalMac = additionalData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray()
|
||||
val finalMac = associatedData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray()
|
||||
processPolyBytes(poly1305, finalMac)
|
||||
val mac = poly1305.finalizeMac(polyBuffer.sliceArray(0 until polyBufferByteCounter))
|
||||
calcNonce.xorWithPositionsAndInsertIntoArray(0, 12, mac, 0, calcNonce, 0)
|
||||
return ubyteArrayOf(encryptedTag) + ciphertext + mac
|
||||
}
|
||||
|
||||
fun streamDecrypt(data: UByteArray, additionalData: UByteArray, tag: UByte) : UByteArray {
|
||||
fun streamDecrypt(data: UByteArray, associatedData: UByteArray, tag: UByte) : UByteArray {
|
||||
val block = UByteArray(64) { 0U }
|
||||
ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 0U).copyInto(block) // This is equivalent to the first 64 bytes of keystream
|
||||
val poly1305 = Poly1305(block)
|
||||
block.overwriteWithZeroes()
|
||||
if (additionalData.isNotEmpty()) {
|
||||
val additionalDataPadded = additionalData + UByteArray(16 - additionalData.size % 16) { 0U }
|
||||
processPolyBytes(poly1305, additionalDataPadded)
|
||||
if (associatedData.isNotEmpty()) {
|
||||
val associatedDataPadded = associatedData + UByteArray(16 - associatedData.size % 16) { 0U }
|
||||
processPolyBytes(poly1305, associatedDataPadded)
|
||||
}
|
||||
block[0] = data[0]
|
||||
ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, block, 1U).copyInto(block)// get the keystream xored with zeroes, but also decrypteg tag marker
|
||||
@@ -137,7 +137,7 @@ class XChaCha20Poly1305Pure(val key: UByteArray, val nonce: UByteArray) {
|
||||
val ciphertext = data.sliceArray(1 until data.size - 16)
|
||||
processPolyBytes(poly1305, ciphertext + UByteArray(((16U + ciphertext.size.toUInt() - block.size.toUInt()) % 16U).toInt()) { 0U } )
|
||||
val plaintext = ChaCha20Pure.xorWithKeystream(calcKey, calcNonce, ciphertext, 2U)
|
||||
val finalMac = additionalData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray()
|
||||
val finalMac = associatedData.size.toULong().toLittleEndianUByteArray() + (ciphertext.size + 64).toULong().toLittleEndianUByteArray()
|
||||
processPolyBytes(poly1305, finalMac)
|
||||
val mac = poly1305.finalizeMac(polyBuffer.sliceArray(0 until polyBufferByteCounter))
|
||||
val expectedMac = data.sliceArray(data.size - 16 until data.size)
|
||||
|
||||
+3
-3
@@ -19,7 +19,7 @@ class ChaCha20Poly1305Test {
|
||||
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(
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
@@ -44,7 +44,7 @@ class ChaCha20Poly1305Test {
|
||||
0x61U, 0x16U, 0x1aU, 0xe1U, 0x0bU, 0x59U, 0x4fU, 0x09U, 0xe2U, 0x6aU, 0x7eU, 0x90U, 0x2eU, 0xcbU, 0xd0U, 0x60U,
|
||||
0x06U, 0x91U
|
||||
)
|
||||
val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData)
|
||||
val result = ChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData)
|
||||
result.hexColumsPrint()
|
||||
assertTrue {
|
||||
result.contentEquals(expected)
|
||||
@@ -53,4 +53,4 @@ class ChaCha20Poly1305Test {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -20,7 +20,7 @@ class XChaCha20Poly1305Test {
|
||||
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(
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
@@ -55,8 +55,8 @@ class XChaCha20Poly1305Test {
|
||||
0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU,
|
||||
0xcfU, 0x49U
|
||||
)
|
||||
val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData)
|
||||
val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, additionalData)
|
||||
val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData)
|
||||
val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, associatedData)
|
||||
|
||||
encrypted.contentEquals(expected) && decrypted.contentEquals(message)
|
||||
}
|
||||
@@ -65,7 +65,7 @@ class XChaCha20Poly1305Test {
|
||||
val message = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val additionalData = ubyteArrayOf(
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
@@ -84,8 +84,8 @@ class XChaCha20Poly1305Test {
|
||||
0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U,
|
||||
0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU
|
||||
)
|
||||
val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, additionalData)
|
||||
val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, additionalData)
|
||||
val encrypted = XChaCha20Poly1305Pure.encrypt(key, nonce, message, associatedData)
|
||||
val decrypted = XChaCha20Poly1305Pure.decrypt(key, nonce, encrypted, associatedData)
|
||||
|
||||
encrypted.contentEquals(expected) && decrypted.contentEquals(message)
|
||||
}
|
||||
@@ -99,7 +99,7 @@ class XChaCha20Poly1305Test {
|
||||
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(
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x50U, 0x51U, 0x52U, 0x53U, 0xc0U, 0xc1U, 0xc2U, 0xc3U, 0xc4U, 0xc5U, 0xc6U, 0xc7U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
@@ -134,7 +134,7 @@ class XChaCha20Poly1305Test {
|
||||
0x98U, 0x79U, 0x47U, 0xdeU, 0xafU, 0xd8U, 0x78U, 0x0aU,
|
||||
0xcfU, 0x49U
|
||||
)
|
||||
// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData) val firstChunk =
|
||||
// val xChaChaPoly = XChaCha20Poly1305Pure(key, associatedData) val firstChunk =
|
||||
// xChaChaPoly.encryptPartialData(message) val finalChunk = xChaChaPoly.finishEncryption().first val result =
|
||||
// firstChunk + finalChunk result.contentEquals(expected)
|
||||
1 == 1
|
||||
@@ -144,7 +144,7 @@ class XChaCha20Poly1305Test {
|
||||
val message = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val additionalData = ubyteArrayOf(
|
||||
val associatedData = ubyteArrayOf(
|
||||
0x00U
|
||||
)
|
||||
val key = ubyteArrayOf(
|
||||
@@ -163,7 +163,7 @@ class XChaCha20Poly1305Test {
|
||||
0xbdU, 0x3bU, 0x8aU, 0xd7U, 0xa1U, 0x9dU, 0xe8U, 0xc4U, 0x55U,
|
||||
0x84U, 0x6fU, 0xfcU, 0x75U, 0x31U, 0xbfU, 0x0cU, 0x2dU
|
||||
)
|
||||
// val xChaChaPoly = XChaCha20Poly1305Pure(key, additionalData)
|
||||
// val xChaChaPoly = XChaCha20Poly1305Pure(key, associatedData)
|
||||
// val firstChunk = xChaChaPoly.encryptPartialData(message)
|
||||
// val finalChunk = xChaChaPoly.finishEncryption().first
|
||||
// val result = firstChunk + finalChunk
|
||||
|
||||
+4
-4
@@ -20,18 +20,18 @@ class EncryptionTest {
|
||||
"ojsAn3c9zIifIrMnydSivHVZ2pBtpAQwYoJhYmEsfE0tROGnOwFWyB9K6LRSv1gB3YqKR9VyM8mpRoUM3UCRRjyiX7bnKdCE1" +
|
||||
"EiX0myiwcY1nUKTgB3keERWtMU07hX7bCtao5nRvDofSj3o3IInHRQh6opltr5asQwn4m1qn029QF").encodeToUByteArray()
|
||||
plaintext.hexColumsPrint()
|
||||
val additionalData = "Additional data 1".encodeToUByteArray()
|
||||
// val additionalData = ubyteArrayOf()
|
||||
val associatedData = "Additional data 1".encodeToUByteArray()
|
||||
// val associatedData = ubyteArrayOf()
|
||||
val keyValue = UByteArray(32) { it.toUByte() }
|
||||
val key = SymmetricKey(keyValue)
|
||||
val encryptor = Crypto.Encryption.createMultipartEncryptor(key)
|
||||
val header = encryptor.startEncryption()
|
||||
val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), additionalData)
|
||||
val ciphertext1 = encryptor.encryptPartialData(plaintext.sliceArray(0 until 100), associatedData)
|
||||
val ciphertext2 = encryptor.encryptPartialData(plaintext.sliceArray(100 until 200))
|
||||
val ciphertext3 = encryptor.encryptPartialData(plaintext.sliceArray(200 until 250))
|
||||
//decrypt
|
||||
val decryptor = Crypto.Encryption.createMultipartDecryptor(key, header)
|
||||
val plaintext1 = decryptor.decryptPartialData(ciphertext1, additionalData)
|
||||
val plaintext1 = decryptor.decryptPartialData(ciphertext1, associatedData)
|
||||
val plaintext2 = decryptor.decryptPartialData(ciphertext2)
|
||||
val plaintext3 = decryptor.decryptPartialData(ciphertext3)
|
||||
|
||||
|
||||
Reference in new issue
Block a user