Added jvm implementation, fixed seal invalid return
This commit is contained in:
		
							parent
							
								
									9cb2701715
								
							
						
					
					
						commit
						7a8640638c
					
				@ -87,4 +87,4 @@ expect object Box {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray) : UByteArray
 | 
					    fun sealOpen(ciphertext: UByteArray, recipientsSecretKey: UByteArray) : UByteArray
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,9 +1,7 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.box
 | 
					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.LibsodiumInitializer
 | 
				
			||||||
import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
					import com.ionspin.kotlin.crypto.util.encodeToUByteArray
 | 
				
			||||||
import com.ionspin.kotlin.crypto.util.toHexString
 | 
					 | 
				
			||||||
import kotlin.random.Random
 | 
					import kotlin.random.Random
 | 
				
			||||||
import kotlin.random.nextUBytes
 | 
					import kotlin.random.nextUBytes
 | 
				
			||||||
import kotlin.test.Test
 | 
					import kotlin.test.Test
 | 
				
			||||||
@ -31,64 +29,82 @@ class BoxTest {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testBoxEasy() {
 | 
					    fun testBoxEasy() {
 | 
				
			||||||
        val message = "Message message message".encodeToUByteArray()
 | 
					        LibsodiumInitializer.initializeWithCallback {
 | 
				
			||||||
        val senderKeypair = Box.keypair()
 | 
					            val message = "Message message message".encodeToUByteArray()
 | 
				
			||||||
        val recipientKeypair = Box.keypair()
 | 
					            val senderKeypair = Box.keypair()
 | 
				
			||||||
        val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
 | 
					            val recipientKeypair = Box.keypair()
 | 
				
			||||||
        val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey)
 | 
					            val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
 | 
				
			||||||
        val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
					            val encrypted = Box.easy(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey)
 | 
				
			||||||
        assertTrue {
 | 
					            val decrypted = Box.openEasy(encrypted, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
				
			||||||
            decrypted.contentEquals(message)
 | 
					            assertTrue {
 | 
				
			||||||
        }
 | 
					                decrypted.contentEquals(message)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertFailsWith<BoxCorruptedOrTamperedDataException>() {
 | 
					            assertFailsWith<BoxCorruptedOrTamperedDataException>() {
 | 
				
			||||||
            val tampered = encrypted.copyOf()
 | 
					                val tampered = encrypted.copyOf()
 | 
				
			||||||
            tampered[1] = 0U
 | 
					                tampered[1] = 0U
 | 
				
			||||||
            Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
					                Box.openEasy(tampered, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testBoxEasyDetached() {
 | 
					    fun testBoxEasyDetached() {
 | 
				
			||||||
        val message = "Message message message".encodeToUByteArray()
 | 
					        LibsodiumInitializer.initializeWithCallback {
 | 
				
			||||||
        val senderKeypair = Box.keypair()
 | 
					            val message = "Message message message".encodeToUByteArray()
 | 
				
			||||||
        val recipientKeypair = Box.keypair()
 | 
					            val senderKeypair = Box.keypair()
 | 
				
			||||||
        val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
 | 
					            val recipientKeypair = Box.keypair()
 | 
				
			||||||
        val encrypted = Box.detached(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey)
 | 
					            val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
 | 
				
			||||||
        val decrypted = Box.openDetached(encrypted.ciphertext, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
					            val encrypted = Box.detached(message, messageNonce, recipientKeypair.publicKey, senderKeypair.secretKey)
 | 
				
			||||||
        assertTrue {
 | 
					            val decrypted = Box.openDetached(
 | 
				
			||||||
            decrypted.contentEquals(message)
 | 
					                encrypted.ciphertext,
 | 
				
			||||||
        }
 | 
					                encrypted.tag,
 | 
				
			||||||
 | 
					                messageNonce,
 | 
				
			||||||
 | 
					                senderKeypair.publicKey,
 | 
				
			||||||
 | 
					                recipientKeypair.secretKey
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            assertTrue {
 | 
				
			||||||
 | 
					                decrypted.contentEquals(message)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertFailsWith<BoxCorruptedOrTamperedDataException>() {
 | 
					            assertFailsWith<BoxCorruptedOrTamperedDataException>() {
 | 
				
			||||||
            val tampered = encrypted.ciphertext.copyOf()
 | 
					                val tampered = encrypted.ciphertext.copyOf()
 | 
				
			||||||
            tampered[1] = 0U
 | 
					                tampered[1] = 0U
 | 
				
			||||||
            Box.openDetached(tampered, encrypted.tag, messageNonce, senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
					                Box.openDetached(
 | 
				
			||||||
 | 
					                    tampered,
 | 
				
			||||||
 | 
					                    encrypted.tag,
 | 
				
			||||||
 | 
					                    messageNonce,
 | 
				
			||||||
 | 
					                    senderKeypair.publicKey,
 | 
				
			||||||
 | 
					                    recipientKeypair.secretKey
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    fun testBeforeNonceAndMessage() {
 | 
					    fun testBeforeNonceAndMessage() {
 | 
				
			||||||
        val message = "Message message message".encodeToUByteArray()
 | 
					        LibsodiumInitializer.initializeWithCallback {
 | 
				
			||||||
        val senderKeypair = Box.keypair()
 | 
					            val message = "Message message message".encodeToUByteArray()
 | 
				
			||||||
        val recipientKeypair = Box.keypair()
 | 
					            val senderKeypair = Box.keypair()
 | 
				
			||||||
        val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
 | 
					            val recipientKeypair = Box.keypair()
 | 
				
			||||||
        val senderComputedSessionKey = Box.beforeNM(recipientKeypair.publicKey, senderKeypair.secretKey)
 | 
					            val messageNonce = Random(0).nextUBytes(crypto_box_NONCEBYTES)
 | 
				
			||||||
        val recipientComputedSessionKey = Box.beforeNM(senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
					            val senderComputedSessionKey = Box.beforeNM(recipientKeypair.publicKey, senderKeypair.secretKey)
 | 
				
			||||||
 | 
					            val recipientComputedSessionKey = Box.beforeNM(senderKeypair.publicKey, recipientKeypair.secretKey)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertTrue {
 | 
					            assertTrue {
 | 
				
			||||||
            senderComputedSessionKey.contentEquals(recipientComputedSessionKey)
 | 
					                senderComputedSessionKey.contentEquals(recipientComputedSessionKey)
 | 
				
			||||||
        }
 | 
					            }
 | 
				
			||||||
        val encrypted = Box.easyAfterNM(message, messageNonce, senderComputedSessionKey)
 | 
					            val encrypted = Box.easyAfterNM(message, messageNonce, senderComputedSessionKey)
 | 
				
			||||||
        val decrypted = Box.openEasyAfterNM(encrypted, messageNonce, recipientComputedSessionKey)
 | 
					            val decrypted = Box.openEasyAfterNM(encrypted, messageNonce, recipientComputedSessionKey)
 | 
				
			||||||
        assertTrue {
 | 
					            assertTrue {
 | 
				
			||||||
            decrypted.contentEquals(message)
 | 
					                decrypted.contentEquals(message)
 | 
				
			||||||
        }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assertFailsWith<BoxCorruptedOrTamperedDataException>() {
 | 
					            assertFailsWith<BoxCorruptedOrTamperedDataException>() {
 | 
				
			||||||
            val tampered = encrypted.copyOf()
 | 
					                val tampered = encrypted.copyOf()
 | 
				
			||||||
            tampered[1] = 0U
 | 
					                tampered[1] = 0U
 | 
				
			||||||
            Box.openEasyAfterNM(tampered, messageNonce, recipientComputedSessionKey)
 | 
					                Box.openEasyAfterNM(tampered, messageNonce, recipientComputedSessionKey)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,229 @@
 | 
				
			|||||||
 | 
					package com.ionspin.kotlin.crypto.box
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.ionspin.kotlin.crypto.LibsodiumInitializer.sodium
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					actual object Box {
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The crypto_box_keypair() function randomly generates a secret key and a corresponding public key.
 | 
				
			||||||
 | 
					     * The public key is put into pk (crypto_box_PUBLICKEYBYTES bytes) and the secret key into
 | 
				
			||||||
 | 
					     * sk (crypto_box_SECRETKEYBYTES bytes).
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun keypair(): BoxKeyPair {
 | 
				
			||||||
 | 
					        val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES)
 | 
				
			||||||
 | 
					        val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
 | 
				
			||||||
 | 
					        sodium.crypto_box_keypair(publicKey.asByteArray(), secretKey.asByteArray())
 | 
				
			||||||
 | 
					        return BoxKeyPair(publicKey, secretKey)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Using crypto_box_seed_keypair(), the key pair can also be deterministically derived from a single key seed (crypto_box_SEEDBYTES bytes).
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun seedKeypair(seed: UByteArray): BoxKeyPair {
 | 
				
			||||||
 | 
					        val publicKey = UByteArray(crypto_box_PUBLICKEYBYTES)
 | 
				
			||||||
 | 
					        val secretKey = UByteArray(crypto_box_SECRETKEYBYTES)
 | 
				
			||||||
 | 
					        sodium.crypto_box_seed_keypair(publicKey.asByteArray(), secretKey.asByteArray(), seed.asByteArray())
 | 
				
			||||||
 | 
					        return BoxKeyPair(publicKey, secretKey)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The crypto_box_easy() function encrypts a message m whose length is mlen bytes, with a recipient's public key pk, a sender's secret key sk and a nonce n.
 | 
				
			||||||
 | 
					     * n should be crypto_box_NONCEBYTES bytes.
 | 
				
			||||||
 | 
					     * c should be at least crypto_box_MACBYTES + mlen bytes long.
 | 
				
			||||||
 | 
					     * This function writes the authentication tag, whose length is crypto_box_MACBYTES bytes, in c,
 | 
				
			||||||
 | 
					     * immediately followed by the encrypted message, whose length is the same as the plaintext: mlen.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun easy(
 | 
				
			||||||
 | 
					        message: UByteArray,
 | 
				
			||||||
 | 
					        nonce: UByteArray,
 | 
				
			||||||
 | 
					        recipientsPublicKey: UByteArray,
 | 
				
			||||||
 | 
					        sendersSecretKey: UByteArray
 | 
				
			||||||
 | 
					    ): UByteArray {
 | 
				
			||||||
 | 
					        val ciphertext = UByteArray(message.size + crypto_box_MACBYTES)
 | 
				
			||||||
 | 
					        sodium.crypto_box_easy(
 | 
				
			||||||
 | 
					            ciphertext.asByteArray(),
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            message.size.toLong(),
 | 
				
			||||||
 | 
					            nonce.asByteArray(),
 | 
				
			||||||
 | 
					            recipientsPublicKey.asByteArray(),
 | 
				
			||||||
 | 
					            sendersSecretKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return ciphertext
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The crypto_box_open_easy() function verifies and decrypts a ciphertext produced by crypto_box_easy().
 | 
				
			||||||
 | 
					     * c is a pointer to an authentication tag + encrypted message combination, as produced by crypto_box_easy(). clen is the length of this authentication tag + encrypted message combination. Put differently, clen is the number of bytes written by crypto_box_easy(), which is crypto_box_MACBYTES + the length of the message.
 | 
				
			||||||
 | 
					     * The nonce n has to match the nonce used to encrypt and authenticate the message.
 | 
				
			||||||
 | 
					     * pk is the public key of the sender that encrypted the message. sk is the secret key of the recipient that is willing to verify and decrypt it.
 | 
				
			||||||
 | 
					     * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun openEasy(
 | 
				
			||||||
 | 
					        ciphertext: UByteArray,
 | 
				
			||||||
 | 
					        nonce: UByteArray,
 | 
				
			||||||
 | 
					        sendersPublicKey: UByteArray,
 | 
				
			||||||
 | 
					        recipientsSecretKey: UByteArray
 | 
				
			||||||
 | 
					    ): UByteArray {
 | 
				
			||||||
 | 
					        val message = UByteArray(ciphertext.size - crypto_box_MACBYTES)
 | 
				
			||||||
 | 
					        val validationResult = sodium.crypto_box_open_easy(
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.size.toLong(),
 | 
				
			||||||
 | 
					            nonce.asByteArray(),
 | 
				
			||||||
 | 
					            sendersPublicKey.asByteArray(),
 | 
				
			||||||
 | 
					            recipientsSecretKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        if (validationResult != 0) {
 | 
				
			||||||
 | 
					            throw BoxCorruptedOrTamperedDataException()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return message
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The crypto_box_beforenm() function computes a shared secret key given a public key pk and a secret key sk,
 | 
				
			||||||
 | 
					     * and puts it into k (crypto_box_BEFORENMBYTES bytes).
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun beforeNM(publicKey: UByteArray, secretKey: UByteArray): UByteArray {
 | 
				
			||||||
 | 
					        val sessionKey = UByteArray(crypto_box_BEFORENMBYTES)
 | 
				
			||||||
 | 
					        sodium.crypto_box_beforenm(sessionKey.asByteArray(), publicKey.asByteArray(), secretKey.asByteArray())
 | 
				
			||||||
 | 
					        return sessionKey
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun easyAfterNM(
 | 
				
			||||||
 | 
					        message: UByteArray,
 | 
				
			||||||
 | 
					        nonce: UByteArray,
 | 
				
			||||||
 | 
					        precomputedKey: UByteArray
 | 
				
			||||||
 | 
					    ): UByteArray {
 | 
				
			||||||
 | 
					        val ciphertext = UByteArray(message.size + crypto_box_MACBYTES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sodium.crypto_box_easy_afternm(
 | 
				
			||||||
 | 
					            ciphertext.asByteArray(),
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            message.size.toLong(),
 | 
				
			||||||
 | 
					            nonce.asByteArray(),
 | 
				
			||||||
 | 
					            precomputedKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return ciphertext
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The _afternm variants of the previously described functions accept a precalculated shared secret key k instead of a key pair.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun openEasyAfterNM(
 | 
				
			||||||
 | 
					        ciphertext: UByteArray,
 | 
				
			||||||
 | 
					        nonce: UByteArray,
 | 
				
			||||||
 | 
					        precomputedKey: UByteArray
 | 
				
			||||||
 | 
					    ): UByteArray {
 | 
				
			||||||
 | 
					        val message = UByteArray(ciphertext.size - crypto_box_MACBYTES)
 | 
				
			||||||
 | 
					        val validationResult = sodium.crypto_box_open_easy_afternm(
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.size.toLong(),
 | 
				
			||||||
 | 
					            nonce.asByteArray(),
 | 
				
			||||||
 | 
					            precomputedKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (validationResult != 0) {
 | 
				
			||||||
 | 
					            throw BoxCorruptedOrTamperedDataException()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return message
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * This function encrypts a message m of length mlen with a nonce n and a secret key sk for a recipient whose
 | 
				
			||||||
 | 
					     * public key is pk, and puts the encrypted message into c.
 | 
				
			||||||
 | 
					     * Exactly mlen bytes will be put into c, since this function does not prepend the authentication tag.
 | 
				
			||||||
 | 
					     * The tag, whose size is crypto_box_MACBYTES bytes, will be put into mac.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun detached(
 | 
				
			||||||
 | 
					        message: UByteArray,
 | 
				
			||||||
 | 
					        nonce: UByteArray,
 | 
				
			||||||
 | 
					        recipientsPublicKey: UByteArray,
 | 
				
			||||||
 | 
					        sendersSecretKey: UByteArray
 | 
				
			||||||
 | 
					    ): BoxEncryptedDataAndTag {
 | 
				
			||||||
 | 
					        val ciphertext = UByteArray(message.size)
 | 
				
			||||||
 | 
					        val tag = UByteArray(crypto_box_MACBYTES)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sodium.crypto_box_detached(
 | 
				
			||||||
 | 
					            ciphertext.asByteArray(),
 | 
				
			||||||
 | 
					            tag.asByteArray(),
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            message.size.toLong(),
 | 
				
			||||||
 | 
					            nonce.asByteArray(),
 | 
				
			||||||
 | 
					            recipientsPublicKey.asByteArray(),
 | 
				
			||||||
 | 
					            sendersSecretKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return BoxEncryptedDataAndTag(ciphertext, tag)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * The crypto_box_open_detached() function verifies and decrypts an encrypted message c whose length is clen using the recipient's secret key sk and the sender's public key pk.
 | 
				
			||||||
 | 
					     * clen doesn't include the tag, so this length is the same as the plaintext.
 | 
				
			||||||
 | 
					     * The plaintext is put into m after verifying that mac is a valid authentication tag for this ciphertext, with the given nonce n and key k.
 | 
				
			||||||
 | 
					     * The function throws [BoxCorruptedOrTamperedDataException] if the verification fails.
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    actual fun openDetached(
 | 
				
			||||||
 | 
					        ciphertext: UByteArray,
 | 
				
			||||||
 | 
					        tag: UByteArray,
 | 
				
			||||||
 | 
					        nonce: UByteArray,
 | 
				
			||||||
 | 
					        sendersPublicKey: UByteArray,
 | 
				
			||||||
 | 
					        recipientsSecretKey: UByteArray
 | 
				
			||||||
 | 
					    ): UByteArray {
 | 
				
			||||||
 | 
					        val message = UByteArray(ciphertext.size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        val validationResult = sodium.crypto_box_open_detached(
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.asByteArray(),
 | 
				
			||||||
 | 
					            tag.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.size.toLong(),
 | 
				
			||||||
 | 
					            nonce.asByteArray(),
 | 
				
			||||||
 | 
					            sendersPublicKey.asByteArray(),
 | 
				
			||||||
 | 
					            recipientsSecretKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (validationResult != 0) {
 | 
				
			||||||
 | 
					            throw BoxCorruptedOrTamperedDataException()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return message
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    actual fun seal(message: UByteArray, recipientsPublicKey: UByteArray): UByteArray {
 | 
				
			||||||
 | 
					        val ciphertextWithPublicKey = UByteArray(message.size + crypto_box_SEALBYTES)
 | 
				
			||||||
 | 
					        sodium.crypto_box_seal(
 | 
				
			||||||
 | 
					            ciphertextWithPublicKey.asByteArray(),
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            message.size.toLong(),
 | 
				
			||||||
 | 
					            recipientsPublicKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return ciphertextWithPublicKey
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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 validationResult = sodium.crypto_box_seal_open(
 | 
				
			||||||
 | 
					            message.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.asByteArray(),
 | 
				
			||||||
 | 
					            ciphertext.size.toLong(),
 | 
				
			||||||
 | 
					            senderPublicKey.asByteArray(),
 | 
				
			||||||
 | 
					            recipientsSecretKey.asByteArray()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (validationResult != 0) {
 | 
				
			||||||
 | 
					            throw BoxCorruptedOrTamperedDataException()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return message
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -60,7 +60,7 @@ actual object SecretStream {
 | 
				
			|||||||
            associatedData.size.toLong()
 | 
					            associatedData.size.toLong()
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        if (validationResult != 0) {
 | 
					        if (validationResult != 0) {
 | 
				
			||||||
            throw SecretStreamCorrupedOrTamperedDataException()
 | 
					            throw SecretStreamCorruptedOrTamperedDataException()
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return DecryptedDataAndTag(result, tagArray[0])
 | 
					        return DecryptedDataAndTag(result, tagArray[0])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,5 @@
 | 
				
			|||||||
package com.ionspin.kotlin.crypto.box
 | 
					package com.ionspin.kotlin.crypto.box
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.ionspin.kotlin.crypto.util.toHexString
 | 
					 | 
				
			||||||
import com.ionspin.kotlin.crypto.util.toPtr
 | 
					import com.ionspin.kotlin.crypto.util.toPtr
 | 
				
			||||||
import kotlinx.cinterop.convert
 | 
					import kotlinx.cinterop.convert
 | 
				
			||||||
import kotlinx.cinterop.pin
 | 
					import kotlinx.cinterop.pin
 | 
				
			||||||
@ -326,7 +325,7 @@ actual object Box {
 | 
				
			|||||||
        messagePinned.unpin()
 | 
					        messagePinned.unpin()
 | 
				
			||||||
        recipientsPublicKeyPinned.unpin()
 | 
					        recipientsPublicKeyPinned.unpin()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return message
 | 
					        return ciphertextWithPublicKey
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -361,4 +360,4 @@ actual object Box {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user