Added tests, fixed bugs
This commit is contained in:
parent
4762bd96d6
commit
9cb2701715
@ -0,0 +1,96 @@
|
||||
package com.ionspin.kotlin.crypto.box
|
||||
|
||||
import com.ionspin.kotlin.bignum.integer.util.hexColumsPrint
|
||||
import com.ionspin.kotlin.crypto.LibsodiumInitializer
|
||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import kotlin.random.Random
|
||||
import kotlin.random.nextUBytes
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
/**
|
||||
* Created by Ugljesa Jovanovic
|
||||
* ugljesa.jovanovic@ionspin.com
|
||||
* on 01-Sep-2020
|
||||
*/
|
||||
class BoxTest {
|
||||
@Test
|
||||
fun keypairTest() {
|
||||
LibsodiumInitializer.initializeWithCallback {
|
||||
val keypair = Box.keypair()
|
||||
assertTrue {
|
||||
keypair.publicKey.size == crypto_box_PUBLICKEYBYTES
|
||||
}
|
||||
assertTrue {
|
||||
keypair.secretKey.size == crypto_box_SECRETKEYBYTES
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBoxEasy() {
|
||||
val message = "Message message message".encodeToUByteArray()
|
||||
val senderKeypair = Box.keypair()
|
||||
val recipientKeypair = Box.keypair()
|
||||
val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
|
||||
val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey)
|
||||
val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
|
||||
assertTrue {
|
||||
decrypted.contentEquals(message)
|
||||
}
|
||||
|
||||
assertFailsWith<BoxCorruptedOrTamperedDataException>() {
|
||||
val tampered = encrypted.copyOf()
|
||||
tampered[1] = 0U
|
||||
Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBoxEasyDetached() {
|
||||
val message = "Message message message".encodeToUByteArray()
|
||||
val senderKeypair = Box.keypair()
|
||||
val recipientKeypair = Box.keypair()
|
||||
val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
|
||||
val encrypted = Box.detached(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey)
|
||||
val decrypted = Box.openDetached(encrypted.ciphertext, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
|
||||
assertTrue {
|
||||
decrypted.contentEquals(message)
|
||||
}
|
||||
|
||||
assertFailsWith<BoxCorruptedOrTamperedDataException>() {
|
||||
val tampered = encrypted.ciphertext.copyOf()
|
||||
tampered[1] = 0U
|
||||
Box.openDetached(tampered, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBeforeNonceAndMessage() {
|
||||
val message = "Message message message".encodeToUByteArray()
|
||||
val senderKeypair = Box.keypair()
|
||||
val recipientKeypair = Box.keypair()
|
||||
val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
|
||||
val senderComputedSessionKey = Box.beforeNM(recipientKeypair.publicKey, senderKeypair.secretKey)
|
||||
val recipientComputedSessionKey = Box.beforeNM(senderKeypair.publicKey, recipientKeypair.secretKey)
|
||||
|
||||
assertTrue {
|
||||
senderComputedSessionKey.contentEquals(recipientComputedSessionKey)
|
||||
}
|
||||
val encrypted = Box.easyAfterNM(message, messageNonce, senderComputedSessionKey)
|
||||
val decrypted = Box.openEasyAfterNM(encrypted, messageNonce, recipientComputedSessionKey)
|
||||
assertTrue {
|
||||
decrypted.contentEquals(message)
|
||||
}
|
||||
|
||||
assertFailsWith<BoxCorruptedOrTamperedDataException>() {
|
||||
val tampered = encrypted.copyOf()
|
||||
tampered[1] = 0U
|
||||
Box.openEasyAfterNM(tampered, messageNonce, recipientComputedSessionKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -73,7 +73,7 @@ class SecretStreamTest {
|
||||
assertTrue {
|
||||
decrypted.decryptedData.contentEquals(message)
|
||||
}
|
||||
assertFailsWith(SecretStreamCorrupedOrTamperedDataException::class) {
|
||||
assertFailsWith(SecretStreamCorruptedOrTamperedDataException::class) {
|
||||
encrypted[encrypted.size - 5] = 0U
|
||||
val decryptState = SecretStream.xChaCha20Poly1305InitPull(key, stateAndHeader.header)
|
||||
val decrypted =
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.ionspin.kotlin.crypto.box
|
||||
|
||||
import com.ionspin.kotlin.crypto.util.toHexString
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.convert
|
||||
import kotlinx.cinterop.pin
|
||||
@ -9,6 +10,8 @@ import libsodium.crypto_box_easy
|
||||
import libsodium.crypto_box_easy_afternm
|
||||
import libsodium.crypto_box_keypair
|
||||
import libsodium.crypto_box_open_detached
|
||||
import libsodium.crypto_box_open_easy
|
||||
import libsodium.crypto_box_open_easy_afternm
|
||||
import libsodium.crypto_box_seal
|
||||
import libsodium.crypto_box_seal_open
|
||||
import libsodium.crypto_box_seed_keypair
|
||||
@ -38,7 +41,6 @@ actual object Box {
|
||||
val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
|
||||
val publicKeyPinned = publicKey.pin()
|
||||
val secretKeyPinned = secretKey.pin()
|
||||
val seed: UByteArray = UByteArray(crypto_box_SEEDBYTES)
|
||||
val seedPinned = seed.pin()
|
||||
crypto_box_seed_keypair(publicKeyPinned.toPtr(), secretKeyPinned.toPtr(), seedPinned.toPtr())
|
||||
publicKeyPinned.unpin()
|
||||
@ -60,7 +62,7 @@ actual object Box {
|
||||
recipientsPublicKey: UByteArray,
|
||||
sendersSecretKey: UByteArray
|
||||
): UByteArray {
|
||||
val ciphertext = UByteArray(message.size - crypto_box_MACBYTES)
|
||||
val ciphertext = UByteArray(message.size + crypto_box_MACBYTES)
|
||||
val ciphertextPinned = ciphertext.pin()
|
||||
|
||||
val messagePinned = message.pin()
|
||||
@ -83,7 +85,7 @@ actual object Box {
|
||||
recipientsPublicKeyPinned.unpin()
|
||||
sendersSecretKeyPinned.unpin()
|
||||
|
||||
return message
|
||||
return ciphertext
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,7 +101,7 @@ actual object Box {
|
||||
sendersPublicKey: UByteArray,
|
||||
recipientsSecretKey: UByteArray
|
||||
): UByteArray {
|
||||
val message = UByteArray(ciphertext.size + crypto_box_MACBYTES)
|
||||
val message = UByteArray(ciphertext.size - crypto_box_MACBYTES)
|
||||
val messagePinned = message.pin()
|
||||
|
||||
val ciphertextPinned = ciphertext.pin()
|
||||
@ -107,7 +109,7 @@ actual object Box {
|
||||
val sendersPublicKeyPinned = sendersPublicKey.pin()
|
||||
val recipientsSecretKeyPinned = recipientsSecretKey.pin()
|
||||
|
||||
crypto_box_easy(
|
||||
val validationResult = crypto_box_open_easy(
|
||||
messagePinned.toPtr(),
|
||||
ciphertextPinned.toPtr(),
|
||||
ciphertext.size.convert(),
|
||||
@ -122,6 +124,10 @@ actual object Box {
|
||||
sendersPublicKeyPinned.unpin()
|
||||
recipientsSecretKeyPinned.unpin()
|
||||
|
||||
if (validationResult != 0) {
|
||||
throw BoxCorruptedOrTamperedDataException()
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
@ -173,6 +179,8 @@ actual object Box {
|
||||
noncePinned.unpin()
|
||||
precomputedKeyPinned.unpin()
|
||||
|
||||
|
||||
|
||||
return ciphertext
|
||||
}
|
||||
|
||||
@ -191,7 +199,7 @@ actual object Box {
|
||||
val noncePinned = nonce.pin()
|
||||
val precomputedKeyPinned = precomputedKey.pin()
|
||||
|
||||
crypto_box_easy_afternm(
|
||||
val validationResult = crypto_box_open_easy_afternm(
|
||||
messagePinned.toPtr(),
|
||||
ciphertextPinned.toPtr(),
|
||||
ciphertext.size.convert(),
|
||||
@ -204,7 +212,11 @@ actual object Box {
|
||||
noncePinned.unpin()
|
||||
precomputedKeyPinned.unpin()
|
||||
|
||||
return ciphertext
|
||||
if (validationResult != 0) {
|
||||
throw BoxCorruptedOrTamperedDataException()
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
/**
|
||||
@ -232,8 +244,8 @@ actual object Box {
|
||||
|
||||
crypto_box_detached(
|
||||
ciphertextPinned.toPtr(),
|
||||
messagePinned.toPtr(),
|
||||
tagPinned.toPtr(),
|
||||
messagePinned.toPtr(),
|
||||
message.size.convert(),
|
||||
noncePinned.toPtr(),
|
||||
recipientsPublicKeyPinned.toPtr(),
|
||||
@ -246,7 +258,6 @@ actual object Box {
|
||||
noncePinned.unpin()
|
||||
recipientsPublicKeyPinned.unpin()
|
||||
sendersSecretKeyPinned.unpin()
|
||||
|
||||
return BoxEncryptedDataAndTag(ciphertext, tag)
|
||||
}
|
||||
|
||||
@ -265,23 +276,22 @@ actual object Box {
|
||||
): UByteArray {
|
||||
val message = UByteArray(ciphertext.size)
|
||||
|
||||
val messagePinned = message.pin()
|
||||
val ciphertextPinned = ciphertext.pin()
|
||||
val tagPinned = tag.pin()
|
||||
|
||||
val messagePinned = message.pin()
|
||||
val noncePinned = nonce.pin()
|
||||
val recipientsSecretKeyPinned = recipientsSecretKey.pin()
|
||||
val sendersPublicKeyPinned = sendersPublicKey.pin()
|
||||
|
||||
|
||||
crypto_box_open_detached(
|
||||
val validationResult = crypto_box_open_detached(
|
||||
messagePinned.toPtr(),
|
||||
ciphertextPinned.toPtr(),
|
||||
tagPinned.toPtr(),
|
||||
message.size.convert(),
|
||||
ciphertext.size.convert(),
|
||||
noncePinned.toPtr(),
|
||||
recipientsSecretKeyPinned.toPtr(),
|
||||
sendersPublicKeyPinned.toPtr()
|
||||
sendersPublicKeyPinned.toPtr(),
|
||||
recipientsSecretKeyPinned.toPtr()
|
||||
)
|
||||
|
||||
ciphertextPinned.unpin()
|
||||
@ -291,6 +301,10 @@ actual object Box {
|
||||
recipientsSecretKeyPinned.unpin()
|
||||
sendersPublicKeyPinned.unpin()
|
||||
|
||||
if (validationResult != 0) {
|
||||
throw BoxCorruptedOrTamperedDataException()
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
@ -318,16 +332,31 @@ actual object Box {
|
||||
|
||||
actual fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray): UByteArray {
|
||||
val message = UByteArray(ciphertext.size - crypto_box_SEALBYTES)
|
||||
val senderPublicKey = UByteArray(crypto_box_SEALBYTES) {
|
||||
message[ciphertext.size - crypto_box_SEALBYTES + it - 1]
|
||||
}
|
||||
val senderPublicKeyPinned = senderPublicKey.pin()
|
||||
val messagePinned = message.pin()
|
||||
val ciphertextPinned = ciphertext.pin()
|
||||
val recipientsSecretKeyPinned = recipientsSecretKey.pin()
|
||||
|
||||
crypto_box_seal_open(messagePinned.toPtr(), ciphertextPinned.toPtr(), recipientsSecretKeyPinned.toPtr())
|
||||
val validationResult = crypto_box_seal_open(
|
||||
messagePinned.toPtr(),
|
||||
ciphertextPinned.toPtr(),
|
||||
ciphertext.size.convert(),
|
||||
senderPublicKeyPinned.toPtr(),
|
||||
recipientsSecretKeyPinned.toPtr()
|
||||
)
|
||||
|
||||
messagePinned.unpin()
|
||||
ciphertextPinned.unpin()
|
||||
senderPublicKeyPinned.unpin()
|
||||
recipientsSecretKeyPinned.unpin()
|
||||
|
||||
if (validationResult != 0) {
|
||||
throw BoxCorruptedOrTamperedDataException()
|
||||
}
|
||||
|
||||
return message
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.ionspin.kotlin.crypto.secretbox
|
||||
|
||||
import com.ionspin.kotlin.crypto.secretstream.SecretStreamCorrupedOrTamperedDataException
|
||||
import com.ionspin.kotlin.crypto.util.toPtr
|
||||
import kotlinx.cinterop.convert
|
||||
import kotlinx.cinterop.pin
|
||||
|
@ -116,7 +116,7 @@ actual object SecretStream {
|
||||
associatedDataPinned?.unpin()
|
||||
tagPinned.unpin()
|
||||
if (validationResult != 0) {
|
||||
throw SecretStreamCorrupedOrTamperedDataException()
|
||||
throw SecretStreamCorruptedOrTamperedDataException()
|
||||
}
|
||||
return DecryptedDataAndTag(message, tag[0])
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user